PaulStoffregen / OneWire

Library for Dallas/Maxim 1-Wire Chips
http://www.pjrc.com/teensy/td_libs_OneWire.html
579 stars 382 forks source link

Initial ESP32 support, ready for testing #40

Closed cbxbiker61 closed 6 years ago

cbxbiker61 commented 6 years ago

Did a simple port to ESP32. I don't have ESP32 hardware at the moment, so I haven't been able to test locally. It should work.

jeffeb3 commented 6 years ago

I have tested this on an ESP32. It functions as well as the digitalRead/digitalWrite/pinMode does. I get the "ESP32 One Wire Testing" message during compilation.

I'm testing with a DS18B20 temperature sensor, and I'm getting errors about 90-95% of the time. I don't have experience with OneWire or DallasTemperature otherwise, so It's possible I'm doing something else wrong. Are there any suggestions/suggested reading for me? Are there common timing/critical pieces that I could test since I've actually got some of the hardware? Maybe there's a way to set up a one wire loop back test to eliminate bad hardware?

PaulStoffregen commented 6 years ago

Are there any suggestions/suggested reading for me

Test on an Arduino Uno/Mega or Teensy board, which are known to work very well.

jeffeb3 commented 6 years ago

Hmmm. I think the problem might be in DallasTemperature, or in my code. When I changed to first finding the address, and then only reading the temperature by that address, it is reading 100% of the time. Maybe the search code uses different parts of the library, or maybe the search code is broken in DT or my code.

Again, if there's any kind of timing or verification you want me to do on this hardware, let me know. Otherwise, I think this code is fine, and the warning could be removed.

jeffeb3 commented 6 years ago

Test on an Arduino Uno/Mega or Teensy board, which are known to work very well

I didn't see that until after I replied. I can try that too, to make sure my application code is hammered out. I'll try that out.

jeffeb3 commented 6 years ago

I have a Leonardo board, and I connected it up the same way, and things are working exactly as they should be. So I started diving deeper into the esp code, and comparing my client code on the Leo.

I was testing with this little snippet right here on both platforms, and I was getting the address found right away every time on the Leo, and the second time every time on the esp32.

#include <OneWire.h>

OneWire onewire(5);

void setup()
{
    Serial.begin(115200);

    // Alow miniterm to load
    delay(1000);

    onewire.reset_search();

    int devices = 0; // Reset the number of devices when we enumerate wire devices

    while (devices == 0)
    {
        uint8_t deviceAddress[8];
        while (onewire.search(deviceAddress))
        {
            Serial.println("Found Addr[0]: 0x" + String(deviceAddress[0], HEX));
            devices++;
        }
        if (devices == 0)
        {
            Serial.println("Didn't find anything");
        }
    }
}

void loop()
{
}

I went poking through the code on this PR, and I found a very reliable and very confusing reason for the problem. If I don't describe the directModeInput as __attribute__((always_inline)) it works the first time, every time, and if I do describe it with that attribute, it never works the first time. This is with dozens of tests while trying other things. I am not very experienced with microcontroller code, or that particular flag, so I have no idea why it's changing the behavior at all. At the most, I could see it being some kind of race condition, but that seems like a stretch. Maybe someone with more knowledge can come up with a better reason.

After removing that, the esp still isn't working as well as the leonardo. My small test case is good, but when I add in more features like wifi, OTA uploading, the OLED display, etc, things get worse. Specifically, it has a hard time searching and reading the scratchpad. It will frequently come up with the wrong resolution, which will then mean that it won't wait the right amount of time between reads, or it will return with a bad number. The numbers are always -127C or +85C, so they aren't hard to filter out. I am guessing the critical delays in the reading and writing are taking longer than they should because some other task is picking up the CPU.

I can limp along with this just fine. I think in general, there should probably be a OneWireEsp or something that uses the FreeRTOS functions to more precisely manage timing. As far as this PR goes, I would be happier if someone can explain the attribute problem, but otherwise, it's not making a gigantic difference. I wonder if it wouldn't be better just to let the default pinMode/digitalRead/Write do the work instead.