Hello guys, i have a problem with my code. so basically the problem in the tittle (Compilation error: invalid use of void expression). This is my code
#include <Ezo_i2c.h> //include the EZO I2C library from https://github.com/Atlas-Scientific/Ezo_I2c_lib
#include <Wire.h> //include arduinos i2c library
#include <sequencer2.h> //imports a 2 function sequencer
#include <Ezo_i2c_util.h> //brings in common print statements
Ezo_board ORP = Ezo_board(98, "ORP"); //create a PH circuit object, who's address is 99 and name is "PH"
Ezo_board EC = Ezo_board(100, "EC"); //create an EC circuit object who's address is 100 and name is "EC"
void step1(); //forward declarations of functions to use them in the sequencer before defining them
void step2();
Sequencer2 Seq(&step1, 1000, &step2, 0); //calls the steps in sequence with time in between them
#include <SPI.h>
#include <SD.h> // Kartu SD
File myFile;
int pinCS = 53;
void setup() {
Wire.begin(); //start the I2C
Serial.begin(9600); //start the serial communication to the computer
Seq.reset(); //initialize the sequencer\
if (!SD.begin(pinCS)) {
Serial.print("SD Card tidak ada");
while (1);
}
}
void loop() {
Seq.run(); //run the sequncer to do the polling
}
void step1(){
//send a read command. we use this command instead of PH.send_cmd("R");
//to let the library know to parse the reading
ORP.send_read_cmd();
EC.send_read_cmd();
}
void step2(){
receive_and_print_reading(ORP); //get the reading from the PH circuit
Serial.print(" ");
receive_and_print_reading(EC); //get the reading from the EC circuit
Serial.println();
myFile = SD.open ("ORP&EC.csv", FILE_WRITE);
if (myFile) {
myFile.print(" Data ORP = ,");
myFile.print(receive_and_print_reading(ORP));
myFile.print("miliVolt, Data EC = ,");
myFile.print(receive_and_print_reading(EC));
myFile.print("us/cm");
Serial.print("data sukses tersimpan");
} else {
Serial.print("data tidak tersimpan");
}
}
This is the above mentioned function in the library
void receive_and_print_reading(Ezo_board &Device) { // function to decode the reading after the read command was issued
Serial.print(Device.get_name()); Serial.print(": "); // print the name of the circuit getting the reading
Device.receive_read_cmd(); //get the response data and put it into the [Device].reading variable if successful
print_success_or_error(Device, String(Device.get_last_received_reading(), 2).c_str()); //print either the reading or an error message
}
You will have to implement printing to file yourself. E.g. the below will print the device name to file
C:\Users\Bangkit\AppData\Local\Temp\.arduinoIDE-unsaved2025125-31864-zgkqg3.arhgt\I2c_read_mulitple_circuits\I2c_read_mulitple_circuits.ino: In function 'void step2()':
C:\Users\Bangkit\AppData\Local\Temp\.arduinoIDE-unsaved2025125-31864-zgkqg3.arhgt\I2c_read_mulitple_circuits\I2c_read_mulitple_circuits.ino:50:50: error: invalid use of void expression
myFile.print(receive_and_print_reading(ORP));
^
C:\Users\Bangkit\AppData\Local\Temp\.arduinoIDE-unsaved2025125-31864-zgkqg3.arhgt\I2c_read_mulitple_circuits\I2c_read_mulitple_circuits.ino:52:49: error: invalid use of void expression
myFile.print(receive_and_print_reading(EC));
^
exit status 1
Compilation error: invalid use of void expression
Below a description of how it can be approached; possibly the easiest way.
void receive_and_print_reading(Ezo_board &Device) { // function to decode the reading after the read command was issued
Serial.print(Device.get_name()); Serial.print(": "); // print the name of the circuit getting the reading
Device.receive_read_cmd(); //get the response data and put it into the [Device].reading variable if successful
print_success_or_error(Device, String(Device.get_last_received_reading(), 2).c_str()); //print either the reading or an error message
}
This function is in the library (file Ezo_i2c_util.cpp).
It takes a board as an argument; in your case ORP or EC. If you want to print the same info to file, you will need to implement this yourself.
The easiest way is probably to copy two functions from Ezo_i2c_util.cpp to you sketch
receive_and_print_reading
print_success_or_error
Rename them in your sketch to receive_and_print_reading_to_file and print_success_or_error_to_file
void receive_and_print_reading_to_file(Ezo_board &Device)
{ // function to decode the reading after the read command was issued
Serial.print(Device.get_name());
Serial.print(": "); // print the name of the circuit getting the reading
Device.receive_read_cmd(); //get the response data and put it into the [Device].reading variable if successful
print_success_or_error(Device, String(Device.get_last_received_reading(), 2).c_str()); //print either the reading or an error message
}
// used for printing either a success_string message if a command was successful or the error type if it wasnt
void print_success_or_error_to_file(Ezo_board &Device, const char *success_string)
{
switch (Device.get_error())
{ //switch case based on what the response code is.
case Ezo_board::SUCCESS:
Serial.print(success_string); //the command was successful, print the success string
break;
case Ezo_board::FAIL:
Serial.print("Failed "); //means the command has failed.
break;
case Ezo_board::NOT_READY:
Serial.print("Pending "); //the command has not yet been finished calculating.
break;
case Ezo_board::NO_DATA:
Serial.print("No Data "); //the sensor has no data to send.
break;
case Ezo_board::NOT_READ_CMD:
Serial.print("Not Read Cmd "); //the sensor has not received a read command before user requested reading.
break;
}
}
Next replace Serial in those **_to_file functions by myFile and in loop call e.g. receive_and_print_reading_to_file(ORP) instead of myFile.print(receive_and_print_reading(ORP)).
Note that there are better ways in my opinion but it's possibly a bit more work because it requires understanding of the library; it's not too difficult in my opinion but I do not have the hardware to test.