OpenBK7231T_App
OpenBK7231T_App copied to clipboard
Add DS18B20 for BL602
Tested and working, however I would like to see crc implemented, there is a lot of bad readings
Could you please try this patch or the version attached for the driver code?
diff --git a/src/driver/drv_ds1820_simple.c b/src/driver/drv_ds1820_simple.c
index be59a73b..e42869c7 100644
@@ -308,6 +309,29 @@ int OWTouchByte(int Pin, int data)
}
+
+
+uint8_t OWcrc( uint8_t *data, uint8_t len)
+{
+ uint8_t crc = 0;
+
+ while (len--) {
+ uint8_t inb = *data++;
+ for (uint8_t i = 8; i; i--) {
+ uint8_t mix = (crc ^ inb) & 0x01;
+ crc >>= 1;
+ if (mix) crc ^= 0x8C;
+ inb >>= 1;
+ }
+ }
+ return crc;
+}
+
+
+
+
+
+
int DS1820_getTemp() {
return t;
}
@@ -323,12 +347,13 @@ void DS1820_AppendInformationToHTTPIndexPage(http_request_t *request)
}
+
void DS1820_OnEverySecond() {
// for now just find the pin used
//
Pin=PIN_FindPinIndexForRole(IOR_DS1820_IO, 99);
-
+ uint8_t scratchpad[9], crc;
if (Pin != 99) { // only if pin is set
// request temp if conversion was requested two seconds after request
// if (dsread == 1 && g_secondsElapsed % 5 == 2) {
@@ -342,26 +367,41 @@ void DS1820_OnEverySecond() {
OWWriteByte(Pin,0xCC);
OWWriteByte(Pin,0xBE);
- Low = OWReadByte(Pin);
- High = OWReadByte(Pin);
-
-
- Val = (High << 8) + Low; // combine bytes to integer
- negative = (High >= 8); // negative temperature
- if (negative)
+ for (int i = 0; i < 9; i++)
+ {
+ scratchpad[i] = OWReadByte(Pin);//read Scratchpad Memory of DS
+ }
+ crc= OWcrc(scratchpad, 8);
+ if (crc != scratchpad[8])
{
- Val = (Val ^ 0xffff) + 1;
+ addLogAdv(LOG_ERROR, LOG_FEATURE_CFG, "DS1820 - Read CRC=%x != calculated:%x \r\n",scratchpad[8],crc);
+ }
+ else
+ {
+ // Low = OWReadByte(Pin);
+ // High = OWReadByte(Pin);
+ Low = scratchpad[0];
+ High = scratchpad[1];
+
+
+ Val = (High << 8) + Low; // combine bytes to integer
+ negative = (High >= 8); // negative temperature
+ if (negative)
+ {
+ Val = (Val ^ 0xffff) + 1;
+ }
+ // Temperature is returned in multiples of 1/16 °C
+ // we want a simple way to display e.g. xx.yy °C, so just multiply with 100 and we get xxyy
+ // --> the last two digits will be the fractional part (Val%100)
+ // --> the whole part of temperature is (int)Val/100
+ // so we want 100/16 = 6.25 times the value (the sign to be able to show negative temperatures is in "factor")
+ Tc = (6 * Val) + Val / 4 ;
+ t = negative ? -1 : 1 * Tc ;
+ dsread=0;
+ crc= OWcrc(scratchpad, 8);
+ addLogAdv(LOG_INFO, LOG_FEATURE_CFG, "DS1820 - Pin=%i temp=%s%i.%02i \r\n",Pin, negative ? "-" : "+", (int)Tc/100 , (int)Tc%100);
+ addLogAdv(LOG_INFO, LOG_FEATURE_CFG, "DS1820 - High=%i Low=%i Val=%i Tc=%i -- Read CRC=%x - calculated:%x \r\n",High, Low, Val,Tc,scratchpad[8],crc);
}
- // Temperature is returned in multiples of 1/16 °C
- // we want a simple way to display e.g. xx.yy °C, so just multiply with 100 and we get xxyy
- // --> the last two digits will be the fractional part (Val%100)
- // --> the whole part of temperature is (int)Val/100
- // so we want 100/16 = 6.25 times the value (the sign to be able to show negative temperatures is in "factor")
- Tc = (6 * Val) + Val / 4 ;
- t = negative ? -1 : 1 * Tc ;
- dsread=0;
- addLogAdv(LOG_INFO, LOG_FEATURE_CFG, "DS1820 - Pin=%i temp=%s%i.%02i \r\n",Pin, negative ? "-" : "+", (int)Tc/100 , (int)Tc%100);
- addLogAdv(LOG_INFO, LOG_FEATURE_CFG, "DS1820 - High=%i Low=%i Val=%i Tc=%i \r\n",High, Low, Val,Tc);
}
else if (g_secondsElapsed % 5 == 0) { // every 5 seconds
// ask for "conversion"
If works fine for me on W800 an BL882H, but it breaks BEKEN. Eve if a temperature reading on my BK7231N seem reasonable, CRC never matches in this case :-(.
BTW: What duration is shown in log for the "usleepds()" loops on BL602 if sensor is not attached? Maybe we can "tweak" the number of nop lines for BL602, too?
I'll try a little later today, but for bl602 I think bl_timer_delay_us function should be used (if it's accurate) instead of playing will all these nops.
I would appreciate your feedback on this approach!
I made some tests here with LN882H and BK7231N an "usleepds" works "o.k." (still with some bad readings from time to time) with "usleep" and a correction factor:
[...]
#elif PLATFORM_BEKEN
usleep((17*r)/10); // "1" is to fast and "2" to slow, 1.7 seems better than 1.5 (only from observing readings, no scope involved)
#elif PLATFORM_LN882H
usleep(5*r); // 5 seems o.k. for now
#else
[...]
there is no "usleep()" for W800 (at least not with additional includes)
if timing is crucial and a bit more of code possible, I also found some calculation for CRC with a (small) lookup-table, derived from the code found here: https://community.st.com/t5/stm32-mcus-security/use-stm32-crc-to-compare-ds18b20-crc/m-p/333749/highlight/true#M4690
// Dallas 1-Wire CRC Test App -
// x^8 + x^5 + x^4 + 1 0x8C (0x131)
// Right Shift// Initialized to Zero
uint8_t Crc8CQuick(uint8_t *Buffer,uint8_t Size)
{ static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C
0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8,
0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 };
uint8_t Crc=0x00;
while(Size--)
{
Crc ^= *Buffer++; // Apply Data
Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits
Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];
}
return(Crc);
}
Looks ok with crc. the factor is mostly this:
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 94 ms
Error:CFG:usleepds duration divergates - proposed factor to adjust usleepds 1.063830
@giedriuslt which GPIO/P# are you using on BL602?
1294_merge_5567f41b03b9 sensor connected
Info:CFG:DS1820 - asked for conversion - Pin 4
Info:CFG:DS1820 - Pin=4 temp=-0.06
Info:CFG:DS1820 - High=255 Low=255 Val=1 Tc=6
Info:CFG:DS1820 - asked for conversion - Pin 4
Info:CFG:DS1820 - Pin=4 temp=-0.06
Info:CFG:DS1820 - High=255 Low=255 Val=1 Tc=6
Info:CFG:DS1820 - asked for conversion - Pin 4
Info:CFG:DS1820 - Pin=4 temp=-0.06
Info:CFG:DS1820 - High=255 Low=255 Val=1 Tc=6
Info:CFG:DS1820 - asked for conversion - Pin 4
Info:CFG:DS1820 - Pin=4 temp=-0.06
Info:CFG:DS1820 - High=255 Low=255 Val=1 Tc=6
Info:CFG:DS1820 - asked for conversion - Pin 4
Info:CFG:DS1820 - Pin=4 temp=-12.06
Info:CFG:DS1820 - High=255 Low=63 Val=193 Tc=1206
disconnected
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 98 ms
Error:CFG:DS1820 - Pin=4 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 100 ms
Error:CFG:DS1820 - Pin=4 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 46 ms
Error:CFG:DS1820 - usleepds(100000) took 99 ms
Error:CFG:DS1820 - Pin=4 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 48 ms
Error:CFG:DS1820 - usleepds(100000) took 100 ms
Error:CFG:DS1820 - Pin=4 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 46 ms
Error:CFG:DS1820 - usleepds(100000) took 94 ms
Error:CFG:usleepds duration divergates - proposed factor to adjust usleepds 1.063830
do you know if your DS18B20 is Analog Devices original or clone like mine: https://www.elektroda.com/rtvforum/viewtopic.php?p=21158431#21158431
It's gpio 1 or pin 2 as I see , one of two free pins on my SM-028 socket. And sensor is clone of family C according to this classification https://github.com/cpetrich/counterfeit_DS18B20 . but I very much doubt clone or not has any relevance here
sorted. something silly
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.81
Info:CFG:DS1820 - High=1 Low=205 Val=461 Tc=2881
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.87
Info:CFG:DS1820 - High=1 Low=206 Val=462 Tc=2887
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.75
Info:CFG:DS1820 - High=1 Low=204 Val=460 Tc=2875
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.62
Info:CFG:DS1820 - High=1 Low=202 Val=458 Tc=2862
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=-0.06
Info:CFG:DS1820 - High=255 Low=255 Val=1 Tc=6
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.50
Info:CFG:DS1820 - High=1 Low=200 Val=456 Tc=2850
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.25
Info:CFG:DS1820 - High=1 Low=196 Val=452 Tc=2825
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.18
Info:CFG:DS1820 - High=1 Low=195 Val=451 Tc=2818
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.06
Info:CFG:DS1820 - High=1 Low=193 Val=449 Tc=2806
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+28.00
Info:CFG:DS1820 - High=1 Low=192 Val=448 Tc=2800
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+27.87
Info:CFG:DS1820 - High=1 Low=190 Val=446 Tc=2787
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+27.81
Info:CFG:DS1820 - High=1 Low=189 Val=445 Tc=2781
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+27.75
Info:CFG:DS1820 - High=1 Low=188 Val=444 Tc=2775
Info:CFG:DS1820 - asked for conversion - Pin 1
Info:CFG:DS1820 - Pin=1 temp=+27.62
Info:CFG:DS1820 - High=1 Low=186 Val=442 Tc=2762
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 46 ms
Error:CFG:DS1820 - usleepds(100000) took 94 ms
Error:CFG:usleepds duration divergates - proposed factor to adjust usleepds 1.063830
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 106 ms
Error:CFG:usleepds duration divergates - proposed factor to adjust usleepds 0.943396
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 93 ms
Error:CFG:usleepds duration divergates - proposed factor to adjust usleepds 1.075269
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 99 ms
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 48 ms
Error:CFG:DS1820 - usleepds(100000) took 99 ms
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 98 ms
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 98 ms
Error:CFG:DS1820 - Pin=1 -- Reset failed
Error:CFG:DS1820 - usleepds(50000) took 47 ms
Error:CFG:DS1820 - usleepds(100000) took 100 ms
I did test disabling interrupts and not, disabling interrupts improves reading accuracy a lot: Tested both for more than 20 hours.
2011/15556 or ~13% failed reading without disabling interrupts 99/19695 or ~0.5% failed readings with interrupts disabled when reading/writing bit.
I think we should use that.
Cool. Side question: where/how are you shipping your logs off to for that period of time?
and unlike for Beken, I'm not seeing powersave 1 have any adverse effect in the very short time my device has been up. This is with a Maxim DS18B20.
I did test disabling interrupts and not, disabling interrupts improves reading accuracy a lot: Tested both for more than 20 hours.
2011/15556 or ~13% failed reading without disabling interrupts 99/19695 or ~0.5% failed readings with interrupts disabled when reading/writing bit.
I think we should use that.
That's impressive, very good!
Maybe we can keep the times with interrupts disabled even shorter if we renable interrupts e.g. directly after reading, and allowing interrupts during "release time". Just an idea to keep the impact as small as possible, has to be checked in real life.
I'm reading logs from port 9000 with ncat
Can you post some tutorial showing how to do it on our forum? Thx! https://www.elektroda.com/rtvforum/forum51.html