Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OneWire device (ex: DS1822) #412

Closed
eziologico opened this issue Jan 20, 2019 · 51 comments · Fixed by #620
Closed

Support OneWire device (ex: DS1822) #412

eziologico opened this issue Jan 20, 2019 · 51 comments · Fixed by #620

Comments

@eziologico
Copy link

Hello,
I'm trying to use a temperature sensor DS1822 with different genuine STM32 boards but the code freeze at the boot on all boards.
The same code and the same DS1822 Sensor run well on Arduino boards.
I'm trying the example code DS18x20_Temperature with the latest OneWire library v2.3.4 and STM23Core v1.4.0 but the problem is still present.

#include <OneWire.h>

// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http:https://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// https://github.com/milesburton/Arduino-Temperature-Control-Library

OneWire  ds(9);  // on pin 10 (a 4.7K resistor is necessary)

void setup(void) {
  Serial.begin(9600);
}

void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad

  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();

  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.print(" Celsius, ");
  Serial.print(fahrenheit);
  Serial.println(" Fahrenheit");
}

If I disconnect the Data Pin from sensor the code run and it print "No more addresses." on the serial port as the sensore doesn't answer.

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Jan 21, 2019

Hi,
Right this is not functional.
There is 2 issues:
1 - digital read/Write too slow on 1.4.0
2 - delayMicroseconds is interruptible

First point is solved thanks the move to LL for GPIO management, this is merge in master and will be available through board manger with 1.5.0.
Second point, I've updated OneWire library to enable interrupt before each delayMicroseconds

Here, the updated library which work with master of the core:
https://github.com/fpistm/OneWire/tree/Arduino_Core_STM32

Note the goal is not to merge that in OneWire library. Better approach would be to have a delayMicroseconds not dependant of interrupt.

@eziologico
Copy link
Author

eziologico commented Jan 22, 2019

Hi @fpistm,
Thank you for your fast reply, you are very responsive!

I downloaded the library and replaced the official one.
So, now the code doesn't freeze anymore, but it still doesn't work properly.
It recognize the DS1822 sensor with the correct ROM-Code but if I heat up the sensor the Data (temperature) is not updated and often/random it return a wrong temperature. Instead, the DS18B20 is not recognized.

STM32 Nucleo F303K8

OneWire library example: "DS18x20_Temperature"
Type: DS1822
Baudrate: 9600

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 1 4B 46 1F FF 10 12 D9  CRC=65
  Temperature = 21.00 Celsius, 69.80 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 9 4B 46 1F FF 10 10 F9  CRC=28
  Temperature = 149.00 Celsius, 300.20 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 1 4B 46 1F FF 10 12 D9  CRC=65
  Temperature = 21.00 Celsius, 69.80 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 1 4B 46 1F FF 10 12 D9  CRC=65
  Temperature = 21.00 Celsius, 69.80 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 9 4B 46 1F FF 10 12 D9  CRC=94
  Temperature = 149.00 Celsius, 300.20 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 9 4B 46 1F FF 10 12 D9  CRC=94
  Temperature = 149.00 Celsius, 300.20 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 50 9 4B 46 1F FF 10 12 D9  CRC=94
  Temperature = 149.00 Celsius, 300.20 Fahrenheit
No more addresses.

Type: DS18B20 "NOT RECOGNIZED!"
Baudrate: 9600

No more addresses.

No more addresses.

No more addresses.

No more addresses.

No more addresses.

No more addresses.

No more addresses.

No more addresses.

I think there is something related to the serial port, because increasing the baud rate from 9600 to 250000 bps also the DS18B20 is recognized with the correct ROM-Code but reporting always a fixed value of 215.50 Celsius even heating up the sensor.

Type: DS1822
Baudrate: 250000

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 7F 1 4B 47 1F FF 11 11 D9  CRC=DC
  Temperature = 23.50 Celsius, 74.30 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 7F 1 4B 47 1F FF 11 11 D9  CRC=DC
  Temperature = 23.50 Celsius, 74.30 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 7F 1 4B 47 1F FF 11 11 D9  CRC=DC
  Temperature = 23.50 Celsius, 74.30 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 7F 1 4B 47 1F FF 11 11 D9  CRC=DC
  Temperature = 23.50 Celsius, 74.30 Fahrenheit
No more addresses.

ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 7F 1 4B 47 1F FF 11 11 D9  CRC=DC
  Temperature = 23.50 Celsius, 74.30 Fahrenheit
No more addresses.

Type: DS18B20
Baudrate: 250000

No more addresses.

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 7F D 4B 47 1F FF D 30 8D  CRC=5
  Temperature = 215.50 Celsius, 419.90 Fahrenheit
No more addresses.

No more addresses.

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 7F D 4B 47 1F FF D 30 8D  CRC=5
  Temperature = 215.50 Celsius, 419.90 Fahrenheit
No more addresses.

No more addresses.

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 7F D 4B 47 1F FF D 30 8D  CRC=5
  Temperature = 215.50 Celsius, 419.90 Fahrenheit
No more addresses.

No more addresses.

The same code on Arduino Nano with your OneWire library seams working well.

OneWire library example: "DS18x20_Temperature"
Type: DS1822 and DS18B20 together
Baudrate: 9600

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 53 1 4B 46 7F FF D 10 E9  CRC=E9
  Temperature = 21.19 Celsius, 70.14 Fahrenheit
ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 48 1 4B 46 1F FF 8 10 3D  CRC=3D
  Temperature = 20.50 Celsius, 68.90 Fahrenheit
No more addresses.

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 4C 1 4B 46 7F FF 4 10 F5  CRC=F5
  Temperature = 20.75 Celsius, 69.35 Fahrenheit
ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 40 1 4B 46 1F FF 10 10 8D  CRC=8D
  Temperature = 20.00 Celsius, 68.00 Fahrenheit
No more addresses.

ROM = 28 F1 7F 97 3 0 0 DA
  Chip = DS18B20
  Data = 1 48 1 4B 46 7F FF 8 10 AD  CRC=AD
  Temperature = 20.50 Celsius, 68.90 Fahrenheit
ROM = 22 C4 7A 33 0 0 0 C6
  Chip = DS1822
  Data = 1 38 1 4B 46 1F FF 8 10 88  CRC=88
  Temperature = 19.50 Celsius, 67.10 Fahrenheit
No more addresses.

DallasTemperature library example: "Multiple"
Type: DS1822 and DS18B20 together
Baudrate: 9600

Dallas Temperature IC Control Library Demo
Locating devices...Found 2 devices.
Parasite power is: OFF
Device 0 Address: 28F17F97030000DA
Device 1 Address: 22C47A33000000C6
Device 0 Resolution: 9
Device 1 Resolution: 9
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.50 Temp F: 72.50
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.50 Temp F: 72.50
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60
Requesting temperatures...DONE
Device Address: 28F17F97030000DA Temp C: 22.00 Temp F: 71.60
Device Address: 22C47A33000000C6 Temp C: 22.00 Temp F: 71.60

Below a tests I did on the STM32 Nucleo board with DallasTemperature library too (that include OneWire library it self) but both sensors doesn't work, neither at 250000 bps:

Dallas Temperature IC Control Library Demo
Locating devices...Found 0 devices.
Parasite power is: OFF
Unable to find address for Device 0
Unable to find address for Device 1
Device 0 Address: 0000000000000000
Device 1 Address: 0000000000000000
Device 0 Resolution: 0
Device 1 Resolution: 0
Requesting temperatures...DONE
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Requesting temperatures...DONE
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Requesting temperatures...DONE
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Requesting temperatures...DONE
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Jan 22, 2019

Which core you used? 1.4.0 or the repo one?

@eziologico
Copy link
Author

Yes, the official STM32Core v1.4.0

@fpistm
Copy link
Member

fpistm commented Jan 23, 2019

Ok, that's why you have those issue, as said in my previous post:

First point is solved thanks the move to LL for GPIO management, this is merge in master and will be available through board manger with 1.5.0

1.4.0 does not have this.

@eziologico
Copy link
Author

Just for information, do you know when v1.5.0 will be available?

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Jan 24, 2019

I have to end USB stuff before releasing it. I hope in the coming weeks

@eziologico
Copy link
Author

Ok, thank you for your help and your great job.

Ezio

@eziologico
Copy link
Author

Hi @fpistm,
the STM32Core v.1.5.0. has been released and I updated to it but the problem I had with the core v.1.4.0 is still there.

The new v.1.5.0 core with your above linked OneWire library seems working setting the serial port baudrate to 9600 but setting the baudrate to 115200 it read randomly wrong temperature datas.

I do not understand the relation between the serial port and OneWire, perhaps it change some timings in the OneWire protocol.

Using the official OneWire library with the new core the code still freeze.

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Feb 16, 2019

Official library can't work due to interrupt disable for delay.
About Serial, as it use IT then I guess it is also related to interrupt.

@eziologico
Copy link
Author

So that means I can not use the Nucleo boards for my projects as I absolutely need to use OneWire sensors!

Ezio

@fpistm
Copy link
Member

fpistm commented Feb 16, 2019

That's means it requires some investigations ;)

@eziologico
Copy link
Author

Ok, so I’m confident in your hands! 😉

Ezio

@fpistm fpistm changed the title OneWire device (DS1822) freeze the code on whatever Nucleo board Support OneWire device (ex: DS1822) Mar 7, 2019
@fpistm fpistm self-assigned this Mar 7, 2019
@eeeeeta
Copy link

eeeeeta commented Mar 10, 2019

I've also had problems getting the OneWire library to work on STM32 - great to hear that you're working on it!

@eziologico
Copy link
Author

I'm glad to know that I'm not the only one in the world with this problem, I thought no one was using Dallas temperature sensors anymore. Normally I use a DS18B20 for each of my projects even just to know the temperature close to the board.

Thank you @fpistm for working on it,

Ezio

@fpistm
Copy link
Member

fpistm commented Mar 18, 2019

Hi @eziologico, @eeeeeta,
I've made an update on my fork.
https://github.com/fpistm/OneWire/tree/Arduino_Core_STM32

I've tested with Official STM32 core 1.5.0 and a Nucleo F303K8, it is now OK at 115200.
One thing I would like to fix before provide a PR to the official OneWire library is to provide a delay µs
uninterruptible.

If you can try and give your feedback.

@eziologico
Copy link
Author

Hi @fpistm,
I was a little bit busy and could not try it before, sorry.
I did some tests with my STM32F303K8 board and it seems to work much better but it's still not perfect, the temperature value still change accordly to the serial port baud rate setting.

at 2400bps (correct value)

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 71 1 4B 46 7F FF C 10 3  CRC=3
  Temperature = 23.06 Celsius, 73.51 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 71 1 4B 46 7F FF C 10 3  CRC=3
  Temperature = 23.06 Celsius, 73.51 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 70 1 4B 46 7F FF C 10 40  CRC=40
  Temperature = 23.00 Celsius, 73.40 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 70 1 4B 46 7F FF C 10 40  CRC=40
  Temperature = 23.00 Celsius, 73.40 Fahrenheit
No more addresses.

at 9600bps (sporadic wrong value)

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6D 21 4B 46 7F FF C 10 68  CRC=87
  Temperature = **534.81** Celsius, **994.66** Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6D 1 4B 46 7F FF C 10 68  CRC=68
  Temperature = 22.81 Celsius, 73.06 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6C 1 4B 46 7F FF C 10 2F  CRC=2B
  Temperature = 22.75 Celsius, 72.95 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6C 1 4B 46 7F FF C 10 2F  CRC=2B
  Temperature = 22.75 Celsius, 72.95 Fahrenheit
No more addresses.

at 57600bps (more wrong value)

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 71 1 5B E6 7F FF C 11 3  CRC=35
  Temperature = 23.06 Celsius, 73.51 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 70 29 5B 46 7F FF C 11 4A  CRC=5B
  Temperature = **663.00** Celsius, **1225.40** Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 70 1 5B 46 7F FF C 11 40  CRC=45
  Temperature = 23.00 Celsius, 73.40 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6F 29 5B 46 7F FF C 11 EE  CRC=F5
  Temperature = **662.94** Celsius, **1225.29** Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 6F 29 5B E6 7F FF C 15 EE  CRC=A7
  Temperature = **662.94** Celsius, **1225.29** Fahrenheit
No more addresses.

at 115200bps (wrong value)

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 74 5 4B 46 7F FF C 12 57  CRC=1D
  Temperature = 87.25 Celsius, 189.05 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 74 5 4B 46 7F FF C 12 57  CRC=1D
  Temperature = 87.25 Celsius, 189.05 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 7F 5 4B 46 7F FF E 12 87  CRC=63
  Temperature = 87.94 Celsius, 190.29 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 74 5 4B 46 7F FF C 12 57  CRC=1D
  Temperature = 87.25 Celsius, 189.05 Fahrenheit
No more addresses.

at 250000bps (wrong value but different than before)

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 7D 3 4B 46 7F FF E 10 16  CRC=D7
  Temperature = 55.81 Celsius, 132.46 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 7D 3 4B 46 7F FF E 10 16  CRC=D7
  Temperature = 55.81 Celsius, 132.46 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 76 3 4B 46 7F FF E 10 D3  CRC=38
  Temperature = 55.38 Celsius, 131.68 Fahrenheit
No more addresses.

ROM = 28 AA 21 8D 1A 13 2 D9
  Chip = DS18B20
  Data = 1 76 3 4B 46 7F FF E 10 D3  CRC=38
  Temperature = 55.38 Celsius, 131.68 Fahrenheit
No more addresses.

I tried different DS18B20 sensors and had the same result.

I replaced the official OneWire library with yours, but I would like to install the official one for the genuine Arduino boards and yours only in the STM32Core environment, if it's possible. (Mac OSX)

Thank you,

Ezio

@eeeeeta
Copy link

eeeeeta commented Mar 23, 2019

Hey @fpistm - thanks a lot for looking into this! The updated OneWire library seems to work perfectly for me (with USART at 115200 baud), although as mentioned above, looks like it might still fail in some edge-cases (which I haven't got to test) - thanks so much for fixing it! :)

@fpistm
Copy link
Member

fpistm commented Mar 23, 2019

@eziologico
Strange, I've tried with F303K8 until 230400 bauds without any issue with my lib.
I also provide it to several users and their feedbacks were OK.
Anyway, I will provide a PR to official library next week which will be compatible with the core with #477. This PR allows to have delayMicroseconds usable when IRQ are disabled.
Let's see with it when available.

@eziologico
Copy link
Author

Hi @fpistm,
thank you for your reply.
I don't know wy I'm still experiencing this issue, I tried it with the "DS18x20_Temperature" example sketch.
Which Data pin do you use? I'm using D9.
Can it be related to it?

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Mar 23, 2019

I don't think it is related to pin, it's mainly GPIO togglling. I'm using D10.

@eziologico
Copy link
Author

Hi @fpistm,
you are right, I tried the pin D10 but I had the same result.
I uninstalled and reinstalled the whole Stm32Core from Board Manager with no luck.
I uploaded the Sketch on a Nucleo144 F429ZI Board and it works well till 2000000 baud.
So, it mean that my STM32F303K8 Board is broken?

Any suggestion?

Thank you,

Ezio

@fpistm
Copy link
Member

fpistm commented Mar 25, 2019

Well hard to tell.
Don't know how you wired your sensor, I power it with 3.3V (of course with a resistor) anyway I've tried with 5V (I've checked the F303K8 datasheet and both D9 (PA8) and D10 (PA11) are 5V tolerant) and it works also (no wrong value).
I guess you have 4.7k resistor, which is required as a pullup from the DATA to VCC?

Anyway, it should be fine to test with #477 and with One wire without my fix about interrupts/noInterrupts usage

@eziologico
Copy link
Author

Hi @fpistm,
yes, I power it with 3.3V and 4.7K pullup resistor from Data to Vcc.
I think there's something strange on my Board, as it works well with the Nucleo144 F429ZI.
I will try with another one, I have one Stm32L432KC Board.

Please can you tell me how to test it with #477, I don’t know how to do it.

Thank you,

Ezio

@davidstoneham
Copy link

I've managed to get the PaulStoffregen/OneWire library working with a STM32L0 board. The issue on these boards is the delayMicroseconds function is highly inaccurate. I used a DMM in Hz mode to compare the timings with an Arduino Uno so I could adjust the delays in the OneWire library. There is also an issue that delayMicroseconds(1) on this chip is actually about 8us. I had to implement a new delay function using an assembly function in order to get the ~1us delays needed for the OneWire library. The read_bit function is where the headaches are since the pin needs to be held low for ~1us then read at ~15us which is impossible with the delayMicroseconds function on an STM32L072 board anyway.

fpistm added a commit to fpistm/Arduino_Core_STM32 that referenced this issue Aug 29, 2019
delayMicroseconds() should not rely to getCurrentMicros()
and should only compute required ticks for the delay
requested.

This allow to use it even if interrupts are disabled.
Example for OneWire library.

Fixes stm32duino#412

Signed-off-by: Frederic Pillon <[email protected]>
fpistm added a commit to fpistm/Arduino_Core_STM32 that referenced this issue Aug 29, 2019
delayMicroseconds() should not rely to getCurrentMicros()
and should only compute required ticks for the delay
requested.

This allow to use it even if interrupts are disabled.
Example for OneWire library.

Fixes stm32duino#412

Signed-off-by: Frederic Pillon <[email protected]>
@fpistm
Copy link
Member

fpistm commented Aug 29, 2019

Support of STM32 series based on cortex-m0 (F0/L0/G0) will be available thanks #620

fpistm added a commit to fpistm/Arduino_Core_STM32 that referenced this issue Aug 30, 2019
delayMicroseconds() should not rely to getCurrentMicros()
and should only compute required ticks for the delay
requested.

This allow to use it even if interrupts are disabled.
Example for OneWire library.

Fixes stm32duino#412

Signed-off-by: Frederic Pillon <[email protected]>
STM32 core based on ST HAL automation moved this from To do to Done Sep 2, 2019
fpistm added a commit that referenced this issue Sep 2, 2019
delayMicroseconds() should not rely to getCurrentMicros()
and should only compute required ticks for the delay
requested.

This allow to use it even if interrupts are disabled.
Example for OneWire library.

Fixes #412

Signed-off-by: Frederic Pillon <[email protected]>
@davidstoneham
Copy link

This issue is still present when the board is running in low temperatures (sub -5°C). I suspect this is due to drop in accuracy of the internal clocks at low temperatures. #620 works well above -5°C but I've had to switch back to my manual implementation of microsecond delays via delayUS_ASM to communication with one wire devices at lower temperatures.

@fpistm
Copy link
Member

fpistm commented Sep 12, 2019

Hi @davidstoneham
I think you guess right. Unfortunately, it is not possible to get an delay in ASM.
Maybe to ease the custom definition of a dedicated delayMicroseconds, it could be defined as weak.

@tshcherban
Copy link

@fpistm I have an issue getting OneWire to work with a system clock other than default. I'm using L051C8T6 CPU, took a SystemClock_Config function and modified it to lower the CPU frequency (from 32 to 16 MHz, changed RCC_OscInitStruct.PLL.PLLDIV to RCC_PLLDIV_4 instead of RCC_PLLDIV_2) and OneWire stops working. Do you have an idea why that can be happening?

@fpistm
Copy link
Member

fpistm commented May 29, 2024

Timing issue. If you decrease the frequency gpio toggling time decrease too. That can explain.

@tshcherban
Copy link

Strange, because there are a few delayMicroseconds calls, which should be at least magnitude greater than GPIO speed itself.

@fpistm
Copy link
Member

fpistm commented May 29, 2024

Right it's stange. Long time I work on this hard to help.

@fpistm
Copy link
Member

fpistm commented May 29, 2024

Maybe the delayMicroseconds precision is the issue.

@tshcherban
Copy link

A bit hard to test it without logic analyzer/scope, will try replacing it with a dedicated timer.

@tshcherban
Copy link

tshcherban commented May 29, 2024

Replaced delayMicroseconds with a:

void delayMicrosecondsImpl(uint32_t us)
{
  uint32_t ticks = us * 16; // 16 MHz
  TIM21->CNT = 0;
  while (TIM21->CNT < ticks)
    ;
}

TIM21 set up to count without prescaler, so 16 ticks per microsecond. Still no luck (for 32 MHz it's working fine).

@tshcherban
Copy link

@fpistm with a home-made logic analyzer I was able to detect some timing issues and partially resolve them by trimming a redundant code.

I'm wondering if all STM arch supports opendrain output? So I can put the fix under one

#if defined(ARDUINO_ARCH_STM32)

@fpistm
Copy link
Member

fpistm commented Jun 6, 2024

OK. Looking at your proposal, DIRECT_MODE macro normally rely on pin configuration not setting a level. Let's see what the OneWire maintainer think.

@tshcherban
Copy link

For STM32 it is replaced with a digitalWriteFast which in turn does LL_GPIO_SetOutputPin / LL_GPIO_ResetOutputPin under the hood.
It colud be even faster if replace DIRECT_WRITE_xxx with LL_GPIO_xxx, but that's too low level and gives a benefit of 1-2 CPU cycles.
From what I could figure out in the OneWire code, DIRECT_MODE_OUTPUT always come in pair with a DIRECT_WRITE_LOW (high does not make sense for opendrain line, and even can damage a device), so for supported platforms and STM32 especially can be just ommited.

@uzi18
Copy link

uzi18 commented Jun 10, 2024

@tshcherban you can try OneWireNg library: https://github.com/pstolarz/OneWireNg

It supports OD:

All bus activities are performed respecting open-drain character of the 1-wire protocol.

During normal 1-wire activities, the master MCU GPIO controlling the bus is never set high 
(providing direct voltage source on the bus) instead the GPIO is switched to the reading mode 
causing the high state seen on the bus via the pull-up resistor.

@tshcherban
Copy link

tshcherban commented Jun 10, 2024

@uzi18 But it still switches GPIO mode from OD-output to input and vice versa? Or reads it while pin stays as an OpenDrain-output?
P.S. if I understood the sources correctly - it does switch GPIO mode

image

My point was to eliminate those switches completely. On STM32 you do not need switch opendrain pin to input to read its state.

@uzi18
Copy link

uzi18 commented Jun 14, 2024

@tshcherban please ask for support with STM32 OD mode @pstolarz it is possible for fast fix with your idea.
Just fill there new issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment