Forum Replies Created

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • in reply to: Problem I2C @ ESP32-CAM and setup PCF8574A #32091
    MAWMN
    Participant

      Hello, can you be more specific, were you able to solve my problem ?? because I still did not find the solution for the reported errr : [ 55886][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263 ??

      thanks

      in reply to: Problem I2C @ ESP32-CAM and setup PCF8574A #31970
      MAWMN
      Participant

        Still Struggeling..

        Trying to reconfig SDA & SCL to NON Default pins on ESP32-CAM AI-Thinker board, NOT Working for PCF8574 Library, does work at the same time for U8g2 Library ?
        
        gives problems with the PCF8574 while the SSD display works fine with it: 
        Monitoring loop Started..
        Init pcf8574...OK
        but after constantly changing the content of the display (Seconds wise), all interrupts of the PCF8574 give :
        [ 55886][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263 
        
        #include <Arduino.h>
        #include <stdint.h>
        #include <esp_camera.h>
        
        //* for I2C
        #include <Wire.h> 
        TwoWire I2C_PINS_NON_DEFAULT = Wire;   // Try to reconfig the wire Lib to use NON Default Pins
        
        #define SCL 15                         // IO15  GPIO15  HSPI_WSO  HS2_CMD     SD-Conn
        #define SDA 14                         // IO14  GPIO14  HSPI_CLK  HS2_CLK     SD-Conn
        
        #define SETBUSSPEED                    // We do want to set the BusSpeed
        #undef SETBUSSPEED                     // We do NOT want to set the BusSpeed
        
        #ifdef SETBUSSPEED
          #define BUSSPEED 100000U             // BusSpeed = 100.000 kHz
          // #define BUSSPEED 400000U             // BusSpeed = 400.000 kHz
        #endif
        
        //* SDD1306 Config
        #include <U8x8lib.h>    // I2C (Maximum Speed SCL +/- 400 kHz)                                      // ! Text Only Library
        U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // ! Text Only (from long list)
        
        //* PCF8574 MultiClick
        #include "PCF8574.h"
        #define PCF_INTERRUPT 0				         // IO0   GPIO0   CAM_PIN_XCLK or CSI_MCLK (Interrupt pin for Encoder & Switch)
        
        // * RotaryEncoder defines (Connected to PCF8574)
        #define encoderPinA  			P0
        #define encoderPinB  			P1
        #define switchPin					P2
        
        // Forward declaration for the Interrupt (See Initialisation of isr_updateEncoder ISR Below), 
        //   necessary here because of the Interrupt Initialisation in the next Line
        void IRAM_ATTR isr_updateEncoder();	
        
        // Initialize PCF-library for used address, SDA & SCL, Interrupt function
        PCF8574 pcf8574(0x38, SDA, SCL, PCF_INTERRUPT, isr_updateEncoder);
          
        
        void IRAM_ATTR isr_updateEncoder() {
          //! DO NOT Read pcf8574.readEncoderValue(encoderPinA, encoderPinB, &encoderValue);
          //!         and pcf8574.digitalRead(switchPin); in the isr_updateEncoder() function here !!!
          //!  this will cause "Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)"
          //!  Keep the interrupt function as short as possible and only set a flag here !!!
          //!  Next in the main loop() DO Read these values by the function getEncValues() and checkButton() !!!
          changed = true;
        }
        
        void ClrScr() {
          // ! *** See : https://github.com/olikraus/u8g2/wiki/u8x8reference
          u8x8.clear();
          delay(50);
          u8x8.clearDisplay();
          delay(50);
          u8x8.setFont(u8x8_font_chroma48medium8_r);      // Normal=1, Larger=2, largest=3, :1 pixel scale
          delay(50);                                      // See : https://github.com/olikraus/u8g2/wiki/fntlist8x8
          u8x8.print("");                                 // Draw text
          delay(50);
          u8x8.flush();
          delay(50);
        }
        
        void Display_Init() {    // ! *** Text Only
          u8x8.begin();                               // Start the Display Object, with NO PowerSaving
          delay(250);                                 // ! *** Extended delay 50 ==> 250 : See datasheet 18-12-2023 page 18 & 32
          u8x8.initDisplay();
          delay(50);         
          u8x8.setPowerSave(0);                       // Seems essentieel, for correct new start !!!
          delay(50);
          ClrScr();
        }
        
        void Display_Text(byte XPos, byte YPos, bool Invert, byte FieldSize, String MyText) {
          // u8x8 library only has LineMode (TEXT Only), for graphics use u8g2 library !!!
          // ! *** When using Graphics we are adressing X and y at pixel level !!!
          // ! *** When using Text Only we are adressing X and y at line level !!!
          // Set Font
          u8x8.setFont(u8x8_font_chroma48medium8_r);    // Small FontSize - 16 char/line
                                                        // See : https://github.com/olikraus/u8g2/wiki/fntlist8x8
        
          // Set Normal / Inverse
          if (Invert == false) {
            u8x8.setInverseFont(0);                     // Draw 'normal' text
          } else {
            u8x8.setInverseFont(1);                     // Draw 'inverse' text
          }
        
          String NewStr = MyText; // Set for when FieldSize is set to 0 (NO Size Control) OR Correct !!!
          if (FieldSize != 0) {
            // Control the Length of the Text Field
            if (MyText.length() > FieldSize) {
              // MyText too long
              NewStr = "";
              for (size_t i = 1; i < FieldSize; i++) NewStr = NewStr + MyText[i];
            }
        
            if (MyText.length() < FieldSize) {
              // MyText too short
              NewStr = MyText;
              while (NewStr.length() < FieldSize) NewStr = NewStr + " ";
            }
          }
          u8x8.drawString(XPos, YPos, NewStr.c_str());
          u8x8.flush();
        }
        
        void setup() {
          //* Init Serial
          Serial.begin(115200);
          delay(3000);              //! We Need at least 3 seconds to start up the serial port for monitoring @ ESP32-Cam in PlatformIO !!!
        
          I2C_PINS_NON_DEFAULT.begin(SDA, SCL);
        
          //* Init OLED-Display
          Display_Init();           // Initialize the display and Start Showing the Information
        
          // Show texts @ the SSD Display
          mText = "Config.Finished.";
          Display_Text(0, 1, false, 16, mText);
        
          mText = "M.A.W.M. Nijland";
          Display_Text(0, 3, false, 16, mText);
        
          mText = "Apeldoorn - 2024";
          Display_Text(0, 5, false, 16, mText);
        
          Serial.println("\nMonitoring loop Started..");
          Serial.flush();
        
          //* Initialize ESP-CAM Interrupt Input
          pinMode(PCF_INTERRUPT, INPUT_PULLUP);
        
        	//* Init PCF8574 pins	
          pcf8574.pinMode(encoderPinA, INPUT_PULLUP);   // Encoder A
          pcf8574.pinMode(encoderPinB, INPUT_PULLUP);   // Encoder B
        
        	// Encoder pins
        	pcf8574.encoder(encoderPinA, encoderPinB);
        
        	// Encoder button
        	pcf8574.pinMode(switchPin, INPUT_PULLUP);
        
          delay(100);
        
        	// Start the PCF8574 library
        	Serial.print("Init pcf8574...");
        	if (pcf8574.begin(0x38)) {
        		// Board/Chip is Acknowledging the I2C Commands
        		Serial.println("OK");
        	} else {
        		// Board/Chip is NOT Acknowledging the I2C Commands
        		Serial.println("NOT OK");
        	}
        }
        
        loop() {
          // etc. etc..
        }
        in reply to: Problem I2C @ ESP32-CAM and setup PCF8574A #31966
        MAWMN
        Participant

          obviously my upload was to big so I repacked it again : sorry for this

          Attachments:
          You must be logged in to view attached files.
          in reply to: Problem I2C @ ESP32-CAM and setup PCF8574A #31965
          MAWMN
          Participant

            In the mean time I have also tested my last code with esp8266, and this works flawlossly, without any error, so why is the esp32 giving me a problem with the Wire library (Timeout)
            “[392120][E][Wire.cpp:513] requestFrom(): i2cRead returned Error 263”

            thanks, MAWMN

            in reply to: PCF8574 how to add / use encoder with multiclick #29086
            MAWMN
            Participant

              Hello,
              just finnished my demo project, see the code below, perhaps also nice to use as an example :

              thanks and bye..

              
              /*
               * PCF8574 GPIO Port Expander
               * https://www.mischianti.org/2020/03/13/pcf8574-i2c-digital-i-o-expander-rotary-encoder-part-2/
               *
               * Connection Overview
               * PCF8574 —- WeMos-D1
               * A0 —- GND
               * A1 —- GND
               * A2 —- GND
               * VSS —- GND
               * VDD —- 5V/3.3V
               * SDA —- D1(PullUp) // GEEL
               * SCL —- D2(PullUp) // GROEN
               * INT —- INT(PullUp) // WIT
               *
               * PCF8574 —- Rot.Encoder
               * P0 —- ENCODER PIN A
               * P1 —- ENCODER PIN B
               * P2 —- ENCODER BUTTON
               *
               */
              #include "Arduino.h"
              #include "PCF8574.h"
              
              // * Wemos-D1 defines
              #define sdaPin D1 // This is the default Pin for Wemos-D1
              #define sclPin D2 // This is the default Pin for Wemos-D1
              // #define sdaPin D5 // ! NOT the default Pin - NOT WORKING @ Wemos-D1 ???
              // #define sclPin D6 // ! NOT the default Pin - NOT WORKING @ Wemos-D1 ???
              #define INTERRUPTED_PIN D3 // Wemos-D1 pin (D3 = Interrupt pin for Encoder)
              
              // * RotaryEncoder defines (Connected to PCF8574)
              #define encoderPinA P0
              #define encoderPinB P1
              #define switchPin P2
              
              // Pre formatted Header for Interrupt (See Initialisation of updateEncoder Interrupt Below),
              // necessary here because of the Interrupt Initialisation in the next Line
              void IRAM_ATTR updateEncoder(); // ! *** IRAM_ATTR because this is the ISR !!!
              
              // Initialize PCF-library Interrupt
              PCF8574 pcf8574(0x38, INTERRUPTED_PIN, updateEncoder); // for Default I2C Pins
              // PCF8574 pcf8574(0x38, sdaPin, sclPin, INTERRUPTED_PIN, updateEncoder); // ! NOT the default Pins - NOT WORKING @ Wemos-D1 ???
              
              // Initialize Rot.Encoder Global variables
              volatile long encoderValue = 0;
              uint8_t encoderButtonVal = HIGH;
              
              bool changed = false;
              
              /*****************************************/
              /***** MULTICLICK_DEBUG_PRINT MACRO *****/
              /*****************************************/
              // ? Uncomment to enable printing out nice debug messages.
              // ? #define MULTICLICK_DEBUG
              #define MULTICLICK_DEBUG
              
              // Define where debug output will be printed.
              #define MULTICLICK_PRINTER Serial
              
              // Setup DEBUG printing MACRO
              #ifdef MULTICLICK_DEBUG
              #define MULTICLICK_DEBUG_PRINT(...) { MULTICLICK_PRINTER.print(__VA_ARGS__); }
              #define MULTICLICK_DEBUG_PRINTLN(...) { MULTICLICK_PRINTER.println(__VA_ARGS__); }
              #else
              #define MULTICLICK_DEBUG_PRINT(...) {}
              #define MULTICLICK_DEBUG_PRINTLN(...) {}
              #endif
              
              //**********************************************************************/
              //! *** Additions tbv MULTI-CLICK: One Button with Multiple Events !!! */
              //**********************************************************************/
              #define maxMulticlickGap 1000 // Time where in between the multiclick must remain
              #define maxLongPress 2000 // Max time in ms. to wait berfore clearing the firstPressTS
              
              bool btnPressed = false;
              bool btnReleased = true;
              int lastBtnState = 0;
              uint32 firstPressTS = 0; // Timestamp of the first btnPress moment
              int clicksCnt = -1; // Count the number of Clicks before the firstPressTS Reset occurs (-1 = OFF)
              bool clickHandled = false;
              //**********************************************************************/
              
              //******************************************************************/
              //! ***** !!! ISR Functie tbv Encoder ButtonTurn & ButtonPress !!! */
              //******************************************************************/
              uint8_t encoderPinALast = LOW;
              uint8_t valPrecEncoderButton = LOW;
              
              void updateEncoder() { // ! *** IRAM_ATTR NOT necessary here for ISR !!!
              // Encoder management
              	uint8_t n = pcf8574.digitalRead(encoderPinA);
              	if ((encoderPinALast == LOW) && (n == HIGH)) {
              		if (pcf8574.digitalRead(encoderPinB) == LOW) {
              // * ClockWise
              			encoderValue++; // ! if we need to change counting for CW & CCW, we need to do it here
              			changed = true; // Changed the value of the encoder
              		} else {
              // * Counter ClockWise
              			encoderValue--; // ! if we need to change counting for CW & CCW, we need to do it here
              			changed = true; // Changed the value of the encoder
              		}
              	}
              	encoderPinALast = n;
              
              // Button management
              	encoderButtonVal = pcf8574.digitalRead(switchPin);
              	if (encoderButtonVal != valPrecEncoderButton) {
              // Changed the value of button
              		changed = true;
              		valPrecEncoderButton = encoderButtonVal;
              	}
              }
              
              //**********************************************************************/
              //! *** Additions tbv MULTI-CLICK: One Button with Multiple Events !!! */
              //**********************************************************************/
              void checkButton(bool buttonVal) {
              	if (buttonVal == 0) {
              		btnPressed = true;
              		btnReleased = false;
              	} else {
              		btnPressed = false;
              		btnReleased = true;
              	}
              
              	if (btnPressed == true) {
              		MULTICLICK_DEBUG_PRINTLN("btnPressed..");
              		if (firstPressTS == 0) {
              			firstPressTS = millis();
              			MULTICLICK_DEBUG_PRINT("firstPressTS set to - ");
              			MULTICLICK_DEBUG_PRINTLN(firstPressTS);
              			clicksCnt = 0;
              		}
              	} else if (btnReleased == true) {
              		MULTICLICK_DEBUG_PRINTLN("btnReleased..");
              	}
              
              	if (lastBtnState != buttonVal) {
              // There is a change in State
              		if (btnReleased == true) {
              // Take action when the button is being Released
              			if ((millis() - firstPressTS) < maxMulticlickGap) {
              				clicksCnt += 1;
              			}
              		}
              	}
              
              	lastBtnState = buttonVal;
              }
              
              // MultiClick Events to trigger
              void singleClickEvent() {
              	MULTICLICK_DEBUG_PRINTLN("Perform singleClickEvent");
              	clickHandled = true;
              }
              
              void doubleClickEvent() {
              	MULTICLICK_DEBUG_PRINTLN("Perform doubleClickEvent");
              	clickHandled = true;
              }
              
              void tripleClickEvent() {
              	MULTICLICK_DEBUG_PRINTLN("Perform tripleClickEvent");
              	clickHandled = true;
              }
              
              void longPressEvent() {
              	MULTICLICK_DEBUG_PRINTLN("Perform longPressEvent");
              	clickHandled = true;
              }
              //**********************************************************************/
              
              //******************************************************/
              //***** Application Setup.. *****/
              //******************************************************/
              void setup() {
              	/**************************/
              	/***** StartUp Serial *****/
              	/**************************/
              	Serial.begin(115200);
              	Serial.println();
              	Serial.flush();
              	delay(1000);
              
              	/*****************************************************/
              	/***** I2C Setup, Encoder Setup *****/
              	/*****************************************************/
              // pcf8574.begin(); // ! ???? DO we NEED This, works also without defining for using the default I2C Pins ????
              // Setup PCF8574 pins
              	pcf8574.pinMode(encoderPinA, INPUT_PULLUP);
              	pcf8574.pinMode(encoderPinB, INPUT_PULLUP);
              
              // Setup Encoder Switch button
              	pcf8574.pinMode(switchPin, INPUT_PULLUP);
              
              // Set low latency with this method or uncomment LOW_LATENCY define in the library
              // Needed for the Encoder
              	pcf8574.setLatency(0);
              
              // Start the PCF8574 library
              	MULTICLICK_DEBUG_PRINT("Init pcf8574…");
              	if (pcf8574.begin()) {
              // Board/Chip is Acknowledging the I2C Commands
              		MULTICLICK_DEBUG_PRINTLN("OK");
              	} else {
              // Board/Chip is NOT Acknowledging the I2C Commands
              		MULTICLICK_DEBUG_PRINTLN("NOT OK");
              	}
              }
              
              //******************************************************/
              //***** Application MAIN Loop.. *****/
              //******************************************************/
              void loop() {
              	if (changed) {
              		MULTICLICK_DEBUG_PRINT("ENCODER -> ");
              		MULTICLICK_DEBUG_PRINT(encoderValue);
              		MULTICLICK_DEBUG_PRINT(" - BUTTON -> ");
              		MULTICLICK_DEBUG_PRINT(encoderButtonVal ? "HIGH -> " : "LOW -> ");
              
              // Get button event and act accordingly
              		checkButton(encoderButtonVal);
              
              		changed = false;
              	}
              
              // handling of the checkButton() function - firstPressTS is running..
              	if (firstPressTS != 0) {
              // Perform ClickEvents based on maxMulticlickGap
              		if ((millis() - maxMulticlickGap) >= firstPressTS) {
              			if (clicksCnt == 1)
              				singleClickEvent();
              			if (clicksCnt == 2)
              				doubleClickEvent();
              			if (clicksCnt == 3)
              				tripleClickEvent();
              			if (clicksCnt <= 3) {
              				clicksCnt = 0;
              			}
              		}
              
              		if ((millis() - maxLongPress) >= firstPressTS) {
              // MULTICLICK_DEBUG_PRINT("numClicks : ");
              // MULTICLICK_DEBUG_PRINTLN(clicksCnt);
              			if (clicksCnt >= 4) {
              // number of clicks out of range
              				MULTICLICK_DEBUG_PRINTLN("numClicks Out of Range..");
              			} else if ((clicksCnt == 0) && (clickHandled == false))
              				longPressEvent();
              
              // Clear firstPressTS to stopped..
              			MULTICLICK_DEBUG_PRINT("firstPressTS cleared @ ");
              			MULTICLICK_DEBUG_PRINTLN(millis());
              			firstPressTS = 0;
              			clicksCnt = 0;
              			clickHandled = false;
              		}
              	}
              }
              
              
              • This reply was modified 1 year, 2 months ago by Renzo Mischianti. Reason: Format code
            Viewing 5 posts - 1 through 5 (of 5 total)