espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.63k stars 7.41k forks source link

Rebooting and Unable to use two ADS1115 in single I2C port #9375

Closed Murugesh-Hobbyist closed 5 months ago

Murugesh-Hobbyist commented 8 months ago

Board

ESP32S3

Device Description

ESP32S3 connected with 2-ADS1115 @ 39 and 40th pins for I2C one with (0x48) another with (0x49)

Hardware Configuration

for I2C,

define SDA0_Pin 39

define SCL0_Pin 40

Version

v2.0.14

IDE Name

Arduino IDE

Operating System

Windows-11

Flash frequency

80

PSRAM enabled

yes

Upload speed

921600

Description

I can point the address of those ADC boards and read the analog values. but if I call them in a if statement, it throws error for the second ADS1115. address for the first one, im using (0x48) and the seond with, (0x49) if i use the board with (0x48), i get no issues but if i fetch for the (0x49) im getting

_Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.

Core 0 register dump: PC : 0x420021cf PS : 0x00060830 A0 : 0x8200207c A1 : 0x3fcebdf0
A2 : 0x003c0301 A3 : 0x3fc95392 A4 : 0x00000003 A5 : 0x00000001
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x820024a4 A9 : 0x3fcebdd0
A10 : 0x3fc91e7c A11 : 0x3c03302c A12 : 0x00000002 A13 : 0xffffffff
A14 : 0x00ff0000 A15 : 0xff000000 SAR : 0x00000015 EXCCAUSE: 0x0000001c
EXCVADDR: 0x003c030d LBEG : 0x400570e8 LEND : 0x400570f3 LCOUNT : 0x00000000

Backtrace: 0x420021cc:0x3fcebdf0 0x42002079:0x3fcebe10 0x420020ab:0x3fcebe30 0x4200215a:0x3fcebe50 0x42001b9d:0x3fcebe70 0x42001c9e:0x3fcebe90 0x42003f2d:0x3fcebeb0

ELF file SHA256: a29005a4d446cba5 Rebooting... �ESP-ROM:esp32s3-20210327 Build:Mar 27 2021 rst:0xc (RTC_SW_CPU_RST),boot:0x28 (SPI_FAST_FLASHBOOT) Saved PC:0x403770f0 SPIWP:0xee mode:DIO, clock div:1 load:0x3fce3808,len:0x44c load:0x403c9700,len:0xbd8 load:0x403cc700,len:0x2a80 entry 0x403c98d0

Sketch

//---------------------------------------------------------Dual_Core_Locking----------------------------------------------------------------------

#if defined(ESP_PLATFORM)
TaskHandle_t task_loop1;
void esploop1(void* pvParameters) {
  setup1();
  for (;;) loop1();
}
#endif

#if defined(ARDUINO_ARCH_MBED_RP2040) || defined(ARDUINO_ARCH_RP2040)
#include <FreeRTOS.h>
#include <semphr.h>
#define xPortGetCoreID get_core_num
#endif

SemaphoreHandle_t bigLock = NULL;

void bigLock_lock() {
  while ((bigLock == NULL) || (xSemaphoreTake(bigLock, (TickType_t)0) == pdFALSE)) { delay(1); }
}

void bigLock_unlock() {
  xSemaphoreGive(bigLock);
}

int count0, count1, rnum;

void set_rnum(int r) {
  bigLock_lock();
  rnum = r;
  bigLock_unlock();
}

int get_rnum() {
  bigLock_lock();
  int r = rnum;
  bigLock_unlock();
  return r;
}

//--------------------------------------------------------I2C-Communication-------------------------------------------------------------------------

#include <Wire.h>
#define SDA0_Pin 39
#define SCL0_Pin 40

//----------------------------------------------------------ADC-ADS1115-----------------------------------------------------------------------------

#include <Adafruit_ADS1X15.h>
Adafruit_ADS1115 ads1;  
Adafruit_ADS1115 ads2;
const byte analogPin = A0;

//----------------------------------------------------------UART-Serial-----------------------------------------------------------------------------
#define rxPin 41
#define txPin 42
HardwareSerial &dwinSerial = Serial2;

//----------------------------------------------------------Dwin-Display------------------------------------------------------------------------------

unsigned char Buffer[9];
byte green[] = { 0x5A, 0xA5, 0x05, 0x82, 0x53, 0x00, 0x00, 0x08 };
byte red[] = { 0x5A, 0xA5, 0x05, 0x82, 0x53, 0x00, 0x00, 0x09 };
byte textoff[] = { 0x5A, 0xA5, 0x08, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

unsigned char incomingData[100];
unsigned char textString[100];  // Chars to send
char receivedFloatArray[50];    // Array created from the useful part of the received char
float receivedFloat;            // float converted from the above array using atof ( )
int check = 1;
float setval = 0;
int analogReading;
float floatVoltageValue;  // ADC analog value converted into voltage (stored as float)
long adcTimer;            //Read and update ADC value every x milliseconds only
bool isit = true;
float tolerance = 0;

//-------------------------------------------------------------Setup-----------------------------------------------------------------------------

void setup() {

  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);

  Wire.begin(SDA0_Pin, SCL0_Pin);
  Serial.begin(115200);
  dwinSerial.begin(115200, SERIAL_8N1,rxPin, txPin);

  while (!Serial) { delay(1); }

#if defined(ESP_PLATFORM)
  xTaskCreatePinnedToCore(
    esploop1,               /* Task function. */
    "loop1",                /* name of task. */
    10000,                  /* Stack size of task */
    NULL,                   /* parameter of the task */
    1,                      /* priority of the task */
    &task_loop1,            /* Task handle to keep track of created task */
    !ARDUINO_RUNNING_CORE); /* pin task to core 0 */
#endif

  bigLock = xSemaphoreCreateMutex();
  count0 = 0;
  count1 = 0;

  Serial.println("DWIN — display — printing numbers");

 // ads.setGain(GAIN_ONE);  // ads.setGain(); ads.setGain(GAIN_SIXTEEN);

  if (!ads1.begin(0x48)) {
    Serial.println("1Failed to initialize ADS.");
    while (1);
  }  

  if (!ads2.begin(0x49)) {
    Serial.println("2Failed to initialize ADS.");
    while (1);
  }

  delay(500);
}

void loop() {
  fetchText();
  readADC();
}

void setup1() {  
  /*

  Wire.begin(SDA0_Pin, SCL0_Pin);

  if (!ads2.begin(0x49)) {
    Serial.println("2Failed to initialize ADS.");
    while (1);
  }

*/
}

void loop1() {

/*
  int16_t  adc5, adc6, adc7, adc8 ;
  float volts5, volts6, volts7, volts8 ;
  adc5 = ads2.readADC_SingleEnded(0);
//  adc6 = ads2.readADC_SingleEnded(1);
//  adc7 = ads2.readADC_SingleEnded(2);
//  adc8 = ads2.readADC_SingleEnded(3);
*/

}

//-------------------------------------------------------------readADC-----------------------------------------------------------------------------

void readADC() {

  int16_t adc1, adc2, adc3, adc4, adc5, adc6, adc7, adc8 ;
  float volts1, volts2, volts3, volts4, volts5, volts6, volts7, volts8 ;

 // adc1 = ads1.readADC_SingleEnded(0);
 // adc2 = ads1.readADC_SingleEnded(1);
 // adc3 = ads1.readADC_SingleEnded(2);
 // adc4 = ads1.readADC_SingleEnded(3);
  adc1 = ads2.readADC_SingleEnded(0);
 adc6 = ads2.readADC_SingleEnded(1);
 adc7 = ads2.readADC_SingleEnded(2);
 adc8 = ads2.readADC_SingleEnded(3);

  if (check == 0 && isit == true) {

  //  if (millis() - adcTimer > 50) {
      analogReading = adc1;
      //  Serial.print(analogReading);    Serial.print("---");
      floatVoltageValue = map(analogReading, 2000, 26600, 0, 1000);
      floatVoltageValue = (floatVoltageValue / 100);
      setval = floatVoltageValue;
 //     adcTimer = millis();
      check = 1;
   // }
  }

 // if (millis() - adcTimer > 50) {
    analogReading = adc1;
    floatVoltageValue = map(analogReading, 2000, 26600, 0, 1000);
    floatVoltageValue = (floatVoltageValue / 100) - setval;
    // Serial.println(floatVoltageValue, 2);
    Serial.println(tolerance);
    if (tolerance > 0) {
      if (tolerance / 2 > abs(floatVoltageValue) && tolerance / 2 != abs(floatVoltageValue)) {
        Serial.println("ookkk");
        dwinSerial.write(green, sizeof(green));
      }
      if (tolerance / 2 <= abs(floatVoltageValue)) {
        Serial.println("Nooooooooooooooooooo");
        dwinSerial.write(red, sizeof(red));
      }
    }
    sendFloatNumber2(tolerance);
    sendFloatNumber1(floatVoltageValue);  // Send to display
  //  adcTimer = millis();
 // }
}

//-------------------------------------------------------------fetchText-----------------------------------------------------------------------------

void fetchText() {
  if (dwinSerial.available() > 0)  // available() returns the number of bytes stored in the buffer
  {
    int i = 0;
    while (dwinSerial.available() > 0)  // empty the buffer into our array
    {
      char incomingByte = dwinSerial.read();  // read 1 character from the dwin display
      delay(2);
      incomingData[i] = incomingByte;
      i++;
    }
    if (incomingData[3] == (byte)0x83)  // VP read instruction is in the returned char array
    {
      int k = 7;
      int j = 0;

      while (incomingData[k] != 0xFF) {
        receivedFloatArray[j] = incomingData[k];
        k++;
        j++;
      }
      dwinSerial.write(textoff, sizeof(textoff));
      dwinSerial.write(textoff, sizeof(textoff));
      receivedFloat = atof(receivedFloatArray);  // String s3 = receivedFloatArray;  receivedFloat = s3.toFloat();

      if (receivedFloat == 0) {delay(2000); check = receivedFloat; }
      if (receivedFloat > 0) { tolerance = receivedFloat; }
      Serial.print("Received float");
      Serial.println(receivedFloat, 2);
      memset(incomingData, 0, sizeof(incomingData));
      memset(receivedFloatArray, 0, sizeof(receivedFloatArray));
    }
  }
}

//-----------------------------------------------------------FloatToHex-----------------------------------------------------------------------------

void FloatToHex(float f, byte* hex) {
  byte* f_byte = reinterpret_cast<byte*>(&f);
  memcpy(hex, f_byte, 4);
}

//---------------------------------------------------------sendFloatNumber1-----------------------------------------------------------------------------

void sendFloatNumber1(float floatValue) {
  dwinSerial.write(0x5A);
  dwinSerial.write(0xA5);
  dwinSerial.write(0x07);
  dwinSerial.write(0x82);
  dwinSerial.write(0x11);
  dwinSerial.write((byte)0x00);  // Write address
  byte hex[4] = { 0 };           // create a hex array for the 4 bytes
  FloatToHex(floatValue, hex);   // convert the float to hex array
  dwinSerial.write(hex[3]);      // The order is flipped (endiannes)
  dwinSerial.write(hex[2]);
  dwinSerial.write(hex[1]);
  dwinSerial.write(hex[0]);
}

//---------------------------------------------------------sendFloatNumber2-----------------------------------------------------------------------------

void sendFloatNumber2(float floatValue) {
  dwinSerial.write(0x5A);
  dwinSerial.write(0xA5);
  dwinSerial.write(0x07);
  dwinSerial.write(0x82);
  dwinSerial.write(0x13);
  dwinSerial.write((byte)0x00);  // Write address
  byte hex[4] = { 0 };           // create a hex array for the 4 bytes
  FloatToHex(floatValue, hex);   // convert the float to hex array
  dwinSerial.write(hex[3]);      // The order is flipped (endiannes)
  dwinSerial.write(hex[2]);
  dwinSerial.write(hex[1]);
  dwinSerial.write(hex[0]);
}

Debug Message

**and when decoded to human readable through exception decoder,**

_PC: 0x420021cf: Adafruit_I2CDevice::begin(bool) at C:\Users\Vasanth\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\Wire\src/Wire.h line 92
EXCVADDR: 0x003c030d

Decoding stack results
0x420021cc: Adafruit_I2CDevice::begin(bool) at C:\Users\Vasanth\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\libraries\Wire\src/Wire.h line 92
0x42002079: Adafruit_ADS1X15::writeRegister(unsigned char, unsigned short) at C:\Users\Vasanth\Documents\Arduino\libraries\Adafruit_ADS1X15\Adafruit_ADS1X15.cpp line 383
0x420020ab: Adafruit_ADS1X15::startADCReading(unsigned short, bool) at C:\Users\Vasanth\Documents\Arduino\libraries\Adafruit_ADS1X15\Adafruit_ADS1X15.cpp line 344
0x42001b9d: readADC() at C:\Users\Vasanth\Desktop\11_Un_Activated_Dual_Core_7inch/11_Un_Activated_Dual_Core_7inch.ino line 178
0x42001c9e: readADC() at C:\Users\Vasanth\Desktop\11_Un_Activated_Dual_Core_7inch/11_Un_Activated_Dual_Core_7inch.ino line 209
0x42003f2d: uartFlushTxOnly at C:\Users\Vasanth\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\cores\esp32\esp32-hal-uart.c line 455_

Other Steps to Reproduce

I tried swapping the boards and changing the address by rewiring and rewriting the codes. except the board with (0x48), all other addresses causes the same rebooting

I have checked existing issues, online documentation and the Troubleshooting Guide

me-no-dev commented 8 months ago

can you please try to make the sketch smaller and just enough to reproduce the problem?

TD-er commented 8 months ago

Not stating there can't be a problem in Espressif/Arduino code.... However when reading about issues with ADS1x15, my first Pavlov reaction is that it currently is quite hard to get the exact chip you think you ordered or getting genuine ones. (when ordering those on the "purple" boards as sold on sites like AliExpress etc.) And on top of that most boards also have pull-up resistors mounted for both I2C pins. If you add multiple of those boards, you essentially make the pull-up stronger and not all I2C devices can pull down hard enough for stable communications. (you could lower the I2C clock speed as a quick test to see if it changes anything)

One simple test to detect quite a lot of fake chips is to set a fixed voltage on each ADC input. For example using a few resistors: 3V3 --R-- Vin --R-- Vin --R-- Vin --R-- Vin --R-- GND And then try sampling each input pin sequentially. You would expect to see the same voltage (+ some noise) being measured on each pin. A lot of fake ones will sometimes give you the voltage of the wrong pin.

Another thing that happens a lot is that ADS1015 is swapped for ADS1115. One is 12 bit at higher sample rate, the other is 16 bit. If you expect the 16 bit version, check the last few bits of the data. Or if you expect the 12 bit, try to see if there are more bits present not set to 0.

So unless you bought the boards from sellers like Adafruit or parts directly from large distributors like Mouser, Digikey, etc., my first bet would be to double check you have a genuine one. There really is a lot of garbage out there and I have lost way too many hours debugging my code only to find out it was fake garbage someone bought.

TD-er commented 8 months ago

And about your code:

    while (dwinSerial.available() > 0)  // empty the buffer into our array
    {
      char incomingByte = dwinSerial.read();  // read 1 character from the dwin display
      delay(2);
      incomingData[i] = incomingByte;
      i++;
    }
    if (incomingData[3] == (byte)0x83)  // VP read instruction is in the returned char array
    {
      int k = 7;
      int j = 0;

      while (incomingData[k] != 0xFF) {
        receivedFloatArray[j] = incomingData[k];
        k++;
        j++;
      }

I don't see any check on array boundaries.

Murugesh-Hobbyist commented 7 months ago

Mates, Thanks for the long response!

Actually in this code, Im connecting DWIN display to show 8 linear displacement sensor values and getting the user inputs to ESP32S3. unable to believe how it is resolved.

when the user resets in the display, HEX value from the display for zero should be 5A A5 08 83 20 00 02 30 FF FF 00 --> text "0" Instead i received 5A A5 08 83 20 00 02 29 30 FF FF --> text ")0"

now its modified and no reboot happening. my doubt is, the MC handled it when single ADC is connected but not at 2. It should failed when i connecting single ADC itself.