Ich habe dieses Wochenende meinen O2-Sensor über eine I2C-Verbindung an meinem Arduino getestet. Das hat auch wunderbar geklappt. Nun möchte ich den Sensorwert nutzen um über eine if-Abfrage, ein Relais zu steuern. Da der Wert ein char ist, bekomme ich aber in der if-Schleife eine Fehlermeldung. Ist es möglich den char-Wert (Sensorwert) in ein double oder so umzuwandeln?
Besten Dank und Grüsse!
Manu
Sketch für den O2-Sensor von Atlas scientific:
#include <Wire.h> //enable I2C.
#include <ctype.h> //for test numeric.
int address; //reserved for I2C ID number.
char computerdata[20]; //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char sensor_data[20]; //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0; //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0; //counter used for sensor_data array.
int time = 1400; //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
byte DO_alarm;
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
}
void loop() {
// *********** Dissolved Oxygen *************
address = 97; //default I2C ID number for EZO Dissolved Oxygen Circuit.
readAtlas();
Serial.print("DOX = ");
Serial.println(sensor_data); //print the data.
Serial.println(Wire.read());
if (sensor_data >= 7.0) { //if the DO is greater than or equal to 6.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
if (sensor_data <= 5.99) { //if the DO is less than or equal to 5.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
}
//------------------------------ readSensor I²C -----------------------------------------------------
void readSensor() {
if (computerdata[0] == 'c' || computerdata[0] == 'r')time = 5000; //if a command has been sent to calibrate or take a reading we wait 1400ms so that the circuit has time to take the reading.
else time = 300; //if any other command has been sent we wait only 300ms.
Wire.beginTransmission(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.
delay(time); //wait the correct amount of time for the circuit to complete its instruction.
//DO_alarm = sensor_data;
Wire.requestFrom(address, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
code = Wire.read(); //the first byte is the response code, we read this separately.
while (Wire.available()) { //are there bytes to receive.
in_char = Wire.read(); //receive a byte.
if (isdigit(in_char)) { //no text wanted.
if (i == 1) { //insert comma after the first digit.
sensor_data[i] = 44;
i += 1; //incr the counter for the array element.
}
sensor_data[i] = in_char; //load this byte into our array.
i += 1; //incr 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.
Wire.endTransmission(); //end the I2C data transmission.
break; //exit the while loop.
}
}
memset(computerdata, 0, sizeof(computerdata)); // empty string
}
//------------------------------ readAtlas --------------------------------------------------------
void readAtlas() {
computerdata[0] = 'r';
readSensor();
computerdata[0] = 's'; //into powersave
computerdata[1] = 'l';
computerdata[2] = 'e';
computerdata[3] = 'e';
computerdata[4] = 'p';
readSensor();
}
Fehlermeldung:
Test.ino: In function 'void loop()':
Test:26: error: invalid operands of types 'char [20]' and 'double' to binary 'operator>='
Test:29: error: invalid operands of types 'char [20]' and 'double' to binary 'operator<='
invalid operands of types 'char [20]' and 'double' to binary 'operator>='
Ich hatte das gestern auch schon ausprobiert, dabei kommen bei mir aber komische Resultate raus und Fehlermeldungen habe ich auch keine erhalten. Habe ich da irgend was übersehen?
Vielen Dank und Grüsse
Manu
Code Ausschintt mit "atol":
#include <Wire.h> //enable I2C.
#include <ctype.h> //for test numeric.
int address; //reserved for I2C ID number.
char computerdata[20]; //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char sensor_data[20]; //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0; //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0; //counter used for sensor_data array.
int time = 1400; //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
byte DO_alarm;
int number; //Test mit atol
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
number = atol(sensor_data);
}
void loop() {
// *********** Dissolved Oxygen *************
address = 97; //default I2C ID number for EZO Dissolved Oxygen Circuit.
readAtlas();
Serial.print("DOX = ");
Serial.println(sensor_data); //print the data.
Serial.print(number);
Serial.println(Wire.read());
if (Wire.read() >= 7.0) { //if the DO is greater than or equal to 6.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
if (Wire.read() <= 5.99) { //if the DO is less than or equal to 5.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
#include <Wire.h> //enable I2C.
#include <ctype.h> //for test numeric.
int address; //reserved for I2C ID number.
char computerdata[20]; //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char sensor_data[20]; //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0; //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0; //counter used for sensor_data array.
int time = 1400; //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
byte DO_alarm;
float number;
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
}
void loop() {
// *********** Dissolved Oxygen *************
address = 97; //default I2C ID number for EZO Dissolved Oxygen Circuit.
readAtlas();
number = atof(sensor_data);
Serial.print("DOX = ");
Serial.println(sensor_data); //print the data.
Serial.println(Wire.read());
Serial.print(number);
if (number >= 7.0) { //if the DO is greater than or equal to 6.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
if (number <= 5.99) { //if the DO is less than or equal to 5.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
}
//------------------------------ readSensor I²C -----------------------------------------------------
void readSensor() {
if (computerdata[0] == 'c' || computerdata[0] == 'r')time = 5000; //if a command has been sent to calibrate or take a reading we wait 1400ms so that the circuit has time to take the reading.
else time = 300; //if any other command has been sent we wait only 300ms.
Wire.beginTransmission(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.
delay(time); //wait the correct amount of time for the circuit to complete its instruction.
//DO_alarm = sensor_data;
Wire.requestFrom(address, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
code = Wire.read(); //the first byte is the response code, we read this separately.
while (Wire.available()) { //are there bytes to receive.
in_char = Wire.read(); //receive a byte.
if (isdigit(in_char)) { //no text wanted.
if (i == 1) { //insert comma after the first digit.
sensor_data[i] = 44;
i += 1; //incr the counter for the array element.
}
sensor_data[i] = in_char; //load this byte into our array.
i += 1; //incr 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.
Wire.endTransmission(); //end the I2C data transmission.
break; //exit the while loop.
}
}
memset(computerdata, 0, sizeof(computerdata)); // empty string
}
//------------------------------ readAtlas --------------------------------------------------------
void readAtlas() {
computerdata[0] = 'r';
readSensor();
computerdata[0] = 's'; //into powersave
computerdata[1] = 'l';
computerdata[2] = 'e';
computerdata[3] = 'e';
computerdata[4] = 'p';
readSensor();
}
Vielen Dank für den Tipp! Jetzt funktioniert es zwar, aber ich erhalte nur eine einstellige Zahl ohne Nachkommastellen. Somit ist es mir nur möglich den Grenzwert auf eine ganze Zahl zu setzen.
wenn du verstanden hast warum, dann versuch es so:
#include <Wire.h> //enable I2C.
#include <ctype.h> //for test numeric.
int address; //reserved for I2C ID number.
char computerdata[20]; //we make a 20 byte character array to hold incoming data from a pc/mac/other.
byte code = 0; //used to hold the I2C response code.
char sensor_data[20]; //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0; //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0; //counter used for sensor_data array.
int time = 1400; //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
byte DO_alarm;
float number;
void setup() //hardware initialization.
{
Serial.begin(9600); //enable serial port.
Wire.begin(); //enable I2C port.
}
void loop() {
// *********** Dissolved Oxygen *************
address = 97; //default I2C ID number for EZO Dissolved Oxygen Circuit.
readAtlas();
number = atof(sensor_data);
Serial.print("DOX = ");
Serial.println(sensor_data); //print the data.
Serial.println(Wire.read());
Serial.print(number);
if (number >= 7.0) { //if the DO is greater than or equal to 6.0
Serial.println("high"); //print "high" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
if (number <= 5.99) { //if the DO is less than or equal to 5.99
Serial.println("low"); //print "low" this is demonstrating that the Arduino is evaluating the DO as a number and not as a string
}
}
//------------------------------ readSensor I²C -----------------------------------------------------
void readSensor() {
if (computerdata[0] == 'c' || computerdata[0] == 'r')time = 5000; //if a command has been sent to calibrate or take a reading we wait 1400ms so that the circuit has time to take the reading.
else time = 300; //if any other command has been sent we wait only 300ms.
Wire.beginTransmission(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.
delay(time); //wait the correct amount of time for the circuit to complete its instruction.
//DO_alarm = sensor_data;
Wire.requestFrom(address, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
code = Wire.read(); //the first byte is the response code, we read this separately.
while (Wire.available()) { //are there bytes to receive.
in_char = Wire.read(); //receive a byte.
if (isdigit(in_char)) { //no text wanted.
if (i == 1) { //insert dot after the first digit.
sensor_data[i] = 46;
i += 1; //incr the counter for the array element.
}
sensor_data[i] = in_char; //load this byte into our array.
i += 1; //incr 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.
Wire.endTransmission(); //end the I2C data transmission.
break; //exit the while loop.
}
}
memset(computerdata, 0, sizeof(computerdata)); // empty string
}
//------------------------------ readAtlas --------------------------------------------------------
void readAtlas() {
computerdata[0] = 'r';
readSensor();
computerdata[0] = 's'; //into powersave
computerdata[1] = 'l';
computerdata[2] = 'e';
computerdata[3] = 'e';
computerdata[4] = 'p';
readSensor();
}
Ich habe mal nachgeforscht und gelesene, dass ein Komma dazu führt dass atof das als Ende der Zahl interpretiert und so keine Nachkommastellen generiert.
Was mir noch nicht klar ist, wiso werden Werte über 10 als 1,2,3 ect. ausgegeben?