Skocz do zawartości

DS18B20 dziwne odczyty


yersey

Pomocna odpowiedź

Wszystko działa dobrze, ale gdy temperatura spadnie poniżej 0 to pokazuje jakiś dziwny odczyt. Siedzę nad tym już drugi dzień i nie wiem o co chodzi. Używam arduino nano. Z góry dziękuję za pomoc 🙂

#include <ModbusRtu.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define SLAVE_ID 1
#define BUTTON_PIN 7
#define RS_PIN 5
#define DS_PIN 10
#define SUN_PIN A1
#define TEMP_REG 0
#define SUN_REG 1

uint16_t au16data[9] = {
  9999, 9999, 2, 3, 2018, 11, 16, 8, 7};

Modbus slave(SLAVE_ID, 0, RS_PIN);
OneWire oneWire(DS_PIN);
DallasTemperature sensors(&oneWire);
DeviceAddress ds18b20 = { 0x28, 0x90, 0x63, 0x45, 0x92, 0x06, 0x02, 0xE0 }; //1
//DeviceAddress ds18b20 = { 0x28, 0x68, 0xA6, 0x45, 0x92, 0x03, 0x02, 0x3C }; //2
//DeviceAddress ds18b20 = { 0x28, 0x12, 0xC6, 0x45, 0x92, 0x08, 0x02, 0x59 }; //3
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int temperature = 9999;
unsigned long getTempTime = 0;
unsigned long lastUpdate = 0;
unsigned long buttonTime = 0;
int buttonHoldTime = 0;
byte sun = 0;
bool lcdLight = true;

void setup() {
  sensors.begin();
  slave.begin( 9600 ); // baud-rate at 9600
  lcd.begin(16,2); 
  pinMode(BUTTON_PIN, INPUT);
}

void loop() {
  temperature = readTemp(); 
  if(temperature != NULL || temperature < 200)
    au16data[TEMP_REG] = temperature;

  sun = readSun();
  if(sun != NULL)
    au16data[SUN_REG] = sun;
    
  slave.poll(au16data, 16);
  
    if(millis()-lastUpdate >= 1500UL)
    {
      lcd.clear();
      printTime();
      lcd.setCursor(0, 1);
      printPage0();
      lastUpdate = millis();
    }
    
  if(digitalRead(BUTTON_PIN) == HIGH){
    if(buttonTime == 0) 
      buttonTime = millis();
      
    buttonHoldTime += millis()-buttonTime;
    buttonTime = millis();
  }
  else{
    if(buttonHoldTime > 750){
      if(lcdLight == true)
        lcdLight = false;
      else lcdLight = true;
    }

    else if(buttonHoldTime < 500 && buttonHoldTime > 50)
      ;
      
    buttonHoldTime = 0;  
    buttonTime = 0;
  }

  if(lcdLight == true) lcd.backlight();
  else lcd.noBacklight();
//////////////////////////////////////
}

int readTemp(){
  
  if(millis()-getTempTime >= 1000UL){
    sensors.requestTemperatures();
    getTempTime = millis();
    return sensors.getTempC(ds18b20)*10;
  }
  else return temperature;
}

byte readSun(){
  return map(analogRead(SUN_PIN), 0, 1023, 0, 100);
}

void printTime(){
    if(au16data[7] < 10)
      lcd.print(0);
    lcd.print(au16data[7]);
    lcd.print(":");
    if(au16data[8] < 10)
      lcd.print(0);
    lcd.print(au16data[8]);
    lcd.print(" ");
    lcd.print(au16data[6]);
    lcd.print(".");
    lcd.print(au16data[5]);
    lcd.print(".");
    lcd.print(au16data[4]);
}

void printPage0(){
    lcd.print("T:");
    lcd.print(au16data[TEMP_REG]/10);
    lcd.print(".");
    lcd.print(au16data[TEMP_REG]-au16data[TEMP_REG]/10*10);
    lcd.print("*C");
    lcd.print(" ");
    lcd.print("SUN:");
    lcd.print(au16data[SUN_REG]);
    lcd.print("%");
}

 

50917540_233674164237651_2049659836483764224_n.jpg

Edytowano przez yersey
Link do komentarza
Share on other sites

@yersey, jeśli dobrze rozumiem to temperaturę przechowujesz w tablicy au16data, zgadza się?

Zadeklarowałeś ją jako typ uint16_t czyli typ bez znaku (mówi o tym pierwsze literka "u" od "unsigned". Reasumując: ta tablica nie potrafi przetrzymywać ujemnych wartości. Musisz zmienić typ danych np. na int16_t lub po prostu na int. Dlaczego akurat wybrałeś taki typ jak uint16_t? To dość mało popularne jak na Arduino 😉 

  • Pomogłeś! 1
Link do komentarza
Share on other sites

4 godziny temu, yersey napisał:

Biblioteka narzuca taki typ, ale to już nie problem, dodam po prostu kolejny element do tablicy oznaczający "minusowość" temperatury.

Nie, nie to brzmi bardzo źle - na pewno nie powinno się tak tego rozwiązywać.

O której bibliotece piszesz? Nie możesz po prostu zadeklarować tablicy w taki sposób, aby pozwalała na zapisywanie wartość ujemnych?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Myślałem pierwotnie, że to zwykłe wyświetlanie danych z czujników na LCD (nie analizowałem kodu), ale skoro masz tu Modbusa, to chyba jednak jest coś więcej. Możesz opisać czym dokładnie jest to urządzenie i co ono ma robić?

Link do komentarza
Share on other sites

@Treker Będzie służyć do monitorowania głównie temperatury w tunelach foliowych (wcześniej trzeba było wstawać w nocy co kilka godzin, bo podajnik węgla potrafił się zaciąć, a jak temperatura by spadła to rip). Teraz wystarczy, że w którymś tunelu spadnie temperatura to w domu włączy się syrena. Mogę też sprawdzać temperaturę na wykresach. Nie jest to pewnie idealne, ale i tak jestem z siebie dumny i przy okazji nauczyłem się masę rzeczy 🙂

 


https://github.com/yersey/arduino-modbus-weather-station

  • Lubię! 1
Link do komentarza
Share on other sites

Ok, teraz ma to większy sens, bo już się bałem, że to zwykły termometr, a masz tam jakieś dziwne rzeczy dorobione 😉

Jednak w takim razie to nic straconego. Możesz dane transmitować jako uint16, ale po odebraniu możesz je sobie rzutować na wersję ze znakiem. Przykład:

void setup() {
  Serial.begin(9600);
  delay(1000);
  
  uint16_t temp = -2;
  Serial.println(temp);
  int16_t temp2 = temp;
  Serial.println(temp2);
  Serial.println((int16_t)temp);
}



void loop() {
}

Możesz to zrobić na dwa sposoby (jak wyżej): możesz przypisać wartość uint16_t do zmiennej typu int16_t i przy wyświetlaniu posługiwać się tą nową zmienną lub możesz przy wyświetlaniu wstawić zapis "(int16_t)" przed nazwą zmiennej uint16_t 🙂 Daj znać czy rozwiązało problem.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.