• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
NodeMCU + LCD+ DS18b20
#1
Witam, 

Zmontowałem prosty układ złożony z 4 sond ds18b20, wyświetlacza LCD i NodeMCU v2.

Wszystko tak naprawdę działa jednak mam kilka pytań.

Wyświetlacz pokazuje mi 4 temperatury. Kolejność która pozycja zczytuje temp z której sondy jest zależna od kolejności podpięcia sond. Czyli pierwsza będzie wpięta pierwsza itp.. Czy jest jakaś możliwość aby urządzenie pamiętało, że każda sonda podłączona w danym miejscu będzie np pierwszą temperaturą itd?

Druga sprawa to teoretyczne pytanie ponieważ podpiąłem SCL z wyświetlacza pod D1 i pod ten sam pin mam podpięte sondy. Działa to bez problemu ale czy takie rozwiążanie ciągnie za sobą negatywne skutki?

Ostatnie pytanie to o wyświetlacz. Zasialanie podpięte pod Vin , spadków napięcia nie zauważyłem. Na wyjściu z płytki jest 4.48 a na pinach I2C waha się miezy 4.48- 4.55V , na pinach już w samym wyświetlaczu tak samo. 
Mimo to wyświetlacz delikatnie "jarzy się" tzn jest to prawie nie zauważalne ale jednak delikatnie pulsuję. Po podłączeniu pod USB w laptopie mniej jednak pod ładowarką do tel bardziej. To normalne dla tych wyświetlaczy?

Pozdrawiam
Kuba
 
Odpowiedź
#2
Witam.
Jak nie załączasz kodu, schematu/zdjęć to możemy sobie tylko pogdybać. DSy mają indywidualne numery seryjne, po nich pytasz co czuje Piotruś, a co Wojtuś. Kolejność podpięcia nie ma znaczenia.
 
Odpowiedź
#3

Masz rację, już się poprawiam.

Kod:
Kod:
#include <OneWire.h>
#include <DallasTemperature.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

BlynkTimer timer;

float Salon=0;
float Balkon=0;
float Kuchnia=0;
float Lazienka=0;


int stanLED_ok=0;
int LED; // wskaźnik działania procesora

char auth[] = "XXXXXXXX       "; //kod autoryzacji blynk

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxx";// nazwa sieci
char pass[] = "xxxxxxx"; // hasło do wifi



void setup()
{
 // Debug console
 Serial.begin(9600);
   lcd.backlight();
   lcd.begin(16,2);
   lcd.init();
Serial.println(LED);

 Blynk.begin(auth, ssid, pass);
 // You can also specify server:
 //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
 //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
 sensors.begin();
 sensors.requestTemperatures();

 timer.setInterval(1000L, temp);
 
 // The begin call takes the width and height. This
 // Should match the number provided to the constructor.
 
}


void  temp()
{

  SALON = sensors.getTempCByIndex(0);
  BALKON = sensors.getTempCByIndex(1);
  KUCHNIA = sensors.getTempCByIndex(2);
  LAZIENKA = sensors.getTempCByIndex(3);
  sensors.requestTemperatures();

 
Blynk.virtualWrite(0,SALON);
Blynk.virtualWrite(1,BALKON);
Blynk.virtualWrite(2,KUCHNIA);
Blynk.virtualWrite(3,LAZIENKA);

stanLED_ok = !stanLED_ok;
 if (stanLED_ok == 0) {
  Blynk.virtualWrite(10,255);Blynk.setProperty(V10,"color","#D3435C");
 }
 else {
   Blynk.virtualWrite(10,255);Blynk.setProperty(V10,"color","#04C0F8");
 }
 
//Blynk.syncAll();
}
void loop()
{
sensors.requestTemperatures();
 lcd.setCursor(0, 0);
 lcd.print("1:");
 lcd.setCursor(2, 0);      
 lcd.print(SALON);
 lcd.setCursor(7,0);
 lcd.print("  2:");
 lcd.setCursor(11,0);
 lcd.print(KUCHNIA);
 lcd.setCursor(0, 1);
 lcd.print("3:");      
 lcd.print(BALKON);
 lcd.setCursor(7,1);
 lcd.print("  4:");
 lcd.setCursor(11,1);
 lcd.print(LAZIENKA);  


 Blynk.run();
 timer.run();
 
}

 
 
Pytania które napisałem powyżej praktycznie rozwiązałem, w bibliotece wyświetlacza zdefiniowałem piny.  Zagadką jest wciąż kolejność sond. U mnie na wyświetlaczu mam je podpisane jako 1,2,3,4 i w zależności którą sonde wetkne pierwszą ta zostaje przypisane do numeru 1.


Tak naprawdę został mi do rozwiązania kolejny problem. Otóż gdy wyłącze Wi-fi w dome to wyświetlacz przestaje pokazywać temperatury a chciałbym aby działał niezależnie od wifi.

Pozdrawiam


Załączone pliki Miniatury
   
 
Odpowiedź
#4
Wydrukuj sobie numery seryjne czujników na serial monitor, potem umieść je w kodzie i wołaj je po tym numerze zamiast po indeksie. Przykładów jest pełno, np. : https://www.instructables.com/id/Get-the...n-Arduino/ .
Blynk.run(); pewnie się blokuje jak nie ma połączenia wifi. W ESP jest funkcja zwracająca status połączenia  WiFi.status() Możesz zrobić taką linijkę zamiast bynk.run: if(  WiFi.status() == WL_CONNECTED) Blynk.run(); .
 
Odpowiedź
#5
Bardzo dziękuję za pomoc,
lcd.print(" 2:");
lcd.setCursor(11,0);
lcd.print(BALKON);
lcd.setCursor(0, 1);
lcd.print("3:");
lcd.print(KUCHNIA);
lcd.setCursor(7,1);
lcd.print(" 4:");
lcd.setCursor(11,1);
lcd.print(LAZIENKA);


if( WiFi.status() == WL_CONNECTED) Blynk.run();
timer.run();


Nadal jest tak samo bez połączenia nie ma wartości na wyświetlaczu. Masz może jeszcze jakiś pomysł?
Jeżeli chodzi o kolejność sond. Mi nie zależy na tym aby podpiąć konkretną sonde jako 1 . Mam zamiar zrobić sondy dołączane poprzez gniazda mini jack. Chciałbym przypisać gniazdo do konkretnej pozycji. Tak żebym zawsze wtykając sonde w gniazdo numer dwa miał na wyświetlaczu temperaturę nr 2 zczytywaną.
 
Odpowiedź
#6
Nie ważne czy podłączysz jackiem, wtyczką telefoniczną, czy na pająka lub w stykówce. Albo robisz sobie osobną magistralę dla każdego czujnika - czyli dla kuchni podpinasz na 2, balkon na pinie 3, itd., albo odczytujesz ich adresy (address, Serial Number). Jest oczywiście przykład z odczytem adresu czujnika w bibliotece, chyba single albo simple. Jest też po polsku, tylko dla innej biblioteki: http://akademia.nettigo.pl/ds18b20/ .
Zresztą możesz zidentyfikować który czujnik gdzie sobie umieściłeś i dopasować do niego program, ale jak np. odepniesz wykryty jako 2 to pozostałe przeskoczą w indeksie, łazienka będzie widoczna jako kuchnia.
Analogicznie timer też jest związany z blinkiem, dołóż jeszcze raz to tutaj (obejmij klamrą tego ifa). Jak nie pomoże zakomentuj te dwie linie i sprawdź czy w ogóle to wystarczy by program działał bez WIFI, może jeszcze gdzieś w setupie trzeba to zrobić.
No i zerknąłem jeszcze raz: Blynk.virtualWrite(0,SALON); - wszystkie takie funkcje związane z WIFI/blinkiem powinieneś zgrupować w jednej, którą wykonasz tylko wtedy gdy jest połączenie WIFI.
 
Odpowiedź
#7
" Jak nie pomoże zakomentuj te dwie linie i sprawdź czy w ogóle to wystarczy by program działał bez WIFI, może jeszcze gdzieś w setupie trzeba to zrobić.
No i zerknąłem jeszcze raz: Blynk.virtualWrite(0,SALON); - wszystkie takie funkcje związane z WIFI/blinkiem powinieneś zgrupować w jednej, którą wykonasz tylko wtedy gdy jest połączenie WIFI."

Podpowiesz jak to wykonać?
 
Odpowiedź
#8
Z tą biblioteką blink jest mały szkopuł, nie ma obiektu wifi, pewnie biblioteka tworzy go wewnątrz na podstawie podanych danych. Funkcje normalnie działające po linijce WiFi.begin(SSID,PASS) u Ciebie nie zadziałają. Może jest jakieś przeniesienie, zadziała np. Blynk.status() == WL_CONNECTED zamiast WiFi.status() == WL_CONNECTED.

Masz funkcję void  temp() i w niej funkcje do LCD i Blink, zrób sobie drugą np. tempBlink(), przenieś do niej wszystko z blink i wywołuj tylko wtedy gdy jest połączenie wifi. 
Nie wiem czy to zadziała, bo timer jest oparty o blink, jak gdzieś tam w tej funkcji też jest połączenie to i tak zawiśnie:
Kod:
#include <OneWire.h>
#include <DallasTemperature.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

BlynkTimer timer;
BlynkTimer timer2;

float Salon=0;
float Balkon=0;
float Kuchnia=0;
float Lazienka=0;


int stanLED_ok=0;
int LED; // wskaźnik działania procesora

char auth[] = "XXXXXXXX       "; //kod autoryzacji blynk

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "xxxxxxx";// nazwa sieci
char pass[] = "xxxxxxx"; // hasło do wifi



void setup()
{
// Debug console
Serial.begin(9600);
  lcd.backlight();
  lcd.begin(16,2);
  lcd.init();
Serial.println(LED);

Blynk.begin(auth, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
sensors.begin();
sensors.requestTemperatures();

timer.setInterval(1000L, temp);
 timer2.setInterval(1000L, tempBlink);
 
// The begin call takes the width and height. This
// Should match the number provided to the constructor.

}


void  temp()
{
 SALON = sensors.getTempCByIndex(0);
 BALKON = sensors.getTempCByIndex(1);
 KUCHNIA = sensors.getTempCByIndex(2);
 LAZIENKA = sensors.getTempCByIndex(3);
 sensors.requestTemperatures();
}


void  tempBlink()
{
if( ! WiFi.status() == WL_CONNECTED) return; //jezeli nie ma polaczenia wyjdz z funkci teraz
Blynk.virtualWrite(0,SALON);
Blynk.virtualWrite(1,BALKON);
Blynk.virtualWrite(2,KUCHNIA);
Blynk.virtualWrite(3,LAZIENKA);

stanLED_ok = !stanLED_ok;
if (stanLED_ok == 0) {
 Blynk.virtualWrite(10,255);Blynk.setProperty(V10,"color","#D3435C");
}
else {
  Blynk.virtualWrite(10,255);Blynk.setProperty(V10,"color","#04C0F8");
}

//Blynk.syncAll();
}




void loop()
{
sensors.requestTemperatures();
lcd.setCursor(0, 0);
lcd.print("1:");
lcd.setCursor(2, 0);      
lcd.print(SALON);
lcd.setCursor(7,0);
lcd.print("  2:");
lcd.setCursor(11,0);
lcd.print(KUCHNIA);
lcd.setCursor(0, 1);
lcd.print("3:");      
lcd.print(BALKON);
lcd.setCursor(7,1);
lcd.print("  4:");
lcd.setCursor(11,1);
lcd.print(LAZIENKA);  

timer.run();
//Mozna w ogole nie urachamiac timera z blinkiem dodajac go do tego ifa blynk.run();
if( WiFi.status() == WL_CONNECTED)
{
Blynk.run();
timer2.run(); //to jest sprawdzane przed uruchomieniem i wewnatrz funkcji przypisanej do timer2
}

}

Nie mam blinka by to przetestować, coś w tym stylu. Co do czujników DS, stały zestaw 4 czujników zawsze będzie miał tą samą kolejność, zmienić się może po dodaniu do 4 piątego, wyjęciu jednego lub zamiany czujnika na inny. Ale bezpieczniej jest przypisać w programie ich zastosowanie po SN, może być tak że masz 4 czujniki, jeden z nich używasz do termostatu i nagle układ sterowany czujnikiem 2 zacznie być sterowany czujnikiem 3 będący w innej części maszyny. Lepiej od razu wykryć brak czujnika, uszkodzenie i zareagować. Jak to jest do monitoringu dla zabawy to nie ma znaczenia, kolejność zawsze powinna być taka sama.
Tu przerobiony przykład SINGLE z biblioteki na 5 czujników.
To co przy kratkach trzeba zakomentować za pierwszym razem, skopiować z monitora portu do programu i potem zakomentować znowu przypisywanie SN po indeksie.
Kod:
// Include the libraries we need
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into port 4 on the Arduino
#define ONE_WIRE_BUS 4

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

// arrays to hold device address
//##################################################################################
// Przed odczytaniem SN
//DeviceAddress insideThermometer1;
//DeviceAddress insideThermometer2;
//DeviceAddress insideThermometer3;
//DeviceAddress insideThermometer4;
//DeviceAddress insideThermometer5;
//##################################################################################
// Po odczytaniu SN
DeviceAddress insideThermometer1 = {0x28, 0xFF, 0x7, 0x15, 0x60, 0x17, 0x3, 0x65};
DeviceAddress insideThermometer2 = {0x28, 0xFF, 0xF5, 0x89, 0x60, 0x17, 0x3, 0xB3};
DeviceAddress insideThermometer3 = {0x28, 0xFF, 0x59, 0x68, 0x60, 0x17, 0x5, 0xBA};
DeviceAddress insideThermometer4 = {0x28, 0xFF, 0xBE, 0x3, 0x60, 0x17, 0x3, 0xE8};
DeviceAddress insideThermometer5 = {0x28, 0xFF, 0x8, 0xE4, 0x60, 0x17, 0x5, 0x29};
/*
* Setup function. Here we do the basics
*/
void setup(void)
{
 // start serial port
 Serial.begin(115200);
 Serial.println("Dallas Temperature IC Control Library Demo");

 // locate devices on the bus
 Serial.print("Locating devices...");
 sensors.begin();
 Serial.print("Found ");
 Serial.print(sensors.getDeviceCount(), DEC);
 Serial.println(" devices.");

 // report parasite power requirements
 Serial.print("Parasite power is: ");
 if (sensors.isParasitePowerMode()) Serial.println("ON");
 else Serial.println("OFF");
 
 // Assign address manually. The addresses below will beed to be changed
 // to valid device addresses on your bus. Device address can be retrieved
 // by using either oneWire.search(deviceAddress) or individually via
 // sensors.getAddress(deviceAddress, index)
 // Note that you will need to use your specific address here
//###################To nie zadziala, zabroniona operacja w C++.
//  insideThermometer = { 0x28, 0x1D, 0x39, 0x31, 0x2, 0x0, 0x0, 0xF0 };

 // Method 1:
 // Search for devices on the bus and assign based on an index. Ideally,
 // you would do this to initially discover addresses on the bus and then
 // use those addresses and manually assign them (see above) once you know
 // the devices on your bus (and assuming they don't change).
//#########################################################################################################
//By odczytac i przypisac SN czujnikow:
//  if (!sensors.getAddress(insideThermometer1, 0)) Serial.println("Unable to find address for Device 0");
//  if (!sensors.getAddress(insideThermometer2, 1)) Serial.println("Unable to find address for Device 1");
//############################### PODMIANA CZUJNIKA, będą dwa odczyty z czujnika na indeksie 3
  if (!sensors.getAddress(insideThermometer3, 3)) Serial.println("Unable to find address for Device 2");
else Serial.println("Przypisano czujnik z indexu 3 do 3");
//  if (!sensors.getAddress(insideThermometer4, 3)) Serial.println("Unable to find address for Device 3");
//  if (!sensors.getAddress(insideThermometer5, 4)) Serial.println("Unable to find address for Device 4");

 // method 2: search()
 // search() looks for the next device. Returns 1 if a new address has been
 // returned. A zero might mean that the bus is shorted, there are no devices,
 // or you have already retrieved all of them. It might be a good idea to
 // check the CRC to make sure you didn't get garbage. The order is
 // deterministic. You will always get the same devices in the same order
 //
 // Must be called before search()
 //oneWire.reset_search();
 // assigns the first address found to insideThermometer
 //if (!oneWire.search(insideThermometer)) Serial.println("Unable to find address for insideThermometer");

 // show the addresses we found on the bus
 Serial.print("Device 0 Address: ");
 printAddress(insideThermometer1);
 Serial.println();

 Serial.print("Device 1 Address: ");
 printAddress(insideThermometer2);
 Serial.println();

   Serial.print("Device 2 Address: ");
 printAddress(insideThermometer3);
 Serial.println();

   Serial.print("Device 3 Address: ");
 printAddress(insideThermometer4);
 Serial.println();

   Serial.print("Device 4 Address: ");
 printAddress(insideThermometer5);
 Serial.println();

 
 // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions)
 sensors.setResolution(insideThermometer1, 12);
  sensors.setResolution(insideThermometer2, 12);
   sensors.setResolution(insideThermometer3, 12);
    sensors.setResolution(insideThermometer4, 12);
     sensors.setResolution(insideThermometer5, 12);

 Serial.print("Device 0 Resolution: ");
 Serial.print(sensors.getResolution(insideThermometer1), DEC);
 Serial.println();

   Serial.print("Device 1 Resolution: ");
 Serial.print(sensors.getResolution(insideThermometer2), DEC);
 Serial.println();

   Serial.print("Device 2 Resolution: ");
 Serial.print(sensors.getResolution(insideThermometer3), DEC);
 Serial.println();

   Serial.print("Device 3 Resolution: ");
 Serial.print(sensors.getResolution(insideThermometer4), DEC);
 Serial.println();

   Serial.print("Device 4 Resolution: ");
 Serial.print(sensors.getResolution(insideThermometer5), DEC);
 Serial.println();
}

// function to print the temperature for a device
void printTemperature(DeviceAddress deviceAddress)
{
 // method 1 - slower
 //Serial.print("Temp C: ");
 //Serial.print(sensors.getTempC(deviceAddress));
 //Serial.print(" Temp F: ");
 //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit

 // method 2 - faster
 float tempC = sensors.getTempC(deviceAddress);
 Serial.print("Temp C: ");
 Serial.print(tempC);
 Serial.print(" Temp F: ");
 Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
}
/*
* Main function. It will request the tempC from the sensors and display on Serial.
*/
void loop(void)
{
 // call sensors.requestTemperatures() to issue a global temperature
 // request to all devices on the bus
 Serial.print("Requesting temperatures...");
 sensors.requestTemperatures(); // Send the command to get temperatures
 Serial.println("DONE");
 
 // It responds almost immediately. Let's print out the data
 printTemperature(insideThermometer1); // Use a simple function to print out the data
printTemperature(insideThermometer2); // Use a simple function to print out the data
 printTemperature(insideThermometer3); // Use a simple function to print out the data
  printTemperature(insideThermometer4); // Use a simple function to print out the data
   printTemperature(insideThermometer5); // Use a simple function to print out the data
 delay(5000);
 
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
 for (uint8_t i = 0; i < 8; i++)
 {
   if (deviceAddress[i] < 16) Serial.print("0");
   Serial.print(deviceAddress[i], HEX);
 }
}
 
Odpowiedź
#9
Próbowałem zrobić jak napisałeś wyżej... nadal to samo. Na zagranicznych forach natknąłem się, że jest to problem który nie tylko mnie spotkał. Dziś już na to nie mam siły. Będę próbował, aż się uda.
 
Odpowiedź
#10
BlynkTimer, to zmieniona biblioteka SimpleTimers.
Obsługuje więcej obiektów, można liczyć czas w cyklach zegarowych, oraz wywoływać funkcję określoną ilość razy.
Poza tym nie różni się niczym od w/w, więc ona nie blokuje programu.
W BlynkSimpleEsp8266.h jest funkcja obsługująca połączenie Wi-Fi, ale tam też nie ma problemów.
Jedyne co przychodzi mi do głowy, to BlynkProtocol.h i funkcja sendCmd.
Status if(!conn.connected) był sprawdzany gdy program wchodził w funkcję, a pętla wysyłająca bufor już tego nie sprawdzała i w momencie utraty połączenia, gdy byliśmy wewnątrz tej pętli, sprzęt się zawieszał.
Piszę w czasie przeszłym, ponieważ ten problem został już dawno rozwiązany. Być może Stark ma jakieś stare biblioteki?
Poza tym jest coś takiego, jak watchdog i w tym programie reset niczego nie popsuje, a na pewno rozwiąże problem.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości