Issue with influxdb post

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");
  }
}

Thanks for the formatted and code tagged code!
During my time as professional large and advanced projects dropped down on my desk a an almost regular basis. This is pretty much such a project.
My rescue was debug printouts gossiping what was going on in the code.
Arm Serial monitor in the IDE, baudrate 115200, use Serial.begin(115200). Then use Serial.println(" Now at position this or that"); Using 2 lines also printing out millis() can be valuable sometimes.
Serial.println("This or that done"); etc...

small update: I was able to stabilize a bit the code, now it seems the wifi/influx http post is causing a lot of instability....it locks 2 arduino wifi rev2, one running my aquarium sketch and another one with simple grove sensors (bme280) which acts as a weather station. The longest uptime I was able to reach before the crash is 12 hours..

I am running the latest libraries and wifi firmware, shall I open an issue in github? Especially for the aquarium I need a reliable system as it turns on/off lights and co2 supplier

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.