UNO Q: DS18B20 fails as an independent thread under Zephyr RTOS

Here is an example (Fig-1) of a multitasking environment with three tasks/threads managed by UNO Q (Zephyr RTOS):

  • Task 1: Acquires and displays the temperature from a DS18B20 sensor
  • Task 2: Blinks LED1 at a 2-second interval
  • Task 3: Blinks LED_BUILTIN at 1 sec interval in the loop() function

My issue is that the DS18B20 sensor delivers zero signal when run as a separate task in a multi-tasking environment (Fig-1). Currently, I am performing this task in the loop() function; where, the DS18B20 sensor is working fine by virtue of @robtillaart modified delayMicroseconds() function in the zephyrCommon.cpp file.

I would greatly appreciate guidance on how to resolve this issue.


Figure-1;

Sketch: (tested in IDE 2.3.7)

#include <zephyr/kernel.h>
#include <OneWire.h>
#include <Arduino_RouterBridge.h>

#define ONE_WIRE_PIN D8
#define LED1_PIN D3

byte addr[8];
byte data[9];

OneWire oneWire(ONE_WIRE_PIN);

// -------------------- Thread configuration ----------
#define STACK_SIZE 2048
#define THREAD1_PRIO 5  //DS
#define THREAD2_PRIO 5  //ledExternal

K_THREAD_STACK_DEFINE(ds18b20_stack, STACK_SIZE);
static struct k_thread ds18b20_thread;

K_THREAD_STACK_DEFINE(led1_stack, STACK_SIZE);
static struct k_thread led1_thread;

// -----------Thread-1: DS18B20 task (shifted in loop() function----
void ds18b20_task(void *, void *, void *) 
{
  while (true) 
  {
         ; //codes are placed in loop() function as they do not work here; gives 0 
  }
}

// ----------- Thread-2: External LED1 blinking (at 2 s interval)-------
void led1_task(void *, void *, void *) 
{
  while (true)
  {
    digitalWrite(LED1_PIN, HIGH);
    k_sleep(K_SECONDS(2)); 

    digitalWrite(LED1_PIN, LOW);
    k_sleep(K_SECONDS(2));  
  }
}

void setup() 
{
  Bridge.begin();
  Monitor.begin();
  k_sleep(K_SECONDS(5));  //delay(5000); let bridge hardware initiate

  pinMode(LED1_PIN, OUTPUT);
  
  oneWire.reset();   //reading 8-byte ROM_code of DS18B20
  oneWire.search(addr);
  for (int i = 0; i < 8; i++) 
  {
    byte y = addr[i];
    if (y < 0x10)
     {
      Monitor.print('0');
    }
    Monitor.print(y, HEX);
    Monitor.print(' ');
  }
  Monitor.println();

  // Create DS18B20 thread-1
/*  k_thread_create(&ds18b20_thread,
                  ds18b20_stack,
                  STACK_SIZE,
                  ds18b20_task,
                  NULL, NULL, NULL,
                  THREAD1_PRIO,
                  0,
                  K_NO_WAIT);*/

  // Create LED1 thread-2
  k_thread_create(&led1_thread,
                  led1_stack,
                  STACK_SIZE,
                  led1_task,
                  NULL, NULL, NULL,
                  THREAD2_PRIO,
                  0,
                  K_NO_WAIT);
}

// --------- Thread-3: Arduino loop() → blink LED_BUILTIN at 1sec interval
void loop() 
{
  digitalWrite(LED_BUILTIN, HIGH);
  k_sleep(K_SECONDS(1));  //

  digitalWrite(LED_BUILTIN, LOW);
  k_sleep(K_SECONDS(1));  
  //---------------------

  oneWire.reset();
  oneWire.select(addr);
  oneWire.write(0x44);  // Start conversion
  k_sleep(K_MSEC(750));  //maximum conversion delay

  oneWire.reset();
  oneWire.select(addr);
  oneWire.write(0xBE);  // Read scratchpad memory
  for (int i = 0; i < 9; i++)
    data[i] = oneWire.read();

  int16_t raw = (data[1] << 8) | data[0];  //compute temp
  float tempC = raw / 16.0;

  Monitor.print("DS18B20: ");
  Monitor.print(tempC);
  Monitor.println(" °C");
}

Output: (DS18B20 is running from within loop() function)

28 AD 47 65 09 00 00 2F //8-byte ROM-Code
DS18B20: 28.00 °C
DS18B20: 29.50 °C
DS18B20: 29.00 °C
DS18B20: 30.00 °C
DS18B20: 31.00 °C

Your code is like nothing I have ever seen before, is possibly incomplete, and definitely incomprehensible. That said, I imagine no amount of code will save you if you haven't got a pull-up resistor on the data pin, which appears to be the case here. I think you should address that first but, being on 3.3v, I'm afraid I don't know the resistor you need. I recognise you may have good reason for not using standard code and libraries for the DS18B20, but it might be a good idea to use them first.

The pull-up resistor is there except that it did not appear in the previous diagram by mistake. The support is that the sensor works in the loop() function.

Task2 and Task3 are working alright concurrently. When I move the DS18B20 codes from loop() function to Task1 to see that Task1 works as a seperate thread, the sensor gives zero reading.

Those Onewire.h Library codes are well functional. Here, I can acquire and visualize the 64-bit/8-byte ROM-code and the 9-byte scratchpad memory of the sensor. These information could be used for diagnostic purposes.

Hello

I uploaded your post #1 code.
I used Arduino IDE 2.3.7. Arduino App Lab was not running. UNO Q 2 MB.
I changed the original definition to #define ONE_WIRE_PIN D10 to suit to my connections.

Arduino IDE Serial Monitor printed programs Monitor.print() text. Result was garbage:

10:28:10.927 -> 28084  43FF 4 16  5103 
10:28:10.962 ->  .05DS18B20: 
10:28:13.746 ->  °C21DS18B20: .210 °C5
10:28:19.284 ->  °C.21DS18B20: 50
10:28:22.033 -> .
10:28:22.033 -> 50DS18B20: 21 °C.
10:28:24.840 -> 0 °CDS18B20: 521.05 °C
10:28:27.627 -> DS18B20: 21.DS18B20: 
10:28:30.394 -> 21 °C05.0
10:28:33.156 ->  °C5DS18B20: 21.210 °C
10:28:35.956 -> DS18B20: 5.
10:28:38.730 ->  °C0DS18B20: 521.
10:28:41.490 -> 50 °C21DS18B20: 
10:28:44.287 -> .DS18B20: 210 °C5.521

I tried all baud rates from 4800 to 2000000 and text printed as scrambled as before.

I loaded our post # 1 code to a new program window and made some modifications:
#define ONE_WIRE_PIN D10 as previous.
I Changed all Monitor to Serial and started serial baud Serial.begin(115200);
I connected a serial to USB adapter on UNO Q TX and RX pins. Used Putty to print temperatures:

** Booting Zephyr OS build v4.2.0-38-g994b835f5936 ***
28 FF 84 43 51 16 04 03
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C
DS18B20: 21.00 °C

Not scrambled at all!

Maybe Monitor printing is not as good as we expect it to be.

There are issues reported for the Q that he has low level clocks problems.
Dive into the code of the monitor printing and you might encounter these (again)

clock problems mentioned here

Maybe I look at the Monitor code.

Just happened when I got ready the previous post, Serial to Putty stopped working. So nothing in Putty. I plugged the serial to USB adapter out and in and nothing.
The led is still blinking and I can see DS18B20 traffic on logic analyzer screen.
Must unplug UNO Q also...

I unplugged and plugged UNO Q and I uploaded previous program:

I loaded our post # 1 code to a new program window and made some modifications:
#define ONE_WIRE_PIN D10 as previous.
I Changed all Monitor to Serial and started serial baud Serial.begin(115200) ;

Now led is blinking and temperatures are printed in Putty window. Let it work a few hours to see if it is working longer.

I was actually alluding to the Dallas temperature library and code thereto, but I think I will jump off this thread!

From that picture thing you posted it appears it is not wired properly. Here is a picture that may help:

Pin-3 (Fig-1) of DS18B20 is the (VDD) pin with which I have connected 3.3V in Fig-1 of Post #1 (Fig-2).


Figure-1:


Figure-2:

===>

Don’t forget if you send data to the serial Monitor it will interpret it as ASCII , so you might not see what you hope for !

I don’t have any hands-on experience with the Uno Q or running this under Zephyr RTOS, but just from a logical point of view I have a possible suspicion.

Since the DS18B20 works in a simple loop but not in the RTOS/threaded setup, I would guess it might be related to timing rather than wiring. The 1-Wire protocol is quite sensitive, and if the execution timing changes (e.g. due to task scheduling or preemption), communication can become unreliable.

Another thought is that the conversion and the read might not be perfectly synchronized anymore. If the sensor is read a bit too early, it can return values like -127°C.

So maybe the issue is less about the sensor itself and more about how the timing behaves in the RTOS context — but that’s just a guess from the outside.

This is an academic exercise aimed at drawing a timeline diagram to illustrate how tasks are executed under Zephyr RTOS. The DS18B20 sensor has been specifically chosen to observe how Zephyr manages the operation of time critical devices.

Sorry, but from your code I only get:
00 00 00 00 00 00 00 00
DS18B20: -0.06 °C
DS18B20: -0.06 °C
DS18B20: -0.06 °C

You need to take care of the following remark.

FYI, the delayMicroseconds() fix will be in the upcoming release of the "Arduino UNO Q Board" platform:

So if you find it a bit daunting to apply a patch manually, you can simply be patient and wait for the next update.

The fix has now been released in version 0.54.1 of the platform. Arduino App Lab will display an offer to install the update.