Skocz do zawartości

Nodemcu v3 (Programowane w arduino ide) problem z pomiarem temperatur


Razor1996

Pomocna odpowiedź

Witam,
Konstruuje termometr który wyświetla zarówno temperatury na wyświetlaczu jak i wysyła ja po wifi. Bazuje na pewnym gotowym projekcie, lecz muszę nanieść kilka zmian. Jedna z nich to wyświetlanie na LCD każdej odczytanej temperatury, a wysyłanie po wifi tylko co np. 5 - ta ilość jest zadawana w programie poprzez define.

Problem wydawał mi się banalny lecz niestety sposób w jaki chciałem go rozwiązać jest nieskuteczny.

Oto kod oryginalny:

void loop() {
 float temp[ilosc];
 //char buffer[10];
 DS18B20.requestTemperatures(); 

 for(int i=0;i<ilosc;i++){
   temp[i] = DS18B20.getTempCByIndex(i);
   //String tempC = dtostrf(temp, 4, 1, buffer);//handled in sendTemp()
   //Serial.print(String(sent)+" Temperature: ");
   //Serial.println(temp);

   //if (temp != prevTemp)
   //{
   //sendTeperatureTS(temp);
   //prevTemp = temp;
   //}
   lcd.setCursor(9, i); // k/w 
   lcd.print("         ");
   lcd.setCursor(9, i); // k/w 
   lcd.print(temp[i]);
   lcd.print(F(" C"));
 }
 sendTeperatureTS(temp);
 int count = myPeriodic;
 while(count--)
 delay(1000);
}

A tak wyglądają moje poprawki

 void loop() {
 float temp[ilosc];
 //char buffer[10];
 DS18B20.requestTemperatures(); 
 licznik ++;

 for(int i=0;i<ilosc;i++){
   temp[i] = DS18B20.getTempCByIndex(i);
   //String tempC = dtostrf(temp, 4, 1, buffer);//handled in sendTemp()
   //Serial.print(String(sent)+" Temperature: ");
   //Serial.println(temp);

   //if (temp != prevTemp)
   //{
   //sendTeperatureTS(temp);
   //prevTemp = temp;
   //}
   lcd.setCursor(9, i); // k/w 
   lcd.print("         ");
   lcd.setCursor(9, i); // k/w 
   lcd.print(temp[i]);
   lcd.print(F(" C"));

 }
 if (licznik == myPeriodic) {
   sendTeperatureTS(temp);
   licznik = 0;
 }

}

Lecz niestety po poprawkach nodemcu wysyła serie temperatur pod rząd i następuje przerwa (jakby czekało na odczyty temperatur ale trwa to kilka sekund). A ja chciałbym aby po każdym odczycie został on wyświetlony na LCD. Zawsze używałem funkcji if (sensors.available()) lecz w tych bibliotekach ona chyba nie istnieje...

Podsumowując brakuje mi funkcji która "wiedziałaby" że własnie odczytano temperaturę, dzięki czemu mógłbym ją wyświetlić i czekać na kolejną.

Biblioteki użyte w programie to #include #include

Link do komentarza
Share on other sites

Oto cały kod.

#include <ESP8266WiFi.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,20,4);  // set the LCD address to 0x3F for a 20 chars and 4 line display

#define myPeriodic 5 //in sec |  pub is 5sec
#define ONE_WIRE_BUS 2  // DS18B20 on arduino pin2 corresponds to D4 on physical board
#define ilosc 4 // ilość czujników - max 4 dla lcd 20x4

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float prevTemp = 0;
const char* server = "xxxxxxxxxxx";
String apiKey ="xxxxxxx";
const char* MY_SSID = "xxxxxxx"; 
const char* MY_PWD = "xxxxxxx";
int sent = 0;
int licznik = 0; 


void setup() {

 Serial.begin(115200);
 connectWifi();

 lcd.init();                      // initialize the lcd 
 lcd.backlight();
 lcd.home();

 lcd.setCursor(0, 0); // k/w 
 lcd.print("Temp. 1: ");

 lcd.setCursor(0, 1); // k/w 
 lcd.print("Temp. 2: ");

 lcd.setCursor(0, 2); // k/w 
 lcd.print("Temp. 3: ");

 lcd.setCursor(0, 3); // k/w 
 lcd.print("Temp. 4: ");

}

void loop() { 
 float temp[ilosc]; 
 //char buffer[10]; 
 DS18B20.requestTemperatures(); 
 licznik ++; 

 for(int i=0;i<ilosc;i++){ 
   temp[i] = DS18B20.getTempCByIndex(i); 
   //String tempC = dtostrf(temp, 4, 1, buffer);//handled in sendTemp() 
   //Serial.print(String(sent)+" Temperature: "); 
   //Serial.println(temp); 

   //if (temp != prevTemp) 
   //{ 
   //sendTeperatureTS(temp); 
   //prevTemp = temp; 
   //} 
   lcd.setCursor(9, i); // k/w 
   lcd.print("         "); 
   lcd.setCursor(9, i); // k/w 
   lcd.print(temp[i]); 
   lcd.print(F(" C")); 

 } 
 if (licznik == myPeriodic) { 
   sendTeperatureTS(temp); 
   licznik = 0; 
 } 

}

void connectWifi()
{
 Serial.print("Connecting to "+*MY_SSID);
 WiFi.begin(MY_SSID, MY_PWD);
 while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
 }

 Serial.println("");
 Serial.println("Connected");
 Serial.println("");  
}//end connect

void sendTeperatureTS(float temp[])
{  
  WiFiClient client;

  if (client.connect(server, 9999)) { // use ip 184.106.153.149 or api.thingspeak.com
  Serial.println("WiFi Client connected ");

  String postStr = apiKey;
  //postStr += "&field1=";
  //postStr += String(temp);
  //postStr += "\r\n\r\n";
  for(int i=0;i<ilosc;i++){
    postStr += "&field";
    postStr += String(i+1);
    postStr += "=";
    postStr += String(temp[i]); 
  }


  client.print("POST /update HTTP/1.1\n");
  client.print("Host: api.thingspeak.com\n");
  client.print("Connection: close\n");
  client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
  client.print("Content-Type: application/x-www-form-urlencoded\n");
  client.print("Content-Length: ");
  client.print(postStr.length());
  client.print("\n\n");
  client.print(postStr);
  delay(1000);

  }//end if
  sent++;
client.stop();
}//end send

EDIT: Już wiem gdzie leży problem!

Gdy program odbierający dane po wifi nie jest włączony ta funkcja (connect):

 if (client.connect(server, 9999)) { // use ip 184.106.153.149 or api.thingspeak.com
  Serial.println("WiFi Client connected ");

Czeka aż 5 sekund na odpowiedź programu, którego praca przez ten cały czas jest wstrzymana. Dlatego też chciałbym zmienić timeout tej funkcji na inną wartość. Ale nigdzie nie mogę go znaleźć. Trzeba przeszukiwać bilbioteki, ponieważ "normalnie" zmienić tylko można client.connect(ip, port) ip i port.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.