pomoc s kódem

Odpovědět
tomduda
Příspěvky: 4
Registrován: 30 kvě 2022, 16:15
Reputation: 0

pomoc s kódem

Příspěvek od tomduda » 30 kvě 2022, 16:19

Zdravím, jsem začátečník v programování, mám zde kód pro ovládání chlorinátoru v bazénu ale nechce mi číst teplotu, čidlo am2301 jsem otestoval s jiným programem a je funkční, poradíte mi někdko kde je chyba???

díky

Kód: Vybrat vše

#include <avr/wdt.h>     // Watchdog
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "aREST.h"
#include <EEPROM.h>
#include "xPL.h"
#include "DHT.h"       // DTH21 Temperature and Humidity.
#include <LiquidCrystal.h> // LCD
#include "EmonLib.h"       // Power current/sensor
EnergyMonitor emon1;       // Create an instance for power current


uint8_t pin_ph = A8;                 // Pin pH Probe
uint8_t pin_redox = A9;              // Pin Redox Probe
uint8_t pin_relay_justsalt = 41;     // Pin to Relay to JustSalt. If state=high -> salt production in progress (red light on)
uint8_t pin_relay_pool_lights = 40;    // Pin to Relay to pool lights.
// uint8_t pin_dth = 2;               // Pin sensor DTH21 Temperature and Humidity.
int pin_water_sensor = 39;           // Pin water leak sensor. Is High when there is a leak. (I had to set it as int...)
uint8_t pin_power_sensor = A11;        // Pin to power sensor.
uint8_t pin_potentiometer_redox = A12; // Pin to potentiometer used to define redox desired range
uint8_t pin_potentiometer_ph = A13;    // Pin to the potentiometer used to calibrate pH
#define pinDHT 2
#define typDHT21 DHT21
DHT dht(pinDHT, typDHT21);

float ph_sensor_value = 0.0;         // value read in Volt (0 to 5)
float ph_value_float = 0.0;            // pH value from 0.0 to 14.0 in float
char ph_value_char[5];             // pH value from 0 to 14 in char

float redox_sensor_value = 0.0;        // value read in Volt (0 to 5)
float redox_value_float = 0.0;       // redox value from -2000 to 2000 mV in float
char redox_value_char[5];          // redox value from -2000 to 2000 in char
int redox_max;                   // define the max value of redox, if more then stop clorine production
int redox_min;                   // define the min value of redox, if less then start clorine production
int redox_range_delta = 20;        // used to calculate the range (from-to) of accepted value. Example: 600-> value are from 600-20/2 to 600+20/2 (from 590 to 610)

float temperature_float = 0.0;
char temperature_char[5];
float humidity_float = 0.0;
char humidity_char[5];

float power_value_float = 0.0;      // Power consumption in Watt
char power_value_char[5];

bool filtration_bool = 0;       // Filtration state. 0 is off, 1 is on
int counter_filtration = 0;       // Count minutes of filtration on 24h // To display to numbers of hours of working on 24h. The filtration time should be Temperature of the water divised by two. (Hours=Temp/2)

byte lights_seq_number = 0;       // Display the save the lights sequence number (from 1 to 16)
byte lights_eeprom_addr = 0;

unsigned long lastReadingTime = 0;
int count_time_30s = 0;           // used to trigger action every 30s (15*2s)
int count_time_30min = 0;         // used to trigger action every 30min (60*30s)
int count_time_24h = 0;           // used to trigger action every 24h (2880*30)

byte mac[] = { 0x00, 0xAC, 0xAE, 0x3F, 0xF1, 0xAD };  // Production MAC address
IPAddress broadcast(192, 168, 100, 255);
EthernetClient client;            // For PushingBox...
EthernetUDP Udp;
xPL xpl;

  LiquidCrystal lcd(12, 11, 5, 4, 3, 8);
  DHT dht(pinDHT, typDHT21);

// PushingBox part
char devid_water_detection[] = "v0660D5BCF75744C";
char serverName[] = "api.pushingbox.com";

//RestAPI Part (for controlling lights)
EthernetServer server(80);
aREST rest = aREST();
int delay_betweent_relay_lights = 150; // time between relay state change in ms

void setup()
{
  //Watchdog part
  MCUSR &= ~_BV(WDRF);      // Clear the reset bit
  WDTCSR |= _BV(WDCE) | _BV(WDE); // Disable the WDT
  WDTCSR = 0;

  Serial.begin(57600);
  pinMode(pin_relay_justsalt, OUTPUT);
  digitalWrite(pin_relay_justsalt, 1);  // do not start clorine production
  pinMode(pin_water_sensor, INPUT_PULLUP);
  digitalWrite(pin_water_sensor, HIGH);

  // Test Pool Light
  pinMode(pin_relay_pool_lights, OUTPUT);
  digitalWrite(pin_relay_pool_lights, 1); // lights off by default

  dht.begin();         // Start tempature and humidity sensor
  emon1.current(11, 66);       // Power Current: input pin, calibration.

  lcd.begin(20, 4); // Init LCD screen, 4 lignes by 20 chars
  lcd.clear();

  // Print the default text on the LCD.
  lcd.setCursor (0, 0);
  lcd.print("Tepl:");
  lcd.setCursor (12, 0);
  lcd.print("pH:");
  lcd.setCursor (0, 1);
  lcd.print("Sonda:");
  lcd.setCursor (0, 2);
  lcd.print("Odber:");
  lcd.setCursor (12, 2);
  lcd.print("T:");
  lcd.setCursor (14, 2);
  lcd.print("...");
  lcd.setCursor (0, 3);
  lcd.print("Cl:");


  Serial.println(F(""));
  Serial.println(F("Starting (v1.0)"));
  printMac(mac);
  delay(100); // delay to boot in case of multiple DHCP requests from others Arduinos //TODO: Put 7000
  while(Ethernet.begin(mac) == 0)
  {
    Serial.println(F("Failed to configure Ethernet using DHCP"));
  }
  printIP();      // Show IP in serial monitor
  Udp.begin(xpl.udp_port);

  xpl.SendExternal = &SendUdPMessage;        // pointer to the send callback
  xpl.AfterParseAction = &AfterParseAction;  // pointer to a post parsing action callback
  xpl.SetSource_P(PSTR("xpl"), PSTR("arduino"), PSTR("piscine")); // parameters for hearbeat message

  //RestAPI part
  rest.function("lights", lightsControl);
  rest.set_id("001");
  rest.set_name("arduino_piscine");


  wdt_enable(WDTO_8S); //enable 8s watchdog
}


void loop()
{
  // RestAPI part
  EthernetClient client = server.available(); //TODO :verifier si pas redondant
//  rest.handle(client);

  xpl.Process();  // heartbeat management

  // Parser part. Read input XPL message
  if(Udp.parsePacket())
  {
    char xPLMessageBuff[XPL_MESSAGE_BUFFER_MAX];
    Udp.read(xPLMessageBuff, XPL_MESSAGE_BUFFER_MAX); // read the packet into packetBufffer
    xpl.ParseInputMessage(xPLMessageBuff);              // parse message
  }

  // Protect if millis return to 0 (every 50 days)
  if (millis() - lastReadingTime < 0)
  {
    lastReadingTime = millis();
  }

  // Show datas on LCD every 2 seconds
  if ((millis() - lastReadingTime) >= 2000)
  {
    // pH Part
    ph_sensor_value = analogRead(pin_ph) * 5000.0 / 1023.0 / 1000.0; // form 0.0 to 5.0 V
    ph_value_float = (0.0178 * ph_sensor_value * 200.0) - 1.889;     // formula to calcul pH from sensor value
    //Serial.println(ph_value_float);
    //Serial.println(analogRead(pin_potentiometer_ph));
    // add calibration
    ph_value_float = ph_value_float + (analogRead(pin_potentiometer_ph) - 512.0) / 500.0; // calibration is from -1 to +1 pH
    lcd.setCursor (15, 0);
    lcd.print("     ");   // Clean lcd old digits
    lcd.setCursor (15, 0);
    lcd.print(ph_value_float, 2);

    // Redox Part
    redox_sensor_value = analogRead(pin_redox) * 5000.0 / 1023.0 / 1000.0;   // form 0.0 to 5.0 V
    redox_value_float = ((2.5 - redox_sensor_value) / 1.037) * 1000.0;     // from -2000 to 2000 mV
    lcd.setCursor (6, 1);
    lcd.print("      ");  // Clean lcd old digits
    lcd.setCursor (6, 1);
    lcd.print(redox_value_float, 0);
    // get min-max redox values accepted
    int potentiometer_redox = analogRead(pin_potentiometer_redox);
    potentiometer_redox = map(potentiometer_redox, 0, 1023, 400, 1100);
    redox_min = potentiometer_redox / 10 * 10 - redox_range_delta / 2;
    redox_max = potentiometer_redox / 10 * 10 + redox_range_delta / 2;
    lcd.setCursor (12, 1);
    lcd.print(redox_min);
    lcd.print("-");
    lcd.print(redox_max);
    lcd.print(" ");

    // DHT Temp and humidity Part
    temperature_float = dht.readTemperature();
    humidity_float = dht.readHumidity();
    lcd.setCursor (5, 0);
    lcd.print("       "); // Clean lcd old digits
    lcd.setCursor (5, 0);
    lcd.print(temperature_float, 1);
    lcd.print("C");

    // Relay JustSalt part. Chlorin Production
    lcd.setCursor (3, 3);
    if (digitalRead(pin_relay_justsalt) == 0)
    {
      lcd.print("ON ");
    }
    else
    {
      lcd.print("OFF");
    }

    // Power sensor
    double Irms = emon1.calcIrms(1480);  // Calculate Power current (Irms only)
    power_value_float = Irms * 232.0;
    lcd.setCursor (6, 2);
    lcd.print("      ");  // Clean lcd old digits
    lcd.setCursor (6, 2);
    lcd.print(power_value_float, 0);

    // Power state
    if (power_value_float > 300)  // Power is more than 300W
    {
      filtration_bool = 1;      // on: filtration in progress
    }
    else
    {
      filtration_bool = 0;
      digitalWrite(pin_relay_justsalt, 1);  // salt production is stopped when filtration is stoped...
    }

    // Water leak detection
    if (digitalRead(pin_water_sensor) == LOW)
    {
      lcd.setCursor (19, 3);
      lcd.print("!");
    }
    else
    {
      lcd.setCursor (19, 3);
      lcd.print(".");
    }
    //Serial.print(digitalRead(pin_water_sensor));
    //lcd.setCursor (19,3);
    //lcd.print(digitalRead(pin_water_sensor));


    // Lights part
    lcd.setCursor (12, 3);
    lcd.print("Lum:");
    if(digitalRead(pin_relay_pool_lights) == 0)
    {
      lcd.print(EEPROM.read(lights_eeprom_addr)); // Display the seq number when pool lights are on
      lcd.print(" ");
    }
    else
    {
      lcd.print("0 ");              // Display 0 when Pool lights are off
    }



    count_time_30s++; // Count 15 cycles for sending XPL every 30s
    lastReadingTime = millis();
  }

  // Send datas as xPL Message every 30 seconds
  if (count_time_30s == 15)
  {
    // pH Part
    dtostrf(ph_value_float , 3, 2, ph_value_char);            // float to char format: XX.XX
    print_sensor_value("pH", analogRead(pin_ph), ph_value_float);   // debug print
    send_xpl_message("ph", ph_value_char);                // send xpl message

    // Redox Part
    dtostrf(redox_value_float, 5, 0, redox_value_char);         // float to char with decimal resolution format: XXXX
    print_sensor_value("Redox", analogRead(pin_redox), redox_value_float);  // debug print
    send_xpl_message("redox", redox_value_char);            // send xpl message

    // DHT Temp and humidity Part
    //Send temperature to XPL
    dtostrf(temperature_float , 3, 2, temperature_char);
    send_xpl_message("temp", temperature_char);     //send xpl message
    //Send humidity to XPL
    dtostrf(humidity_float , 3, 2, humidity_char);
    send_xpl_message("humidity", humidity_char);  //send xpl message

    // Relay JustSalt part
    if (digitalRead(pin_relay_justsalt) == 0)
    {
      send_xpl_message("justsaltstate", "on");  // on: electrolyse in progress
    }
    else
    {
      send_xpl_message("justsaltstate", "off");
    }

    // Power sensor
    dtostrf(power_value_float , 4, 0, power_value_char);
    send_xpl_message("current", power_value_char);  //send xpl message

    // Power state
    if (filtration_bool == 1)             // Power is more than 300W, filtration in progress
    {
      send_xpl_message("state", "on");  // on: filtration in progress
    }
    else
    {
      send_xpl_message("state", "off");
    }

    // Water leak sensor
    if (digitalRead(pin_water_sensor) == LOW)
    {
      send_xpl_message("leak", "on");     // water leak detected
      sendToPushingBox(devid_water_detection);//Send Push with PushingBox in case of water leak every 30s
    }


    //if (count_time_30min % 2 == 0)    // every 1min, used to count minutes of active filtration on 24h
    //{
    if (filtration_bool == 1)       // if filtration in progress
    {
      counter_filtration++;
    }
    //itoa (counter_filtration, char test, 10);
    //send_xpl_message("timer", String(counter_filtration));
    count_time_24h++;
    //}

    count_time_30s = 0;
    count_time_30min++;
  }


  if (count_time_30min == 60)     // every 30min (60*30s)
  {

    if ((redox_value_float > redox_max) && (filtration_bool == 1))    // if to much clorine and filtration in progress
    {
      digitalWrite(pin_relay_justsalt, 1);              // Set the relay to stop Clorine production
    }
    if ((redox_value_float < redox_min) && (filtration_bool == 1))
    {
      digitalWrite(pin_relay_justsalt, 0);              // Set the relay to start Clorine production
    }

    count_time_30min = 0;
  }

  if (count_time_24h == 2880)     // every 24h (1440*1min)
  {
    //Serial.println(count_time_24h);
    lcd.setCursor (14, 2);
    lcd.print("      ");
    lcd.setCursor (14, 2);
    lcd.print(counter_filtration / 60);
    lcd.print("h");
    if (counter_filtration % 60 < 10)
    {
      lcd.print("0");
    }
    lcd.print(counter_filtration % 60);

    counter_filtration = 0;
    count_time_24h = 0;
  }


  wdt_reset();  //Reset the Watchdog timer
}




// Send UDP Message
void SendUdPMessage(char *buffer)
{
  Udp.beginPacket(broadcast, xpl.udp_port);
  Udp.write(buffer);
  Udp.endPacket();
}

// Print MAC Address
void printMac (const byte *buf)
{
  Serial.print(F("MAC: "));
  for (byte i = 0; i < 6; ++i)
  {
    if (buf[i] >= 0 && buf[i] <= 16)
      Serial.print(F("0"));
    Serial.print( buf[i], HEX );
    if (i < 5)
      Serial.print(F(":"));
  }
  Serial.println("");
}

// Print IP address
void printIP()
{
  // print your local IP address:
  Serial.print(F("My IP address: "));
  for (byte thisByte = 0; thisByte < 4; thisByte++)
  {
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(F("."));
  }
  Serial.println();
}

// Print debug info into serial monitor
void print_sensor_value(char* name, int sensor_value, float value)
{
  //print the results to the serial monitor for debug:
  Serial.print(name);
  Serial.print(F(" sensor: "));
  Serial.print(sensor_value);
  Serial.print(F(" output: "));
  Serial.println(value);
}

// Send XPL Message
void send_xpl_message(char* type, char* current)
{
  xPL_Message msg;
  msg.hop = 1;
  msg.type = XPL_TRIG;
  msg.SetTarget_P(PSTR("*"));
  msg.SetSchema_P(PSTR("sensor"), PSTR("basic"));
  msg.AddCommand_P(PSTR("device"), PSTR("piscine"));
  msg.AddCommand("type", type);
  msg.AddCommand("current", current);
  xpl.SendMessage(&msg);
}

// Parse input XPL messages
// usage: xpl-sender -m xpl-cmnd -t xpl-arduino.piscine -c justsalt.on000000
// should have a length of 8 for class because of a bug in the lib :(. That's why I added some "0".
void AfterParseAction(xPL_Message * message)
{
  if (xpl.TargetIsMe(message))
  {
    // If we get an XPL packet, then turn on or off the Chlorine production
    if (message->IsSchema_P(PSTR("justsalt"), PSTR("on000000")))
    {
      digitalWrite(pin_relay_justsalt, 0);
      Serial.println(F("Turning ON Justsalt"));
      send_xpl_message("justsaltstate", "on");
    }
    if (message->IsSchema_P(PSTR("justsalt"), PSTR("off00000")))
    {
      digitalWrite(pin_relay_justsalt, 1);
      Serial.println(F("Turning OFF Justsalt"));
      send_xpl_message("justsaltstate", "off");
    }
  }
  // show all messages
  //Serial.println(message->toString());
}


//Function for sending the request to PushingBox
void sendToPushingBox(char devid[])
{
  client.stop();

  if (client.connect(serverName, 80))
  {
    Serial.println("PB connected");

    Serial.println("PB sendind request");
    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: Arduino");
    client.println();
  }
  else
  {
    Serial.println("PB connection failed");
  }
}




// Controle lights of pool from RestAPI
// Usage : curl http://192.168.100.119/lights?params=actionOn
int lightsControl(String command)
{

  //Serial.println(command);

  if(command == "actionOn")
  {
    digitalWrite(pin_relay_pool_lights, 0);
    return 1;
  }
  else if(command == "actionOff")
  {
    digitalWrite(pin_relay_pool_lights, 1);
    return 1;
  }

  else if(command == "actionBlanc")
  {
    return poolLightRunSequence(1);
  }

  else if(command == "actionBleu")
  {
    return poolLightRunSequence(2);
  }

  else if(command == "actionCyan")
  {
    return poolLightRunSequence(4);
  }

  else if(command == "actionVert")
  {
    return poolLightRunSequence(6);
  }

  else if(command == "actionJaune")
  {
    return poolLightRunSequence(8);
  }

  else if(command == "actionRouge") 
  {
    return poolLightRunSequence(10);
  }

  else if(command == "actionViolet")
  {
    return poolLightRunSequence(11);
  }

  else if(command == "actionVariation1")
  {
    return poolLightRunSequence(13);
  }

  else if(command == "actionVariation2")
  {
    return poolLightRunSequence(14);
  }

  else if(command == "actionVariation3")
  {
    return poolLightRunSequence(15);
  }

  else if(command == "actionVariation4")
  {
    return poolLightRunSequence(16);
  }

  else if(command == "boutonC")
  {
    digitalWrite(pin_relay_pool_lights, 1);
    delay(delay_betweent_relay_lights);
    digitalWrite(pin_relay_pool_lights, 0);
    delay(delay_betweent_relay_lights);
    return 1;
  }

  else
  {
    return 0;
  }

  return 0;
}


int poolLightRunSequence(byte desired_seq_number)
{

  // Get actual sequence number
  int actual_seq_number = EEPROM.read(lights_eeprom_addr);

  // Calcul the number of toogle to rich the derised num from the actual seq_num
  if(actual_seq_number == desired_seq_number)
  {
    // Toogle 16 times if same color ?
    for (int i = 1; i <= 16; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }
  else if(actual_seq_number > desired_seq_number)
  {
    int num = 16 - actual_seq_number + desired_seq_number;
    for (int i = 1; i <= num; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }
  else
  {
    int num = desired_seq_number - actual_seq_number;
    for (int i = 1; i <= num; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }

  // Write new sequence number into eeprom
  EEPROM.write(lights_eeprom_addr, desired_seq_number);

  return 1;
}

Uživatelský avatar
kiRRow
Příspěvky: 1152
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: pomoc s kódem

Příspěvek od kiRRow » 30 kvě 2022, 17:10

Kód prosím vkládat mezi tag code ( pátá ikonka z leva ) ... musíš uznat, že to vypadá fakt lépe. Doporučuji ještě dodat odkud to máš. Mohli bychom se tam proklikat ke schématům, možná nějaký článek jak to kdo myslel ...

tomduda
Příspěvky: 4
Registrován: 30 kvě 2022, 16:15
Reputation: 0

Re: pomoc s kódem

Příspěvek od tomduda » 30 kvě 2022, 18:51

Ok díky , jj určitě je to lepší, člověk hned neví co a jak jsem tu poprvé.

tomduda
Příspěvky: 4
Registrován: 30 kvě 2022, 16:15
Reputation: 0

Re: pomoc s kódem

Příspěvek od tomduda » 30 kvě 2022, 18:53

tomduda píše:
30 kvě 2022, 16:19
Zdravím, jsem začátečník v programování, mám zde kód pro ovládání chlorinátoru v bazénu ale nechce mi číst teplotu, čidlo am2301 jsem otestoval s jiným programem a je funkční, poradíte mi někdko kde je chyba???
Zdroj https://clement.storck.me/blog/2014/08/ ... a-piscine/


díky

Kód: Vybrat vše

#include <avr/wdt.h>     // Watchdog
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>
#include "aREST.h"
#include <EEPROM.h>
#include "xPL.h"
#include "DHT.h"       // DTH21 Temperature and Humidity.
#include <LiquidCrystal.h> // LCD
#include "EmonLib.h"       // Power current/sensor
EnergyMonitor emon1;       // Create an instance for power current


uint8_t pin_ph = A8;                 // Pin pH Probe
uint8_t pin_redox = A9;              // Pin Redox Probe
uint8_t pin_relay_justsalt = 41;     // Pin to Relay to JustSalt. If state=high -> salt production in progress (red light on)
uint8_t pin_relay_pool_lights = 40;    // Pin to Relay to pool lights.
// uint8_t pin_dth = 2;               // Pin sensor DTH21 Temperature and Humidity.
int pin_water_sensor = 39;           // Pin water leak sensor. Is High when there is a leak. (I had to set it as int...)
uint8_t pin_power_sensor = A11;        // Pin to power sensor.
uint8_t pin_potentiometer_redox = A12; // Pin to potentiometer used to define redox desired range
uint8_t pin_potentiometer_ph = A13;    // Pin to the potentiometer used to calibrate pH
#define pinDHT 2
#define typDHT21 DHT21
DHT dht(pinDHT, typDHT21);

float ph_sensor_value = 0.0;         // value read in Volt (0 to 5)
float ph_value_float = 0.0;            // pH value from 0.0 to 14.0 in float
char ph_value_char[5];             // pH value from 0 to 14 in char

float redox_sensor_value = 0.0;        // value read in Volt (0 to 5)
float redox_value_float = 0.0;       // redox value from -2000 to 2000 mV in float
char redox_value_char[5];          // redox value from -2000 to 2000 in char
int redox_max;                   // define the max value of redox, if more then stop clorine production
int redox_min;                   // define the min value of redox, if less then start clorine production
int redox_range_delta = 20;        // used to calculate the range (from-to) of accepted value. Example: 600-> value are from 600-20/2 to 600+20/2 (from 590 to 610)

float temperature_float = 0.0;
char temperature_char[5];
float humidity_float = 0.0;
char humidity_char[5];

float power_value_float = 0.0;      // Power consumption in Watt
char power_value_char[5];

bool filtration_bool = 0;       // Filtration state. 0 is off, 1 is on
int counter_filtration = 0;       // Count minutes of filtration on 24h // To display to numbers of hours of working on 24h. The filtration time should be Temperature of the water divised by two. (Hours=Temp/2)

byte lights_seq_number = 0;       // Display the save the lights sequence number (from 1 to 16)
byte lights_eeprom_addr = 0;

unsigned long lastReadingTime = 0;
int count_time_30s = 0;           // used to trigger action every 30s (15*2s)
int count_time_30min = 0;         // used to trigger action every 30min (60*30s)
int count_time_24h = 0;           // used to trigger action every 24h (2880*30)

byte mac[] = { 0x00, 0xAC, 0xAE, 0x3F, 0xF1, 0xAD };  // Production MAC address
IPAddress broadcast(192, 168, 100, 255);
EthernetClient client;            // For PushingBox...
EthernetUDP Udp;
xPL xpl;

  LiquidCrystal lcd(12, 11, 5, 4, 3, 8);
  DHT dht(pinDHT, typDHT21);

// PushingBox part
char devid_water_detection[] = "v0660D5BCF75744C";
char serverName[] = "api.pushingbox.com";

//RestAPI Part (for controlling lights)
EthernetServer server(80);
aREST rest = aREST();
int delay_betweent_relay_lights = 150; // time between relay state change in ms

void setup()
{
  //Watchdog part
  MCUSR &= ~_BV(WDRF);      // Clear the reset bit
  WDTCSR |= _BV(WDCE) | _BV(WDE); // Disable the WDT
  WDTCSR = 0;

  Serial.begin(57600);
  pinMode(pin_relay_justsalt, OUTPUT);
  digitalWrite(pin_relay_justsalt, 1);  // do not start clorine production
  pinMode(pin_water_sensor, INPUT_PULLUP);
  digitalWrite(pin_water_sensor, HIGH);

  // Test Pool Light
  pinMode(pin_relay_pool_lights, OUTPUT);
  digitalWrite(pin_relay_pool_lights, 1); // lights off by default

  dht.begin();         // Start tempature and humidity sensor
  emon1.current(11, 66);       // Power Current: input pin, calibration.

  lcd.begin(20, 4); // Init LCD screen, 4 lignes by 20 chars
  lcd.clear();

  // Print the default text on the LCD.
  lcd.setCursor (0, 0);
  lcd.print("Tepl:");
  lcd.setCursor (12, 0);
  lcd.print("pH:");
  lcd.setCursor (0, 1);
  lcd.print("Sonda:");
  lcd.setCursor (0, 2);
  lcd.print("Odber:");
  lcd.setCursor (12, 2);
  lcd.print("T:");
  lcd.setCursor (14, 2);
  lcd.print("...");
  lcd.setCursor (0, 3);
  lcd.print("Cl:");


  Serial.println(F(""));
  Serial.println(F("Starting (v1.0)"));
  printMac(mac);
  delay(100); // delay to boot in case of multiple DHCP requests from others Arduinos //TODO: Put 7000
  while(Ethernet.begin(mac) == 0)
  {
    Serial.println(F("Failed to configure Ethernet using DHCP"));
  }
  printIP();      // Show IP in serial monitor
  Udp.begin(xpl.udp_port);

  xpl.SendExternal = &SendUdPMessage;        // pointer to the send callback
  xpl.AfterParseAction = &AfterParseAction;  // pointer to a post parsing action callback
  xpl.SetSource_P(PSTR("xpl"), PSTR("arduino"), PSTR("piscine")); // parameters for hearbeat message

  //RestAPI part
  rest.function("lights", lightsControl);
  rest.set_id("001");
  rest.set_name("arduino_piscine");


  wdt_enable(WDTO_8S); //enable 8s watchdog
}


void loop()
{
  // RestAPI part
  EthernetClient client = server.available(); //TODO :verifier si pas redondant
//  rest.handle(client);

  xpl.Process();  // heartbeat management

  // Parser part. Read input XPL message
  if(Udp.parsePacket())
  {
    char xPLMessageBuff[XPL_MESSAGE_BUFFER_MAX];
    Udp.read(xPLMessageBuff, XPL_MESSAGE_BUFFER_MAX); // read the packet into packetBufffer
    xpl.ParseInputMessage(xPLMessageBuff);              // parse message
  }

  // Protect if millis return to 0 (every 50 days)
  if (millis() - lastReadingTime < 0)
  {
    lastReadingTime = millis();
  }

  // Show datas on LCD every 2 seconds
  if ((millis() - lastReadingTime) >= 2000)
  {
    // pH Part
    ph_sensor_value = analogRead(pin_ph) * 5000.0 / 1023.0 / 1000.0; // form 0.0 to 5.0 V
    ph_value_float = (0.0178 * ph_sensor_value * 200.0) - 1.889;     // formula to calcul pH from sensor value
    //Serial.println(ph_value_float);
    //Serial.println(analogRead(pin_potentiometer_ph));
    // add calibration
    ph_value_float = ph_value_float + (analogRead(pin_potentiometer_ph) - 512.0) / 500.0; // calibration is from -1 to +1 pH
    lcd.setCursor (15, 0);
    lcd.print("     ");   // Clean lcd old digits
    lcd.setCursor (15, 0);
    lcd.print(ph_value_float, 2);

    // Redox Part
    redox_sensor_value = analogRead(pin_redox) * 5000.0 / 1023.0 / 1000.0;   // form 0.0 to 5.0 V
    redox_value_float = ((2.5 - redox_sensor_value) / 1.037) * 1000.0;     // from -2000 to 2000 mV
    lcd.setCursor (6, 1);
    lcd.print("      ");  // Clean lcd old digits
    lcd.setCursor (6, 1);
    lcd.print(redox_value_float, 0);
    // get min-max redox values accepted
    int potentiometer_redox = analogRead(pin_potentiometer_redox);
    potentiometer_redox = map(potentiometer_redox, 0, 1023, 400, 1100);
    redox_min = potentiometer_redox / 10 * 10 - redox_range_delta / 2;
    redox_max = potentiometer_redox / 10 * 10 + redox_range_delta / 2;
    lcd.setCursor (12, 1);
    lcd.print(redox_min);
    lcd.print("-");
    lcd.print(redox_max);
    lcd.print(" ");

    // DHT Temp and humidity Part
    temperature_float = dht.readTemperature();
    humidity_float = dht.readHumidity();
    lcd.setCursor (5, 0);
    lcd.print("       "); // Clean lcd old digits
    lcd.setCursor (5, 0);
    lcd.print(temperature_float, 1);
    lcd.print("C");

    // Relay JustSalt part. Chlorin Production
    lcd.setCursor (3, 3);
    if (digitalRead(pin_relay_justsalt) == 0)
    {
      lcd.print("ON ");
    }
    else
    {
      lcd.print("OFF");
    }

    // Power sensor
    double Irms = emon1.calcIrms(1480);  // Calculate Power current (Irms only)
    power_value_float = Irms * 232.0;
    lcd.setCursor (6, 2);
    lcd.print("      ");  // Clean lcd old digits
    lcd.setCursor (6, 2);
    lcd.print(power_value_float, 0);

    // Power state
    if (power_value_float > 300)  // Power is more than 300W
    {
      filtration_bool = 1;      // on: filtration in progress
    }
    else
    {
      filtration_bool = 0;
      digitalWrite(pin_relay_justsalt, 1);  // salt production is stopped when filtration is stoped...
    }

    // Water leak detection
    if (digitalRead(pin_water_sensor) == LOW)
    {
      lcd.setCursor (19, 3);
      lcd.print("!");
    }
    else
    {
      lcd.setCursor (19, 3);
      lcd.print(".");
    }
    //Serial.print(digitalRead(pin_water_sensor));
    //lcd.setCursor (19,3);
    //lcd.print(digitalRead(pin_water_sensor));


    // Lights part
    lcd.setCursor (12, 3);
    lcd.print("Lum:");
    if(digitalRead(pin_relay_pool_lights) == 0)
    {
      lcd.print(EEPROM.read(lights_eeprom_addr)); // Display the seq number when pool lights are on
      lcd.print(" ");
    }
    else
    {
      lcd.print("0 ");              // Display 0 when Pool lights are off
    }



    count_time_30s++; // Count 15 cycles for sending XPL every 30s
    lastReadingTime = millis();
  }

  // Send datas as xPL Message every 30 seconds
  if (count_time_30s == 15)
  {
    // pH Part
    dtostrf(ph_value_float , 3, 2, ph_value_char);            // float to char format: XX.XX
    print_sensor_value("pH", analogRead(pin_ph), ph_value_float);   // debug print
    send_xpl_message("ph", ph_value_char);                // send xpl message

    // Redox Part
    dtostrf(redox_value_float, 5, 0, redox_value_char);         // float to char with decimal resolution format: XXXX
    print_sensor_value("Redox", analogRead(pin_redox), redox_value_float);  // debug print
    send_xpl_message("redox", redox_value_char);            // send xpl message

    // DHT Temp and humidity Part
    //Send temperature to XPL
    dtostrf(temperature_float , 3, 2, temperature_char);
    send_xpl_message("temp", temperature_char);     //send xpl message
    //Send humidity to XPL
    dtostrf(humidity_float , 3, 2, humidity_char);
    send_xpl_message("humidity", humidity_char);  //send xpl message

    // Relay JustSalt part
    if (digitalRead(pin_relay_justsalt) == 0)
    {
      send_xpl_message("justsaltstate", "on");  // on: electrolyse in progress
    }
    else
    {
      send_xpl_message("justsaltstate", "off");
    }

    // Power sensor
    dtostrf(power_value_float , 4, 0, power_value_char);
    send_xpl_message("current", power_value_char);  //send xpl message

    // Power state
    if (filtration_bool == 1)             // Power is more than 300W, filtration in progress
    {
      send_xpl_message("state", "on");  // on: filtration in progress
    }
    else
    {
      send_xpl_message("state", "off");
    }

    // Water leak sensor
    if (digitalRead(pin_water_sensor) == LOW)
    {
      send_xpl_message("leak", "on");     // water leak detected
      sendToPushingBox(devid_water_detection);//Send Push with PushingBox in case of water leak every 30s
    }


    //if (count_time_30min % 2 == 0)    // every 1min, used to count minutes of active filtration on 24h
    //{
    if (filtration_bool == 1)       // if filtration in progress
    {
      counter_filtration++;
    }
    //itoa (counter_filtration, char test, 10);
    //send_xpl_message("timer", String(counter_filtration));
    count_time_24h++;
    //}

    count_time_30s = 0;
    count_time_30min++;
  }


  if (count_time_30min == 60)     // every 30min (60*30s)
  {

    if ((redox_value_float > redox_max) && (filtration_bool == 1))    // if to much clorine and filtration in progress
    {
      digitalWrite(pin_relay_justsalt, 1);              // Set the relay to stop Clorine production
    }
    if ((redox_value_float < redox_min) && (filtration_bool == 1))
    {
      digitalWrite(pin_relay_justsalt, 0);              // Set the relay to start Clorine production
    }

    count_time_30min = 0;
  }

  if (count_time_24h == 2880)     // every 24h (1440*1min)
  {
    //Serial.println(count_time_24h);
    lcd.setCursor (14, 2);
    lcd.print("      ");
    lcd.setCursor (14, 2);
    lcd.print(counter_filtration / 60);
    lcd.print("h");
    if (counter_filtration % 60 < 10)
    {
      lcd.print("0");
    }
    lcd.print(counter_filtration % 60);

    counter_filtration = 0;
    count_time_24h = 0;
  }


  wdt_reset();  //Reset the Watchdog timer
}




// Send UDP Message
void SendUdPMessage(char *buffer)
{
  Udp.beginPacket(broadcast, xpl.udp_port);
  Udp.write(buffer);
  Udp.endPacket();
}

// Print MAC Address
void printMac (const byte *buf)
{
  Serial.print(F("MAC: "));
  for (byte i = 0; i < 6; ++i)
  {
    if (buf[i] >= 0 && buf[i] <= 16)
      Serial.print(F("0"));
    Serial.print( buf[i], HEX );
    if (i < 5)
      Serial.print(F(":"));
  }
  Serial.println("");
}

// Print IP address
void printIP()
{
  // print your local IP address:
  Serial.print(F("My IP address: "));
  for (byte thisByte = 0; thisByte < 4; thisByte++)
  {
    Serial.print(Ethernet.localIP()[thisByte], DEC);
    Serial.print(F("."));
  }
  Serial.println();
}

// Print debug info into serial monitor
void print_sensor_value(char* name, int sensor_value, float value)
{
  //print the results to the serial monitor for debug:
  Serial.print(name);
  Serial.print(F(" sensor: "));
  Serial.print(sensor_value);
  Serial.print(F(" output: "));
  Serial.println(value);
}

// Send XPL Message
void send_xpl_message(char* type, char* current)
{
  xPL_Message msg;
  msg.hop = 1;
  msg.type = XPL_TRIG;
  msg.SetTarget_P(PSTR("*"));
  msg.SetSchema_P(PSTR("sensor"), PSTR("basic"));
  msg.AddCommand_P(PSTR("device"), PSTR("piscine"));
  msg.AddCommand("type", type);
  msg.AddCommand("current", current);
  xpl.SendMessage(&msg);
}

// Parse input XPL messages
// usage: xpl-sender -m xpl-cmnd -t xpl-arduino.piscine -c justsalt.on000000
// should have a length of 8 for class because of a bug in the lib :(. That's why I added some "0".
void AfterParseAction(xPL_Message * message)
{
  if (xpl.TargetIsMe(message))
  {
    // If we get an XPL packet, then turn on or off the Chlorine production
    if (message->IsSchema_P(PSTR("justsalt"), PSTR("on000000")))
    {
      digitalWrite(pin_relay_justsalt, 0);
      Serial.println(F("Turning ON Justsalt"));
      send_xpl_message("justsaltstate", "on");
    }
    if (message->IsSchema_P(PSTR("justsalt"), PSTR("off00000")))
    {
      digitalWrite(pin_relay_justsalt, 1);
      Serial.println(F("Turning OFF Justsalt"));
      send_xpl_message("justsaltstate", "off");
    }
  }
  // show all messages
  //Serial.println(message->toString());
}


//Function for sending the request to PushingBox
void sendToPushingBox(char devid[])
{
  client.stop();

  if (client.connect(serverName, 80))
  {
    Serial.println("PB connected");

    Serial.println("PB sendind request");
    client.print("GET /pushingbox?devid=");
    client.print(devid);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(serverName);
    client.println("User-Agent: Arduino");
    client.println();
  }
  else
  {
    Serial.println("PB connection failed");
  }
}




// Controle lights of pool from RestAPI
// Usage : curl http://192.168.100.119/lights?params=actionOn
int lightsControl(String command)
{

  //Serial.println(command);

  if(command == "actionOn")
  {
    digitalWrite(pin_relay_pool_lights, 0);
    return 1;
  }
  else if(command == "actionOff")
  {
    digitalWrite(pin_relay_pool_lights, 1);
    return 1;
  }

  else if(command == "actionBlanc")
  {
    return poolLightRunSequence(1);
  }

  else if(command == "actionBleu")
  {
    return poolLightRunSequence(2);
  }

  else if(command == "actionCyan")
  {
    return poolLightRunSequence(4);
  }

  else if(command == "actionVert")
  {
    return poolLightRunSequence(6);
  }

  else if(command == "actionJaune")
  {
    return poolLightRunSequence(8);
  }

  else if(command == "actionRouge") 
  {
    return poolLightRunSequence(10);
  }

  else if(command == "actionViolet")
  {
    return poolLightRunSequence(11);
  }

  else if(command == "actionVariation1")
  {
    return poolLightRunSequence(13);
  }

  else if(command == "actionVariation2")
  {
    return poolLightRunSequence(14);
  }

  else if(command == "actionVariation3")
  {
    return poolLightRunSequence(15);
  }

  else if(command == "actionVariation4")
  {
    return poolLightRunSequence(16);
  }

  else if(command == "boutonC")
  {
    digitalWrite(pin_relay_pool_lights, 1);
    delay(delay_betweent_relay_lights);
    digitalWrite(pin_relay_pool_lights, 0);
    delay(delay_betweent_relay_lights);
    return 1;
  }

  else
  {
    return 0;
  }

  return 0;
}


int poolLightRunSequence(byte desired_seq_number)
{

  // Get actual sequence number
  int actual_seq_number = EEPROM.read(lights_eeprom_addr);

  // Calcul the number of toogle to rich the derised num from the actual seq_num
  if(actual_seq_number == desired_seq_number)
  {
    // Toogle 16 times if same color ?
    for (int i = 1; i <= 16; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }
  else if(actual_seq_number > desired_seq_number)
  {
    int num = 16 - actual_seq_number + desired_seq_number;
    for (int i = 1; i <= num; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }
  else
  {
    int num = desired_seq_number - actual_seq_number;
    for (int i = 1; i <= num; i++)
    {
      digitalWrite(pin_relay_pool_lights, 1);
      delay(delay_betweent_relay_lights);
      digitalWrite(pin_relay_pool_lights, 0);
      delay(delay_betweent_relay_lights);
    }
  }

  // Write new sequence number into eeprom
  EEPROM.write(lights_eeprom_addr, desired_seq_number);

  return 1;
}

ondraN
Příspěvky: 932
Registrován: 08 srp 2019, 20:01
Reputation: 0

Re: pomoc s kódem

Příspěvek od ondraN » 31 kvě 2022, 09:48

Zkus tát typ čidla AM2301. Knihovna ho zná. Možná je tam nějaký rozdíl oproti DHT21.

Kód: Vybrat vše

#define pinDHT 2
#define typDHT21 AM2301
DHT dht(pinDHT, typDHT21);

tomduda
Příspěvky: 4
Registrován: 30 kvě 2022, 16:15
Reputation: 0

Re: pomoc s kódem

Příspěvek od tomduda » 31 kvě 2022, 15:16

Děkuji za pomoc, funguje to...

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 17 hostů