Search code examples
stringintegeresp32arduino-esp32panic

ESP32 panic'ed with string to int


I'm not a specialist in coding, I try to put toghether some code to control over bluetooth a signal generator with ESP32. I managed to make it functional with a number and now I try to conect some variables from BTLE.

Here is my code:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

String valor;
long previousMillis_BLE1 = 0;
int interval_BLE1 = 1000;

BLEServer* pServer = NULL;
BLECharacteristic* pCharacteristic = NULL;

#define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"

class MyCallbacks: public BLECharacteristicCallbacks {
    void onWrite(BLECharacteristic *pCharacteristic) {
      std::string value = pCharacteristic->getValue();



      if (value.length() > 0) {
        valor = "";
        for (int i = 0; i < value.length(); i++){
          //Serial.print(value[i]); // Presenta value.
          valor = valor + value[i];
        }

        
       // Serial.print("valor = ");
        Serial.println(valor); // Presenta valor.
      }
    }
};



const byte CPS1 = 3;
const byte CPS2 = 4;

unsigned long TotalTeeth = 10;
unsigned long MissingTeeth = 2;
unsigned long TeethBetweenMissingTeeth = 0;

unsigned long RPM = 800;

//long RPM = valor.toInt();
//unsigned long RPM = valor.toInt();
//int RPM = valor.toInt();
//long int RPM = valor.toInt();


const unsigned long MicrosecondsPerMinute = 1000000ul * 60;


void setup() {

Serial.begin(115200);

  // Create the BLE1 Device
  BLEDevice::init("MyESP32_BLE1");

  // Create the BLE Server
  pServer = BLEDevice::createServer();

  BLEService *pService = pServer->createService(SERVICE_UUID);

  pCharacteristic = pService->createCharacteristic(
                      CHARACTERISTIC_UUID,
                      BLECharacteristic::PROPERTY_READ   |
                      BLECharacteristic::PROPERTY_WRITE  |
                      BLECharacteristic::PROPERTY_NOTIFY |
                      BLECharacteristic::PROPERTY_INDICATE
                    );

  pCharacteristic->setCallbacks(new MyCallbacks());
  pService->start();

  BLEAdvertising *pAdvertising = pServer->getAdvertising();
  pAdvertising->start();


  pinMode(CPS1, OUTPUT);
  pinMode(CPS2, OUTPUT);

}


void loop() {

  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
  float TemperatureBLE1 = random(10,60000)/1000.0; // 3 decimals
  float HumidityBLE1 = random(5,99000)/1000.0;  // 3 decimals

  String temperatureBLE1 = String(TemperatureBLE1,3);
  String humidityBLE1 = String(HumidityBLE1,3);
  String tem_hum_BLE1 = temperatureBLE1 + "," + humidityBLE1;

      std::string value = pCharacteristic->getValue();
      pCharacteristic->setValue(tem_hum_BLE1.c_str()); // Notify.
      pCharacteristic->notify();
      
  previousMillis_BLE1 = currentMillis;     
  interval_BLE1 = random(500,1000);
  }

  unsigned long pulsesPerMinute = RPM * TotalTeeth;
  unsigned long microsecondsPerPulse = MicrosecondsPerMinute / pulsesPerMinute;
  unsigned long microsecondsPerHalfPulse = microsecondsPerPulse / 2;

  for (int i = 0; i < TotalTeeth - MissingTeeth - (TeethBetweenMissingTeeth * (MissingTeeth - 1)); i++)
  {
    Tooth(microsecondsPerHalfPulse);
  }

  for (int i = 0; i < MissingTeeth; i++)
  {
    ToothMissing(microsecondsPerHalfPulse);

    // Between pairs of missing teeth, insert this many teeth
    if (i < MissingTeeth - 1)
    {
      for (int j = 0; j < TeethBetweenMissingTeeth; j++)
      {
        Tooth(microsecondsPerHalfPulse);
      }
    }
  }


}

void Tooth(int duration)
{
  digitalWrite(CPS1, HIGH);
  digitalWrite(CPS2, HIGH);
  delayMicroseconds(duration);
  digitalWrite(CPS1, LOW);
  digitalWrite(CPS2, LOW);
  delayMicroseconds(duration);
}

void ToothMissing(int duration)
{
  // two delays for both halves of a missing pulse
  delayMicroseconds(duration);
  delayMicroseconds(duration);

}

This part of code is what I try and don't work. I uncoment it one by one to test and every line reboot forever the ESP32.

//long RPM = valor.toInt();
//unsigned long RPM = valor.toInt();
//int RPM = valor.toInt();
//long int RPM = valor.toInt();

Do you know any other method to convert the variable "valor" to a number? I think that is a string...

Thank you in advance, Dan

//long RPM = valor.toInt();
//unsigned long RPM = valor.toInt();
//int RPM = valor.toInt();
//long int RPM = valor.toInt();

Any of them meet teh ESP32 to panic and reboot forever.


Solution

  • The problem is that valor.toInt() returns 0. This results in pulsesPerMinute in unsigned long pulsesPerMinute = RPM * TotalTeeth; being equal to zero as well. Then, in the following line unsigned long microsecondsPerPulse = MicrosecondsPerMinute / pulsesPerMinute;, there is a division by zero because pulsesPerMinute is zero. To solve this, you should place the line long RPM = valor.toInt(); in the onWrite method, because right now, RPM is once calculated, at the start of the program and at that moment valor isn't initialized yet, resulting in valor.toInt() returning 0. Besides that, it is advisable to check the value of RPM before calculating the pulsesPerMinute.

    Example code in which those issues are fixed (I haven't tested this code):

    #include <BLEDevice.h>
    #include <BLEUtils.h>
    #include <BLEServer.h>
    
    String valor;
    long previousMillis_BLE1 = 0;
    int interval_BLE1 = 1000;
    
    BLEServer* pServer = NULL;
    BLECharacteristic* pCharacteristic = NULL;
    
    const byte CPS1 = 3;
    const byte CPS2 = 4;
    
    unsigned long TotalTeeth = 10;
    unsigned long MissingTeeth = 2;
    unsigned long TeethBetweenMissingTeeth = 0;
    
    long RPM = 800;
    
    const unsigned long MicrosecondsPerMinute = 1000000ul * 60;
    
    #define SERVICE_UUID        "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
    #define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
    
    class MyCallbacks: public BLECharacteristicCallbacks {
        void onWrite(BLECharacteristic *pCharacteristic) {
          std::string value = pCharacteristic->getValue();
    
          if (value.length() > 0) {
            valor = "";
            for (int i = 0; i < value.length(); i++){
              //Serial.print(value[i]); // Presenta value.
              valor = valor + value[i];
            }
    
            
           // Serial.print("valor = ");
            Serial.println(valor); // Presenta valor.
          }
          RPM = valor.toInt();
        }
    };
    
    void setup() {
    
    Serial.begin(115200);
    
      // Create the BLE1 Device
      BLEDevice::init("MyESP32_BLE1");
    
      // Create the BLE Server
      pServer = BLEDevice::createServer();
    
      BLEService *pService = pServer->createService(SERVICE_UUID);
    
      pCharacteristic = pService->createCharacteristic(
                          CHARACTERISTIC_UUID,
                          BLECharacteristic::PROPERTY_READ   |
                          BLECharacteristic::PROPERTY_WRITE  |
                          BLECharacteristic::PROPERTY_NOTIFY |
                          BLECharacteristic::PROPERTY_INDICATE
                        );
    
      pCharacteristic->setCallbacks(new MyCallbacks());
      pService->start();
    
      BLEAdvertising *pAdvertising = pServer->getAdvertising();
      pAdvertising->start();
    
    
      pinMode(CPS1, OUTPUT);
      pinMode(CPS2, OUTPUT);
    
    }
    
    
    void loop() {
    
      unsigned long currentMillis = millis();
    
      if(currentMillis - previousMillis_BLE1 > interval_BLE1) {
      float TemperatureBLE1 = random(10,60000)/1000.0; // 3 decimals
      float HumidityBLE1 = random(5,99000)/1000.0;  // 3 decimals
    
      String temperatureBLE1 = String(TemperatureBLE1,3);
      String humidityBLE1 = String(HumidityBLE1,3);
      String tem_hum_BLE1 = temperatureBLE1 + "," + humidityBLE1;
    
          std::string value = pCharacteristic->getValue();
          pCharacteristic->setValue(tem_hum_BLE1.c_str()); // Notify.
          pCharacteristic->notify();
          
      previousMillis_BLE1 = currentMillis;     
      interval_BLE1 = random(500,1000);
      }
    
      if (RPM == 0) {
        // handle error, for example:
        Serial.println("RPM is 0, returning from loop...");
        return;
    
      }
      unsigned long pulsesPerMinute = RPM * TotalTeeth;
      unsigned long microsecondsPerPulse = MicrosecondsPerMinute / pulsesPerMinute;
      unsigned long microsecondsPerHalfPulse = microsecondsPerPulse / 2;
    
      for (int i = 0; i < TotalTeeth - MissingTeeth - (TeethBetweenMissingTeeth * (MissingTeeth - 1)); i++)
      {
        Tooth(microsecondsPerHalfPulse);
      }
    
      for (int i = 0; i < MissingTeeth; i++)
      {
        ToothMissing(microsecondsPerHalfPulse);
    
        // Between pairs of missing teeth, insert this many teeth
        if (i < MissingTeeth - 1)
        {
          for (int j = 0; j < TeethBetweenMissingTeeth; j++)
          {
            Tooth(microsecondsPerHalfPulse);
          }
        }
      }
    
    
    }
    
    void Tooth(int duration)
    {
      digitalWrite(CPS1, HIGH);
      digitalWrite(CPS2, HIGH);
      delayMicroseconds(duration);
      digitalWrite(CPS1, LOW);
      digitalWrite(CPS2, LOW);
      delayMicroseconds(duration);
    }
    
    void ToothMissing(int duration)
    {
      // two delays for both halves of a missing pulse
      delayMicroseconds(duration);
      delayMicroseconds(duration);
    
    }
    

    EDIT: Removed double declaration and changed type of RPM to right type.