hi all
I am running since 2 years an aquarium controller with an Arduino Wifi Rev2 with Atlas board (ph, temp and conductivity sensors) and would like now to store the metrics in a Influx db . I am able to run a simple http post sketch and load data into Influx, however when I try to do it in my aquarium sketch it gets stuck in loop and not sending any data to Influx...any hint?
#include "arduino_secrets.h"
#include <Wire.h> // enable I2C.
#include <RCSwitch.h> // enable RF transmission.
#include "rgb_lcd.h" // enable LCD.
#include <SPI.h>
#include <Time.h>
#include "DHT.h" // enable DHT Temperature sensor.
#include <WiFiNINA.h> // change to #include <WiFi101.h> for MKR1000
#define TOTAL_CIRCUITS 3 // <-- CHANGE THIS | set how many I2C circuits are attached to the Tentacle
#define DHTPIN A0 // what pin we're connected to
#define DHTTYPE DHT11 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
// Enter your sensitive data in arduino_secrets.h
const char ssid[] = SECRET_SSID;
const char pass[] = SECRET_PASS;
// Network / Wifi settings
int status = WL_IDLE_STATUS;
WiFiClient client;
unsigned long epoch;
int hour = (epoch % 86400L) / 3600;
// Influx code
byte host[] = {192, 168, 1, 120};
int port = 8086;
char buff[256];
// Atlas code
const unsigned int send_readings_every = 5000; // set at what intervals the readings are sent to the computer (NOTE: this is not the frequency of taking the readings!)
unsigned long next_serial_time;
char sensordata[30]; // A 30 byte character array to hold incoming data from the sensors
byte sensor_bytes_received = 0; // We need to know how many characters bytes have been received
byte code = 0; // used to hold the I2C response code.
byte in_char = 0; // used as a 1 byte buffer to store in bound bytes from the I2C Circuit.
int channel_ids[] = {100, 101, 102}; // <-- CHANGE THIS. A list of I2C ids that you set your circuits to.
char *channel_names[] = {"PH", "EC", "Temp"}; // <-- CHANGE THIS. A list of channel names (must be the same order as in channel_ids[]) - only used to designate the readings in serial communications
String readings[TOTAL_CIRCUITS]; // an array of strings to hold the readings of each channel
int channel = 0; // INT pointer to hold the current position in the channel_ids/channel_names array
const unsigned int reading_delay = 2000; // time to wait for the circuit to process a read command. datasheets say 1 second.
unsigned long next_reading_time; // holds the time when the next reading should be ready from the circuit
boolean request_pending = false; // wether or not we're waiting for a reading
// variables & stuff
float pH, temp, ec;
rgb_lcd lcd;
const int colorR = 0;
const int colorG = 100;
const int colorB = 255;
String data;
// RF code
RCSwitch mySwitch = RCSwitch();
void setup()
{
Serial.begin(9600); // Set the hardware serial port.
Wire.begin(); // enable I2C port.
// RF init
mySwitch.enableTransmit(2);
mySwitch.setPulseLength(166);
mySwitch.setRepeatTransmit(4);
// LCD init
lcd.display();
lcd.begin(16, 2);
// Atlas sensors init
next_serial_time = millis() + send_readings_every; // calculate the next point in time we should do serial communications
data = "";
// Temp sensor init
dht.begin();
// Wifi connect
Serial.println("Attempting to connect to WPA network...");
status = WiFi.begin(ssid, pass);
// if unable to connect, halt
if (status != WL_CONNECTED)
{
Serial.println("Couldn't get a WiFi connection");
while (true)
;
}
// if the conneciton succeeded, print network info
else
{
Serial.println("Connected to network");
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
Serial.println("Getting date and time from network...");
// wait 10 seconds for connection:
delay(10000);
// Time related code
epoch = WiFi.getTime();
Serial.print("Epoch received: ");
Serial.println(epoch);
Serial.print("Hour calculated: ");
int hour = (epoch % 86400L) / 3600;
Serial.println(hour);
}
}
void loop()
{
// Run readings
do_sensor_readings();
do_serial();
// Do other stuff here (Update a display, etc)
delay(2000); // service the alarm timers once per second
lcd.setRGB(colorR, colorG, colorB);
lcd.setCursor(0, 0);
lcd.print("pH:");
lcd.print(pH);
lcd.print(" ");
lcd.print("uS:");
lcd.print(ec);
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(temp);
influx();
// if (hour >= 13 && hour < 21) {
// LedOn();
// } else {
// LedOff();
// }
}
// do serial communication in a "asynchronous" way
void do_serial()
{
if (millis() >= next_serial_time)
{ // is it time for the next serial communication?
for (int i = 0; i < TOTAL_CIRCUITS; i++)
{ // loop through all the sensors
Serial.print(channel_names[i]); // print channel name
Serial.print(":\t");
Serial.println(readings[i]); // print the actual reading
}
next_serial_time = millis() + send_readings_every;
}
}
// take sensor readings in a "asynchronous" way
void do_sensor_readings()
{
if (request_pending)
{ // is a request pending?
if (millis() >= next_reading_time)
{ // is it time for the reading to be taken?
receive_reading(); // do the actual I2C communication
}
}
else
{ // no request is pending,
channel = (channel + 1) % TOTAL_CIRCUITS; // switch to the next channel (increase current channel by 1, and roll over if we're at the last channel using the % modulo operator)
request_reading(); // do the actual I2C communication
}
}
// Request a reading from the current channel
void request_reading()
{
request_pending = true;
Wire.beginTransmission(channel_ids[channel]); // call the circuit by its ID number.
Wire.write('r'); // request a reading by sending 'r'
Wire.endTransmission(); // end the I2C data transmission.
next_reading_time = millis() + reading_delay; // calculate the next time to request a reading
}
// Receive data from the I2C bus
void receive_reading()
{
sensor_bytes_received = 0; // reset data counter
memset(sensordata, 0, sizeof(sensordata)); // clear sensordata array;
Wire.requestFrom(channel_ids[channel], 48, 1); // call the circuit and request 48 bytes (this is more then we need).
code = Wire.read();
while (Wire.available())
{ // are there bytes to receive?
in_char = Wire.read(); // receive a byte.
if (in_char == 0)
{ // if we see that we have been sent a null command.
Wire.endTransmission(); // end the I2C data transmission.
break; // exit the while loop, we're done here
}
else
{
sensordata[sensor_bytes_received] = in_char; // load this byte into our array.
sensor_bytes_received++;
}
}
if (channel_names[channel] == "PH")
{ //sensore PH
pH = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
if (pH >= 6.7)
{ //if the pH is greater than or equal to 6.7, activate co2 supply via RF link
Serial.print("pH is basic, activating CO2 : ");
//led2.on(); //Blynk led co2
//digitalWrite(LED, HIGH);
Serial.println(pH, 3);
mySwitch.send(5330227, 24);
}
if (pH < 6.7)
{ //if the pH is less than or equal to 6.7, power off co2 supply via RF link
Serial.print("pH is ok, turning off CO2 : ");
//led2.off(); //Blynk led co2
//digitalWrite(LED, LOW);
Serial.println(pH, 3);
mySwitch.send(5330236, 24);
}
}
if (channel_names[channel] == "Temp")
{ //sensore temperatura
temp = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
}
if (channel_names[channel] == "EC")
{ //sensore conduttivitĂ
ec = atof(sensordata); //convert the string to a floating point number so it can be evaluated by the Arduino
}
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(t) || isnan(h))
{
Serial.println("Failed to read from DHT");
}
switch (code)
{ // switch case based on what the response code is.
case 1: // decimal 1 means the command was successful.
readings[channel] = sensordata;
break; // exits the switch case.
case 2: // decimal 2 means the command has failed.
readings[channel] = "error: command failed";
break; // exits the switch case.
case 254: // decimal 254 means the command has not yet been finished calculating.
readings[channel] = "reading not ready";
break; // exits the switch case.
case 255: // decimal 255 means there is no further data to send.
readings[channel] = "error: no data";
break; // exits the switch case.
}
request_pending = false; // set pending to false, so we can continue to the next sensor
}
void LedOn()
{
Serial.println("Turning on LED Lights");
// led1.on();
mySwitch.send(5330371, 24);
}
void LedOff()
{
Serial.println("Turning off LED Lights, good night :)");
// led1.off();
mySwitch.send(5330380, 24);
}
void influx()
{
// Send data to Influx
if (client.connect(host, port))
{
sprintf(buff, "aquarium ph=%.2f,temp_int=%.2f,µS=%.2f", pH, temp, ec);
client.print("String being posted to Influx: ");
Serial.println(buff);
// send the HTTP POST request:
client.println("POST /write?db=aquarium HTTP/1.1");
client.println("User-Agent: Arduino/1.0");
client.println("Host: arduino");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: " + String(strlen(buff)));
client.println();
client.println(buff);
}
else
{
// if you couldn't make a connection:
Serial.println("connection failed");
}
}