Using G19, G21, G22, G23, G25 or G33 as I2C pin on Atom Lite



  • Hi,
    I'm trying to attach a DS18B20 (5 pcs, 3 meter), temperature sensors working with oneWire. I can't seem to get any reading on an Atom Matrix.

    Here's a short version of my code.

    #include <Arduino.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    // GPIO where the DS18B20 is connected to
    const uint8_t oneWireBus = ONEWIREBUS;
    
    // Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(oneWireBus);
    
    // Pass our oneWire reference to Dallas Temperature sensor
    DallasTemperature sensors(&oneWire);
    
    float DS18B20_temperature = -100.0;
    
    void setup() {
      sensors.begin();
    }
    
    void loop() {
      sensors.requestTemperatures();
      const float temperature = sensors.getTempCByIndex(0);
      Serial.println(temperature);
      const unsigned int num_DS18B20 = sensors.getDeviceCount();
      Serial.printf("Number of DS18B20: %d\n", num_DS18B20);
      for (unsigned int i=0; i<num_DS18B20; ++i) {
        DeviceAddress mac;
        sensors.getAddress(mac, i);
        const float temperature = sensors.getTempCByIndex(i);
        Serial.println(temperature);
      }
    }
    

    I have tested my breadboard setup and the code with a NodeMCU and using a NodeMCU I can get the temperatures. When using my NodeMCU, I make sure to use the default SDA pin for it to work.

    I googled around and I can find multiple posts that claim that we can use almost any pin as SDA so I wonder how I can change GPIO25 to be SDA on an Atom Lite?

    In this post, EXT.IO Unit and UIFlow 1.4.5.1, there is comment hinting that 3 meter long wires could be too long and that 100cm is the longest at most.



  • Hello @Balta

    I think you missed enabling Serial on your M5Atom. Try including:

    #include <M5Atom.h>
    

    then in setup() enable Serial and disable I2C to have GPIO25 and GPIO21 freed up for use with OneWire:

    // Enable Serial, disable I2C, enable Display
    M5.begin(true, false, true);
    

    and I would add some delay in your loop():

    delay(1000);
    

    BTW: In my M5Atom setup I've verified all available GPIOs (19, 22, 23, 33, 21 and 25) successfully to work with OneWire.

    Good luck
    Felix

    For reference - full code using GPIO25:

    #include <M5Atom.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    // GPIO where the DS18B20 is connected to
    const uint8_t oneWireBus = GPIO_NUM_25;
    
    // Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(oneWireBus);
    
    // Pass our oneWire reference to Dallas Temperature sensor
    DallasTemperature sensors(&oneWire);
    
    float DS18B20_temperature = -100.0;
    
    void setup() {
      // Enable Serial, disable I2C, enable Display
      M5.begin(true, false, true);
      sensors.begin();
    }
    
    void loop() {
      sensors.requestTemperatures();
      const float temperature = sensors.getTempCByIndex(0);
      Serial.println(temperature);
      delay(1000);
    }
    


  • @felmue Thanks for your help.
    I've tried your suggestion of adding

    #include <M5Atom.h>
    ...
    M5.begin(true, false, true);
    

    And I was getting 85 which, according to a google search, means there is an error but I can see the mac addresses of all my 5 probes. What bothers me is that looking at the code of M5.begin(true, false, true); and according to your previous comment, I skip the I2C initialization which I was already doing before adding that line since I wasn't calling Wire.begin(25,21,10000);. I really don't see what would help my I2C problem. By adding M5.begin(true, false, true);, the only thing I add is initializing the display which I don't have on my atom lite.

    I've tried essentially the same code with my nodemcu, the same DS18B20 sensors and I can read the mac addresses and all 5 temperature no problem.

    I also have a Feather Huzzah esp8266 and a Feather Huzzah 32 esp32 that I will try out later.

    Could it be that the atom lite is not providing enough mA to the sensors?



  • Hi @Balta,

    If you don't need the I2C bus at all, you can disable it like this:

    Wire.~TwoWire();
    

    Try it to see if it solves your problem.



  • Hello @Balta

    you are absolutely correct - as long as you don't call Wire.begin(25,21,10000) GPIO25 or GPIO21 should be available for OneWire.

    Unfortunately I only have one DS18B20 so I cannot fully recreate your setup. Did you try your M5Atom Lite setup with only one sensor?

    Good luck!
    Felix


  • M5Stack

    before you start the I2C communication. you could scan the I2C bus, check does the device address exist.

    and also you could try use other pins. like 21, 22.

    make sure the sensor sda and scl has pull up resistor. (because atom pins don't have pullup resistor)



  • Thanks for all the great responses.

    I actually figure it out. I knew that my sensors were working because I could get the same code to work when using a ESP8266. I'm currently using GPIO25 for my 5 DS18B20 temperature sensors and I'm also using a 4.7 Ohm resistor as suggested by Dallas. At first, I could not see any sensor. After some thinkering, I was able to get the mac addresses of all 5 sensors with the Atom Lite but the temperature was ALWAYS 85. Googling for 85, someone said that we have to wait 750 ms after calling sensors.requestTemperatures();

      sensors.requestTemperatures();
      delay(750);  // This seems critical to get the sensors to work with AtomLite
    

    Then I can proceed to get the temperatures like so. Note that this only illustrates the spirit of what needs to be done and I haven't tested the exact code that follows.

    #include <M5Atom.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    
    // GPIO where the DS18B20 is connected to
    const uint8_t oneWireBus = GPIO_NUM_25;
    
    // Setup a oneWire instance to communicate with any OneWire devices
    OneWire oneWire(oneWireBus);
    
    // Pass our oneWire reference to Dallas Temperature sensor
    DallasTemperature sensors(&oneWire);
    
    void setup() {
      M5.begin(true, false, true);  // But I need to test without this line.
      sensors.begin();
    }
    
    
    void loop() {
      sensors.requestTemperatures();
      delay(750);  // This seems critical to get the sensors to work with AtomLite
    
      const unsigned int num_DS18B20 = sensors.getDeviceCount();
    
      for (unsigned int i=0; i<num_DS18B20; ++i) {
        DeviceAddress mac;
        sensors.getAddress(mac, i);
        delay(10);
        const float temperature = sensors.getTempCByIndex(i);
        send_MQTT(mac, temperature);
        }
      }
      delay(10000);
    }
    

    I hope that this information will be useful for someone else trying to hookup some DS18B20 to an Atom Lite.