stm32duino / Arduino_Core_STM32

STM32 core support for Arduino
https://github.com/stm32duino/Arduino_Core_STM32/wiki
Other
2.81k stars 966 forks source link

Support OneWire device (ex: DS1822) #412

Closed eziologico closed 5 years ago

eziologico commented 5 years ago

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://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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

Which core you used? 1.4.0 or the repo one?

eziologico commented 5 years ago

Yes, the official STM32Core v1.4.0

fpistm commented 5 years ago

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 commented 5 years ago

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

Thank you,

Ezio

fpistm commented 5 years ago

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

eziologico commented 5 years ago

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

Ezio

eziologico commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

Ezio

fpistm commented 5 years ago

That's means it requires some investigations ;)

eziologico commented 5 years ago

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

Ezio

eeeeeta commented 5 years ago

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

eziologico commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

@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 delayMicrosecondsusable when IRQ are disabled. Let's see with it when available.

eziologico commented 5 years ago

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 commented 5 years ago

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

eziologico commented 5 years ago

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 commented 5 years ago

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 commented 5 years ago

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

fpistm commented 5 years ago

Well, to use it, you have to use the git repo then after adding this in your gitconfig:

[Alias]
    pr = "!f() { git fetch -fu ${2-origin} refs/pull/$1/head:pr/$1 && git checkout pr/$1; }; f"

simply do: git pr 477 origin

this will fetch the PR on a branch pr/477 and checkout it.

fpistm commented 5 years ago

Official PR done https://github.com/PaulStoffregen/OneWire/pull/69 Old branch with interrupt fix available here: https://github.com/fpistm/OneWire/tree/Arduino_Core_STM32_Interrupt_Workaround

fpistm commented 5 years ago

Official PR PaulStoffregen/OneWire#69 merged in official OneWire. PR #477 also merged in master. Currently, only cortex-M0 (F0/L0/G0) could not work with OneWire library. A timer based delayMicroseconds will be provided later to support this, at this time it works with workaround available here: https://github.com/fpistm/OneWire/tree/Arduino_Core_STM32_Interrupt_Workaround

kiloWATT21 commented 5 years ago

Hi,

i ran into a problem trying to read data from DS18B20 with NUCLEO-F030R8. I installed OneWire lib from here https://github.com/fpistm/OneWire/tree/Arduino_Core_STM32_Interrupt_Workaround , deleted the official one, and uploaded to my board. Temp sensor is connected to 3V3, GND, Data pin has 4k7 pull-up on PA4. I tried different baud rates but it only shows "No more addresses.", but i can see that sensor responds on a scope.

Is there anything else i have to do or just use your lib?

fpistm commented 5 years ago

Hi @kiloWATT21 It seems your setup is correct. I've just tested and the sensor is found. Anyway values are not correct. Timing is critical for OneWire. On cortex M0 based board the workaround is enough anyway on some other this is not enough. As I mentioned before:

A timer based delayMicroseconds will be provided later

kiloWATT21 commented 5 years ago

Oh, i see.

By "later" do you mean in 1.6 core? Any predictions on when it's going to be released?

fpistm commented 5 years ago

Unfortunately, I don't think cortex M0 fix will be in 1.6.0.

kiloWATT21 commented 5 years ago

Are you gonna let us know if you have any solution for M0 + OneWire?

fpistm commented 5 years ago

If the current workaround for M0 doesn't work, no. Issue is identified and required to be implemented as said before.

fpistm commented 5 years ago

Support of STM32 series based on cortex-m3/4/7 delivered in release 1.6.0 Support of STM32 series based on cortex-m0 (F0/L0/G0) will be added later.

davidstoneham commented 5 years ago

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 commented 5 years ago

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

davidstoneham commented 5 years ago

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 commented 5 years ago

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 commented 4 months ago

@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 commented 4 months ago

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

tshcherban commented 4 months ago

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

fpistm commented 4 months ago

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

fpistm commented 4 months ago

Maybe the delayMicroseconds precision is the issue.

tshcherban commented 4 months ago

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

tshcherban commented 4 months ago

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 commented 4 months ago

@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 commented 4 months ago

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 commented 4 months ago

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 commented 4 months ago

@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 commented 4 months ago

@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.