RS-232 serial communication with pH meter

I’m trying to control a Jenco 6230N pH meter with an arduino uno R3. The connection is made through a nine-pin RS-232 port. I am using a MAX232 card to convert between RS-232 and TTL. I set up software serial pins at digital 2 and 3 (TX and RX, respectively) and connected the MAX232 TX to Arduino RX and visa versa. Ground to ground, VCC to 5V output on the arduino. The meter requires 9600 baud, 8-N-1 ASCII encoded transmission and remains quiet until it receives a start code (“S00”). Using 232Analyzer, I’ve confirmed that the meter will give a single transmission the current reading when it receives S00. This is a 26 character array that terminates in .

The problem is, I can’t get the arduino to interface with the pH meter. When I do a serial_meter.read() I get -1, which I believe means there’s nothing to read. When I do serial_meter.available() I get 0. This happens even when I send the start code.

Some possible causes I’ve thought of but couldn’t address:

  1. The format of the transmission from arduino doesn’t match the expected start signal. S00 from 232Analyzer may be different from serial_meter.println(“S00”).

  2. The MAX232 card is distorting the signal somehow.

  3. I succeed in sending the start signal, but I miss the response.

Here’s a sample of the code:

#include <Softwareserial.h>

const int rxpin = 3;
const int txpin = 2;
SoftwareSerial serial_meter(rxpin, txpin);
char incoming = 0;
void setup {
Serial.begin(9600);
serial_meter.begin(9600);
String place_holder = “”;
}// setup

void loop {

serial_meter.println(“S00”);
if (serial_meter.available > 0) {
while (serial_meter.available > 0 {
incoming = serial_meter.read();
place_holder += incoming;
}// while loop to get all the chars
}// if there’s incoming chars, read them
Serial.print(“Received: “);
Serial.println(place_holder);
place_holder = “”;
delay(1000);
}// loop

Any suggestions for getting the two devices to communicate? Thanks.

I can add a fourth one:

  1. The device is picky about serial timings.

In this case don't use the SoftwareSerial it's not exact enough in timings to communicate with picky devices. I had similar problems with a RN-XV from Roving Networks, they went away as soon as I switched to the hardware serial interface.

SoftwareSerial does work with some devices but try connecting a scope and see the timing differences you get. They are not exceptionally high but as I wrote: a picky device gets confused and reacts unpredictably.

Pylon,

Thanks for the suggestion. I just tried it out and didn't get any improvement. Do you know how hardware serial is different from software serial? Also, I am using the hardware serial to monitor the readings from the meter. If I do a Serial.println(), does that send the signal through the USB port AND the hardwired TX pin? Or do I have to specify which pin it goes through?

Thanks!

does that send the signal through the USB port AND the hardwired TX pin? Or do I have to specify which pin it goes through?

Yes the hardware serial transmit signal is on arduino digital pin 1 (and only on pin 1, it can't be 'reassigned') and available to be wired to a TTL to RS232 level converter if you wish.

Lefty

I’ve gone back and tried to just send serial information between my Uno and Leonardo, the simplest case I could think of. I’m not getting any communication between them.

I have TX <-> RX between the boards. Ground to Ground. 5V to 5V. This makes me think I have a problem with the code. I’ve gone through my arduino cookbook and the examples on the website/forum but I can’t figure out what’s missing.

I’m using this code for the transmitter (Uno)

String start_code = "S00\n";
String inputString = "";
boolean stringComplete = false;
char incomingByte = 0;   // for incoming serial data
int avail = -1;
void setup() {
       
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
        Serial.println("Attempting Contact");
    //    establishContact();
        inputString.reserve(200);
}

void loop() {
  Serial.println("LooP");    
  
  if (stringComplete) {
        Serial.println(inputString);
        inputString = "";
        stringComplete = false;      
             }
        delay(500);
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print(start_code);
    delay(300);
  }
}// establish contact


void serialEvent() {
  while (Serial.available()){
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar =='\n') {
      stringComplete = true;
    }
  }
}// serial event

I’m using this code for the receiver (Leonardo)

String inputString = "";
boolean stringComplete = false;

void setup() {
  Serial1.begin(9600);
  while(!Serial) {
    ;
  }
  inputString.reserve(200);
  
  
}


void loop() {
  
  if (stringComplete) {
    Serial.println(inputString);
    inputString = "";
    stringComplete = false;
  }
}


void serialEvent() {
  while (Serial1.available()) {
    char inChar = (char)Serial1.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
  
}

I couldn't get serialEvent() to work, so I went to this instead. Now I can communicate between the arduinos, but when I modified the sketch for communicating with the meter I still get nothing.

String start_code = "S00\n";
String inputString = "";
boolean stringComplete = false;
char incomingByte = 0;   // for incoming serial data
int avail = -1;
void setup() {
       
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
        Serial.println("Attempting Contact");
    //    establishContact();
        inputString.reserve(200);
}

void loop() {
  Serial.print(start_code);    
  if (Serial.available()) {
    while (Serial.available() > 0) {
      char inChar = Serial.read();
      inputString += inChar;
    }
    Serial.println(inputString);
    inputString = "";
  }
  if (stringComplete) {
        Serial.println(inputString);
        inputString = "";
        stringComplete = false;      
             }
        delay(2500);
}

I just picked up an adapter so I can attach the 232Max to the computer running 232Analyzer. What I've learned is that the transmission from the arduino is in the proper format, but when I send a transmission to the arduino, it fails to recognize the transmission. I've taken out the Serial.print() in case it was blocking the incoming transmission, but even then I don't see it. So it looks like the issue is the arduino receiving end.

I couldn't get serialEvent() to work, so I went to this instead. Now I can communicate between the arduinos, but when I modified the sketch for communicating with the meter I still get nothing.

It looks to me like you are trying to use the hardware serial port to talk to the Serial Monitor AND the pH probe at the same time. Make up your mind which you are going to talk to. You can't talk to both.

Yeah, I was trying to follow the previous advice to try using the hardware serial to talk to the pH meter rather than software, but I didn't know of a way to monitor what was happening if the hardware serial was being used to talk to the meter. I've since started using a leonardo. The hardware serial goes to monitor and serial1 goes to the meter. I'm not sure if serial1 is a hardware or software serial, though nor am I sure if it makes a difference. Either way, I'm not getting anything from the meter through serial1.

I've done some more careful monitoring of the COM1 port when the PC controls the pH meter and I've found a whole slew of commands being used that I didn't find before (the PC successfully controls the meter). They look like this:

IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_WAIT_ON_MASK) IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_COMMSTATUS) IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_HANDFLOW) IRP_MJ_DEVICE_CONTROL (IOCTL_SERIAL_GET_TIMEOUTS)

None of these commands appear when I monitor what comes out of the arduino using the PC. I've even tried sending the ASCII characters transmitted during these commands, but that didn't work.