I am trying to put together a pH/ORP meter using two stamps from Atlas Scientific. I have the code for both pH and ORP. When I load each code independently they function well, but when I try to put the together and have first pH and second ORP read, the second will not work correctly. I have printed the received serial bytes for the second reading and there is a lot of garbage displayed. It seems like after the first receiving the serial buffer never flushes. .flush(); does nothing.
Here is the code with the two sections separated. Many thanks for any suggestion.
#include <SoftwareSerial.h>
SoftwareSerial LCD(2, 3); // LCD
SoftwareSerial ORP(4, 5); // ORP stamp
SoftwareSerial pH(8, 9);
void setup()
{
ORP.begin(9600);
pH.begin(9600);
LCD.begin(9600);
Serial.begin(9600);
LCD.print("?f");
LCD.print("?c0");
}
void loop()
{
char inData_pH[15];
char string_pH[15];
float pH_val = 0.0;
byte holding; //define holding
byte i; //define for loop
pH.print("read(26.5)"); //tell stamp to take single reading
pH.print((char)13);
delay(1000);
pH.listen(); //listen to pH port
while(pH.available() > 3) { // wait until greater than 3 bytes
holding = pH.available(); //hold pH stamp info
for(i=0; i <= holding; i++) { //assemble stamp data
inData_pH[i] = pH.read();
}
}
inData_pH[holding]='\0';
sscanf(inData_pH, "%*3c%s ", string_pH);
if (atoi(string_pH) != 0) {
pH_val = atof(string_pH);
}
Serial.print("pH Sensor output: [");
Serial.print(inData_pH);
Serial.println("]");
LCD.print("?y0");
LCD.print("?x00");
LCD.print("pH value: ");
LCD.println(pH_val);
// ******************************************************************************
char inData_ORP[24];
char string_ORP[8];
int index =0;
int ORP_val = 0;
ORP.print("read()c\r");
delay(1000);
while (ORP.available() > 0 && index < 24)
{
inData_ORP[index] = ORP.read();
index++;
}
inData_ORP[index] = '\0';
sscanf(inData_ORP, "%*s %s", string_ORP);
ORP_val = atoi(string_ORP);
Serial.print("ORP Sensor output: [");
Serial.print(inData_ORP);
Serial.println("]");
LCD.print("?y2");
LCD.print("?x00");
LCD.print("ORP value: ");
LCD.println(ORP_val);
}
Check the documentation and examples for SoftwareSerial. I believe you can't have more than one SoftwareSerial instance active at a time. There should be commands to activate and deactivate (not sure if those are the correct terms...) each instance of SoftwareSerial to multiplex them.
Thank you guys. Much appreciated.
I clean up the code a bit and trace the problem to the listen(); Either pH.listen(); or ORP.listen(); but not the two of them together. How do you change this dynamically ?
If using multiple software serial ports, only one can receive data at a time.
Have a look at the listen method. This allows you to control which port is receiving data. However, it has its downsides
Enables the selected software serial port to listen. Only one software serial port can listen at a time; data that arrives for other ports will be discarded. Any data already received is discarded during the call to listen() (unless the given instance is already listening).
Depending on what you are doing this may or may not be a problem.
Thank you. Took me abit to understand that the library is just making multiple serial ports available, there is still just one serial buffer.
I made it work, checking for a CR in the receiving string and shifting to listen to the other port once detected.
I haven't used it, but I remember reading that there is an AltSoftSerial which avoids the 'one port at a time' restrictions of the standard SoftwareSerial implementation.
I haven't used it, but I remember reading that there is an AltSoftSerial which avoids the 'one port at a time' restrictions of the standard SoftwareSerial implementation.
Only because AltSoftSerial is tied to a specific pair of pins, not whichever pins the user wants to use.