zbx-sadman / zabbuino

Zabbix agent for Arduino
92 stars 14 forks source link

DS18B20 не верные показания минусовой температуры #7

Closed foremannn closed 7 years ago

foremannn commented 7 years ago

Добрый день! При использовании датчиков температуры 18B20 не корректно выводятся отрицательные температуры. При опросе датчика zabbix_get получаю цифры -103278.6424, -103278.9324, -103278.1824 и т.п. (реальна температура около нуля). Можно это как-то исправить?

Странная история. Я специально сейчас в src\ow_sensors.cpp подсунул tRaw = 0xFC90; (-55 по даташиту) перед началом вычислений. Result: -55.0. С 0xFF5E тоже всё нормально. Т.е. математически верно вычисляется. Исправить можно, если найти на каком этапе корежится tRaw. Попробуйте перед if (tRaw & 0x8000) сделать Serial.println(tRaw) (и после каждой операции с этой переменной - тоже можно), активировать отладку (FEATURE_DEBUG_TO_SERIAL_LOW) и в IDE Serial Monitor посмотреть, что вываливается при опросе. Ну и я, как свободный хвост с DS18B20 найду, суну его в холодильник. Насколько быстро - не могу сказать.

Добавил в ow_sensors.cpp `// Negative value of temperature testing // if (signBit) ... signBit = false; Serial.println(tRaw); if (tRaw & 0x8000) { signBit = true; // Some magic passes are need to get correct temperature value // Refer to DS18B20's datasheet, Table 1. Temperature/Data Relationship Serial.println(tRaw); tRaw = (tRaw ^ 0xffff) + 1; // 2's comp Serial.println(tRaw); }

// Do 'unfloat' procedure for using number with my ltoaf() subroutine: multiply temp to 0.0625 (1/16 C) Serial.println(tRaw); tRaw = 100; Serial.println(tRaw); tRaw = ((tRaw 6) + (tRaw / 4)); Serial.println(tRaw);

if (signBit) { Serial.println(tRaw); tRaw = -tRaw; Serial.println(tRaw); }

Serial.println(tRaw); ltoaf(tRaw, _dst, 4); Serial.println(tRaw);

rc = RESULT_IN_BUFFER;

finish: gatherSystemMetrics(); // Measure memory consumption delete owDevice; return rc; }`

Далее zabbix_get с уличного датчика получаю (минусовая температура): 4294967280 4294967280 4294901776 4294901776 4288415296 1032791824 1032791824 3262175472 3262175472 3262175472 Result: -103279.1824

с датчика в помещении: 384 384 38400 240000 240000 240000 Result: 24.0

foremannn commented 7 years ago

Пробовал экспериментальный Zabbuino 1.2.0, там на выходе тоже не верно выдает, но цифры другие - 4094, 4095.

zbx-sadman commented 7 years ago

Да, похоже, что до начала вычислений в tRaw выставляются лишние старшие биты. 4294967280 => FFFF FFF0, по даташиту естественно, такого числа быть не может. Я примерно понял, где может скрываться ошибка, но сейчас под рукой у меня DS-ок нет...

Предполагаю, что можно на данный момент попробовать купировать лишние биты:

...
tRaw = tRaw & 0xFFFF; //     << Вставить эту строчку в ow_sensors.cpp
signBit = false;
if (tRaw & 0x8000) {
foremannn commented 7 years ago

Спасибо большое за помощь, вроде бы заработало, идут показания с датчика -1, -0.5, -1.5 градуса (переменная облачность). Посмотрю какие будут показания в течении дня и ночью.

Может быть, конечно, что то не так с датчиками (приехали из китая), но пока ждал из того же китая ардуину пробовал вот этот софт (http://purebasic.mybb.ru/viewtopic.php?id=475) там проблем не было, отрицательная температура отображалась как положено.

zbx-sadman commented 7 years ago

Нет, похоже у меня там что-то перекосило после применения 32-bit переменной вместо 16-bit, как в оригинальном коде. А она была введена для того, чтобы правильно отмасштабировать показания и избавится от "дорогих" float-переменных и связанных с ними операций. На улице же у меня термометра нет, так что ошибка так и оставалась незамеченной.

zbx-sadman commented 7 years ago

Я пересмотрел код, проблема, по-моему, тут:

  tRaw = (((int16_t) scratchPad[DS18X20_BYTE_TEMP_MSB]) << 8) | scratchPad[DS18X20_BYTE_TEMP_LSB];

Нужно привести к виду

  tRaw = (((int32_t) scratchPad[DS18X20_BYTE_TEMP_MSB]) << 8) | scratchPad[DS18X20_BYTE_TEMP_LSB];

т.е. _int16t заменить на _int32t. Тогда грязный хак со сбросом старших битов не понадобится. Проверьте, пожалуйста и я внесу изменения в master-branch.

foremannn commented 7 years ago

Сделал, только результат наверное будет только завтра, сейчас на улице +1 градус.

foremannn commented 7 years ago

Все хорошо, минусовая идет нормальная: 1