I have been using the Atlas Scientific Ph and EC stamps on a Mega using the dedicated hard-serial pins and after a bit of fussing everything works well. I went and moved over to an Uno and the softserial library. Everything works great, except the Ph stamp only responds with a value 3/4 the time. The EC stamp works perfectly, gets the "r" and "\r" and blinks, spits out a reading 1.5 seconds later. Ph always blinks like it's getting something but I think some of the time it's just getting the and not the "r" command because it blinks less. I have tried multiple Uno boards, multiple pin positions, even multiple Ph stamps and the problem stays the same- EC is always fine.
#include <SoftwareSerial.h> //add the soft serial libray
// Here's a EC device connect to pins 2 and 3
SoftwareSerial ECstamp(2,3);
SoftwareSerial Phstamp(4, 5);
// A Ph device connected to 4 and 5
...
down in the program
...
if (com=="PH") // PH get a PH reading
{
Phstamp.listen();
delay(100);
Phstamp.print("r"); //send read to Atlas
Phstamp.print((char)13); //send CR
delay(2000);
sa = Phstamp.available();
Serial.println(sa); // for debug see what it's getting
if (sa > 0) { // if buffer not empty process buffer content
for (int i=0; i < sa; i++){
char inchar = (char)Phstamp.read(); //get the char we just received
phstring += inchar; //add it to the inputString
if(inchar == '\r') {ph_stringcomplete = true;} //if the incoming character is a , set the flag -Not currently using this flag
}
} //end for loop
Serial.print("{Ph=");
Serial.print(phstring);
Serial.println("}");
phstring = ""; //clear the string:
ph_stringcomplete = false; //reset the flage used to tell if we have recived a completed string
delay(100);
} //end PH command block
if (com=="EC") // EC reading
{
ECstamp.listen();
ECstamp.print("r"); //send read to Atlas
ECstamp.print("\r");
delay(2000); // time to get chars
sa = ECstamp.available(); // count serial buffer bytes
if (sa > 0) { // if buffer not empty process buffer content
for (int i=0; i < sa; i++){
char inchar = (char)ECstamp.read(); //get the char we just received
ecstring += inchar; //add it to the inputString
if(inchar == '\r') {ec_stringcomplete = true;} //if the incoming character is a , set the flag -Not currently using this
}
}
Serial.print("{EC=");
Serial.print(ecstring);
Serial.println("}");
ecstring = ""; //clear the string:
ec_stringcomplete = false; //reset the flag used to tell if we have recived a completed string
delay(100);
} //end EC block
more then half the time, it works great and I get a value, the rest of the time sa=0 - and from the blink I infer no "r" command was received or interpreted by the stamp just a .. I am pretty riddled as to why is works 50-75% and not all the time and as to why the EC stamp works all the time. I have tried all sorts of things like sending a before the "r" command, putting little delays in, anyone have any ideas, suggestions for things to try? My understanding of softserial intricacies are mimimal and maybe there is more robust way to do this..
Do you have any way to independently verify the sensor? and is this behavior new or has something changed during it's use? both or either might well fix it. If it's operation has changed then perhaps it need factory repair or replacement, if it has done it from the beginning then perhaps there's an issue with the interface or possibly it is in another internal mode that has different measurement definitions than the one you wrote the sketch for. This is because you have explored your sketch completely it would seem and it appears well written. With that and Occam in mind those two idea's are what popped up when I read the post. For example I have a PC program that can read and re-program my GPS unit. and there just... might be one available for your device that will work on your PC too... Just some random thoughts...
Try using the example sketch off the atlas scientific website to check the stamp; it works flawlessly for me. Then troubleshoot your code. I found that delays in the wrong place can be very problematic.
Doc, thanks for taking a look at my sketch. Yes, Have verified the functionality of the Ph stamp using both an Arduino Mega and a USB->serial "debugger that Atlas sells. Because it works fine with the basically the same code on a Mega (different in that my Mega sketch uses hard serial), I suspect that the details of softserial are at the core of my strange problem. I am going to return to the Atlas sample code to see if a single instance of softserial is reliable.
Thanks
Quentin
Usually the transmission of byte with SoftwareSerial is much more reliable than the reception because for the transmission the interrupts are turned off during the shift-out of the bits while this is not the case for the reception. If your sensor sends some bytes while the Arduino is handling timer events or hardware serial interrupts it may be possible that the delay between on bit and the following gets to big and slips to the next bit, loosing one. Even the timing of the sending part is not really accurate, the receiving part is often unreliable to unusable with higher baud rates (>9600 in my experience, with very picky devices even less). The less the Arduino is doing apart from the SoftwareSerial communication, the better it works.
You can try to put a cli()/sei() pair of statements around your read calls on the SoftwareSerial and see if that gives you better results. If possible go for the hardware serial interfaces on the Mega.
You don't mention what version of Arduino IDE you're on. Newer ones (1.0+) bundle an interrupt-driven software serial implementation that (1) should me more reliable than the old one and (2) needs interrupts. If you're using an older IDE, go get "newsoftserial" which is interrupt driven.
You don't mention what bit rate you're using. Even the interrupt driven implementation spends a lot of time in timing loops reading individual bits. There is a sweet spot around 9.6-19.2kbts where the timing is slow enough to be accurate and reliable, but fast enough that you can get other stuff done.
sa = Phstamp.available();
Serial.println(sa); // for debug see what it's getting
This sort of thing could be problematic because the input timing on the software serial is critical, but the output on Serial.println() could potentially block waiting for the serial out buffer to drain. Better to wait to write out the debugging until a less critical timing point. The interrupt-driven serial is more forgiving on this.