I did some research of my own before asking this question, and stumbled across this Arduino forum discussion. In case it was indeed a memory issue, I tried converting what I thought were my own string variables in the program with the c_str() function. I immediately realized that the variables I'm sending to the serial monitor are actually chars.
For this reason, I come to you, mighty StackExchange. Is this really a memory issue, or is my Arduino just somehow faulty? What can I change to fix my problem?
#include <Ezo_i2c.h>
#include <Ezo_i2c_util.h>
#include <iot_cmd.h>
#include <sequencer1.h>
#include <sequencer2.h>
#include <sequencer3.h>
#include <sequencer4.h>
#include <Wire.h> //enable I2C.
#define HUM_address 111 //default I2C ID number for EZO Humidity sensor.
#define O2_address 108 //default I2C ID number for EZO O2 sensor.
#define CO2_address 105 //default I2C ID number for EZO CO2 sensor.
#define printtab(x) Serial.print(String(x) + "\t ");
#define printline Serial.println();
//EZO-HUM vars
// | |
// V V
char computerdata[32]; //we make a 32 byte character array to hold incoming data from a pc/mac/other.
byte received_from_computer = 0; //we need to know how many characters have been received.
byte serial_event = false; //a flag to signal when data has been received from the pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char Humidity_data[22]; //we make a 22-byte character array to hold incoming data from the Humidity sensor.
byte in_char = 0; //used as a 1 byte buffer to store inbound bytes from the Humidity sensor.
byte i = 0; //counter used for Humidity_data array.
int time_ = 1000; //used to set the delay needed to process the command sent to the EZO Humidity sensor.
//EZO-CO2 vars
// | |
// V V
byte CO2_code = 0; //used to hold the I2C response code.
char CO2_data[20]; //we make a 20-byte character array to hold incoming data from the Co2 sensor.
byte CO2_in_char = 0; //used as a 1 byte buffer to store inbound bytes from the Co2 sensor.
int CO2_time_ = 1000; //used to set the delay needed to process the command sent to the EZO Co2 sensor.
//EZO-O2 vars
// | |
// V V
byte O2_code = 0; //used to hold the I2C response code.
char O2_data[20]; //we make a 20-byte character array to hold incoming data from the o2 sensor.
byte O2_in_char = 0; //used as a 1 byte buffer to store inbound bytes from the o2 sensor.
int O2_time_ = 1000; //used to set the delay needed to process the command sent to the EZO o2 sensor.
char *HUM; //char pointer used in string parsing.
char *TMP; //char pointer used in string parsing.
char *NUL; //char pointer used in string parsing (the sensor outputs some text that we don't need).
char *DEW; //char pointer used in string parsing.
char *O2_reading;
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
while (!Serial); //wait for serial monitor to be open
}
void loop() { //the main loop.
// if (serial_event == true) { //if a command was sent to the EZO device.
// for (i = 0; i <= received_from_computer; i++) { //set all char to lower case, this is just so this exact sample code can recognize the "sleep" command.
// computerdata[i] = tolower(computerdata[i]); //"Sleep" ≠ "sleep"
// //computerdata[i] = "r";
// }
// i=0; //reset i, we will need it later
computerdata[0] = 'r';
//---------------------------------------------------------EZO-HUM Sensor-----------------------------------------------------------------------------//
Wire.beginTransmission(HUM_address); //call the circuit by its ID number.
Wire.write(computerdata); //transmit the command that was sent through the serial port.
Wire.endTransmission(); //end the I2C data transmission.
// Need to talk to each sensor separately. Because they're all Atlas Scientific EZO sensors, they all respond to the same commands
if (strcmp(computerdata, "sleep") != 0) { //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.
//if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the Humidity sensor.
delay(time_); //wait the correct amount of time for the circuit to complete its instruction.
Wire.requestFrom(HUM_address, 23, 1); //call the circuit and request 22 bytes.
code = Wire.read(); //the first byte is the response code, we read this separately.
switch (code) { //switch case based on what the response code is.
case 1: //decimal 1.
//Serial.println("HUM Success"); //means the command was successful.
break; //exits the switch case.
case 2: //decimal 2.
Serial.println("HUM Failed"); //means the command has failed.
break; //exits the switch case.
case 254: //decimal 254.
Serial.println("HUM Pending"); //means the command has not yet been finished calculating.
break; //exits the switch case.
case 255: //decimal 255.
Serial.println("HUM No Data"); //means there is no further data to send.
break; //exits the switch case.
}
while (Wire.available()) { //are there bytes to receive.
in_char = Wire.read(); //receive a byte.
Humidity_data[i] = in_char; //load this byte into our array.
i += 1; //incur the counter for the array element.
if (in_char == 0) { //if we see that we have been sent a null command.
i = 0; //reset the counter i to 0.
break; //exit the while loop.
}
}
HUM = strtok(Humidity_data, ","); //let's pars the string at each comma.
TMP = strtok(NULL, ","); //let's pars the string at each comma.
NUL = strtok(NULL, ","); //let's pars the string at each comma (the sensor outputs the word "DEW" in the string, we dont need it.
DEW = strtok(NULL, ","); //let's pars the string at each comma.
// HUM.c_str();
// TMP.c_str();
// NUL.c_str();
// DEW.c_str();
printtab(HUM);
printtab(TMP);
printtab(DEW);
// if (computerdata[0] == 'r') string_pars(); //uncomment this function if you would like to break up the comma separated string into its individual parts.
}
//---------------------------------------------------------EZO-O2 Sensor-----------------------------------------------------------------------------//
Wire.beginTransmission(O2_address); //call the circuit by its ID number.
Wire.write(computerdata); //transmit the command that was sent through the serial port.
Wire.endTransmission(); //end the I2C data transmission.
if (strcmp(computerdata, "sleep") != 0) { //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.
//if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the Humidity sensor.
delay(O2_time_); //wait the correct amount of time for the circuit to complete its instruction.
Wire.requestFrom(O2_address, 22, 1); //call the circuit and request 22 bytes.
O2_code = Wire.read(); //the first byte is the response code, we read this separately.
switch (O2_code) { //switch case based on what the response code is.
case 1: //decimal 1.
//Serial.println("O2 Sensor Success"); //means the command was successful.
break; //exits the switch case.
case 2: //decimal 2.
Serial.println("O2 Sensor Failed"); //means the command has failed.
break; //exits the switch case.
case 254: //decimal 254.
Serial.println("O2 Sensor Pending"); //means the command has not yet been finished calculating.
break; //exits the switch case.
case 255: //decimal 255.
Serial.println("O2 Sensor No Data"); //means there is no further data to send.
break; //exits the switch case.
}
while (Wire.available()) { //are there bytes to receive.
O2_in_char = Wire.read(); //receive a byte.
O2_data[i] = (int)O2_in_char; //load this byte into our array.
i += 1; //incur the counter for the array element.
if (O2_in_char == 0) { //if we see that we have been sent a null command.
i = 0; //reset the counter i to 0.
break; //exit the while loop.
}
}
O2_reading = strtok(O2_data, ","); //let's pars the string at each comma.
printtab(O2_reading);
//if (computerdata[0] == 'r') O2_string_pars(); //This code also doesn't output any information.
}
//---------------------------------------------------------EZO-CO2 Sensor-----------------------------------------------------------------------------//
Wire.beginTransmission(CO2_address); //call the circuit by its ID number.
Wire.write(computerdata); //transmit the command that was sent through the serial port.
Wire.endTransmission(); //end the I2C data transmission.
if (strcmp(computerdata, "sleep") != 0) { //if the command that has been sent is NOT the sleep command, wait the correct amount of time and request data.
//if it is the sleep command, we do nothing. Issuing a sleep command and then requesting data will wake the Humidity sensor.
delay(CO2_time_); //wait the correct amount of time for the circuit to complete its instruction.
Wire.requestFrom(CO2_address, 22, 1); //call the circuit and request 22 bytes.
CO2_code = Wire.read(); //the first byte is the response code, we read this separately.
switch (CO2_code) { //switch case based on what the response code is.
case 1: //decimal 1.
//Serial.println("CO2 Sensor Success"); //means the command was successful.
break; //exits the switch case.
case 2: //decimal 2.
Serial.println("CO2 Sensor Failed"); //means the command has failed.
break; //exits the switch case.
case 254: //decimal 254.
Serial.println("CO2 Sensor Pending"); //means the command has not yet been finished calculating.
break; //exits the switch case.
case 255: //decimal 255.
Serial.println("CO2 Sensor No Data"); //means there is no further data to send.
break; //exits the switch case.
}
while (Wire.available()) { //are there bytes to receive.
CO2_in_char = Wire.read(); //receive a byte.
CO2_data[i] = CO2_in_char; //load this byte into our array.
//Serial.println((int)CO2_in_char);
i += 1; //incur the counter for the array element.
if (CO2_in_char == 0) { //if we see that we have been sent a null command.
i = 0; //reset the counter i to 0.
break; //exit the while loop.
}
}
printtab(CO2_data);
printline;
}
serial_event = false; //reset the serial event flag
}
Wire
locking up from bad communication. Add debug prints to your code to find out exactly where it stops...i
cannot be incremented to the point whereHumidity_data[i] = in_char;
overflows.O2_data[i] = (int)O2_in_char;
You're relying oni
having made it back to a zero value in both places, which also does not seem to be guaranteed for the same reason.Wire.endTransmission()
andWire.requestFrom()
. They might indicate an error in the I2C communication. Are you using additional pullup resistors on the I2C lines? How long is the cable to the sensor?