Arduino Polska Forum
Problem z kodem do stacji meteo - Wersja do druku

+- Arduino Polska Forum (https://forum.arduinopolska.pl)
+-- Dział: Korzystanie z Arduino (https://forum.arduinopolska.pl/dzial-korzystanie-z-arduino)
+--- Dział: Programowanie w Arduino (https://forum.arduinopolska.pl/dzial-programowanie-w-arduino)
+--- Wątek: Problem z kodem do stacji meteo (/watek-problem-z-kodem-do-stacji-meteo)

Strony: 1 2


Problem z kodem do stacji meteo - Mr2208 - 07-08-2019

Witam.

Mam problem z kodem do stacji meteo mierzącej wilgotność, temperaturę oraz zanieczyszczenie powietrza w cząstkach PM2.5 i PM10.
Stacja składa się z nadajnika i odbiornika. Do nadajnika czyli do arduino nano są podłączone czujniki: DHT22 i PMS7003 oraz moduł transmisji radiowej NRF24L01, a do odbiornika czyli arduino nano jest podłączony moduł NRF24L01 i wyświetlacz, na którym są wyświetlone dane przesłane przez nadajnik. Problem tkwi w tym, że dane z DHT22 są wyświetlane normalnie na wyświetlaczu, a dane z PMS7003 przybierają wartość 0. Czujnik PMS7003 był sprawdzany przykładem z biblioteki przy aktualnym podłączeniu czujnika.
Dlatego prosiłbym o pomoc i sprawdzenie kodu.

Biblioteka PMS7003:https://github.com/fu-hsi/PMS

Kod-Nadajnik
Kod:
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <DHT.h>
#include "PMS.h"

#define DHTPIN 5               
#define DHTTYPE DHT22         
DHT dht(DHTPIN, DHTTYPE);

PMS pms(Serial);
PMS::DATA data2;


RF24 transmit (7,8);                           
byte address [5] = "00001";                    

struct package
  {
    int temperature = 0;
    int humidity = 0;
    int PM25 = 0;
    int PM10 = 0;
  };

typedef struct package Package;
Package data;

void setup() {
  dht.begin();
  transmit.begin();
  transmit.openWritingPipe(address);           
  transmit.setPALevel(RF24_PA_MAX);            
  transmit.setDataRate(RF24_250KBPS);          
  transmit.setChannel(100);                    
  transmit.stopListening();
  Serial.begin(9600);
  }

void loop() {
  data.temperature = dht.readTemperature();
  data.humidity = dht.readHumidity();
  data.PM25 = (data2.PM_AE_UG_2_5);
  data.PM10 = (data2.PM_AE_UG_10_0);
  pms.requestRead();
  transmit.write(&data,sizeof(data));
  delay(1000);                                
}

Kod-Odbiornik
Kod:
#include <LiquidCrystal_I2C.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <Timers.h>


RF24 receive (7,8);                       
byte address [5] = "00001";              
LiquidCrystal_I2C lcd(0x27, 16, 2);



struct package
  {
    int temperature = 0;
    int humidity = 0;
    int PM25 = 0;
    int PM10 = 0;
  };

typedef struct package Package;
Package data;

void setup() {
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Otrzymane dane");
  receive.begin();
  receive.openReadingPipe(0,address);    
  receive.setPALevel(RF24_PA_MIN);      
  receive.setDataRate(RF24_250KBPS);    
  receive.setChannel(100);              
  receive.startListening();               
  }

void loop() {

  if (receive.available())               
  {
    receive.read(&data, sizeof(data));
    lcd.setCursor(0,0);
    lcd.print(data.temperature);
    lcd.print("C  ");
    lcd.print(data.humidity);
    lcd.print("%");
    lcd.setCursor(0,1);
    lcd.print(data.PM25);
    lcd.print("ug/m3  ");
    lcd.print(data.PM10);
    lcd.print("ug/m3");
   
  }
  delay(5000);
  lcd.clear();
}



RE: Problem z kodem do stacji meteo - kaczakat - 07-08-2019

Skoro sprawdziłeś odczyt z czujnika i działa, to teraz sprawdź jak dane są przesyłane, np. zamiast przesyłać rzeczywistą zmienną to wymyśl sobie zmienna++ i 100+zmienna1++, i je wysyłaj co sekundę. Będziesz widział czy są przesyłane prawidłowo. Ten czujnik nie zwraca jakiegoś floata?
No i zająłeś sprzętowy UART na odczyt czujnika, ale zawsze możesz sobie zrobić jakiś softowy na wolnym pinie tylko do wysyłania danych i lokalnie obserwować czy w końcowym programie również odczyty są prawidłowe.


RE: Problem z kodem do stacji meteo - Mr2208 - 07-08-2019

(07-08-2019, 22:13)kaczakat napisał(a): Skoro sprawdziłeś odczyt z czujnika i działa, to teraz sprawdź jak dane są przesyłane, np. zamiast przesyłać rzeczywistą zmienną to wymyśl sobie zmienna++ i 100+zmienna1++, i je wysyłaj co sekundę. Będziesz widział czy są przesyłane prawidłowo. Ten czujnik nie zwraca jakiegoś floata?
No i zająłeś sprzętowy  UART na odczyt czujnika, ale zawsze możesz sobie zrobić jakiś softowy na wolnym pinie tylko do wysyłania danych i lokalnie obserwować czy w końcowym programie również odczyty są prawidłowe.
Sprawdziłem odczyty ze zmienną ++ i wiadomo że liczba nie dodawała się co 1 ale to przez delay, jednak wynik był widoczny na wyświetlaczu. O Softwareowym UART to ja nie pomyślałem, spróbuję i zobaczę jak to wyjdzie Big Grin.


RE: Problem z kodem do stacji meteo - kaczakat - 08-08-2019

W odbiorniku nie powinieneś mieć żadnego delaya.
Jeśli masz nowe dane:
-odbierasz,
-czyścisz ekran,
-wyświetlasz,
-nasłuchujesz nowych danych.
W nadajniku jest to obojętne jak zaplanujesz kiedy wysyłasz, delay na pierwsze testy też jest OK, ale odbiornik powinien być gotowy na akcję zawsze.


RE: Problem z kodem do stacji meteo - Mr2208 - 08-08-2019

(08-08-2019, 15:12)kaczakat napisał(a): W odbiorniku nie powinieneś mieć żadnego delaya.
Jeśli masz nowe dane:
-odbierasz,
-czyścisz ekran,
-wyświetlasz,
-nasłuchujesz nowych danych.
W nadajniku jest to obojętne jak zaplanujesz kiedy wysyłasz, delay na pierwsze testy też jest OK, ale odbiornik powinien być gotowy na akcję zawsze.
Kod:
#include <LiquidCrystal_I2C.h>
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <Timers.h>

Timer Timer1;

RF24 receive (7,8);                       
byte address [5] = "00001";              
LiquidCrystal_I2C lcd(0x27, 16, 2);



struct package
  {
    int temperature = 0;
    int humidity = 0;
    int PM25 = 0;
    int PM10 = 0;
  };

typedef struct package Package;
Package data;

void setup() {
  lcd.begin();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Otrzymane dane");
  receive.begin();
  receive.openReadingPipe(0,address);    
  receive.setPALevel(RF24_PA_MIN);      
  receive.setDataRate(RF24_250KBPS);    
  receive.setChannel(100);              
  receive.startListening();
  Timer1.begin(SECS(10));              
  }

void loop() {
    if(Timer1.available())
{
  lcd.clear();
  delay(1);
  Timer1.restart();
}
  if (receive.available())               
  {
    receive.read(&data, sizeof(data));
    lcd.setCursor(0,0);
    lcd.print(data.temperature);
    lcd.print("C  ");
    lcd.print(data.humidity);
    lcd.print("%");
    lcd.setCursor(0,1);
    lcd.print(data.PM25);
    lcd.print("ug/m3  ");
    lcd.print(data.PM10);
    lcd.print("ug/m3");
   
  }
}
Poprawiłem kod odbiornika, jednak dane z czujnika PMS7003 nie wyświetlają się w dalszym ciągu.


RE: Problem z kodem do stacji meteo - Mr2208 - 08-08-2019

(08-08-2019, 15:12)kaczakat napisał(a): W odbiorniku nie powinieneś mieć żadnego delaya.
Jeśli masz nowe dane:
-odbierasz,
-czyścisz ekran,
-wyświetlasz,
-nasłuchujesz nowych danych.
W nadajniku jest to obojętne jak zaplanujesz kiedy wysyłasz, delay na pierwsze testy też jest OK, ale odbiornik powinien być gotowy na akcję zawsze.
Kod:
#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>
#include <DHT.h>
#include "PMS.h"
#include <SoftwareSerial.h>

SoftwareSerial Serial2(10, 11);

PMS pms(Serial2);
PMS::DATA data2;

#define DHTPIN 5                // do not connect to pin 0 or pin 1
#define DHTTYPE DHT22          // Define DHT11 module
DHT dht(DHTPIN, DHTTYPE);//create DHT object called dht


RF24 transmit (7,8);                            //create RF24 object called transmit
byte address [5] = "00001";                     //set address to 00001

struct package
  {
    int temperature = 0;
    int humidity = 0;
    int PM25 = 0;
    int PM10 = 0;
  };

typedef struct package Package;
Package data;

void setup() {
 
  Serial2.begin(9600);
  Serial.begin(57600);
 
  dht.begin();
  transmit.begin();
  transmit.openWritingPipe(address);            //open writing pipe to address 00001
  transmit.setPALevel(RF24_PA_MAX);             //set RF power output to maximum
  transmit.setDataRate(RF24_250KBPS);           //set datarate to 250kbps
  transmit.setChannel(100);                     //set frequency to channel 100
  transmit.stopListening();

  }

void loop() {

    if (pms.read(data2))
  {

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data2.PM_AE_UG_2_5);

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data2.PM_AE_UG_10_0);

    Serial.println();
  }
  data.temperature = dht.readTemperature();
  data.humidity = dht.readHumidity();
  data.PM25 = (data2.PM_AE_UG_2_5);
  data.PM10 = (data2.PM_AE_UG_10_0);
  pms.requestRead();
  transmit.write(&data,sizeof(data));
  delay(1000);                                 
}
Dopisałem do odbiornika wyświetlanie danych na serial monitorze i podłączyłem czujnik przez softwareserial, w tym przypadku na serial monitorze nie pojawia się kompletnie nic.
Kod:
#include "PMS.h"
#include <SoftwareSerial.h>

SoftwareSerial Serial2(10, 11);

PMS pms(Serial2);
PMS::DATA data2;

void setup()
{
  Serial.begin(57600);   // GPIO1, GPIO3 (TX/RX pin on ESP-12E Development Board)
  Serial2.begin(9600);  // GPIO2 (D4 pin on ESP-12E Development Board)
}

void loop()
{
  if (pms.read(data2))
  {
    Serial.print("PM 1.0 (ug/m3): ");
    Serial.println(data2.PM_AE_UG_1_0);

    Serial.print("PM 2.5 (ug/m3): ");
    Serial.println(data2.PM_AE_UG_2_5);

    Serial.print("PM 10.0 (ug/m3): ");
    Serial.println(data2.PM_AE_UG_10_0);

    Serial.println();
  }

  // Do other stuff...
}
Tu jest zmodyfikowany przeze mnie przykład z podłączonym czujnikiem przez soft serial i o dziwo wyniki pomiaru pojawiają się na serial monitorze.


RE: Problem z kodem do stacji meteo - Mr2208 - 08-08-2019

Zacząłem usuwać linijki kodu po stronie nadajnika i dane z czujnika PMS7003 zaczęły się pojawiać po usunięciu tych linijek, a dokładnie linii z void setup odpowiedzialnych za obsługę modułu nrf24l01
Kod:
  transmit.begin();
  transmit.openWritingPipe(address);           
  transmit.setPALevel(RF24_PA_MAX);           
  transmit.setDataRate(RF24_250KBPS);           
  transmit.setChannel(100);                   
  transmit.stopListening();
Czym może być to spowodowane?


RE: Problem z kodem do stacji meteo - kaczakat - 09-08-2019

Może jednak Twoje moduły nie mają wystarczającej mocy zasilania
transmit.setPALevel(RF24_PA_MAX); ja dodaję zamiast tego transmit.setPALevel(RF24_PA_MIN);
Na min działa zazwyczaj bez kondensatora.
transmit.setDataRate(RF24_250KBPS); tego nie używam, więc wartość domyślna.


RE: Problem z kodem do stacji meteo - Mr2208 - 09-08-2019

(09-08-2019, 12:16)kaczakat napisał(a): Może jednak Twoje moduły nie mają wystarczającej mocy zasilania
transmit.setPALevel(RF24_PA_MAX);    ja dodaję zamiast tego transmit.setPALevel(RF24_PA_MIN); 
Na min działa  zazwyczaj bez kondensatora.           
  transmit.setDataRate(RF24_250KBPS);        tego nie używam, więc wartość domyślna.
Nawet jeśli odłączę nrf24 zostawiając linijki obsługujące ten moduł to i tak jest ten sam problem, brak danych z PMS7003 na serialu. Może biblioteka nrf24l01 koliduje z PMS7003. To samo jest gdy usunę linijkę odpowiedzialną za prędkość transmisji i ustawię moc transmisji na minimum Confused .


RE: Problem z kodem do stacji meteo - kaczakat - 10-08-2019

Jeśli odłączasz jakiś moduł to być może wisi na etapie inicjalizacji czekając na konkretną odpowiedź. Jak coś testujesz to powinieneś mieć komunikat wysyłany co 1s na UART np. ze zmienną++, jakiś migający led w loop, coś co pozwala stwierdzić, że program ruszył i działa, nawet jeśli nie dogaduje się z jakimś konkretnym podzespołem.
PMS korzysta z UART, NRF z SPI, DHT to albo jakiś dziki 1-wire albo coś ala i2c albo i2c. Ciężko tu zrobić jakiś konflikt. O DTH słyszałem, że lubi się zawiesić i wysyła jakieś głupoty aż do odłączenia zasilania, że warto go zasilić z pinu IO i co jakiś czas zapobiegawczo odłączyć. Sprawdź też jak często możesz czytać wskazania z tych czujników, nie wiem jak PMS ale co 1s dla DHT to może być za często, na pewno się podgrzewa co zmienia wskazania i temperatury i RH, nie wiem co tam mierzysz, ale czujnik nadaje się co najwyżej do WC lub pogody, a tu pomiar raz na minutę to świat. Oczywiście zamiast delay trzeba użyć millis() by odmierzać sobie czasy między pomiarami.