0

I'm trying to make a temperature logger that posts to MySQL. I have done this successfully, but my code will only run for approximately 15-20 minuets. I don't think it is a power issue as I have tried running it off a 2 amp USB wall charger, computer USB that is set to never sleep, and a 9 volt supply to the barrel plug on the Arduino Uno.

I am using the W5500 Ethernet shield from Adafruit. I'm also using the W5500 Ethernet Shield library and 6 of the DS18B20 temperature sensors.

I know there is a way to do a better delay function, but I don't think it would cause the Arduino to quit after 20 minutes. Could some memory be getting full causing the Arduino to crash?

Any ideas? I'm leaning more to something with the shield. Could it be something with the buffer size?

Thanks.

Code:

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Ethernet.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>

int ms_int = 30000; //recording delay (60000 = 1 Minute)
int circuit_num = 23; //The Circuit assigned to this arduino
long cycle = 0;
long max_Cycle = 0;

//probes
#define ONE_WIRE_BUS 2  // arduino pin2 for white wire
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);

//network
byte mac_addr[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server_addr(1, 1, 1, 1); // IP of the MySQL *server* here
char user[] = "UN"; // MySQL user login username
char password[] = "PW"; // MySQL user login password
// Sample query
char INSERT_DATA[] = "INSERT INTO arduino.temp_log (id_probe, circuit_num, temp, cycle) VALUES ('%d',%d,%s,%d)";
char s_query[] = "SELECT MAX(cycle) FROM arduino.temp_log"; // Select max cycle  from tbl
char query[128];
char temperature[10];
EthernetClient client;
MySQL_Connection conn((Client *)&client);
// Create an instance of the cursor passing in the connection
MySQL_Cursor cur = MySQL_Cursor(&conn);

void setup() {
  Serial.begin(115200);
  delay(69);
  pinMode(11, OUTPUT); //conected led
  digitalWrite(11, LOW);
  while (!Serial); // wait for serial port to connect only for leo
  Ethernet.begin(mac_addr);
  Serial.println("Connecting...");
  if (conn.connect(server_addr, 3306, user, password)) {
    digitalWrite(11, HIGH);
    delay(169); //Firm handshake
  } else {
    Serial.println("Connection failed. Check connections, and Configs");
    digitalWrite(11, LOW);
  }
  //Get CYCLE MAX
  //select
  row_values *row = NULL;
  Serial.println("1) Getting Cycle MAX");
  // Initiate the query class instance
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  // Execute the query
  cur_mem->execute(s_query);
  // Fetch the columns (required) but we don't use them.
  column_names *columns = cur_mem->get_columns();
  // Read the row (we are only expecting the one)
  do {
    row = cur_mem->get_next_row();
    if (row != NULL) {
      max_Cycle = atol(row->values[0]);
    }
  } while (row != NULL);
  // Deleting the cursor also frees up memory used
  delete cur_mem;
  // Show the result
  Serial.print("  Max Cycle= ");
  Serial.println(max_Cycle);
  Serial.println("Getting First temp");
  DS18B20.requestTemperatures();
  delay(569);
  Serial.println("Got it!");
}
float temp;
float temp2;
float temp3;
float temp4;
float temp5;
float temp6;

void loop() {
  DS18B20.requestTemperatures(); //request temps
  delay(69);
  temp = DS18B20.getTempCByIndex(0); //assign temps 1-6
  temp2 = DS18B20.getTempCByIndex(1);
  temp3 = DS18B20.getTempCByIndex(2);
  temp4 = DS18B20.getTempCByIndex(3);
  temp5 = DS18B20.getTempCByIndex(4);
  temp6 = DS18B20.getTempCByIndex(6);
  cycle = max_Cycle + 1 ; //increment cycle by one
  post(1 , circuit_num, temp, cycle); //probe 1
  post(2 , circuit_num, temp2, cycle); //probe 1
  post(3 , circuit_num, temp3, cycle); //probe 1
  post(4 , circuit_num, temp4, cycle); //probe 1
  post(5 , circuit_num, temp5, cycle); //probe 1
  post(6 , circuit_num, temp6, cycle); //probe 1
  delay(2* 60 * 1000); //interv at to record // total one minute
 // delay(ms_int); //interv at to record //total two min
}

void post (int id_probe, int circuit_num, float temp, int cycle) {
  MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn);
  // Save
  dtostrf(temp, 4, 4, temperature);
  sprintf(query, INSERT_DATA, id_probe, circuit_num, temperature, cycle);
  cur_mem->execute(query); // Execute the query
  delete cur_mem;
}

EDIT:

I added this function: int freeRam () { extern int __heap_start, *__brkval; int v; return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval); }

Then added: CODE: Serial.println(freeRam()); At the very beginning of my void loop.

The serial results were as follow: Connected to server version 5.7.17-log 775 623 623 623 623 623 ... Total of 254 Serial prints of 623 ... 623

Then to no reason at all the code as stopped. The code posted 1529 times to mysql server, with a duration of 10min and 13sec.

I'm still clueless as to why my code is terminating.

Any other ideas? things to try?

Now I'm trying this:

void post (float temp, float temp2, float temp3, float temp4, float temp5, float temp6, int cycle) { MySQL_Cursor *cur_mem = new MySQL_Cursor(&conn); // Save dtostrf(temp, 5, 2, temperature); //dtostrf(floatVar, minStringWidthIncDecimalPoint, numVarsAfterDecimal, charBuf); dtostrf(temp2, 5, 2, temperature2); dtostrf(temp3, 5, 2, temperature3); dtostrf(temp4, 5, 2, temperature4); dtostrf(temp5, 5, 2, temperature5); dtostrf(temp6, 5, 2, temperature6); sprintf(query, INSERT_DATA, temperature, temperature2, temperature3, temperature4, temperature5, temperature6, cycle); cur_mem->execute(query); // Execute the query delete cur_mem; Serial.println(query); // Serial.println("Data recorded."); }

I'm going to see how long my code will run with out the select statement As I think that was the problem.

  • Well you could move all those string literals out of RAM and into PROGMEM for a start... – Majenko Jan 31 '17 at 0:18
  • Do you mean f() to do this? – Mason Younger Jan 31 '17 at 6:00
  • So I have removed every existence of Serial.print("stuff"); and my code still only ran for 34 min with 3949 Posts to mySQL. Could anyone help me more with the PROGMEM memory? RAM? SRAM? Is there a way to see what memory I'm consuming. Maybe right the memory to another column in MySQL table? – Mason Younger Feb 1 '17 at 14:20
  • If doing that increased you run time then I'm pretty certain its a memory leak or fragmentation issue. The only bit of dynamic memory is the SQL connection. So can you share it between all 6 calls to post? If that increases your run time to about 3 hours then can you only reallocate it when its failed for some reason? Another idea would be writing your own version of new. – Code Gorilla Feb 1 '17 at 15:01
  • Are you saying do something like: post(1 , circuit_num, temp,temp2,temp3,temp4,temp5,temp6, cycle); //all the probes So that it posts all the probes in one insert statement? – Mason Younger Feb 1 '17 at 16:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.