Problem I2C @ ESP32-CAM and setup PCF8574A

Home Forums esp32 Problem I2C @ ESP32-CAM and setup PCF8574A

Tagged: ,

Viewing 4 reply threads
  • Author
    Posts
    • #31937
      MAWMN
      Participant
        
        /************************************************/
        /***** I2C library for PCF8574 (XREEF)      *****/
        /***** I2C chip = PCA8574A – addr 0x38       *****/
        /***** with A0=x, A1=x, A2=x (x= GND)        *****/
        /************************************************/
        /***** ESP32-CAM I2C bus uses pins:          *****/
        /***** GPIO15 = SCL (ESP32_CAM)              *****/
        /***** GPIO14 = SDA (ESP32_CAM)              *****/
        /************************************************/
        

        Problem I2C @ ESP32-CAM (AI Thinker Board)
        cpp

        
        #include <Wire.h>
        
        #define SCL 15 // IO15 GPIO15 HSPI_WSO HS2_CMD SD-Conn
        #define SDA 14 // IO14 GPIO14 HSPI_CLK HS2_CLK SD-Conn
        
        #include "PCF8574.h" // PCF8574 library @ 2.3.7
        #define PCF_INTERRUPT 0 // IO0 GPIO0 CAM_PIN_XCLK or CSI_MCLK (Interrupt pin for Encoder & Switch)
        
        // Pre-formatted Header for the Interrupt (See initialization of updateEncoder Interrupt Below),
        // necessary because of the Interrupt initialization in the next line
        void IRAM_ATTR updateEncoder(); // ! *** IRAM_ATTR because this is the ISR !!!
        
        // Initialize PCF-library Interrupt
        PCF8574 pcf8574(0x38, PCF_INTERRUPT, updateEncoder); // for Default I2C Pins
        

        Result:

        • Init pcf8574…begin(sda, scl) -> 21 22
        • Using interrupt pin (not all pins support interrupts)
        • STATUS –> 4
        • NOT OK <== Wrong SDA and SCL port

        After Change

        
        #include <Wire.h>
        
        #define SCL 15 // IO15 GPIO15 HSPI_WSO HS2_CMD SD-Conn
        #define SDA 14 // IO14 GPIO14 HSPI_CLK HS2_CLK SD-Conn
        
        #include "PCF8574.h" // PCF8574 library @ 2.3.7
        #define PCF_INTERRUPT 0 // IO0 GPIO0 CAM_PIN_XCLK or CSI_MCLK (Interrupt pin for Encoder & Switch)
        
        // Pre-formatted Header for the Interrupt (See initialization of updateEncoder Interrupt Below),
        // necessary because of the Interrupt initialization in the next line
        void IRAM_ATTR updateEncoder(); // ! *** IRAM_ATTR because this is the ISR !!!
        
        // Initialize PCF-library SDA & SCL
        PCF8574 pcf8574(0x38, SDA, SCL);
        
        


        Question:
        How to also setup the PCF_INTERRUPT?

        Result:

        • Init pcf8574…begin(sda, scl) -> 14 15 <== This is OK now
        • But also need the Interrupt setup. How to do this?
        • STATUS –> 4
        • NOT OK <== Why is it still showing NOT OK?
        • This topic was modified 10 months, 1 week ago by Renzo Mischianti. Reason: reformat
      • #31944
        Renzo Mischianti
        Keymaster

          Hi,
          for the interrupt you can use this constructor:

          
          	PCF8574(uint8_t address, int sda, int scl, uint8_t interruptPin,  void (*interruptFunction)());
          

          And the code become like so

          
          #define INTERRUPTED_PIN D7
           
          void ICACHE_RAM_ATTR interruptFunction();
           
          // initialize library
          PCF8574 pcf8574(0x38, SDA, SCL, INTERRUPTED_PIN, interruptFunction);
          

          Bye Renzo

          • #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

          • #31966
            MAWMN
            Participant

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

            • #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..
                }
              • #32090
                LillianSkye
                Participant

                  It helped me, Thank you.

                  • #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

                Viewing 4 reply threads
                • You must be logged in to reply to this topic.
                Exit mobile version