espressif / arduino-esp32

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

Use pin I2C pin 43 as I/O for DS18B20 temp sensor #8324

Closed teastainGit closed 1 year ago

teastainGit commented 1 year ago

Board

ESP32 S3R8

Device Description

LilyGO T-Display S3

Hardware Configuration

GPIO43 is suggested by LilyGO as the I2C pins, they are brought out to the JST connector. I am trying to connect a DS18B20 "oneWire" temp sensor that will work on other GPIO but mot pin 43 or 44. I2C devices work on these pins as expected.

Version

v2.0.6 at first and then deleted it and installed v2.0.9, no change!

IDE Name

Arduino IDE v2.1.0

Operating System

MacOS Ventura 13.4

Flash frequency

QIO 80

PSRAM enabled

yes

Upload speed

460800

Description

I am trying to connect a Dallas Semiconductor DS18B20 temperature sensor to either the GPIO43 or the JST pin 43, which are probably the same circuit. There is no response from the sensor at all, the oscilloscope shows 3.3v steady. The sensor works on GPIO 1 (or GPIO 18, e.g.). The pin 43 can be programmed as an input or an output successfully, but not the serial serial I/O of the DS18B20. Further another user says that the JST pin 43 works in ESPHome, but we cannot get it to work on Arduino. I cannot understand why it works in only one software. My question therefore is: "Is there a configuration setup for the LilyGO T-Display S3 that configures GPIO43 for I2C only? How can we free it up?"

Sketch

#include <OneWire.h>
#include <DallasTemperature.h>
const int oneWireBus = 43;     
OneWire oneWire(oneWireBus);
DallasTemperature sensors(&oneWire);

void setup() {
  // Start the Serial Monitor
  Serial.begin(115200);
  delay(200);
  Serial.println(" setup  ");
  delay(200);
   sensors.begin();
}

void loop() {
  sensors.requestTemperatures(); 
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);
  Serial.println("ºC");
  Serial.println("   ");
  delay(2000);

### Debug Message

```plain
Do not think this is the issue!

Other Steps to Reproduce

It works on ESPHome, but not Arduino IDE.

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

Jason2866 commented 1 year ago

Try latest Arduino core 2.0.9

teastainGit commented 1 year ago

Try latest Arduino core 2.0.9 @Jason2866 Jason2866 Arduino IDE 2.1.0 would only offer v2.0.6 at first so I deleted it and installed v2.0.9, no change! I was hopeful!

lbernstone commented 1 year ago

pin 43 is used by the UART serial. If you use USB CDC for your serial connection, you should be able to use this pin.

teastainGit commented 1 year ago

So, still no joy! Here are my settings, cribbed from the LilyGO LilyGO T-Display S3 GitHub repository !

Screenshot 2023-06-18 at 11 28 20 PM

An observation: When I upload my sketch by USB I see the little DS18B20 indicator flicker as if showing the upload data!? It does not flicker when using GPIO 1, e.g. Some advice from lbernstone that 43 is U0TXD makes sense if I'm seeing download data on the GPIO43, maybe? What command in the sketch setup (like PINMODE, which works perfectly with digitalRead and digitalWrite) but what setting can free-up pin 43 as 1wire serial? Thanks for listening! -Terry

SuGlider commented 1 year ago

GPIO43 is by default UART0 TX pin. This pin is used by default to send all boot messages and also any LOG message. It is possible to detach TX/RX UART0 pins , but Arduino Core 2.0.6 has not that patch. It is necessary to update to 2.0.9 and just use Serial.end() (CDC on Boot Disabled) or Serial0.end() (CDC on Boot Enabled).

In Arduino 2.0.6, it Not executing Serial0.end() can "mix" Logging Messages (noise) with your OneWire signal , even using Serial.end() will not detach U0TXD and it won't work. HardwareSerial uses IOMux to assign pinpads to the UART peripheral, HardwareSerial::end() will detach it from IOMux, leaving it free for OneWire.

Update:

https://github.com/espressif/arduino-esp32/pull/7402 has been merged into 2.0.6 and this is necessary to allow HardwareSerial::end() to detach completely TX and RX. It may be necessary to first runSerial0.begin(1152000) followed by Serial0.end() in order to set the default RX0/TX0 GPIOs that will be assigned to UART0. ==> Just tested it, it is just necessary to execute Serial0.end() to free pin 43.

SuGlider commented 1 year ago

@teastainGit - Let me know it executing Serial0.end() solves this issue.

teastainGit commented 1 year ago

SuGlider Here is a screen shot showing all the advice I followed. It is not yet working, to be clear. (I use CDC on boot (Enabled) because my output is Serial.print!)

Screenshot 2023-06-20 at 2 21 24 PM

Thanks to all for your help, I think we are getting closer! -Terry

SuGlider commented 1 year ago

@teastainGit - Is it working correctly?

teastainGit commented 1 year ago

@teastainGit - Is it working correctly?

Sorry to not be clear, it was late when I stopped testing! I think we are on the right track, but I have done all the suggestions and still no success. I do not have a project waiting for an answer, just curious as to why it works on GPIO 1 but not 43 -Terry

VojtechBartoska commented 1 year ago

is this still valid @teastainGit ?

teastainGit commented 1 year ago

VojtechBartoska Thanks for asking! After I read your question I set the experiment up again, with ESP32 2.0.11 and all other libraries updated... Nope. I tied it on my new LilyGO T-Display S3 AMOLED and... Nope. No help from LilyGO . I also asked at the ESP32 Arduino GitHub Issues and no solution there. -Terry

SuGlider commented 1 year ago

I do not have a project waiting for an answer, just curious as to why it works on GPIO 1 but not 43

GPIOs 43 and 44 are default UART pins. GPIO1 is "free" for use. The issue seems related to being able to detach the GIPOs 43 and 44 from IO Mux and UART. The execution of Serial0.end() shall do it, but I read the code again and realized that because, it has never been initialized, it also doesn't run the code to detach the IO MUX.

Therefore, @teastainGit, please try you code in this way:

void setup() {
  // Serial0 is the UART0 when the S3 CDC is enabled
  Serial0.begin(115200); // this will initialize the UART with GPIOs 43 and 44, marking those pins to be detached
  Serial0.end(); // this will detach GPIOs 43 and 44

  // code as usual...
  Serial.begin();
  delay(200);
  Serial.println(" setup ");
  delay(200);
  sensors.begin();
}
SuGlider commented 1 year ago

@teastainGit - Please try Arduino Core 2.0.13. It shall sove this issue. Please let me know. When using ESP32S3 USB CDC, Serial will be the USB port and Serial0 will be the UART (GPIO 43/44). Just add a Serial0.end() to the setup() in order to detach Pins 43 and 44, for using these pins with OneWire.

teastainGit commented 1 year ago

What is it about ver 2.0.13 that shall make it worK? I set the CDC on Boot "Enabled" and the suggested sketch changes for Serial0:

#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(43);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial0.begin(115200);
  Serial0.end();
  Serial.begin();
  delay(200);
  Serial.println(" setup ");
  delay(200);
  sensors.begin();
}

void loop() {
  sensors.requestTemperatures();
  float temperatureC = sensors.getTempCByIndex(0);
  Serial.print(temperatureC);
  Serial.println("ºC");
  Serial.println("   ");
  delay(2000);
}

I tried again with all updated libraries and this version of ESP32 as well, but no luck. Again, the sensor LED flickered dimly during download, but the sensor would not work, giving a reading of -127. But the sensor works on GPIO 1 just fine. I also wrote this sketch to test 43 and 44 as output and input, and it worked perfectly!

const int buttonPin = 44;  // the number of the pushbutton pin
const int ledPin = 43;     // the number of the LED pin
int buttonState = 0;

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  buttonState = digitalRead(buttonPin);
  Serial.println(buttonState);
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
  delay(100);
}

I am not stuck on a project, just curious what is happening. BTW it is a LilyGO T-Display S3 . -Terry

Jason2866 commented 1 year ago

The used lib can be the reason for non working too. Have you tried a other sensor, not OneWire?

teastainGit commented 1 year ago

I cannot find another DS18B20 library and I am using the one suggested by Random Nerd Tutorials “https://randomnerdtutorials.com/esp32-ds18b20-temperature-arduino-ide[/](https://randomnerdtutorials.com/esp32-ds18b20-temperature-arduino-ide/)“ using an ESP32 DevKit. I have two LilyGO T-Display S3 and one LilyGO T-Display S3 AMOLED and the DS18B20 does not work on any of them. I connect to their intended I2C JST connector at the end of the board. These are connected to GPIO43 and 44 and work fine as: I2C temp sensor SHT30 Discrete inputs Discrete output The DS18B20 works fine on these boards using GPIO 1, 2 and so on. The DS18B20 works fine on other ESP32 boards including the M5Stack Core Basic, which is -DOWD series.

But...on the M5Stack "StampS3" model (ESP32S3), It does not work on pins 43 or 44, but does on other pins, GPIO1 e.g. (!) So it is not limited to the LilyGO T-Display S3, but it does fail on other ESP32 S3s as well. So, there's THAT. -Terry

Jason2866 commented 1 year ago

The onewire lib does a lot of low level settings. There is a high chance that not all gpios are correctly handled in the lib for the S3. Since other sensors do work well I think it is the lib

Jason2866 commented 1 year ago

@teastainGit @SuGlider It IS the onewire lib. This line prevents the use https://github.com/PaulStoffregen/OneWire/blob/v2.3.7/util/OneWire_direct_gpio.h#L200 It is wrong (left over from the time only ESP32 existed) and not needed anymore. The test can be removed completely.

SuGlider commented 1 year ago

Thanks @Jason2866 - Nice catch! @teastainGit - You may need to change the code line that @Jason2866 has found as the source of the issue. ESP32S3 has more GPIOs than the ESP32 and that if ( digitalPinIsValid(pin) && pin <= 33 ) // pins above 33 can be only inputs shall be changed to if ( digitalPinIsValid(pin) && pin <= NUM_DIGITAL_PINS) NUM_DIGITAL_PINS comes from pins_arduino.h linked to the Variant board.

teastainGit commented 1 year ago

OK GUYS!!! SuGlider, Jason2866 THAT'S IT! Thanks for all your help and determination. I edited the lib util and it now works as it is supposed to. -Terry

369Martin369 commented 8 months ago

Am confused...error is still present in version 2.3.7. needed to increase to 44 for T-Display

matsekberg commented 6 months ago

I have exactly the same issue on a ESP32S3 but on pin 38 so its not a USART issue. I will try the util library fix....

matsekberg commented 6 months ago

And the change in the util library worked !! I will also test this library: https://github.com/junkfix/esp32-ds18b20