// PSTR F() makro
#include <DHT.h>
//#include <math.h>
#include <Ethernet.h>
#include<avr/wdt.h> // Header for watchdog timers in AVR
//#define NOP __ams__("nop\n\t") // definice NOP (ceka jeden cyklus procesoru)
// piny pro jednotlive DHT senzory
#define Rack_DHTPIN 2
#define U_Racku_DHTPIN 3
#define Venku_DHTPIN 4
#define U_Vody_DHTPIN 5
#define Okno2_DHTPIN 6
#define U_Schodu_DHTPIN 7
#define Prizemi_DHTPIN 8
#define Prujezd_DHTPIN 9
// piny pro Ethernet modul W5100 v pripade Arduino Nano
#define SS 10
#define MOSI 11
#define MISO 12
#define SCK 13
// piny pro Ethernet W5500
#define SS 10 //W5500 CS
#define RST 7 //W5500 RST For mega RST 11
//#define CS 4 //SD CS pin
#define ArduinoID 112 // ID arduina, kterym se identifikuje v DB
byte sensor_sensors;
DHT dht[] = {
{Rack_DHTPIN, DHT22},
{U_Racku_DHTPIN, DHT22},
{Venku_DHTPIN, DHT22},
{U_Vody_DHTPIN, DHT22},
{Okno2_DHTPIN, DHT22},
{U_Schodu_DHTPIN, DHT22},
{Prizemi_DHTPIN, DHT22},
{Prujezd_DHTPIN, DHT22}
};
//String conn_err_log_to_send;
byte sensor_measure_cnt = 0; // kolikate mereni v poradi na jednotlivem senzoru
#define sensor_max_cnt 5 // kolik mereni z kazdeho senzoru se provadi
//String sensor_name[3] = { "Rack" , "U_Racku", "Venku" } ;
float sensor_temp = 0;
float sensor_hum = 0;
#define sensor_temp_min_limit -30
#define sensor_temp_max_limit 80
#define sensor_hum_min_limit 0
#define sensor_hum_max_limit 100
float sensor_temp_min_act = 32000;
float sensor_temp_max_act = -32000;
float sensor_hum_min_act = 32000;
float sensor_hum_max_act = -32000;
float sensor_temp_sum = 0;
float sensor_hum_sum = 0;
byte sensor_cnt = 0; // pocet skutecne namerenych hodnot (pro vypocet prumerovani)
String sensor_log = "";
long time_tmp; // pomocna promenna pro mereni doby cteni senzoru
//byte measure_cnt = 0;
int sensor_act = 0;
String string_to_send = "errlog=";
#define clock_second 500 // pauza mezi jednotlivymi vterinami - spravne ma byt 1000ms
#define clock_wait 500 // pauza mezi jednotlivymi merenimi
// stavove slovo
long process_status = 0; // pro rizeni procesu - jednotlive bity jsou faze procesu (mereni, odesilani, ...)
#define send_DB_data_ok 0 // bit 0 - send_DB_data_ok - data v poradku odeslana na server do DB
#define DHTread 1 // bit 1 - priznak ze je na rade cteni DHT senzoru (pouziva se v kombinaci s time_to_SensorRead)
#define time_to_SensorRead 2 // bit 2 - priznak, ktery urcuje ze se cte z nejakeho senzoru. Shazuje se pokud se treba odesila do DB, abuy se do toho nepletlo cteni ze senzoru.
#define SensorDataReady 3 // bit 3 - priznak, ze jsou data namerena a je mozne je odeslat do DB
#define StringToSendReady 4 // bit 4 - priznak, ze string_to_send je kompletni tj. data ze senzoru + ArduinoID, time, response_time
#define DataSendOK 5 // bit 5 - data byla odeslana na server a ten odpovedel
#define ServerResponseOK 6 // bit 6 - pokud odpoved serveru je v poradku
#define asecond_change 7 // bit 7 - priznak zmeny sekundy
#define time_to_ReadValue 8 // bit 8 - uplynul cas pro dalsi odecet hodnot ze senzoru
#define DSread 9 // bit 9 - priznak ze je na rade cteni senzoru DS18B20 (pouziva se v kombinaci s time_to_SensorRead)
#define time_to_ETH_Send 10 // bit 10 - priznak ze je cas na odeslani dat pres Ethernet
#define time_to_ETH_Parse_Response 11 // bit 11 - priznak ze je cas na odeslani dat pres Ethernet
// bit 4 -
// bit 5 -
// bit 31 -
long info_word = 0; // informační slovo (typ ethernet shieldu, link status, ...)
#define no_ethernet_shield 0 // bit 0 - EthernetNoHardware
#define W5100 1 // bit 1 - EthernetW5100
#define W5200 2 // bit 2 - EthernetW5200
#define W5500 3 // bit 3 - EthernetW5500
#define link 4 // bit 4 - Link Status
#define TIMED_OUT 5 // bit 5 - client.connect() fail - TIMED_OUT
#define INVALID_SERVER 6 // bit 6 - client.connect() fail - INVALID_SERVER
#define TRUNCATED 7 // bit 7 - client.connect() fail - TRUNCATED
#define INVALID_RESPONSE 8 // bit 8 - client.connect() fail - INVALID_RESPONSE
#define UNKNOWN_ERROR 9 // bit 9 - client.connect() fail - UNKNOWN_ERROR
#define ETH_korekce 10 // bit 10 - parse_server_response() korekce casu
#define BadServerResponse 11 // bit 11 - nekorektni odpoved serveru, stejny vyznam jako ServerResponseOK
#define ETH_response_timeout 12 // bit 12 - priznak kdyz server neodpovi v danem case
//#define no_ethernet_shield 0 // bit 31 -
// _____ _ _ _ \\// __
// | ____| |_| |__ ___ _ __ _ __ ___| |_ _ __ _ __ ___ _ __ ___ \/ _ __ _ __ /_/
// | _| | __| '_ \ / _ \ '__| '_ \ / _ \ __| _____ | '_ \| '__/ _ \| '_ ` _ \ / _ \ '_ \| '_ \ / _ \
// | |___| |_| | | | __/ | | | | | __/ |_ |_____| | |_) | | | (_) | | | | | | __/ | | | | | | __/
// |_____|\__|_| |_|\___|_| |_| |_|\___|\__| | .__/|_| \___/|_| |_| |_|\___|_| |_|_| |_|\___|
// |_|
// parametry sitoveho pripojeni
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(172, 17, 13, 83);
IPAddress dns(8, 8, 8, 8);
IPAddress gateway(172, 17, 13, 1);
IPAddress subnet(255, 255, 252, 0);
bool nalez;
String response_time, server_response, sending_time;
//byte send_attempt = 0;
int ETH_send_attempt_act = 0;
#define ETH_send_attempt_max 3
#define ETH_TimeOut 5000
//int TimeOut = 5000;
int ETH_timeout;
// vytvoří objekt EthernetClient s názvem "client"
EthernetClient client;
// promenne pro clock without rtc (funkce clock_change)
unsigned long sensor_next_read, next_second;
//byte ahour, aminute, asecond;
int year, month, date, day, hour, minute, second;
byte ayear, amonth, adate, aday, ahour, aminute, asecond, asecond_old, aminute_old;
//bool asecond_change;
// ____ _____ _____ _ _ ____
// / ___|| ____|_ _| | | | _ \
// \___ \| _| | | | | | | |_) |
// ___) | |___ | | | |_| | __/
// |____/|_____| |_| \___/|_|
void setup() {
// put your setup code here, to run once:
//string_to_send.reserve(512);
// You can use Ethernet.init(pin) to configure the CS pin
//Ethernet.init(10); // Most Arduino shields
//Ethernet.init(5); // MKR ETH shield
//Ethernet.init(0); // Teensy 2.0
//Ethernet.init(20); // Teensy++ 2.0
//Ethernet.init(15); // ESP8266 with Adafruit Featherwing Ethernet
//Ethernet.init(33); // ESP32 with Adafruit Featherwing Ethernet
Serial.begin(9600);
for (auto& sensor : dht) {
sensor_sensors++;
sensor.begin();
}
// _____ _ _ _ _
// | ____| |_| |__ ___ _ __ _ __ ___| |_ ___ ___| |_ _ _ _ __
// | _| | __| '_ \ / _ \ '__| '_ \ / _ \ __| _____ / __|/ _ \ __| | | | '_ \
// | |___| |_| | | | __/ | | | | | __/ |_ |_____| \__ \ __/ |_| |_| | |_) |
// |_____|\__|_| |_|\___|_| |_| |_|\___|\__| |___/\___|\__|\__,_| .__/
// |_|
// RobotDyn Ethernet
// vvvvvvvvvvv
//pinMode(LED_BUILTIN, OUTPUT);
//digitalWrite(LED_BUILTIN, HIGH);
//pinMode(SS, OUTPUT);
//pinMode(RST, OUTPUT);
//pinMode(CS, OUTPUT);
//digitalWrite(SS, LOW);
//digitalWrite(CS, HIGH);
/* If you want to control Reset function of W5500 Ethernet controller */
//digitalWrite(RST,HIGH);
//Serial.println("Definuje Pinmode a nastavi Digitalwrite pro Erthernet");
// ^^^^^^^^^^^
// zacatek Ethernetu
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// inicializuje síťové zařízení s adresou MAC
//if (Ethernet.begin(mac)){Serial.println("DHCP dalo adresu");} else{Serial.println("DHCP nedalo adresu");} // pokud chci adresu z DHCP
Ethernet.begin(mac, ip, dns, gateway, subnet); // inicializace s pevnou IP adresou
Serial.println("Ethernet.begin(mac, ip, dns, gateway, subnet);");
delay(2000); //počká až se inicializuje Ethernet, aby mohl přečíst LINK stav
bitClear(info_word, no_ethernet_shield); bitClear(info_word, W5100); bitClear(info_word, W5200); bitClear(info_word, W5500); // vycisti info bity, aby tam nezustalo neco z drivejska
if (Ethernet.hardwareStatus() == EthernetNoHardware) {bitSet(info_word, no_ethernet_shield); Serial.println("FAIL - Ethernet shield was not found.");}
else if (Ethernet.hardwareStatus() == EthernetW5100) {bitSet(info_word, W5100); Serial.println("OK - W5100 Ethernet controller detected.");}
else if (Ethernet.hardwareStatus() == EthernetW5200) {bitSet(info_word, W5200); Serial.println("OK - W5200 Ethernet controller detected.");}
else if (Ethernet.hardwareStatus() == EthernetW5500) {bitSet(info_word, W5500); Serial.println("OK - W5500 Ethernet controller detected.");}
if (Ethernet.linkStatus() == Unknown) {bitSet(info_word, link); Serial.println("FAIL - Link status unknown. Link status detection is only available with W5200 and W5500.");}
else if (Ethernet.linkStatus() == LinkON) {bitSet(info_word, link); Serial.println("OK - Link status: On");}
else if (Ethernet.linkStatus() == LinkOFF) {bitClear(info_word, link); Serial.println("FAIL - Link status: Off");}
Ethernet.setRetransmissionTimeout(300); // timeout pro pokus navazani spojeni
Ethernet.setRetransmissionCount(10); // pocet pokusu na spojeni
client.setConnectionTimeout(1000); // Set the timeout for client.connect() and client.stop()
Serial.print("IP: ");
Serial.print(Ethernet.localIP());
Serial.print(" ; Gate: ");
Serial.print(Ethernet.gatewayIP());
Serial.print(" ; Subnet: ");
Serial.print(Ethernet.subnetMask());
Serial.print(" ; DNS: ");
Serial.println(Ethernet.dnsServerIP());
// Serial.println("Pripojuji...");
// konec Ethernetu
set_initial_state();
// ****************************************************
// Pri startu si Arduino stahne a nastavi spravny cas
// ****************************************************
/*
while(!bitRead(info_word,ETH_korekce)){
server_response = "";
Serial.println("INFO - send_data_to_server");
time_tmp = millis();
string_to_send = "give_me_date";
response_time = 99;
//send_data_to_server(ArduinoID, "give_me_date", "rt=99", &server_response, response_time, sending_time);
send_data_to_server();
sending_time = String(millis() - time_tmp);
Serial.print("Server response : ");Serial.println(server_response);
//parse_server_response(server_response,&year,&month,&date,&day,&hour,&minute,&second,&ok_bool,&korekce_bool);
// reset_count += 1;
// if (reset_count == 3) {softwareReset( WDTO_60MS);} //call reset
// Serial.println(reset_count);
}
*/
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
}
// _ _ _ _
// ___| | ___ ___| | __ ___| |__ ___ ___| | __
// / __| |/ _ \ / __| |/ / / __| '_ \ / _ \/ __| |/ /
// | (__| | (_) | (__| < | (__| | | | __/ (__| <
// \___|_|\___/ \___|_|\_\ _____ \___|_| |_|\___|\___|_|\_\
// |_____|
void clock_check(){
bitClear(process_status,asecond_change);
//bitClear(process_status,time_to_ReadValue);
if(abs(millis() - sensor_next_read) <= 10*clock_wait and millis() >= sensor_next_read){
sensor_next_read = millis() + clock_wait;
//Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.print("_sensor_next_read");
bitSet(process_status,time_to_ReadValue);
}
if(abs(millis() - next_second) <= 10*clock_second and millis() >= next_second){
next_second = millis() + clock_second;
asecond++;
bitSet(process_status,asecond_change);
if (asecond > 59){asecond = 0; aminute++;}
if (aminute > 59){aminute = 0; ahour++;}
if (ahour > 23){ahour = 0;}
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.print("_");
}
}
// ____ _ _ _____ _ _ _ _
// | _ \| | | |_ _| (_)_ __ (_) |_ __ ____ _| |_ _ ___ ___
// | | | | |_| | | | | | '_ \| | __| \ \ / / _` | | | | |/ _ \/ __|
// | |_| | _ | | | | | | | | | |_ \ V / (_| | | |_| | __/\__ \
// |____/|_| |_| |_| _____ |_|_| |_|_|\__| _____ \_/ \__,_|_|\__,_|\___||___/
// |_____| |_____|
void sensor_init_values(){
sensor_temp = 0;
sensor_hum = 0;
sensor_temp_min_act = 32000;
sensor_temp_max_act = -32000;
sensor_hum_min_act = 32000;
sensor_hum_max_act = -32000;
sensor_temp_sum = 0;
sensor_hum_sum = 0;
sensor_cnt = 0;
sensor_log = "";
}
// ____ _ _ _____ _
// | _ \| | | |_ _| _ __ ___ __ _ __| |
// | | | | |_| | | | | '__/ _ \/ _` |/ _` |
// | |_| | _ | | | | | | __/ (_| | (_| |
// |____/|_| |_| |_| _____ |_| \___|\__,_|\__,_|
// |_____|
void DHT22_read(){
bitClear(process_status,time_to_ReadValue); // prave se cte a tak priznak vynuluj, aby se necetlo hned pri dalsim pruchodu
if(sensor_measure_cnt < sensor_max_cnt){ // Zjisti, jestli neni pocet mereni na maximu a pokud jeste ne, bude se pokracovat dalsim merenim
sensor_measure_cnt++; // pokud nejsem na maximu, zvys poradi mereni o 1
}
else if (sensor_measure_cnt >= sensor_max_cnt && sensor_act < sensor_sensors){sensor_act++; sensor_measure_cnt = 0;} // pokud pocet mereni dosahl maxima, ale nejedna se o posledni senzor
else{sensor_act = 0; sensor_measure_cnt = 0; bitClear(process_status,DHTread); // Vynuluj citace senzoru a mereni a zrus cteni z DHT, aby se uz nezapisovalo do promennych mereni.
bitSet(process_status,DSread); sensor_init_values(); } // Nastav cteni z dalsiho senzoru. V tomto pripade DS18B20 a vynuluj promenne pro cteni senzoru.
//Serial.print("[sensor_read] sensor_act = "); Serial.println(sensor_act);
if(bitRead(process_status,DHTread)){ // pokud predesle zvysovani poctu mereni a cisla senzoru vyhodnotilo, ze se ma cist
time_tmp = micros();
sensor_temp = dht[sensor_act].readTemperature();
sensor_hum = dht[sensor_act].readHumidity();
if (isnan(sensor_hum) || isnan(sensor_temp)) {
if(sensor_log != 0){sensor_log += "-";}
sensor_log += sensor_measure_cnt; sensor_log += ".NaN";
//Serial.print("sensor_log v sensor_read v INSAN"); Serial.print(sensor_act); Serial.print(".DHT : "); Serial.println(sensor_log);
}
else if (sensor_hum < sensor_hum_min_limit || sensor_hum > sensor_hum_max_limit){
if(sensor_log != 0){sensor_log += "-";}
sensor_log += sensor_measure_cnt; sensor_log += ".Range_hum_"; sensor_log += sensor_hum;
//Serial.print(sensor_act); Serial.print(" : "); Serial.println(sensor_log);
}
else if(sensor_temp < sensor_temp_min_limit || sensor_temp > sensor_temp_max_limit) {
//Serial.print(" - "); Serial.print(sensor_name ); Serial.print(" : "); Serial.print(i); Serial.print(". measure Out of range (t="); Serial.print(sensor_temp ); Serial.print("C h="); Serial.print(sensor_hum ); Serial.println("%)");
//string_to_send += sensor_name ; string_to_send += " : "; string_to_send += sensor_cnt ; string_to_send += ". measure Out of range (t="; string_to_send += sensor_temp ; string_to_send += "C h="; string_to_send += sensor_hum ; string_to_send += "%)$";
if(sensor_log != 0){sensor_log += "-";}
sensor_log += sensor_measure_cnt; sensor_log += ".Range_temp_"; sensor_log += sensor_temp ;
//Serial.print(sensor_act ); Serial.print(" : "); Serial.println(sensor_log );
}
else {
sensor_hum_sum += sensor_hum ; sensor_temp_sum += sensor_temp ; sensor_cnt +=1;
if (sensor_hum_max_act <= sensor_hum ){sensor_hum_max_act = sensor_hum ;} // zjisti, jestli se jedna o maximum a pokud ano, zmeni hodnotu maxima
if (sensor_hum_min_act >= sensor_hum ){sensor_hum_min_act = sensor_hum ;} // zjisti, jestli se jedna o minimum a pokud ano, zmeni hodnotu minima
if (sensor_temp_max_act <= sensor_temp ){sensor_temp_max_act = sensor_temp ;} // zjisti, jestli se jedna o maximum a pokud ano, zmeni hodnotu maxima
if (sensor_temp_min_act >= sensor_temp ){sensor_temp_min_act = sensor_temp ;} // zjisti, jestli se jedna o minimum a pokud ano, zmeni hodnotu minima
//Serial.print("OK - "); Serial.print(sensor_name ); Serial.print(" : "); Serial.print(sensor_cnt ); Serial.print(". measure (t="); Serial.print(sensor_temp ); Serial.print(" , h="); Serial.print(sensor_hum ); Serial.print("% , t_max="); Serial.print(sensor_temp_max_act ); Serial.print("C , t_min="); Serial.print(sensor_temp_min_act ); Serial.print("C , h_max="); Serial.print(sensor_hum_max_act ); Serial.print("% , h_min="); Serial.print(sensor_hum_min_act ); Serial.print("%)");
}
time_tmp = micros() - time_tmp;
if (sensor_measure_cnt >= sensor_max_cnt){ // Pokud je dosazeno plneho poctu mereni vypocti vyslednou hodnotu, vytvor retezec pro odeslani a nastav priznaky, aby se data odeslala na server
//Serial.print(F ("[sensor_read] VYPOCET - sensor_cnt = "));Serial.print(sensor_cnt);
// *******************************************
// *** VYPOCET VYSLEDNE HODNOTY k ODESLANI ***
// *******************************************
if(sensor_cnt >= 3){
sensor_temp_sum -= sensor_temp_max_act ; sensor_temp_sum -= sensor_temp_min_act ; sensor_hum_sum -= sensor_hum_max_act ; sensor_hum_sum -= sensor_hum_min_act ; sensor_cnt -= 2;
sensor_temp = sensor_temp_sum / sensor_cnt ; sensor_hum = sensor_hum_sum / sensor_cnt ;
}
else if(sensor_cnt >= 1){
sensor_temp = sensor_temp_sum / sensor_cnt ; sensor_hum = sensor_hum_sum / sensor_cnt ;
}
else{ sensor_temp =-99; sensor_hum =-99; sensor_temp_max_act =0; sensor_temp_min_act =0; sensor_hum_max_act =0; sensor_hum_min_act =0;
//string_to_send += sensor_act ; string_to_send += " : "; string_to_send += "No data measured !!!$";
}
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
// ******************************************
// *** VYTVORENI RETEZCE DAT PRO ODESLANI ***
// ******************************************
//t0,t1,... - teploty z cidla 0,1,...
//h0,h1,... - vlhkosti z cidla 0,1,...
//dt0,dt1,... - delta teploty (rozptyl mereni) z cidla 0,1,...
//dh0,dh1,... - delta vlhkosti (rozptyl mereni) z cidla 0,1,...
//rt - response time (predesle) komunikace se serverem
//log - error log
//String t;
string_to_send = "";
string_to_send += "t"; string_to_send += sensor_act; string_to_send += "="; string_to_send += sensor_temp ; string_to_send += "&";
string_to_send += "dt"; string_to_send += sensor_act; string_to_send += "="; string_to_send += (sensor_temp_max_act -sensor_temp_min_act ); string_to_send += "&";
string_to_send += "h"; string_to_send += sensor_act; string_to_send += "="; string_to_send += sensor_hum ; string_to_send += "&";
string_to_send += "dh"; string_to_send += sensor_act; string_to_send += "="; string_to_send += (sensor_hum_max_act -sensor_hum_min_act ); string_to_send += "&";
//Serial.print(F ("[sensor_read] string_to_send = "));Serial.println(string_to_send);
//Serial.println(F("[sensor_read] SensorDataReady(0) -- DHTread(1) -- time_to_SensorRead(1) -------------"));
//sensor_init_values();
//bitClear(process_status,SensorDataReady);
//bitSet(process_status,DHTread);
//bitSet(process_status,time_to_SensorRead);
// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
sensor_init_values(); // vynuluje promenne mereni, aby bylo pripraveno pro mereni dalsiho senzoru
bitClear(process_status,time_to_SensorRead); bitSet(process_status,time_to_ETH_Send); // pozastav mereni a spust odeslani na server
Serial.println("");
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.print("_ [DHT_read] - ");Serial.println(string_to_send);
//Serial.print("[sensor_read]"); Serial.print(" - dokonceno cteni z jednoho senzoru ");
}
// if(sensor_measure_cnt >= sensor_max_cnt && sensor_act >= sensor_sensors-1){
// sensor_act = 0; sensor_measure_cnt = 0;
// bitClear(process_status,DHTread); bitClear(process_status,time_to_SensorRead);
// }
//if (sensor_act == 0 && sensor_measure_cnt == 0){bitClear(process_status,DHTread); bitClear(process_status,time_to_SensorRead);}
} // od if DHTread tj. mereni a vypocet
else{ // bitSet(process_status,DSread); // dalsi typ senzoru v poradi, pokud by byly pripojeny senzory DS18B20
}
////}
}
// _ _ _ _
// ___ ___ _ __ __| | __| | __ _| |_ __ _ | |_ ___ ___ ___ _ ____ _____ _ __
// / __|/ _ \ '_ \ / _` | / _` |/ _` | __/ _` | | __/ _ \ / __|/ _ \ '__\ \ / / _ \ '__|
// \__ \ __/ | | | (_| | | (_| | (_| | || (_| | | || (_) | \__ \ __/ | \ V / __/ |
// |___/\___|_| |_|\__,_| _____ \__,_|\__,_|\__\__,_| _____ \__\___/ _____ |___/\___|_| \_/ \___|_|
// |_____| |_____| |_____|
//void send_data_to_server(byte id, String td, String data_to_send, String* server_response, String rt, String st){
void send_data_to_server(){
// když se podaří spojení se serverem tak....
// číslo 80 je sdandardní číslo portu pro html
// while(!client){
Serial.println(F("INFO - send_data_to_server in function"));
// *** doplni k datum ze senzoru ArduinoID, response, time, ...
if(!bitRead(process_status,StringToSendReady)){
string_to_send += "rt="; string_to_send += response_time;
string_to_send += "&time="; // prevod ahour, aminute, asecond do formatu HH:MM:SS
if (ahour < 10){string_to_send += "0"; string_to_send += ahour;} else{string_to_send += ahour;} string_to_send += ":";
if (aminute < 10){string_to_send += "0"; string_to_send += aminute;} else{string_to_send += aminute;} string_to_send += ":";
if (asecond < 10){string_to_send += "0"; string_to_send += asecond;} else{string_to_send += asecond;}
string_to_send += "&id="; string_to_send += ArduinoID;
bitSet(process_status,StringToSendReady);
}
//client_connect_tmp = client.connect("www.krtek.eu", 80);
//Serial.print("client_connect_tmp = "); Serial.println(client_connect_tmp);
switch (client.connect("www.krtek.eu", 80)) {
case 1:
Serial.println(F("OK - SUCCESS -> Client connected"));
ETH_send_attempt_act++;
//Serial.println("Pripojeni probehlo v poradku");
// odešle požadavek POST na vrácení stránky test.html
//Serial.print(F("INFO - data_to_send = "));Serial.println(data_to_send); // data += "&st="; data += st;
//data += td; data += "&rt="; data += response_time; data += "&st="; data += st; data += "&"; data += data_to_send; data += "&err="; data += conn_err_log_to_send;
//Serial.print(F("INFO - data = "));Serial.println(data);
/*char buffer[128] {'\0'};
strcpy_P(buffer, PSTR("POST /arduino/add.php HTTP/1.1\r\n"
"Host: www.krtek.eu\r\n"
"\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Content-Length: \r\n"));
strcat_P(buffer, PSTR("123456789a123456789b123456789c\r\n"));
client.print(buffer);
*/
client.println("POST /arduino/add.php HTTP/1.1");
client.println("Host: www.krtek.eu"); // SERVER ADDRESS HERE TOO
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(string_to_send.length());
client.println();
client.print(string_to_send);
ETH_timeout = ETH_TimeOut;
while ((!client.available()) && (ETH_timeout > 0))
{
delay(1);
ETH_timeout = ETH_timeout - 1;
}
if (ETH_timeout > 0)
{
//ETH_TimeOut -= ETH_timeout;
response_time = String(ETH_TimeOut - ETH_timeout);
Serial.print(F("INFO - Odezva serveru v case: ")); Serial.print(response_time); Serial.println(F("ms"));
//Serial.print(ETH_TimeOut - ETH_timeout);
bitSet(process_status,DataSendOK); // rozhodnout, jestli je to nutne
bitClear(process_status,time_to_ETH_Send);
bitSet(process_status,time_to_ETH_Parse_Response);
}
else
{
Serial.println(F("FAIL - Server neodpovida..."));
bitSet(info_word,ETH_response_timeout); bitClear(process_status,DataSendOK);
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
wdt_enable(WDTO_60MS);
}
// připraví proměnou pro případ když nalezneme naše řídící znaky
nalez = false;
// do této hodnoty se nám budou ukládat data
// String data = "";
server_response = "";
// dokud je stánka dostupná...
while (client.available())
{
//...do proměné c zapiš bajt odeslaný ze serveru
char c = client.read();
// když objevíš náš počátečný kontrolní znak
// tak nález bude true - pravda
// když konečný tak false
if (c == '<') nalez = true;
if (c == '>') nalez = false;
// když je nález tak ukládej znaky do proměné data
// protože by se nám ukládal i první řídící znak tak,
// jen ukládej když je znak rozdílný od '<'
if (nalez && (c!='<')) server_response = server_response + c;
}
// .... když už není co číst a stránka není dostupná
// zastav připojení a vypiš na serial "Odpojeno"
client.stop();
//bitSet(process_status,send_DB_data_ok);
//bitSet(process_status,DataSendOK);
client.flush();
Serial.println(F("INFO - Odpojeno."));
Serial.println();
ETH_send_attempt_act++;
break;
case (-1):
Serial.println(F("FAIL - TIMED_OUT -> Client not connected"));
bitClear(process_status,DataSendOK); bitSet(process_status, TIMED_OUT); //conn_err_log_to_send += "Connection to DB ("; conn_err_log_to_send += send_DB_data_cnt; conn_err_log_to_send += ". attempt) - TIMED_OUT$";
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
ETH_send_attempt_act++;
//wdt_enable(WDTO_60MS);
break;
case (-2):
Serial.println(F("FAIL - INVALID_SERVER -> Client not connected"));
bitClear(process_status,DataSendOK); bitSet(process_status, INVALID_SERVER); //conn_err_log_to_send += "Connection to DB ("; conn_err_log_to_send += send_DB_data_cnt; conn_err_log_to_send += ". attempt) - INVALID_SERVER$";
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
ETH_send_attempt_act++;
//wdt_enable(WDTO_60MS);
break;
case (-3):
Serial.println(F("FAIL - TRUNCATED -> Client not connected"));
bitClear(process_status,DataSendOK); bitSet(process_status, TRUNCATED); //conn_err_log_to_send += "Connection to DB ("; conn_err_log_to_send += send_DB_data_cnt; conn_err_log_to_send += ". attempt) - TRUNCATED$";
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
ETH_send_attempt_act++;
//wdt_enable(WDTO_60MS);
break;
case (-4):
Serial.println(F("FAIL - INVALID_RESPONSE -> Client not connected"));
bitClear(process_status,DataSendOK); bitSet(process_status, INVALID_RESPONSE); //conn_err_log_to_send += "Connection to DB ("; conn_err_log_to_send += send_DB_data_cnt; conn_err_log_to_send += ". attempt) - INVALID_RESPONSE$";
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
ETH_send_attempt_act++;
//wdt_enable(WDTO_60MS);
break;
default:
Serial.println(F("FAIL - UNKNOWN_ERROR -> Client not connected"));
bitClear(process_status,DataSendOK); bitSet(process_status, UNKNOWN_ERROR); //conn_err_log_to_send += "Connection to DB ("; conn_err_log_to_send += send_DB_data_cnt; conn_err_log_to_send += ". attempt) - UNKNOWN_ERROR$";
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
ETH_send_attempt_act++;
//wdt_enable(WDTO_60MS);
break;
}
}
// _ __ __ _ _ __ ___ ___ ___ ___ _ ____ _____ _ __ _ __ ___ ___ _ __ ___ _ __ ___ ___
// | '_ \ / _` | '__/ __|/ _ \ / __|/ _ \ '__\ \ / / _ \ '__| | '__/ _ \/ __| '_ \ / _ \| '_ \/ __|/ _ \
// | |_) | (_| | | \__ \ __/ \__ \ __/ | \ V / __/ | | | | __/\__ \ |_) | (_) | | | \__ \ __/
// | .__/ \__,_|_| |___/\___| _____ |___/\___|_| \_/ \___|_| _____ |_| \___||___/ .__/ \___/|_| |_|___/\___|
// |_| |_____| |_____| |_|
// =============================================
// Parsovani odpovedi serveru - korekce, v_cajku
// =============================================
void parse_server_response() {
//void parse_server_response(String server_date, int* syear) {
Serial.print("INFO - server_date_substring = ");Serial.println(server_response.substring(0,8));
if(server_response.substring(0,8)=="_korekce"){ // pokud server usoudi, ze se cas prilis rozchazi, vrati korekci a Arduino si prepise cas, aby souhlasil se serverem
String tmp=server_response.substring(9,13);
ayear=tmp.toInt();
// Serial.print(year);
// Serial.print("-");
tmp=server_response.substring(14,16);
amonth=tmp.toInt();
// Serial.print(month);
// Serial.print("-");
tmp=server_response.substring(17,19);
adate=tmp.toInt();
// Serial.print(date);
// Serial.print(" ");
tmp=server_response.substring(20,22);
ahour=tmp.toInt();
// Serial.print(hours);
// Serial.print(":");
tmp=server_response.substring(23,25);
aminute=tmp.toInt();
// Serial.print(minutes);
// Serial.print(":");
tmp=server_response.substring(26,28);
asecond=tmp.toInt();
// Serial.print(seconds);
// Serial.print("_");
tmp=server_response.substring(29,30);
aday=tmp.toInt();
// Serial.print(day);
//*sok=true; // korektni odpoved od serveru
//*skorekce=true; // pozadavek na korekci
// set the initial time here:
// DS3231 seconds, minutes, hours, day, date, month, year
bitSet(process_status,ServerResponseOK);
//Serial.println("!!! setDS3231time(seconds,minutes,hours,day,date,month,year); !!!");
} // od if korekce
else if (server_response.substring(0,8)=="_v_cajku") {
//Serial.print("Bez korekce");
//*sok=true; // korektni odpoved od serveru
//*skorekce=false; // bez korekce
bitSet(process_status,ServerResponseOK);
} // od else if 1
else {
//*sok=false; // nekorektni odpoved od serveru
//*skorekce=false; // bez korekce
bitSet(process_status,time_to_ETH_Send);
bitClear(process_status,time_to_ETH_Parse_Response);
//error_log_to_send += "ERROR - PARSE - Korekce: "; error_log_to_send += server_date.substring(0,8);
bitClear(process_status,ServerResponseOK);
bitSet(info_word,BadServerResponse);
//Serial.println("!!! doplnit opakovani odeslani dat seend_data() !!!");
} // od else if 2
} // od void parse_server_response
void set_initial_state() {
bitSet(process_status,DHTread);
bitSet(process_status,time_to_SensorRead);
bitClear(process_status,SensorDataReady);
bitClear(process_status,StringToSendReady);
bitSet(process_status,time_to_ReadValue);
bitClear(process_status,DataSendOK);
bitClear(process_status,ServerResponseOK);
ETH_send_attempt_act = 0;
sensor_init_values();
}
// _ ___ ___ ____
// | | / _ \ / _ \| _ \
// | | | | | | | | | |_) |
// | |__| |_| | |_| | __/
// |_____\___/ \___/|_|
void loop() {
clock_check(); // musi zde byt, aby fungovaly hodiny
/*
if(!bitRead(process_status,DHTread) && !bitRead(process_status,time_to_SensorRead) && bitRead(process_status,asecond_change) && asecond == 0){set_initial_state();
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.println("_set_initial_state()");
}
if(bitRead(process_status,DHTread) && bitRead(process_status,time_to_SensorRead) && bitRead(process_status,time_to_ReadValue)){ // pokud se ma cist z DHT
DHT22_read(); // postupne cte vsechny DHT22 pokud je nastaveny priznak "process_status.DHTread==1" a "process_status.time_to_SensorRead==1"
// pokud se skonci se čtením z konkretniho senzoru DHT22_read() vytvori string_to_send s daty a nastavi "process_status.time_to_SensorRead==0" a "process_status.SensorDataReady == 1"
// jestlze skonci cteni z posledniho senzoru, nastav krome "process_status.time_to_SensorRead==0" take "process_status.DHTread==1"
// Poznamka: "process_status.DHTread" je z duvodu, ze by bylo vice druhu senzoru. Pak by pribyl napriklad priznak "process_status.DS18B20read" a funkce "DS18B20_read()"
}
if(ETH_send_attempt_act >= ETH_send_attempt_max){bitSet(process_status,DataSendOK); bitSet(process_status,ServerResponseOK);} // pokud probehlo ETH_send_attempt_max neuspesnych pokusu o odeslani dat, vyprdni se na to, prohlas to za odeslane a pokracuj dal v mereni
if(bitRead(process_status,SensorDataReady) && !bitRead(process_status,DataSendOK)){
//send_data_to_server(); // Pokud je nastaven "process_status.SensorDataReady==1" , funkce send_data_to_server() k tomu prida ArduinoID, response_time, atd a odesle na server do DB
// Jestlize se prenos podari, nastavi se priznak "process_status.DataSendOK=1"
// V opacnem pripade se inkrementuje pocet pokusu "ETH_send_attempt_act++" a nastaví se jeden z chybovych priznaku "info_word.TIMED_OUT" , "info_word.INVALID_SERVER" , "info_word.TRUNCATED" , "info_word.INVALID_RESPONSE" , "info_word.UNKNOWN_ERROR" , "info_word.ETH_response_timeout"
bitSet(process_status,DataSendOK);
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.println("_send_data_to_server()");
}
if(bitRead(process_status,DataSendOK) && !bitRead(process_status,ServerResponseOK)){
//parse_server_response();
bitSet(process_status,ServerResponseOK);
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.println("_parse_server_response()");
}
if(bitRead(process_status,DataSendOK) && bitRead(info_word,BadServerResponse) && !bitRead(process_status,ServerResponseOK)){ // pokud byla data odeslana a odpoved serveru neni dle ocekavani odesli data znovu
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.println("_ nejde odeslat, prdim na to !!!");
bitClear(process_status,DataSendOK);
bitClear(process_status,ServerResponseOK);
bitClear(process_status,SensorDataReady);
}
if(bitRead(process_status,DataSendOK) && bitRead(process_status,ServerResponseOK) && bitRead(process_status,DHTread) && !bitRead(process_status,time_to_SensorRead)){
Serial.print(ahour);Serial.print(":");Serial.print(aminute);Serial.print(":");Serial.print(asecond);Serial.print("_ Nahazuji process_status,time_to_SensorRead");Serial.print("time_to_SensorRead");Serial.print(bitRead(process_status,time_to_SensorRead));Serial.print("DHTread");Serial.println(bitRead(process_status,DHTread));
bitSet(process_status,time_to_SensorRead);
bitClear(process_status,DataSendOK);
bitClear(process_status,ServerResponseOK);
}
*/
// ****************************************************************************
/*
if(bitRead(process_status,in_process)){ // Pokud jsem v procesu cteni a odesilani
if(bitRead(process_status,time_to_SensorRead)){ // Maji se cist data z nejakeho senzoru
if(bitRead(process_status,DHTread)){DHT22_read();} // Ctou se data z DHT22
if(bitRead(process_status,DSread)){()} // Ctou se data z DS18B20
}
else if(ETH_send_attempt_act >= ETH_send_attempt_max){ // Pokud byl dosazen maximalni pocet pokusu o odeslani
bitSet(process_status,time_to_SensorRead); bitClear(process_status,SensorDataReady); // nastav ze se ma cist a ze se nema odesilat
bitClear(process_status,DataSendOK); bitClear(process_status,ServerResponseOK); bitClear(info_word,BadServerResponse); // a vynuluj vsechny priznaky odesilani
}
else if(bitRead(process_status,SensorDataReady)){ // Data jsou pripravena, muze zacit odesilani
if(bitRead(process_status,DataSendOK)){ // Pokud jsou data jiz odeslana
if(bitRead(process_status,ServerResponseOK)){ // Pokud je navic i spravna odpoved serveru
bitSet(time_to_SensorRead); bitClear(SensorDataReady); // nastav ze se ma cist a ze se nema odesilat
bitClear(DataSendOK); bitClear(ServerResponseOK); bitClear(BadServerResponse); // a vynuluj vsechny priznaky odesilani
}
else if(BadServerResponse){ // Pokud neni spravna odpoved serveru tak nastav priznaky, aby se zacalo odesilat znovu
bitClear(DataSendOK); bitClear(ServerResponseOK); bitClear(BadServerResponse); // a vynuluj vsechny priznaky odesilani a zkus to znovu
}
else {parse_server_response()} // precti odpoved
}
else{ // pokud data nejsou odeslana na server, tak je odesli
send_data_to_server() // odesli data na server
}
}
}
else{vse skoncilo, cekej na celou minutu}
BadServerResponse
*/
// ****************************************************************************
// ##############################################################################
if(bitRead(process_status,time_to_SensorRead) && bitRead(process_status,time_to_ReadValue)){ // Maji se cist data z nejakeho senzoru a nastal cas kdy hodnotu precist
if(bitRead(process_status,DHTread)){DHT22_read();} // Ctou se data z DHT22. Pokud funkce "DHTread" precte a zpracuje data z jednoho senzoru nastavi priznak "time_to_ETH_Send" a vynuluje priznak "time_to_SensorRead"
if(bitRead(process_status,DSread)){delay(1);} // Ctou se data z DS18B20. Pokud funkce "DSread" precte a zpracuje data z jednoho senzoru nastavi priznak "time_to_ETH_Send" a vynuluje priznak "time_to_SensorRead"
}
if(bitRead(process_status,time_to_ETH_Send)){send_data_to_server();} // Pokud je cas data odeslat tj. je nastaven priznak "time_to_ETH_Send" odesli data a pokud se to povede nastav priznak "time_to_ETH_Parse_Response" aby se rozparsovala odpoved
if(bitRead(process_status,time_to_ETH_Parse_Response)){parse_server_response();} // Pokud se povedlo odeslani dat rozparsuj odpoved. Pokud dava smysl nastav priznak "time_to_SensorRead" aby se cetl dalsi senzor
// Pokud je odpoved spatna, nastav opet priznak "time_to_ETH_Send" aby se data zkusila odeslat znovu
// ##############################################################################
//ETH_send_attempt_act < ETH_send_attempt_max
//bitClear(process_status,ServerResponseOK);
// bitSet(info_word,BadServerResponse);
//process_status,ServerResponseOK
//if(bitRead(process_status,SensorDataReady) && ETH_send_attempt_act <= ETH_send_attempt_max){
// send_data_to_server();
//}
//else {}
//if(bitRead(process_status,SensorDataReady)){
// sensor_calc();
// prepare_data_to_send();
//}
// _
// /\/\ ___ _ __ ___ _ __ (_)
// / \ / _ \ '__/ _ \ '_ \| |
// / /\/\ \ __/ | | __/ | | | |
// \/ \/\___|_| \___|_| |_|_|
/*
if (bitRead(process_status,asecond_change) && asecond == 5) {
Serial.println(F("============================================="));
Serial.println(F("=========== M E R E N I ============="));
Serial.println(F("============================================="));
}
*/
// for (int i = 0; i < 4; i++) {
// temperature[i] = dht[i].readTemperature();
// humidity[i] = dht[i].readHumidity();
// }
// for (int i = 0; i < 4; i++) {
// Serial.print(F("Temperature "));
// Serial.print(i);
// Serial.println(temperature[i]);
// Serial.print(F("Humidity "));
// Serial.print(i);
// Serial.println(humidity[i]);
// }
// Mereni DHT Rack - 5. 15. 25. 35. a 45. vterina
// ==============================
/*
if (bitRead(process_status,asecond_change) && (asecond == 5 || asecond == 15 || asecond == 25 || asecond == 35 || asecond == 45)) {
//Serial.print("[LOOP] sensor_act = ");
Serial.print(sensor_act);Serial.print(" :: ");Serial.println(sensor_measure_cnt);
Serial.println(F("--- MERIM --- 5,15,25,35,45 -- SensorDataReady(0) -- DHTread(1) -- time_to_SensorRead(1) -------------"));
bitClear(process_status,SensorDataReady);
bitSet(process_status,DHTread);
bitSet(process_status,time_to_SensorRead);
//sensor_measure_cnt++;
//bitSet(process_status, DHTread);
//bitSet(process_status,time_to_SensorRead);
//Serial.print("Cas cteni sensor_Rack: "); Serial.print(time_tmp); Serial.println("us");
}
*/
/*
if (bitRead(process_status,asecond_change) && (asecond == 10 || asecond == 20 || asecond == 30 || asecond == 40 || asecond == 50)) {
//Serial.println(F("--- MERIM2 ------------------------------------------"));
//Serial.print(F("string_to_send = "));Serial.println(string_to_send);
//sensor_matrix_show();
//Serial.print("Cas cteni sensor_Rack: "); Serial.print(time_tmp); Serial.println("us");
}*/
if (bitRead(process_status,asecond_change) && asecond == 155) {
sensor_measure_cnt = 0;
Serial.print("string_to_send = ");Serial.println(string_to_send);
//sensor_calc();
//prepare_data_to_send();
//sensor_matrix_show();
//sensor_matrix_clear();
//prepare_data_to_send();
//delay(10000);
string_to_send = "errlog=";
}
/*
==========================================================================================================================================
LEGENDA:
+-----------------------------------------+
| jake podminky musi byt splneny |
+=========================================+
| DHT22_read() |
+=========================================+
| priznaky, ktere se nastavi po dokonceni |
+-----------------------------------------+
==========================================================================================================================================
==========================================================================================================================================
==========================================================================================================================================
+-----------------------------------------+
| process_status.DHTread == 1 |
| process_status.time_to_SensorRead == 1 |
| process_status.time_to_ReadValue == 1 |
+=========================================+
| DHT22_read() |
+=========================================+
| + process_status.DHTread = 0,1 |
| + process_status.time_to_SensorRead = 0 |
| + process_status.SensorDataReady = 1 |
| - sensor_log = NaN, Range |
+-----------------------------------------+
+--------------------------------------+
| process_status.SensorDataReady == 1 |
| process_status.DataSendOK == 0 |
+======================================+
| send_data_to_server() |
+======================================+
| + process_status.DataSendOK = 1 |
//| + process_status.SensorDataReady = 0 |
| - process_status.DataSendOK = 0 |
| - ETH_send_attempt_act++ |
| - info_word.TIMED_OUT = 1 |
| - info_word.INVALID_SERVER = 1 |
| - info_word.TRUNCATED = 1 |
| - info_word.INVALID_RESPONSE = 1 |
| - info_word.UNKNOWN_ERROR = 1 |
| - info_word.ETH_response_timeout = 1 |
+--------------------------------------+
+---------------------------------------+
| process_status.DataSendOK == 1 |
+=======================================+
| parse_server_response() |
+=======================================+
| + process_status,ServerResponseOK = 1 |
| - process_status,ServerResponseOK = 0 |
| - info_word,BadServerResponse = 1 |
+---------------------------------------+
*/
}