espressif / arduino-esp32

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

EEPROM: EEPROM.end() crashes and reboots #928

Closed GrooverFromHolland closed 6 years ago

GrooverFromHolland commented 6 years ago

Hardware:

Board: DOIT ESP32 DEVKIT V1 Core Installation/update date: 17/November/2017 IDE name: VisualStudio 2017 with visualMicro Flash Frequency: 80Mhz Upload Speed: 921600

Description:

First i have to mention that i cannot use the EspExceptionDecoder because my sketch is not compiling in the Arduino IDE: error: 'class BLEClient' has no member named 'isConnected'. This is not related to my problem. My problem is that if i want to write to EEPROM, after EEPROM.commit() or EEPROM.end() the application crashes and reboots. All EEPROM examples I could find work OK.

Sketch:

/**
* A BLE client with IR receiver
*/
#include <dummy.h>
#include <IRremote.h>
#include <boarddefs.h>
#include "BLEDevice.h"
#include"bt.h"
#include "BLEScan.h"
#include "EEPROM.h"

//IR
int RECV_PIN = 22;
IRrecv irrecv(RECV_PIN);
decode_results results;
//BLE
static BLEUUID serviceUUID("0000ffe0-0000-1000-8000-00805f9b34fb");
// The characteristic of the remote service we are interested in:
static BLEUUID     charUUID("0000ffe1-0000-1000-8000-00805f9b34fb");
static BLEClient*  pClient;
static BLEAddress  *pServerAddress;
static boolean doConnect = false;
static boolean connected = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
const byte stx = 2;
const byte etx = 3;
const byte dle = 10;
byte brite = 0;
int hue = 0;
int step = 2;
byte sendbufferHue[7] = { stx,30,dle,brite,0,0,etx };;
byte sendbufferBrite[7] = { stx,1,dle,brite,0,0,etx };;
boolean powerSet = false;
volatile bool clearToSend = true;
volatile bool tosend = true;
int briteUpDown = 1;
int hueUpDown = 1;
int countHue = 0;
bool valuesChanged = false;
//timer and eeprom
ulong startMillis = 0;
bool timerIsRunning = false;
bool safeToWrite = false;
byte packetBrite[7];
byte packetHue[7];

//packet = stx;cmd;dle;byte;byte;byte;etx (fixt length = 7)

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
    /**
    * Called for each advertising BLE server.
    */
    void onResult(BLEAdvertisedDevice advertisedDevice)
    {
        Serial.print("BLE Advertised Device found: ");
        Serial.println(advertisedDevice.toString().c_str());
        // We have found a device, let us now see if it contains the service we are looking for.
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID))
        {
            Serial.print("Found our device!  address: ");
            int rssi = advertisedDevice.getRSSI();
            Serial.print("Rssi: ");
            Serial.println(rssi);
            advertisedDevice.getScan()->stop();
            pServerAddress = new BLEAddress(advertisedDevice.getAddress());
            doConnect = true;
        }
    }
};

void setup()
{
    Serial.begin(115200);
    Serial.setDebugOutput(true);
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    Serial.println("Starting Arduino BLE Client application...");
    EEPROM.begin(14);
    if (!EEPROM.begin(14))
    {
        Serial.println("failed to initialise EEPROM"); delay(1000000);
    }
    Serial.print(" Bright read from Flash: ");
    for (int i = 0; i < 7; i++)
    {
        packetBrite[i] = byte(EEPROM.read(i));
        Serial.print(byte(packetBrite[i])); Serial.print(" ");
    }
    Serial.println(" ");
    Serial.print(" Hue read from Flash: ");
    for (int i = 6; i < 14; i++)
    {
        packetHue[i] = byte(EEPROM.read(i));
        Serial.print(byte(packetHue[i])); Serial.print(" ");
    }
    Serial.println(" ");
    BLEDevice::init("");
    // Retrieve a Scanner and set the callback we want to use to be informed when we
    // have detected a new device.  Specify that we want active scanning and start the
    // scan to run for 40 seconds.
    BLEScan* pBLEScan = BLEDevice::getScan();
    pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
    pBLEScan->setActiveScan(true);
    pBLEScan->start(40);
}
static void notifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify)
{
    char dest[length];
    char hexArray[length];
    for (int cnt = 0; cnt < length; cnt++)
    {
        // convert byte to its ascii representation
        //sprintf(&dest[cnt * 2], "%02X", pData[cnt]);
        hexArray[cnt] = (int)pData[cnt];
    }
    if (hexArray[0] == 79)
    {
        clearToSend = true;
        Serial.println("Clear  to send = true!");
    }
    else
    {
        Serial.println("NOT Clear  to send !");
        clearToSend = false;
    }
    Serial.print(" Notification to send = ");
    Serial.println(tosend);
}

bool connectToServer(BLEAddress pAddress)
{
    int cnt = 0;
    pClient = BLEDevice::createClient();
    Serial.println(" - Created client");
    delay(200);
    Serial.print("Forming a connection to ");
    Serial.println(pAddress.toString().c_str());
    pClient->connect(pAddress);
    delay(1000);
    BLERemoteService* pRemoteService = pClient->getService(serviceUUID);
    if (pRemoteService == nullptr)
    {
        Serial.print("Failed to find our service UUID: ");
        Serial.println(serviceUUID.toString().c_str());
        return false;
    }
    Serial.println(" - Found our service");
    delay(500);
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    delay(500);
    if (pRemoteCharacteristic == nullptr)
    {
        Serial.print("Failed to find our characteristic UUID: ");
        Serial.println(charUUID.toString().c_str());
        return false;
    }
    Serial.println(" - Found our characteristic");

    //// Read the value of the characteristic.
    //std::string value = pRemoteCharacteristic->readValue();
    ////uint8_t value = pRemoteCharacteristic->readValue();
    //Serial.print("The characteristic value was: ");
    //Serial.println(value.c_str());
    delay(500);
    Serial.print("registerForNotify ");
    pRemoteCharacteristic->registerForNotify(notifyCallback);
}

void SendValue(byte sendbuffer[7])
{

    if (connected  && tosend)
    {
        Serial.print("to send = ");
        Serial.println(tosend);
        tosend = false;
        clearToSend = false;
        //digitalWrite(LED_BUILTIN, HIGH);
        // Set the characteristic's value to be the array of bytes .
        //pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
        pRemoteCharacteristic->writeValue(sendbuffer, 7);
        //timerIsRunning = false;
    }
}

bool CheckTime()
{
    unsigned long currentMillis = millis();

    if ((valuesChanged) && (!timerIsRunning))
    {
        Serial.println(" here");
        startMillis = millis();
        timerIsRunning = true;
    }

    //Serial.println(" here");
    if ((timerIsRunning) && (currentMillis - startMillis >= 5000L))//3600L * 1000
    {
        //Serial.println(" here passed");

        // time passed ;    
        return true;
    }
    else
    {
        return false;
    }
}

void WriteEEeprom()
{

    //for (int i = 0; i < 7; i++)
    //{
    //  packetBrite[i] = byte(EEPROM.read(i));
    //  if (packetBrite[i] != sendbufferBrite[i])
    //  {
    //      EEPROM.write(i, sendbufferBrite[i]);
    //      Serial.print(" Written Bright to Eeprom adrres ");
    //      Serial.print(i);
    //      Serial.print(" ");
    //      Serial.println(packetBrite[i]);
    //      EEPROM.commit();

    //  }
    //  else
    //  {
    //      Serial.println(" Same value in Eeprom");
    //      
    //  }
    //  

    //}
    //Serial.println(" Hue read from Flash:");

    //for (int i = 6; i < 14; i++)
    //{
    //  packetHue[i] = byte(EEPROM.read(i));
    //  Serial.print(byte(EEPROM.read(i))); Serial.print(" ");
    //  if (packetHue[i] != sendbufferHue[i])
    //  {
    //      EEPROM.write(i, sendbufferHue[i]);
    //      Serial.println(" Written Hue to Eeprom");
    //      EEPROM.commit();

    //  }
    //  else
    //  {
    //      Serial.println(" Same value in Eeprom");
    //  }
    //}
    ////EEPROM.commit();

    EEPROM.begin(14);

    for (int i = 0; i < 14; i++)
    {
        EEPROM.write(i, 27);
        yield();
    }
    EEPROM.end();

    timerIsRunning = false;

}

void loop()
{
    if (CheckTime())
    {
        WriteEEeprom();
        valuesChanged = false;
    }

    if (irrecv.decode(&results))
    {
        Serial.println(results.value, DEC);
        if (results.value == 218148001)
        {
            if ((brite <= 250) && (brite > -1))
            {
                tosend = true;
                brite += 5;
                sendbufferBrite[0] = stx;
                sendbufferBrite[1] = 30;
                sendbufferBrite[2] = dle;
                sendbufferBrite[3] = brite;
                sendbufferBrite[4] = 0;
                sendbufferBrite[5] = 0;
                sendbufferBrite[6] = etx;
                Serial.print("bright is: ");
                Serial.println(brite);
                valuesChanged = true;
                SendValue(sendbufferBrite);
            }
        }
        if (results.value == 218115105)
        {
            if (brite >= 5)
            {
                tosend = true;
                brite -= 5;
                sendbufferBrite[0] = stx;
                sendbufferBrite[1] = 30;
                sendbufferBrite[2] = dle;
                sendbufferBrite[3] = brite;
                sendbufferBrite[4] = 0;
                sendbufferBrite[5] = 0;
                sendbufferBrite[6] = etx;
                Serial.print("bright is: ");
                Serial.println(brite);
                valuesChanged = true;
                SendValue(sendbufferBrite);
            }
        }
        if ((results.value == 218141343) || (results.value == 218112045))
        {
            Serial.println(hue);
            if (clearToSend)
            {
                hue += step;
            }
            Serial.println(hue);
            tosend = true;
            sendbufferHue[0] = stx;
            sendbufferHue[1] = 1;
            sendbufferHue[2] = dle;
            sendbufferHue[3] = 255;
            sendbufferHue[4] = hue;
            sendbufferHue[5] = 255;
            sendbufferHue[6] = etx;
            if (hue >= 255) hue = 0;
            valuesChanged = true;
            SendValue(sendbufferHue);
        }

        clearToSend = false;
        irrecv.resume(); // Receive the next value
    }

    // If the flag "doConnect" is true then we have scanned for and found the desired
    // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
    // connected we set the connected flag to be true.
    if (doConnect == true)
    {
        Serial.println("Enabling IRin");
        irrecv.enableIRIn(); // Start the receiver      
        Serial.println("Enabled IRin");
        if (connectToServer(*pServerAddress)) {
            Serial.println("We are now connected to the BLE Server.");
            connected = true;
            int32_t p = esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P7);
            Serial.print("Set power =: ");
            Serial.println(p);
            int32_t setp = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT);
            Serial.print("Setted power =: ");
            Serial.println(setp);
        }
        else
        {
            Serial.println("We have failed to connect to the server; there is nothin more we will do.");
            ESP.restart();
        }
        doConnect = false;
    }
    if (pClient->isConnected() == true)
    {
        digitalWrite(LED_BUILTIN, HIGH);
    }
    else
    {
        digitalWrite(LED_BUILTIN, LOW);
        BLEScan* pBLEScan = BLEDevice::getScan();
        pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
        pBLEScan->setActiveScan(true);
        pBLEScan->start(40);
    }
}

Debug Messages:

Opening port Port open 218148001 bright is: 5 to send = 1 [D][BLERemoteCharacteristic.cpp:543] writeValue(): >> writeValue(), length: 7 [D][BLEDevice.cpp:105] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 3] ... ESP_GATTC_WRITE_CHAR_EVT [D][BLERemoteCharacteristic.cpp:565] writeValue(): << writeValue here Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed) Register dump: PC : 0x400dafbc PS : 0x00060034 A0 : 0x400851e8 A1 : 0x3ffc0c80
A2 : 0x00000001 A3 : 0x00000002 A4 : 0x000000ff A5 : 0x40088e98
A6 : 0x00000000 A7 : 0x3ffd50e0 A8 : 0x800811f0 A9 : 0x3ff5f024
A10 : 0x3ffc10dc A11 : 0x20000000 A12 : 0x00000400 A13 : 0x3ffda2a0
A14 : 0x00000000 A15 : 0x00290000 SAR : 0x00000015 EXCCAUSE: 0x00000007
EXCVADDR: 0x00000000 LBEG : 0x400012c5 LEND : 0x400012d5 LCOUNT : 0xfffffff8

Backtrace: 0x400dafbc:0x3ffc0c80 0x400851e5:0x3ffc0ca0 0x4008650e:0x00000000

Rebooting... ets Jun 8 2016 00:22:57

stickbreaker commented 6 years ago

@GrooverFromHolland you might want to do a little reading about how this device functions, specifically review ATTR_IRAM

You are registering a callback that is not guaranteed to be loaded while using EEPROM() which has to disable instruction caching while it operates.

Chuck.

GrooverFromHolland commented 6 years ago

@stickbreaker. I googled ATTR_IRAM and couldnot find any information on that, also checked all used libraries and did not find ATTR_IRAM! So how is this related to my problem?

stickbreaker commented 6 years ago

@GrooverFromHolland do a Google search on readthedocs

The ESP32 only has 520kB of RAM, a small part ~128kB is the instruction cache. It loads program code from the 4MB FLASH, then executes from this RAM. The EEPROM() library emulates the EEPROM in a AVR processor by allocating a RAM buffer of the Requested Size (multiple of 4096 bytes, because the FLASH has to ERASE 4kB at a time). It then applies your EEPROM.write() to this RAM buffer, when you commit() it Disables Cache because it has to Take control of the FLASH, (background code loading is frozen) Issues the Flash Erase command (which can take a long Time, tens to hundreds of ms). Since this task is held waiting for the Hardware, FreeRTOS finds another task that it can release, or in your case, BLE issues a callback. But, since you did not tell the compiler to always keep the callback in RAM, the Callback code is still in the FLASH which is eraseing a sector for EEPROM(). Since the background instruction loading function needs to use the cache and the FLASH to service this callback. It explodes.

Callbacks, Interrupts, any code that can execute out of order needs to always reside in the limited 128kB instructionRam. So any code that can be called out of order needs ATTR_IRAM which forces the compiler to keep it in RAM forever. AND, every call from that code must ALSO be in RAM at all times. So, be parsimonious about which code you call.

class ATTR_IRAM MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks

Chuck.

GrooverFromHolland commented 6 years ago

@stickbreaker. I tried to implement you suggestion, but i don't understand much c++. When i build it I am getting a build error: Ble_remote.ino: 52:45: error: expected initializer before ':' token class ATTR_IRAM MyAdvertisedDeviceCallbacks *: public BLEAdvertisedDeviceCallbacks. How to resolve this?

stickbreaker commented 6 years ago

@GrooverFromHolland, Sorry working on Window XP Pascal program right now, Brain Fade, Try IRAM_ATTR

class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks
{
    /**
    * Called for each advertising BLE server.
    */
    void IRAM_ATTR onResult(BLEAdvertisedDevice advertisedDevice)
    {
        Serial.print("BLE Advertised Device found: ");
        Serial.println(advertisedDevice.toString().c_str());
        // We have found a device, let us now see if it contains the service we are looking for.
        if (advertisedDevice.haveServiceUUID() && advertisedDevice.getServiceUUID().equals(serviceUUID))
        {
            Serial.print("Found our device!  address: ");
            int rssi = advertisedDevice.getRSSI();
            Serial.print("Rssi: ");
            Serial.println(rssi);
            advertisedDevice.getScan()->stop();
            pServerAddress = new BLEAddress(advertisedDevice.getAddress());
            doConnect = true;
        }
    }
};

Chuck.

GrooverFromHolland commented 6 years ago

@stickbreaker. No luck wth that: Compiling 'Ble_remote' for 'DOIT ESP32 DEVKIT V1'

Ble_remote.cpp.o*: In function MyAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice) Ble_remote.ino:59: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x3) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x4) Ble_remote.ino:59: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x6) dangerous relocation l32r literal placed after use .literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice Ble_remote.ino:62: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x44) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x8) Ble_remote.ino:64: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xdf) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0xc) Ble_remote.ino:66: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xf2) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x10) Ble_remote.ino:69: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x139) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x14) Ble_remote.ino:70: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x150) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x18) Ble_remote.ino:59: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xc) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x1c) Ble_remote.ino:60: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x16) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x20) Ble_remote.ino:60: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x20) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x24)

Ble_remote.cpp.o*: In function std::__cxx11::basic_string<char, std::char_traits, std::allocator >::~basic_string()

Error linking for board DOIT ESP32 DEVKIT V1 basic_string.h:544: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x28) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x28) Build failed for project 'Ble_remote'

Ble_remote.cpp.o*: In function MyAdvertisedDeviceCallbacks::onResult(BLEAdvertisedDevice) Ble_remote.ino:62: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x30) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x2c) Ble_remote.ino:62: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x3e) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x30) Ble_remote.ino:62: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xd6) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x34) Ble_remote.ino:64: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xe4) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x38) Ble_remote.ino:65: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xec) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x3c) Ble_remote.ino:66: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0xfa) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x40) Ble_remote.ino:67: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x106) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x44) Ble_remote.ino:68: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x10e) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x48) Ble_remote.ino:68: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x114) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x4c) Ble_remote.ino:69: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x11c) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x50) Ble_remote.ino:69: (.iram1[MyAdvertisedDeviceCallbacks onResult(BLEAdvertisedDevice)]+0x127) dangerous relocation l32r literal placed after use (.literal._ZN27MyAdvertisedDeviceCallbacks8onResultE19BLEAdvertisedDevice+0x54)

collect2.exe*: error: ld returned 1 exit status

stickbreaker commented 6 years ago

@GrooverFromHolland , looks like you are going to have to attach it from the other direction. separate the EEPROM() functions away from BLE

I just spent some time on your code, can you explain what this is suppose to do?

if (pClient->isConnected() == true) {
  digitalWrite(LED_BUILTIN, HIGH);
  }
else{
  digitalWrite(LED_BUILTIN, LOW);
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setActiveScan(true);
  pBLEScan->start(40);
  }

It's at the end of your main loop.

This local variable pBLEScan() only exists for a very very short time?

Chuck.

GrooverFromHolland commented 6 years ago

@stickbreaker. That code is to show me that there is a connection with the device i am targetting and if the conection is lost for some reason: rescan and try to reconnect.

stickbreaker commented 6 years ago

@GrooverFromHolland my question was that you are creating a pointer to an object, then discarding the pointer. The pointer goes out of scope, does the dynamic object get destroyed? created by BLEDevice::getScan()

Dumb question. I just read through BLEDevice.cpp. (ignore it)

If you don't do the EEPROM() calls does everything else work?

Chuck.

GrooverFromHolland commented 6 years ago

@stickbreaker. Yes, It works perfect without Eeprom.

GrooverFromHolland commented 6 years ago

Update: Tested with Preferences.h instead of EEPROM.h and got the same problem. This means it is not likely that Preferences.h nor EEPROM.h is the cause. After removing IRremote.h and simulating the IRremote code everyting worked fine again, even with both Preferences and EEPROM. Now I must find another IRremote library that is compatible with EEPROM.h and BLE. Any help on this will be appreciated.

beegee-tokyo commented 6 years ago

Didn't try on ESP32 yet, but I was using IRLib2 on an ESP8266 project and it works fine there.

mitchsf commented 6 years ago

I gave up on IRRemote, and I also tried an RMT library that did not work reliably. I ended up using an ATTiny85 running IRRemote, and a serial connection to the ESP32. Obviously it would have been ideal to have a working IR library running on the ESP32.

GrooverFromHolland commented 6 years ago

UPdate: Finally after a lot if digging in IRremote I found a solution that is working. I deleted everything in IrSend.ccp (maybe not necessary, but I do not need it ), modified _IRremoteh so void enableIRIn (); can have a bool as parameter: void enableIRIn (bool enable );, modified irRecv.ccp to:

`void  IRrecv::enableIRIn(bool enable)
{
    // Interrupt Service Routine - Fires every 50uS
#ifdef ESP32
    // ESP32 has a proper API to setup timers, no weird chip macros needed
    // simply call the readable API versions :)
    // 3 timers, choose #1, 80 divider nanosecond precision, 1 to count up

    if (enable) {

        timer = timerBegin(1, 80, 1);
        timerAttachInterrupt(timer, &IRTimer, 1);
        // every 50ns, autoreload = true
        timerAlarmWrite(timer, 50, true);
        timerAlarmEnable(timer);
}
    else {

        timerEnd(timer);
        timerDetachInterrupt(timer);
    }`

Before writing to eeprom or preferences I use irrecv.enableIRIn(false); and after irrecv.enableIRIn(true); Also irrecv.enableIRIn(true); must be called after there is a BLE connection.

everslick commented 6 years ago

This issue is closed, because it looks as if it is not a bug or problem with the ESP32 Arduino core or its support libraries. For general API usage questions or help on specific coding challenges, please visit the arduino-esp32 Gitter channel. If you feel this issue was closed in error, reopen it and comment, why you think this is a bug in the Arduino-Core.

skrodahl commented 5 years ago

GrooverFromHolland's solution works, but his instructions are not correct. I've written the solution here, together with another problem that prevents IRremote.h from compiling on ESP32: https://hackaday.io/project/46280-muffsy-stereo-relay-input-selector/log/156747-full-functionality-rotational-encoder-and-remote-control