/*
* Last Updated - March 21, 2012
* Open Ocean Reef Controller by Brandon Bearden
*
* This work is licensed under the Creative Commons
* Attribution-NonCommercial-ShareAlike 3.0 Unported License.
* To view a copy of this license, visit
* http://creativecommons.org/licenses/by-nc-sa/3.0/
* or send a letter to Creative Commons, 444 Castro Street,
* Suite 900, Mountain View, California, 94041, USA.
*
* IN NO EVENT SHALL THE LICENSE HOLDER BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
* SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE COPYRIGHT
* HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE LICENSE HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
* AND THE LICENCE HOLDER HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
*/
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include <Time.h>
/* ******** Ethernet Card Settings ******** */
// Set this to your Ethernet Card Mac Address
byte mac[] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
/* ******** NTP Server Settings ******** */
/* us.pool.ntp.org NTP server
(Set to your time server of choice) */
IPAddress timeServer(96, 44, 157, 90);
/* Set this to the offset (in seconds) to your local time
This example is GMT - 6 */
const long timeZoneOffset = -21600L;
/* Syncs to NTP server every 15 seconds for testing,
set to 1 hour or more to be reasonable */
unsigned int ntpSyncTime = 15;
/* ALTER THESE VARIABLES AT YOUR OWN RISK */
// local port to listen for UDP packets
unsigned int localPort = 8888;
// NTP time stamp is in the first 48 bytes of the message
const int NTP_PACKET_SIZE= 48;
// Buffer to hold incoming and outgoing packets
byte packetBuffer[NTP_PACKET_SIZE];
// A UDP instance to let us send and receive packets over UDP
EthernetUDP Udp;
// Keeps track of how long ago we updated the NTP server
unsigned long ntpLastUpdate = 0;
// Check last time clock displayed (Not in Production)
time_t prevDisplay = 0;
void setup() {
Serial.begin(9600);
// Ethernet shield and NTP setup
int i = 0;
int DHCP = 0;
DHCP = Ethernet.begin(mac);
//Try to get dhcp settings 30 times before giving up
while( DHCP == 0 && i < 30){
delay(1000);
DHCP = Ethernet.begin(mac);
i++;
}
if(!DHCP){
Serial.println("DHCP FAILED");
for(;;); //Infinite loop because DHCP Failed
}
Serial.println("DHCP Success");
//Try to get the date and time
int trys=0;
while(!getTimeAndDate() && trys<10) {
trys++;
}
}
// Do not alter this function, it is used by the system
int getTimeAndDate() {
int flag=0;
Udp.begin(localPort);
sendNTPpacket(timeServer);
delay(1000);
if (Udp.parsePacket()){
Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer
unsigned long highWord, lowWord, epoch;
highWord = word(packetBuffer[40], packetBuffer[41]);
lowWord = word(packetBuffer[42], packetBuffer[43]);
epoch = highWord << 16 | lowWord;
epoch = epoch - 2208988800 + timeZoneOffset;
flag=1;
setTime(epoch);
ntpLastUpdate = now();
}
return flag;
}
// Do not alter this function, it is used by the system
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011;
packetBuffer[1] = 0;
packetBuffer[2] = 6;
packetBuffer[3] = 0xEC;
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
Udp.beginPacket(address, 123);
Udp.write(packetBuffer,NTP_PACKET_SIZE);
Udp.endPacket();
}
// Clock display of the time and date (Basic)
void clockDisplay(){
Serial.print(hour());
printDigits(minute());
printDigits(second());
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
}
// Utility function for clock display: prints preceding colon and leading 0
void printDigits(int digits){
Serial.print(":");
if(digits < 10)
Serial.print('0');
Serial.print(digits);
}
// This is where all the magic happens...
void loop() {
// Update the time via NTP server as often as the time you set at the top
if(now()-ntpLastUpdate > ntpSyncTime) {
int trys=0;
while(!getTimeAndDate() && trys<10){
trys++;
}
if(trys<10){
Serial.println("ntp server update success");
}
else{
Serial.println("ntp server update failed");
}
}
// Display the time if it has changed by more than a second.
if( now() != prevDisplay){
prevDisplay = now();
clockDisplay();
}
}
//------------------------setup------------------------------
void setup()
{
// Comment out the line below to use pins 0 and 1 to control the coolers .
Serial.begin(38400 ); // Starts communication with the serial port 0 for debug messages .
Serial3.begin ( 38400 ); // Starts communication with the serial port 2 which are connected to the " stamps" .
// Set the pin function.
pinMode(alarmPin, OUTPUT); // Pino 0;
pinMode(desativarFanPin, OUTPUT); // Pino 1;
pinMode (ChipSelect_SD, OUTPUT); // Pino 4 ou 5;
pinMode(ledPinUV, OUTPUT); // Pino 8;
pinMode(ledPinBlue, OUTPUT); // Pino 9;
pinMode(ledPinWhite, OUTPUT); // Pino 10;
pinMode(ledPinRoyBlue, OUTPUT); // Pino 11;
pinMode(ledPinRed, OUTPUT); // Pino 12;
pinMode(fanPin, OUTPUT); // Pino 13;
pinMode(multiplexadorS0Pin, OUTPUT); // Pino 16;
pinMode(multiplexadorS1Pin, OUTPUT); // Pino 17;
pinMode(aquecedorPin, OUTPUT); // Pino 42;
pinMode(chillerPin, OUTPUT); // Pino 43;
pinMode(ledPinMoon, OUTPUT); // Pino 44;
pinMode(wavemaker1, OUTPUT); // Pino 45;
pinMode(wavemaker2, OUTPUT); // Pino 46;
pinMode(ozonizadorPin, OUTPUT); // Pino 47;
pinMode(reatorPin, OUTPUT); // Pino 48;
pinMode(SelectSlave_ETH, OUTPUT); // Pino 53;
pinMode(sensor1, INPUT); // Pino A0;
pinMode(sensor2, INPUT); // Pino A1;
pinMode(sensor3, INPUT); // Pino A2;
pinMode(sensor4, INPUT); // Pino A3;
pinMode(sensor5, INPUT); // Pino A4;
pinMode(sensor6, INPUT); // Pino A5;
pinMode(bomba1Pin, OUTPUT); // Pino A6;
pinMode(bomba2Pin, OUTPUT); // Pino A7;
pinMode(bomba3Pin, OUTPUT); // Pino A8;
pinMode(dosadora1, OUTPUT); // Pino A9;
pinMode(dosadora2, OUTPUT); // Pino A10;
pinMode(dosadora3, OUTPUT); // Pino A11;
pinMode(dosadora4, OUTPUT); // Pino A12;
pinMode(dosadora5, OUTPUT); // Pino A13;
pinMode(dosadora6, OUTPUT); // Pino A14;
pinMode(ChipSelect_RFM, OUTPUT); // Pino A15;
//**************** PCF8575 ****************
pinMode (temporizador1, OUTPUT); // Pino 80;
pinMode (temporizador2, OUTPUT); // Pino 81;
pinMode (temporizador3, OUTPUT); // Pino 82;
pinMode (temporizador4, OUTPUT); // Pino 83;
pinMode (temporizador5, OUTPUT); // Pino 84;
pinMode (solenoide1Pin, OUTPUT); // Pino 85;
myGLCD.InitLCD(LANDSCAPE); // Image orientation in LCD .
clearScreen(); // Clean the LCD .
myTouch.InitTouch(LANDSCAPE); // Orientation of the " touch screen " .
myTouch.setPrecision ( PREC_MEDIUM ); // Set the accuracy of the " touch screen " .
ReadDallasAddress ();
sensors.begin(); //Inicia as leituras das sondas de temperatura.
sensors.setResolution(sensor_agua, 10); // Define a resolução em 10 bits.
sensors.setResolution(sensor_dissipador, 10); // Define a resolução em 10 bits.
sensors.setResolution(sensor_ambiente, 10); // Define a resolução em 10 bits.
sensors.requestTemperatures(); // Chamada para todos os sensores.
tempC = (sensors.getTempC(sensor_agua)); // Lê a temperatura da água
tempH = (sensors.getTempC(sensor_dissipador)); // Lê a temperatura do dissipador.
tempA = (sensors.getTempC(sensor_ambiente)); // Lê a temperatura do ambiente.
if(PCF8575TS_S == true)
{
PCF8575.begin(endereco_PCF8575TS); // Inicia a comunicação com o PCF8575TS
for(int i = 0; i < 16; i++)
{
PCF8575.pinMode(i, OUTPUT);
delay(100);
PCF8575.digitalWrite(i, LOW);
}
}
rtc.halt(false); // Inicia o funcionamento do RTC.
byte k = EEPROM.read(0);
if(k != 222) // Verifica se a EEPROM foi formatada por este programa
{
setFont(LARGE, 255, 0, 0, 0, 0, 0);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_textos[225]))); // "FORMATANDO A EEPROM..."
myGLCD.print(buffer, CENTER, 115);
EEPROM.write(0, 222); // Indica que a EEPROM foi formatada por este programa
for (int i = 1; i < 4096; i++)
{
EEPROM.write(i, 0); // Formata a eeprom
}
}
k = EEPROM.read(796); // Copia valores dos LEDs para a eeprom.
if(k != 222)
{
SaveLEDToEEPROM();
}
// Lê a variáveis guardadas na EEPROM.
ReadFromEEPROM();
lertpaEEPROM();
lerPHAEEPROM();
lerPHREEPROM();
lerORPEEPROM();
lerDENEEPROM();
ler_dosadora_EEPROM();
ler_luz_noturna_EEPROM();
ler_timers_EEPROM();
ler_coolersEEPROM();
ler_tempPotEEPROM();
ler_wave_EEPROM();
ler_calib_dosadora_EEPROM();
ler_predefinido_EEPROM();
check_erro_tpa_EEPROM();
selecionar_SPI(SD_CARD); // Seleciona disposito SPI que será utilizado.
while(!card.init(SPI_FULL_SPEED, ChipSelect_SD)) // Inicia a comunicação com o cartão SD.
{
setFont(LARGE, 255, 0, 0, 0, 0, 0);
myGLCD.print("PLEASE INSERT A SD CARD.", CENTER, 115);
Serial.println(F("Please insert a SD CARD"));
}
volume.init(&card);
root.openRoot(&volume);
t = rtc.getTime(); // Atualiza as variáveis que usam o RTC.
check_arquivo_temp_agua(); // Corrige o log de temperatura
check_arquivo_ph_agua(); // Corrige o log de pH da água
check_arquivo_ph_reator(); // Corrige o log de pH do reator
check_arquivo_orp(); // Corrige o log de ORP
check_arquivo_densidade(); // Corrige o log de densidade
if(Stamps == true)
{
//iniciar_stamp_ph_reator(); // Lê o pH do reator
iniciar_stamp_orp(); // Lê a ORP
iniciar_stamp_densidade(); // Lê a densidade
iniciar_stamp_ph_aquario(); // Lê o pH do aquário
}
if(Ethernet_Shield == true)
{
selecionar_SPI(ETHER_CARD); // Seleciona disposito SPI que será utilizado.
Ethernet.begin(mac, ip, dnsServer, gateway, subnet, SelectSlave_ETH); // Configuração do servidor.
server.begin(); // Inicia o servidor.
Serial.print(F("Ip Server: "));
Serial.println(Ethernet.localIP());
}
strcpy(buffer,Username);
strcat(buffer,token);
strcat(buffer,APIKEY);
base64_encode(Auth1, buffer, strlen(buffer)); // Cria a senha do servidor.
/* if(RFM12B == true)
{
selecionar_SPI(RFM); // Seleciona disposito SPI que será utilizado.
rf12_initialize(myNodeID,freq,network); // Inicializa o RFM12B
}*/
clearScreen(); // Limpa o LCD.
mainScreen(true); // Exibe a tela inicial no LCD.
}
//*****************************************************************************************
//************************* Funções do ethernet shield ************************************
//*****************************************************************************************
boolean Ethernet_Shield = true; // Change to "false" if not connected to an Ethernet Shield Arduino .
const char *Username = "ckindig123"; // Place here the user name registered in joy-reef.com
const char *APIKEY = "91733d7"; // Cole here ApiKey generated by joy-reef.com
const byte maxima_tentativa = 3; // Maximum number of authentication attempts .
const byte intervalo_tentativa = 15; // Waiting time (in minutes ) for retries.
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // The MAC must be unique on your local network .
byte ip[] = {192, 168, 0, 139}; // Configure the IP according to its local network.
IPAddress dnsServer(8, 8, 8, 8); // Configure the IP according to its local network. This is Google's DNS is generally not necessary to change .
IPAddress gateway(192, 168, 0, 1); // Set the " Gateway " as their local network.
IPAddress subnet(255, 255, 255, 0); // Configure the network mask as your local network .
EthernetServer server(5000); // Insert here the number of the configured port on your router to redirect.
// The port number must be compulsorily either: 80 , 5000, 6000, 7000, 8000, 8080 or 9000 .
unsigned long intervalo = 0;
char *inParse[25];
boolean web_teste = false;
byte tentativa = 0;
boolean web_dosage = false;
unsigned long millis_dosagem = 0;
unsigned long millis_enviar = 0;
boolean web_calibracao = false;
const char *token = ":";
char Auth1[50];
unsigned long teste_led_millis = 0;
void processRequest()
{
char clientline[110];
char line[110];
char *requestString;
char *RequestString;
byte index = 0;
EthernetClient client = server.available();
uint8_t remoteIP[4];
IPAddress joyreef(5, 249, 155, 195);
client.getRemoteIP(remoteIP);
if (client)
{
Serial.print(remoteIP[0]);
Serial.print(".");
Serial.print(remoteIP[1]);
Serial.print(".");
Serial.print(remoteIP[2]);
Serial.print(".");
Serial.println(remoteIP[3]);
if(((remoteIP[0] == joyreef[0]) && (remoteIP[1] == joyreef[1]) && (remoteIP[2] == joyreef[2]) && (remoteIP[3] == joyreef[3])) ||
((remoteIP[0] == ip[0]) && (remoteIP[1] == ip[1]) && (remoteIP[2] == ip[2])))
{
while (client.connected())
{
if (client.available())
{
char c = client.read();
if (c != '\n' && c != '\r')
{
if(index < 110)
{
clientline[index] = c;
line[index] = c;
index++;
}
continue;
}
clientline[index] = 0;
line[index] = 0;
Serial.println(clientline);
if (strstr(clientline, "GET /"))
{
if(strstr(clientline,"?"))
{
//ignore any page request just look at the GET
requestString = strstr(clientline,"=") + 1;
(strstr(clientline, " HTTP"))[0] = 0;
RequestString = strstr(line,"=") + 1;
(strstr(line, " HTTP"))[0] = 0;
readRequest(requestString, RequestString);
}
}
break;
}
}
}
delay(2);
client.stop();
}
}
void readRequest(char *request, char *Request)
{
char inData[50];
char *requestString;
byte count = 0;
char *str;
char *p;
boolean invalidPass = true;
char *pass;
boolean terminador = false;
char credencial[50];
EthernetClient client = server.available();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[8]))); // "HTTP/1.1 200 OK"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[9]))); // "Content-Type: application/json"
client.println(buffer);
client.println();
pass = strtok(Request, ",");
base64_decode(pass, pass, strlen(pass));
base64_decode(credencial, Auth1, strlen(Auth1));
invalidPass = strcmp (pass, credencial);
requestString = strstr(request,",") + 1;
if (invalidPass == false)
{
for(int j = 0; j < strlen(requestString); j++)
{
if(request[j]!='K')
{
inData[j] = requestString[j];
}
if(requestString[j] == 'K')
{
inData[j] = '\0';
p = inData;
terminador = true;
while ((str = strtok_r(p, ",", &p)) != NULL)
{
inParse[count] = str;
count++;
}
}
}
}
if ((invalidPass == false) && (tentativa < maxima_tentativa) && (terminador == true))
{
tentativa = 0;
requestAction(atoi(inParse[0]));
}
else
{
tentativa++;
if(tentativa <= maxima_tentativa)
{
intervalo = millis();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[10]))); // "{\"response\":\"000\"}"
client.print(buffer);
}
else
{
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[11]))); // "{\"response\":\"001\",\"interval\":\""
client.print(buffer + String((intervalo_tentativa * 60) - ((millis() - intervalo) / 1000)) + "\"}");
}
delay(2);
client.stop();
}
}
void requestAction(byte ID)
{
byte cont = 0;
byte dia;
EthernetClient client = server.available();
float lunarCycle = moonPhase(t.year, t.mon, t.date); //get a value for the lunar cycle
switch (ID)
{
case 0: // Home
client.print(F("{\"theatsink\":"));
client.print(tempH);
client.print(F(",\"twater\":"));
client.print(tempC);
client.print(F(",\"tamb\":"));
client.print(tempA);
client.print(F(",\"waterph\":"));
client.print(PHA);
client.print(F(",\"reactorph\":"));
client.print(PHR);
client.print(F(",\"orp\":"));
client.print(ORP);
client.print(F(",\"dens\":"));
client.print(DEN);
client.print(F(",\"wLedW\":"));
client.print(LedToPercent(wled_out));
client.print(F(",\"bLedW\":"));
client.print(LedToPercent(bled_out));
client.print(F(",\"rbLedW\":"));
client.print(LedToPercent(rbled_out));
client.print(F(",\"redLedW\":"));
client.print(LedToPercent(rled_out));
client.print(F(",\"uvLedW\":"));
client.print(LedToPercent(uvled_out));
client.print(F(",\"unix\":"));
client.print(rtc.getTimeStamp());
client.print(F(",\"running\":"));
client.print(millis()/1000);
client.print(F(",\"speed\":"));
client.print(LedToPercent(fanSpeed));
client.print(F(",\"moonPhase\":"));
client.print(fase);
client.print(F(",\"iluminated\":"));
client.print(lunarCycle *100);
client.print(F("}"));
break;
case 1:
// Send{case, mode, association}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
byte numberOfDevices = 0;
float temperatura1 = 0;
float temperatura2 = 0;
float temperatura3 = 0;
sensors.begin();
numberOfDevices = sensors.getDeviceCount();
for(byte k = 0; k < numberOfDevices; k++)
{
// Pesquisar endereços
if(sensors.getAddress(tempDeviceAddress, k))
{
if (k == 0)
{
temperatura1 = sensors.getTempC(tempDeviceAddress);
for (byte i=0; i<8; i++)
{
sonda1[i] = tempDeviceAddress[i];
}
}
if (k == 1)
{
temperatura2 = sensors.getTempC(tempDeviceAddress);
for (byte i=0; i<8; i++)
{
sonda2[i] = tempDeviceAddress[i];
}
}
if (k == 2)
{
temperatura3 = sensors.getTempC(tempDeviceAddress);
for (byte i = 0; i < 8; i++)
{
sonda3[i] = tempDeviceAddress[i];
}
}
}
}
client.print(F("{\"number\":"));
client.print(numberOfDevices);
if(numberOfDevices < 2)
{
if(sonda_associada_1 == 1)
{
sonda_associada_2 = 0;
sonda_associada_3 = 0;
}
else if(sonda_associada_2 == 1)
{
sonda_associada_1 = 0;
sonda_associada_3 = 0;
}
else if(sonda_associada_3 == 1)
{
sonda_associada_1 = 0;
sonda_associada_2 = 0;
}
}
client.print(F(",\"p1\":"));
client.print(temperatura1);
client.print(F(",\"p2\":"));
client.print(temperatura2);
client.print(F(",\"p3\":"));
client.print(temperatura3);
client.print(F(",\"ap1\":"));
client.print(sonda_associada_1);
client.print(F(",\"ap2\":"));
client.print(sonda_associada_2);
client.print(F(",\"ap3\":"));
client.print(sonda_associada_3);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
sonda_associada_1 = atoi(inParse[2]); // 0,3,2,K
sonda_associada_2 = atoi(inParse[3]);
sonda_associada_3 = atoi(inParse[4]);
for(byte i = 0; i < 8; i++)
{
if(sonda_associada_1 == 1)
{
sensor_agua[i] = sonda1[i];
}
else if(sonda_associada_1 == 2)
{
sensor_agua[i] = sonda2[i];
}
else
{
sensor_agua[i] = sonda3[i];
}
if(sonda_associada_2 == 1)
{
sensor_dissipador[i] = sonda1[i];
}
else if(sonda_associada_2 == 2)
{
sensor_dissipador[i] = sonda2[i];
}
else
{
sensor_dissipador[i] = sonda3[i];
}
if(sonda_associada_3 == 1)
{
sensor_ambiente[i] = sonda1[i];
}
else if(sonda_associada_3 == 2)
{
sensor_ambiente[i] = sonda2[i];
}
else
{
sensor_ambiente[i] = sonda3[i];
}
}
contador_temp = 0;
temperatura_agua_temp = 0;
temperatura_dissipador_temp = 0;
temperatura_ambiente_temp = 0;
sensors.requestTemperatures(); // Chamada para todos os sensores.
tempC = (sensors.getTempC(sensor_agua)); // Lê a temperatura da água
tempH = (sensors.getTempC(sensor_dissipador)); // Lê a temperatura do dissipador.
tempA = (sensors.getTempC(sensor_ambiente)); // Lê a temperatura do ambiente.
SaveDallasAddress();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 2: //config date & time //Send (case, mode, date, month, year, hour, minute, second, day of week)
if(atoi(inParse[1]) == 0) // To save time and date send inParse[1] = 1
{
client.print(F("{\"date\":\""));
client.print(t.year);
client.print(F("-"));
client.print(t.mon);
client.print(F("-"));
client.print(t.date);
client.print(F("\",\"time\":\""));
client.print(t.hour);
client.print(F(":"));
client.print(t.min);
client.print(F(":"));
client.print(t.sec);
client.print(F("\"}"));
}
else
{
dia = validateDate(atoi(inParse[4]), atoi(inParse[3]), atoi(inParse[2]));
dia = validateDateForMonth(atoi(inParse[4]), atoi(inParse[3]), atoi(inParse[2]));
rtc.halt(true);
rtc.setDate(dia, atoi(inParse[3]), atoi(inParse[2]));
rtc.setTime(atoi(inParse[5]), atoi(inParse[6]), atoi(inParse[7]));
rtc.setDOW(calcDOW(atoi(inParse[4]), atoi(inParse[3]), atoi(inParse[2])));
rtc.halt(false);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 3:
if(atoi(inParse[1]) == 0) // Send (case, mode, values)
{
client.print(F("{\"hour\":"));
client.print(hora);
client.print(F(",\"minute\":"));
client.print(minuto);
client.print(F(",\"duration\":"));
client.print(duracaomaximatpa);
client.print(F(",\"monday\":"));
client.print(semana_e[0]);
client.print(F(",\"tuesday\":"));
client.print(semana_e[1]);
client.print(F(",\"wednesday\":"));
client.print(semana_e[2]);
client.print(F(",\"thursday\":"));
client.print(semana_e[3]);
client.print(F(",\"friday\":"));
client.print(semana_e[4]);
client.print(F(",\"saturday\":"));
client.print(semana_e[5]);
client.print(F(",\"sunday\":"));
client.print(semana_e[6]);
client.print(F(",\"status\":"));
client.print(bitRead(tpa_status,2));
client.print(F("}"));
}
if(atoi(inParse[1]) == 1)
{
hora = atoi(inParse[2]);
minuto = atoi(inParse[3]);
duracaomaximatpa = atoi(inParse[4]);
for(byte i = 0; i < 7; i++)
{
semana_e[i] = atoi(inParse[i + 5]);
}
SalvartpaEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
if(atoi(inParse[1]) == 2)
{
bitWrite(tpa_status,2,atoi(inParse[2]));
Salvar_erro_tpa_EEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 4: //individual led test - load first values
if (atoi(inParse[1]) == 0) //Send (case, mode, wled, rled, rbled, rled, uvled)
{
client.print(F("{\"wLedW\":"));
client.print(wled_out);
client.print(F(",\"bLedW\":"));
client.print(bled_out);
client.print(F(",\"rbLedW\":"));
client.print(rbled_out);
client.print(F(",\"uvLedW\":"));
client.print(uvled_out);
client.print(F(",\"redLedW\":"));
client.print(rled_out);
client.print(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to change values
{
wled_out_temp = atoi(inParse[2]);
bled_out_temp = atoi(inParse[3]);
rbled_out_temp = atoi(inParse[4]);
rled_out_temp = atoi(inParse[5]);
uvled_out_temp = atoi(inParse[6]);
web_teste = true;
teste_led_millis = millis();
teste_em_andamento = true;
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
else if (atoi(inParse[1]) == 2)
{
web_teste = false;
teste_em_andamento = false;
ler_predefinido_EEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 5:
// Send{case, mode, color, first position}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"value0\":"));
for(byte i = 1 + atoi(inParse[3]); i < 9 + atoi(inParse[3]); i++)
{
client.print(cor[atoi(inParse[2])][i - 1]);
if(i < 8 + atoi(inParse[3]))
{
client.print(",\"value" + String(i - atoi(inParse[3])) + "\":");
}
}
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values temporarily
{
for (int i = atoi(inParse[3]); i < atoi(inParse[3]) + 8; i++)
{
cont++;
cor[atoi(inParse[2])][i] = atoi(inParse[3 + cont]);
}
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
else if (atoi(inParse[1]) == 2) // mode = 2 to save values to eeprom
{
SaveLEDToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
else if (atoi(inParse[1]) == 3) // mode = 3 to discard values
{
ReadFromEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 6: //moonlight
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"min\":"));
client.print(MinI);
client.print(F(",\"max\":"));
client.print(MaxI);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
MinI = atoi(inParse[2]);
MaxI = atoi(inParse[3]);
Salvar_luz_noturna_EEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 7: //fan led
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"minfan\":"));
client.print(HtempMin);
client.print(F(",\"maxfan\":"));
client.print(HtempMax);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
HtempMin = atof(inParse[2]);
HtempMax = atof(inParse[3]);
salvar_coolersEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 8: //reduce led power
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"templimit\":"));
client.print(tempHR);
client.print(F(",\"potred\":"));
client.print(potR);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
tempHR = atoi(inParse[2]);
potR = atoi(inParse[3]);
salvar_tempPotEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 9: //water temperature control
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"setTemp\":"));
client.print(setTempC);
client.print(F(",\"offTemp\":"));
client.print(offTempC);
client.print(F(",\"alarmTemp\":"));
client.print(alarmTempC);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
setTempC = atof(inParse[2]);
offTempC = atof(inParse[3]);
alarmTempC = atof(inParse[4]);
SaveTempToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 10:// dosage manual
// send (case, dosing pump selected, dose)
dosadora_selecionada = atoi(inParse[1]);
tempo_dosagem = map ((atof(inParse[2])*2), 0, fator_calib_dosadora_e[dosadora_selecionada], 0, 60000);
tempo_dosagem /= 2;
web_dosage = true;
client.print("{\"wait\":" + String((tempo_dosagem / 1000) + 10) + "}");
millis_dosagem = millis();
break;
case 11:// Calibration
if(atoi(inParse[1]) == 0)// send (case, mode, dosing pump selected)
{
dosadora_selecionada = atoi(inParse[2]);
config_valores_calib_temp();
client.print(F("{\"calib\":"));
client.print(fator_calib_dosadora[dosadora_selecionada]);
client.println(F("}"));
}
else if(atoi(inParse[1]) == 1)// send (case, mode, dosing pump selected) mode = 1 to dose
{
dosadora_selecionada = atoi(inParse[2]);
client.print(F("{\"wait\":70}"));
web_calibracao = true;
millis_dosagem = millis();
}
else if(atoi(inParse[1]) == 2)// send (case, mode, dosing pump selected, factor of calibration) mode = 2 to save
{
dosadora_selecionada = atoi(inParse[2]);
fator_calib_dosadora[dosadora_selecionada] = atof(inParse[3]);
for(byte i = 0; i < 6; i++)
{
fator_calib_dosadora_e[i] = fator_calib_dosadora[i];
}
Salvar_calib_dosadora_EEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 12:
if(atoi(inParse[1]) == 0) // Send (case, mode, dosing pump selected)
{
config_valores_dosadoras_temp();
config_valores_dosadoras_temp2();
dosadora_selecionada = atoi(inParse[2]);
client.print(F("{\"hStart\":"));
client.print(hora_inicial_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"mStart\":"));
client.print(minuto_inicial_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"hEnd\":"));
client.print(hora_final_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"mEnd\":"));
client.print(minuto_final_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"monday\":"));
client.print(segunda_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"tuesday\":"));
client.print(terca_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"wednesday\":"));
client.print(quarta_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"thursday\":"));
client.print(quinta_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"friday\":"));
client.print(sexta_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"saturday\":"));
client.print(sabado_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"sunday\":"));
client.print(domingo_dosagem_personalizada[dosadora_selecionada]);
client.print(F(",\"quantity\":"));
client.print(quantidade_dose_dosadora_personalizada[dosadora_selecionada]);
client.print(F(",\"dose\":"));
client.print(dose_dosadora_personalizada[dosadora_selecionada]);
client.print(F(",\"onoff\":"));
client.print(modo_personalizado_on[dosadora_selecionada]);
client.println(F("}"));
}
else if(atoi(inParse[1]) == 1) // Send (case, mode, dosing pump selected, values)
{
dosadora_selecionada = atoi(inParse[2]);
hora_inicial_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[3]);
minuto_inicial_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[4]);
hora_final_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[5]);
minuto_final_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[6]);
segunda_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[7]);
terca_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[8]);
quarta_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[9]);
quinta_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[10]);
sexta_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[11]);
sabado_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[12]);
domingo_dosagem_personalizada[dosadora_selecionada] = atoi(inParse[13]);
quantidade_dose_dosadora_personalizada[dosadora_selecionada] = atoi(inParse[14]);
dose_dosadora_personalizada[dosadora_selecionada] = atof(inParse[15]);
modo_personalizado_on[dosadora_selecionada] = atoi(inParse[16]);
config_valores_salvar_dosadoras();
criar_arquivos();
Salvar_dosadora_EEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 13: //PH control
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"setPHA\":"));
client.print(setPHA);
client.print(F(",\"offPHA\":"));
client.print(offPHA);
client.print(F(",\"alarmPHA\":"));
client.print(alarmPHA);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
setPHA = atof(inParse[2]);
offPHA = atof(inParse[3]);
alarmPHA = atof(inParse[4]);
SavePHAToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 14: // Calcium Reactor PH control
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"setPHR\":"));
client.print(setPHR);
client.print(F(",\"offPHR\":"));
client.print(offPHR);
client.print(F(",\"alarmPHR\":"));
client.print(alarmPHR);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
setPHR = atof(inParse[2]);
offPHR = atof(inParse[3]);
alarmPHR = atof(inParse[4]);
SavePHRToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 15: // ORP control
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"setORP\":"));
client.print(setORP);
client.print(F(",\"offORP\":"));
client.print(offORP);
client.print(F(",\"alarmORP\":"));
client.print(alarmORP);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
setORP = atoi(inParse[2]);
offORP = atoi(inParse[3]);
alarmORP = atoi(inParse[4]);
SaveORPToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 16: // Density control
// Send{case, mode, value}
if (atoi(inParse[1]) == 0) // mode = 0 to read values
{
client.print(F("{\"setDEN\":"));
client.print(setDEN);
client.print(F(",\"offDEN\":"));
client.print(offDEN);
client.print(F(",\"alarmDEN\":"));
client.print(alarmDEN);
client.println(F("}"));
}
else if (atoi(inParse[1]) == 1) // mode = 1 to save values
{
setDEN = atoi(inParse[2]);
offDEN = atoi(inParse[3]);
alarmDEN = atoi(inParse[4]);
SaveDENToEEPROM();
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
case 17:
break;
case 18:// Timers
if(atoi(inParse[1]) == 0)// send (case, mode, timer selec.)
{
temporizador = atoi(inParse[2]);
config_valores_timers_temp();
client.print(F("{\"hStart\":"));
client.print(on_hora[temporizador]);
client.print(F(",\"mStart\":"));
client.print(on_minuto[temporizador]);
client.print(F(",\"hEnd\":"));
client.print(off_hora[temporizador]);
client.print(F(",\"mEnd\":"));
client.print(off_minuto[temporizador]);
client.print(F(",\"activated\":"));
client.print(temporizador_ativado[temporizador]);
client.println(F("}"));
}
else if(atoi(inParse[1]) == 1)// send (case, mode, timer selected, values) mode = 1 to save
{
web_timer = true;
temporizador = atoi(inParse[2]);
on_hora[temporizador] = atoi(inParse[3]);
on_minuto[temporizador] = atoi(inParse[4]);
off_hora[temporizador] = atoi(inParse[5]);
off_minuto[temporizador] = atoi(inParse[6]);
temporizador_ativado[temporizador] = atoi(inParse[7]);
config_valores_salvar_timers();
salvar_timers_EEPROM();
bitWrite(temporizador_modificado,(temporizador + 1),1);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[7]))); // "{\"response\":\"ok\"}"
client.println(buffer);
}
break;
}
}
void dosagem_manual()
{
digitalWrite(dosadora[dosadora_selecionada], HIGH);
delay(tempo_dosagem);
digitalWrite(dosadora[dosadora_selecionada], LOW);
}
void calibrar()
{
digitalWrite(dosadora[dosadora_selecionada], HIGH);
delay(60000);
digitalWrite(dosadora[dosadora_selecionada], LOW);
}
void enviar_dados()
{
char dados[6];
EthernetClient client;
IPAddress joyreef(5, 249, 155, 195);
String OneString;
int ContentLength = 0;
OneString = Username;
ContentLength += OneString.length();
dtostrf(tempC,5,2,dados);
OneString = String(dados);
ContentLength += OneString.length();
dtostrf(tempH,5,2,dados);
OneString = String(dados);
ContentLength += OneString.length();
dtostrf(tempA,5,2,dados);
OneString = String(dados);
ContentLength += OneString.length();
dtostrf(PHA,5,2,dados);
OneString = String(dados);
ContentLength += OneString.length();
dtostrf(PHR,5,2,dados);
OneString = String(dados);
ContentLength += OneString.length();
OneString = String(DEN);
ContentLength += OneString.length();
OneString = String(ORP);
ContentLength += OneString.length();
OneString = String(rtc.getTimeStamp());
ContentLength += OneString.length();
ContentLength += 140;
Serial.println(F("Connecting..."));
if (client.connect(joyreef, 80))
{
Serial.println(F(">> Connected <<"));
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[0]))); // "POST /api/temp HTTP/1.1"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[1]))); // "Host: www.joy-reef.eu"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[2]))); // "Authorization: Basic "
client.print(buffer);
client.println(Auth1);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[3]))); // "Cache-Control: no-cache"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[4]))); // "Content-Type: application/x-www-form-urlencoded"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[5]))); // "Connection: close"
client.println(buffer);
strcpy_P(buffer, (char*)pgm_read_word_near(&(tabela_strings[6]))); // "Content-Length: "
client.print(buffer);
client.println(ContentLength);
client.println();
client.print(F("{\"userName\":\""));
client.print(Username);
client.print(F("\",\"minute\":\""));
client.print(rtc.getTimeStamp());
client.print(F("\",\"A\":")); // Temp. da água
client.print(dtostrf(tempC,5,2,dados));
client.print(F(",\"B\":")); // Temp. dissipador
client.print(dtostrf(tempH,5,2,dados));
client.print(F(",\"C\":")); // Temp. ambiente
client.print(dtostrf(tempA,5,2,dados));
client.print(F(",\"D\":")); // PH do aquário
client.print(dtostrf(PHA,4,2,dados));
client.print(F(",\"E\":")); // PH do reator de cálcio
client.print(dtostrf(PHR,4,2,dados));
client.print(F(",\"F\":")); // Densidade
client.print(DEN);
client.print(F(",\"G\":")); // ORP
client.print(ORP);
client.print(F(",\"H\":")); // Status chiller, 0 = desligado e 1 = ligado
client.print(bitRead(status_parametros,0));
client.print(F(",\"I\":")); // Status aquecedor, 0 = desligado e 1 = ligado
client.print(bitRead(status_parametros,1));
client.print(F(",\"J\":")); // Status reator de cálcio, 0 = desligado e 1 = ligado
client.print(bitRead(status_parametros,5));
client.print(F(",\"K\":")); // Status ozonizador, 0 = desligado e 1 = ligado
client.print(bitRead(status_parametros,7));
client.print(F(",\"L\":")); // Status reposição de água doce, 0 = desligado e 1 = ligado
client.print(bitRead(Status,1));
client.print(F(",\"M\":")); // Status niveis, 0 = baixo e 1 = normal
client.print(nivel_status);
client.print(F(",\"N\":")); // Status TPA, 0 = desligado e 1 = ligado
client.print(bitRead(tpa_status,0));
client.print(F(",\"O\":"));
client.print(bitRead(temporizador_status,1)); // Status timer 1, 0 = desligado e 1 = ligado
client.print(F(",\"P\":"));
client.print(bitRead(temporizador_status,2)); // Status timer 2, 0 = desligado e 1 = ligado
client.print(F(",\"Q\":"));
client.print(bitRead(temporizador_status,3)); // Status timer 3, 0 = desligado e 1 = ligado
client.print(F(",\"R\":"));
client.print(bitRead(temporizador_status,4)); // Status timer 4, 0 = desligado e 1 = ligado
client.print(F(",\"S\":"));
client.print(bitRead(temporizador_status,5)); // Status timer 5, 0 = desligado e 1 = ligado
client.print(F(",\"T\":")); // Sinaliza falha na TPA
client.print(bitRead(tpa_status,2));
client.println(F("}"));
delay(5);
client.stop();
}
else
{
Serial.println(F("Can't connect!"));
}
}
Return to Show your controller
Users viewing this topic: No registered users and 2 guests