Troubleshooting

ESP32-S3 i2c for RGB sensor

userHead Thomas.Sepe 2024-04-03 10:58:37 260 Views1 Replies

I can't get this code to work! I get no response at all when I send an “r” with carriage return. It should report back the 3 values for R, G, B, but It seems like my serial command doesn't even get sent. 

this code works fine withe an esp32-e but not with the esp32-s3. what am I doing wrong?


//This code will output data to the Arduino serial monitor.
//Type commands into the Arduino serial monitor to control the EZO RGB.

#include <Wire.h>                //enable I2C.
#define SDA1_Pin 1               // select ESP32  I2C pins
#define SCL1_Pin 2
#define address 112              //default I2C ID number for EZO RGB.

char computerdata[20];           //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte received_from_computer = 0; //we need to know how many characters have been received.
byte serial_event = 0;           //a flag to signal when data has been rRGBeived from the pc/mac/other.
byte code = 0;                   //used to hold the I2C response code.
char RGB_data[32];               //we make a 32 byte character array to hold incoming data from the RGB circuit. This is the max I2C input buffer size for an Arduino
byte in_char = 0;                //used as a 1 byte buffer to store inbound bytes from the RGB Circuit.
byte i = 0;                      //counter used for RGB_data array.
int time_ = 250;                 //used to change the delay needed depending on the command sent to the EZO Class RGB Circuit.

void setup()                     //hardware initialization.
{
 Serial.begin(115200);          //enable serial port.
 Serial.println("starting comms");
 Wire.begin(SDA1_Pin, SCL1_Pin);                //enable I2C port. (SDA pin, SDL pin)
}

void serialEvent() {                                                              //this interrupt will trigger when the data coming from the serial monitor(pc/mac/other) is received.
 received_from_computer = Serial.readBytesUntil(13, computerdata, 20);           //we read the data sent from the serial monitor(pc/mac/other) until we see a <CR>. We also count how many characters have been received.
 computerdata[received_from_computer] = 0;                                       //stop the buffer from transmitting leftovers or garbage.
 serial_event = true;                                                            //set the serial event flag.
 Serial.println("there is a serial event");
}

void loop() {                                                                     //the main loop.
 if (serial_event == true) {                                                     //if a command was sent to the EZO device.
   Serial.println("is true");
   for (i = 0; i <= received_from_computer; i++) {                               //set all char to lower case, this is just so this exact sample code can recognize the "sleep" command.
     computerdata[i] = tolower(computerdata[i]);                                 //"Sleep" ≠ "sleep"
   }
   i = 0;                                                                        //reset i, we will need it later


   Wire.beginTransmission(address);                                              //call the circuit by its ID number.
   Wire.write(computerdata);                                                     //transmit the command that was sent through the serial port.
   //Wire.endTransmission();     //end the I2C data transmission.
   int result = Wire.endTransmission();
   Serial.println(result);

   if (result != 0) {
     Serial.print("I2C transmission error: ");
     Serial.println(result);
     // Handle error, e.g., retry
   } else {


     if (strcmp(computerdata, "sleep") != 0) {                                     //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.
       //if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the RGB circuit.

       delay(time_);                                                               //wait the correct amount of time for the circuit to complete its instruction.

       Wire.requestFrom(address, 32, 1);                                           //call the circuit and request 32 bytes (this could be too small, but it is the max i2c buffer size for an Arduino)
       code = Wire.read();                                                         //the first byte is the response code, we read this separately.

       switch (code) {                           //switch case based on what the response code is.
         case 1:                                 //decimal 1.
           Serial.println("Success");            //means the command was successful.
           break;                                //exits the switch case.

         case 2:                                 //decimal 2.
           Serial.println("Failed");             //means the command has failed.
           break;                                //exits the switch case.

         case 254:                               //decimal 254.
           Serial.println("Pending");            //means the command has not yet been finished calculating.
           break;                                //exits the switch case.

         case 255:                               //decimal 255.
           Serial.println("No Data");            //means there is no further data to send.
           break;                                //exits the switch case.
       }

       while (Wire.available()) {                 //are there bytes to receive.
         in_char = Wire.read();                   //receive a byte.
         RGB_data[i] = in_char;                   //load this byte into our array.
         i += 1;                                  //incur the counter for the array element.
         if (in_char == 0) {                      //if we see that we have been sent a null command.
           i = 0;                                 //reset the counter i to 0.
           break;                                 //exit the while loop.
         }
       }

       Serial.println(RGB_data);                  //print the data.
       Serial.println();                          //this just makes the output easier to read by adding an extra blank line
     }
     serial_event = false;                        //reset the serial event flag.
   }
 }

}
 

2024-04-04 11:22:29

I solved the problem. the esp32-S3 does not do on serialEvent interrupts. so I took everything in the serialEvent functiovn and put it inside the loop. solution below:
 

 

void loop() { //the main loop.

 

while (Serial.available()) {

received_from_computer = Serial.readBytesUntil(13, computerdata, 20); //we read the data sent from the serial monitor(pc/mac/other) until we see a <CR>. We also count how many characters have been received.

computerdata[received_from_computer] = 0; //stop the buffer from transmitting leftovers or garbage.

 

for (i = 0; i <= received_from_computer; i++) { //set all char to lower case, this is just so this exact sample code can recognize the "sleep" command.

computerdata[i] = tolower(computerdata[i]); //"Sleep" ≠ "sleep"

}

i = 0; //reset i, we will need it later

 

Wire.beginTransmission(address); //call the circuit by its ID number.

Wire.write(computerdata); //transmit the command that was sent through the serial port.

Wire.endTransmission(); //end the I2C data transmission.
 

if (strcmp(computerdata, "sleep") != 0) { //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.

//if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the RGB circuit.


 

delay(time_); //wait the correct amount of time for the circuit to complete its instruction.


---- rest of code
}

 

 


 

userHeadPic Thomas.Sepe