#include <HardwareSerial.h>
#define RXD2 16
#define TXD2 17
#define RS485_EN 4 // Pin pro ovládání DE/RE
HardwareSerial mySerial(2);
// Globální proměnné s výchozími hodnotami
String idZarizeni = "";
String alarmViditelnosti = "";
String stavHardwaru = "";
String viditelnostJednaMinuta = "0";
String viditelnostDesetMinut = "0";
String kodPocasi = "";
String okamzityPwKod = "";
String patnactMinutPwKod = "";
String hodinaPwKod = "";
String intenzitaVody = "0";
String soucetVody = "0";
String soucetSnehu = "0";
String teplota = "0";
String jasPozadi = "0";
void setup() {
pinMode(RS485_EN, OUTPUT);
digitalWrite(RS485_EN, LOW); // Nastavení do režimu přijímání
Serial.begin(115200);
mySerial.begin(9600, SERIAL_8N1, RXD2, TXD2);
Serial.println("Vaisala PWD12 RS-485 Reader");
}
void loop() {
if (mySerial.available()) {
char data[256];
int dataIdx = 0;
while (mySerial.available()) {
char c = mySerial.read();
if (c == '\n' || dataIdx >= 255) {
break;
}
data[dataIdx++] = c;
delay(2);
}
data[dataIdx] = '\0';
if (isValidData(data)) {
Serial.print("Přijato: ");
Serial.println(data);
parsePWD12Data(data);
} else {
Serial.println("Neplatná nebo prázdná data přijatá.");
}
}
}
bool isValidData(char* data) {
return (strstr(data, "PW ") != NULL);
}
void parsePWD12Data(char* data) {
char* start = strstr(data, "PW ");
if (start == NULL) {
Serial.println("Chyba: Neplatný formát dat.");
return;
}
start += 4;
// Rozdělení řádku na pole
String pole[14]; // Pole pro uložení polí
int poleIndex = 0;
// Zpracování prvního pole zvlášť, rozdělení na tři jednociferná pole
for (int i = 0; i < 3 && start[i] != '\0'; ++i) {
if (start[i] >= '0' && start[i] <= '9') {
pole[poleIndex++] = String(start[i]);
}
}
char* field = strtok(start + 3, " "); // Začátek za prvními třemi číslicemi
while (field != NULL && poleIndex < 14) {
pole[poleIndex++] = String(field);
field = strtok(NULL, " ");
}
// Kontrola, zda máme očekávaný počet polí
if (poleIndex < 14) {
Serial.println("Chyba: Neúplná data.");
return;
}
// Nahrazení neplatných dat "NO"
for (int i = 0; i < 14; ++i) {
if (pole[i] == "/" || pole[i] == "//" || pole[i] == "///" || pole[i] == "////" || pole[i] == "/////") {
pole[i] = "NO";
}
}
// Zpracování polí a přiřazení globálním proměnným
idZarizeni = pole[0];
alarmViditelnosti = pole[1];
stavHardwaru = pole[2];
viditelnostJednaMinuta = pole[3];
viditelnostDesetMinut = pole[4];
kodPocasi = pole[5];
okamzityPwKod = pole[6];
patnactMinutPwKod = pole[7];
hodinaPwKod = pole[8];
intenzitaVody = pole[9];
soucetVody = pole[10];
soucetSnehu = pole[11];
teplota = pole[12];
jasPozadi = pole[13];
Serial.print("ID zařízení: ");
Serial.println(idZarizeni);
Serial.print("Alarm viditelnosti: ");
Serial.println(visibilityAlarmDescription(alarmViditelnosti));
Serial.print("Stav hardwaru: ");
Serial.println(hardwareStatusDescription(stavHardwaru));
Serial.print("Viditelnost (průměr za 1 min): ");
Serial.print(viditelnostJednaMinuta);
Serial.println(" m");
Serial.print("Viditelnost (průměr za 10 min): ");
Serial.print(viditelnostDesetMinut);
Serial.println(" m");
Serial.print("Okamžitý kód počasí: ");
Serial.print(" (" + String(kodPocasi) + ") ");
Serial.println(weatherCodeDescription(kodPocasi));
Serial.print("Okamžitý PW kód: ");
Serial.print(" (" + String(okamzityPwKod) + ") ");
Serial.println(pwCodeDescription(okamzityPwKod));
Serial.print("15 min PW kód: ");
Serial.println(pwCodeDescription(patnactMinutPwKod));
Serial.print("1 hod PW kód: ");
Serial.println(pwCodeDescription(hodinaPwKod));
Serial.print("Intenzita srážek: ");
Serial.print(intenzitaVody);
Serial.println(" mm/h");
Serial.print("Kumulativní součet vody: ");
Serial.print(soucetVody);
Serial.println(" mm");
Serial.print("Kumulativní součet sněhu: ");
Serial.print(soucetSnehu);
Serial.println(" mm");
Serial.print("Teplota: ");
Serial.print(teplota);
Serial.println(" °C");
Serial.print("Jas pozadí: ");
Serial.println(jasPozadi);
}
String visibilityAlarmDescription(String code) {
if (code == "0") return "Zařízení je v pořádku";
else if (code == "1") return "Alarm viditelnosti 1";
else if (code == "2") return "Alarm viditelnosti 2";
else if (code == "3") return "Alarm viditelnosti 3";
return "Neznámý";
}
String hardwareStatusDescription(String code) {
if (code == "0") return "Zařízení je v pořádku";
else if (code == "1") return "Chyba hardwaru";
else if (code == "2") return "Varování hardwaru";
else if (code == "3") return "Alarm zpětného rozptylu";
else if (code == "4") return "Varování zpětného rozptylu";
return "Neznámý";
}
String pwCodeDescription(String code) {
if (code == "0" || code == "00") return "Vývoj oblačnosti nepozorován nebo nepozorovatelný";
else if (code == "1" || code == "01") return "Oblačnost se obecně rozpadá nebo méně vyvíjí";
else if (code == "2" || code == "02") return "Stav oblohy celkově beze změn";
else if (code == "3" || code == "03") return "Oblačnost se obecně tvoří nebo vyvíjí";
else if (code == "4" || code == "04") return "Viditelnost snížena kouřem (např. požáry, průmyslový kouř nebo sopečný popel)";
else if (code == "5" || code == "05") return "Oparem";
else if (code == "6" || code == "06") return "Rozšířený prach v ovzduší, nezvednutý větrem při nebo poblíž stanice v době pozorování";
else if (code == "7" || code == "07") return "Prach nebo písek zvednutý větrem při nebo poblíž stanice v době pozorování, ale bez dobře vyvinutých prachových nebo písečných vírů a bez prachové nebo písečné bouře";
else if (code == "8" || code == "08") return "Dobře vyvinuté prachové nebo písečné víry viditelné při nebo poblíž stanice během předchozí hodiny nebo v době pozorování, ale bez prachové nebo písečné bouře";
else if (code == "9" || code == "09") return "Prachová nebo písečná bouře viditelná při pozorování nebo během předchozí hodiny při stanici";
else if (code == "10") return "Mlha";
else if (code == "11") return "Proudy mělké mlhy nebo ledové mlhy při stanici, ne hlouběji než asi 2 metry na zemi nebo 10 metrů na moři";
else if (code == "12") return "Více či méně souvislá mělká mlha nebo ledová mlha při stanici, ne hlouběji než asi 2 metry na zemi nebo 10 metrů na moři";
else if (code == "13") return "Viditelný blesk, bez slyšitelného hromu";
else if (code == "14") return "Srážky na dohled, nedosahující země nebo povrchu moře";
else if (code == "15") return "Srážky na dohled, dosahující země nebo povrchu moře, ale vzdálené, tj. odhadované na více než 5 km od stanice";
else if (code == "16") return "Srážky na dohled, dosahující země nebo povrchu moře, blízko, ale ne při stanici";
else if (code == "17") return "Bouřka, ale bez srážek v době pozorování";
else if (code == "18") return "Nárazový vítr při nebo v dohledu stanice během předchozí hodiny nebo v době pozorování";
else if (code == "19") return "Trychtýřová mračna při nebo v dohledu stanice během předchozí hodiny nebo v době pozorování";
else if (code == "20") return "Mrholení (nezmrzající) nebo sněhové zrníčka, nepadající jako přeháňky";
else if (code == "21") return "Déšť (nezmrzající), nepadající jako přeháňky";
else if (code == "22") return "Sníh, nepadající jako přeháňky";
else if (code == "23") return "Déšť a sníh nebo ledové kroupy, nepadající jako přeháňky";
else if (code == "24") return "Mrznoucí mrholení nebo mrznoucí déšť, nepadající jako přeháňky";
else if (code == "25") return "Přeháňky deště";
else if (code == "26") return "Přeháňky sněhu, nebo deště a sněhu";
else if (code == "27") return "Přeháňky krup, nebo deště a krup";
else if (code == "28") return "Mlha nebo ledová mlha";
else if (code == "29") return "Bouřka (srážky nebo bez srážek)";
else if (code == "30") return "Mírná nebo středně silná prachová nebo písečná bouře, zeslábla během předchozí hodiny";
else if (code == "31") return "Mírná nebo středně silná prachová nebo písečná bouře, bez výrazné změny během předchozí hodiny";
else if (code == "32") return "Mírná nebo středně silná prachová nebo písečná bouře, začala nebo zesílila během předchozí hodiny";
else if (code == "33") return "Silná prachová nebo písečná bouře, zeslábla během předchozí hodiny";
else if (code == "34") return "Silná prachová nebo písečná bouře, bez výrazné změny během předchozí hodiny";
else if (code == "35") return "Silná prachová nebo písečná bouře, začala nebo zesílila během předchozí hodiny";
else if (code == "36") return "Mírné nebo střední sněžení, většinou nízké (pod úroveň očí)";
else if (code == "37") return "Těžké sněžení, většinou nízké (pod úroveň očí)";
else if (code == "38") return "Mírné nebo střední sněžení, většinou vysoké (nad úroveň očí)";
else if (code == "39") return "Těžké sněžení, většinou vysoké (nad úroveň očí)";
else if (code == "40") return "Mlha nebo ledová mlha v dálce v době pozorování, ale ne při stanici během předchozí hodiny, mlha nebo ledová mlha zasahující nad úroveň pozorovatele";
else if (code == "41") return "Mlha nebo ledová mlha v skvrnách";
else if (code == "42") return "Mlha nebo ledová mlha, obloha viditelná, zeslábla během předchozí hodiny";
else if (code == "43") return "Mlha nebo ledová mlha, obloha neviditelná, zeslábla během předchozí hodiny";
else if (code == "44") return "Mlha nebo ledová mlha, obloha viditelná, bez výrazné změny během předchozí hodiny";
else if (code == "45") return "Mlha nebo ledová mlha, obloha neviditelná, bez výrazné změny během předchozí hodiny";
else if (code == "46") return "Mlha nebo ledová mlha, obloha viditelná, začala nebo zesílila během předchozí hodiny";
else if (code == "47") return "Mlha nebo ledová mlha, obloha neviditelná, začala nebo zesílila během předchozí hodiny";
else if (code == "48") return "Mlha ukládající jíní, obloha viditelná";
else if (code == "49") return "Mlha ukládající jíní, obloha neviditelná";
else if (code == "50") return "Mrholení, nezmrzající, přerušované, slabé v době pozorování";
else if (code == "51") return "Mrholení, nezmrzající, souvislé, slabé v době pozorování";
else if (code == "52") return "Mrholení, nezmrzající, přerušované, střední v době pozorování";
else if (code == "53") return "Mrholení, nezmrzající, souvislé, střední v době pozorování";
else if (code == "54") return "Mrholení, nezmrzající, přerušované, silné (husté) v době pozorování";
else if (code == "55") return "Mrholení, nezmrzající, souvislé, silné (husté) v době pozorování";
else if (code == "56") return "Mrholení, mrznoucí, slabé";
else if (code == "57") return "Mrholení, mrznoucí, střední nebo husté (silné)";
else if (code == "58") return "Mrholení a déšť, slabé";
else if (code == "59") return "Mrholení a déšť, střední nebo silné";
else if (code == "60") return "Déšť, nezmrzající, přerušovaný, slabý v době pozorování";
else if (code == "61") return "Déšť, nezmrzající, souvislý, slabý v době pozorování";
else if (code == "62") return "Déšť, nezmrzající, přerušovaný, střední v době pozorování";
else if (code == "63") return "Déšť, nezmrzající, souvislý, střední v době pozorování";
else if (code == "64") return "Déšť, nezmrzající, přerušovaný, silný v době pozorování";
else if (code == "65") return "Déšť, nezmrzající, souvislý, silný v době pozorování";
else if (code == "66") return "Déšť, zmrzající, slabý";
else if (code == "67") return "Déšť, zmrzající, střední nebo silný";
else if (code == "68") return "Sníh a déšť, slabý";
else if (code == "69") return "Sníh a déšť, střední nebo silný";
else if (code == "70") return "Sněžení, přerušované, slabé v době pozorování";
else if (code == "71") return "Sněžení, souvislé, slabé v době pozorování";
else if (code == "72") return "Sněžení, přerušované, střední v době pozorování";
else if (code == "73") return "Sněžení, souvislé, střední v době pozorování";
else if (code == "74") return "Sněžení, přerušované, silné v době pozorování";
else if (code == "75") return "Sněžení, souvislé, silné v době pozorování";
else if (code == "76") return "Ledová zrna (nepadající přeháňky)";
else if (code == "77") return "Sněhové krupky";
else if (code == "78") return "Zrnitý sníh (ledové jehličky)";
else if (code == "79") return "Ledová zrna padající z mlhy";
else if (code == "80") return "Přeháňky slabého deště";
else if (code == "81") return "Přeháňky středního nebo silného deště";
else if (code == "82") return "Přeháňky velmi silného deště";
else if (code == "83") return "Přeháňky slabého sněhu nebo déšť a sníh smíšený";
else if (code == "84") return "Přeháňky středního nebo silného sněhu nebo déšť a sníh smíšený";
else if (code == "85") return "Přeháňky slabého sněhu";
else if (code == "86") return "Přeháňky středního nebo silného sněhu";
else if (code == "87") return "Přeháňky slabých krup nebo déšť a kroupy smíšený";
else if (code == "88") return "Přeháňky středních nebo silných krup nebo déšť a kroupy smíšený";
else if (code == "89") return "Slabý déšť s krupobitím, s nebo bez hromů";
else if (code == "90") return "Mírný nebo silný déšť s krupobitím, s nebo bez hromů";
else if (code == "91") return "Bouřka slabá nebo střední s deštěm a/nebo sněhem";
else if (code == "92") return "Bouřka silná s deštěm a/nebo sněhem";
else if (code == "93") return "Bouřka slabá nebo střední s krupobitím nebo sněhovými krupkami";
else if (code == "94") return "Bouřka silná s krupobitím nebo sněhovými krupkami";
else if (code == "95") return "Bouřka bez krupobití nebo sněhových krupek, vzdálená";
else if (code == "96") return "Bouřka bez krupobití nebo sněhových krupek, blízká";
else if (code == "97") return "Bouřka s krupobitím nebo sněhovými krupkami, vzdálená";
else if (code == "98") return "Bouřka s krupobitím nebo sněhovými krupkami, blízká";
else if (code == "99") return "Bouřka bez srážek";
else return "Neznámý kód počasí";
}
String weatherCodeDescription(String code) {
if (code.length() == 0 || code.length() > 2) {
return "Neznámý kód";
}
char type = code.charAt(0);
char intensity = ' ';
if (code.length() == 2) {
intensity = code.charAt(1);
}
switch (type) {
case 'C':
return "Žádné srážky";
case 'P':
return "Srážky";
case 'L':
return "Mrholení";
case 'R':
switch (intensity) {
case '+':
return "Silný déšť";
case '-':
return "Slabý déšť";
default:
return "Déšť";
}
case 'S':
switch (intensity) {
case '+':
return "Silný sníh";
case '-':
return "Slabý sníh";
default:
return "Sníh";
}
case 'IP':
return "Ledové krupky";
case 'Z':
switch (intensity) {
case 'L':
return "Slabé mrznoucí mrholení";
case 'R':
return "Silné mrznoucí déšť";
default:
return "Mrznoucí srážky";
}
case 'SP':
return "Kroupy";
case 'SG':
return "Sněhové zrno";
case 'IC':
return "Ledové krystaly";
default:
return "Neznámý kód";
}
}