Problem Communicating with Medical Equipment over RS232 using Arduino Uno

I've been trying to send a message from Arduino Uno to a device over an RS232 serial interface, and then receive a reply which will be displayed on the PC serial monitor. I've used the AltSoftSerial library in my code. So far however I have not received any reply from the device. I've used a 'straight-through' cable from my RS232 shield to the device. I've included the following important information from the device manual:

The Graseby Model 3000/500 3100/505 pumps are designed to interface
with a computer that supports an RS-232 serial port. The device is
configured for Data Circuit-terminating Equipment (DCE).

Each character transmitted over the link will be an ASCII character
using 1 start bit, 8 data bits, no parity and 1 stop bit. Transmission is
software selectable through Biomedical special functions to 9600
(default), 4800, 2400, 1200, 600, 300 baud. The eight data bits are
transmitted in standard order, which is least significant bit first, most
significant bit last.

Also, my code is here:

#include <AltSoftSerial.h> 

AltSoftSerial pumpSerial; // define global variables
int debugLED = 13; 

void setup() { 
 
  pinMode(debugLED,OUTPUT);
  Serial.begin(9600); //
  Serial.println("USB Interface Begin");
  pumpSerial.begin(9600); //
  Serial.println("RS-232 Interface Begin");
  
}

void loop() {
  
  char to_pump[10] = "<09M773C>"; // define the outgoing record  
  
  if (pumpSerial.available() > 0){ // check software serial port for bytes
    
    digitalWrite(debugLED, HIGH); // blink debug LED to indicate when data is received
    
    byte byte1 = pumpSerial.read(); // CHECK
    Serial.println(byte1); // CHECK
    
    delay(10);
    digitalWrite(debugLED, LOW);
  
  }
  else{
    
    pumpSerial.write(to_pump); // ?? writes binary data to the serial port
        
    Serial.print(to_pump);
    Serial.println(" was sent.");
    
    delay(5000); // delay whilst waiting for reply
    
  }
  
} // end loop

The transceive operation seems to work fine to me, but I am unable to get any sort of reply from the device! I've already checked that the shield works, that the baud rates are the same, and the cable worked when tested with a voltmeter so I think the problem must either be with my code or the type of RS232 cable? Does anyone have any advice or suggestions? Thanks!

Might be the cable; what do you mean by 'straight-through' cable ? At the very least, RX should go to TX and vice versa. You may also well need to hold one of the pins high to tell the pump it's clear to send.

Hi wildbill, so this is what I found before for the pump pinout:

1 No connection
2 Rx
3 Tx
4 No connection
5 Gnd
6 No connection
7 Clear to send (CTS)
8 Request to send (RTS)
9 +5V out

And the shield pinout which I found here Arduino RS232 Shield Wiki - DFRobot said that Tx was 2 and Rx was 3. So this made me think I needed a 'straight-through' cable, which I'm assuming directs the RX directly to the TX pins. I'm not sure about how to go about holding one of the pins high using the shield, but that could well be the problem!!

From the RS-232 shield information, only Rx, Tx and Gnd are defined. So it could be that these criteria are being ignored altogether:

The host asserts RTS (Request to Send) prior to sending a command. If
ready, the pump shall respond by asserting CTS (Clear to Send) within
20 milliseconds of RTS active. The host may keep RTS asserted
indefinitely. Unless there is a fault, the pump shall keep CTS asserted
as long as RTS is asserted.

Do you think there would be a way to fix this?

Those devices look rather expensive so I would not be inclined to experiment with them. Furthermore, unless you're planning on using them for non-medical purposes, I wouldn't touch them with a barge pole.

That said, if I were to try to get the pump talking, I'd try connecting the 5V on it to RTS and see if CTS goes high. No need to have the arduino connected for such a test. If that works, you might well be able to have the pump convince itself it's ready to talk to the arduino.

Thanks, this project is just for proof of concept so no need to worry about my level of ineptitude where people's health is concerned! :smiley: Your suggestion worked, but only when not connected to the Arduino of course. Do you think I should just hardwire pins 9 and 8 together at the pump end inside the connector in order to get the thing working when connected to Arduino, or do you know of a way to actually implement RTS/CTS flow control using Arduino and the MAX3232?

Arduino pins are not compatible with RS232 as such.
Even if your medical device is OK with 0/5V signalling (some devices ARE), the logic is inverted from what it should be.
That'll be right if you run it through a MAX232 or similar device.
It's possible that you could get away with a simple inverter (LOW in -- HIGH out, HIGH in -- LOW out), but no guarantees.

For RTS and CTS, you might get away with just hard-wiring them (jumpering RTS to CTS).

http://www.tldp.org/HOWTO/Text-Terminal-HOWTO.html#toc11.7

The device is configured for Data Circuit-terminating Equipment (DCE).

Based on the device's pinout connections,

1 No connection
2 Rx
3 Tx
4 No connection
5 Gnd
6 No connection
7 Clear to send (CTS)
8 Request to send (RTS)
9 +5V out

It looks like you need a crossover cable shown below
(see note - signal directions are reversed)

Runaway Pancake:
This is the only info I could find on the levels:

The pump RS232 module converts TTL data transmitted by CPU1 into RS232 levels,
and converts received RS232 level data to TTL levels.

Do you think this should be ok when used with the MAX3232?
From the pump information I assumed I'd need to connect pin 9 to pin 8 ie 5V to RTS in order to fool the pump that it is constantly asserted?

dlloyd:

It looks like you need a crossover cable shown below

From what I understand, my shield crosses over the lines from Rx and Tx already:

So...
What I think seems like the best option is to hardwire RTS to 5V and then leave out checking CTS completely? Although it would be preferable to check it in someway, from what I've heard I don't think it's possible to do this with Arduino. Do you think this sounds like the best way to go?

Thanks! :grin:

faye_310:
Runaway Pancake:
This is the only info I could find on the levels:

The pump RS232 module converts TTL data transmitted by CPU1 into RS232 levels,
and converts received RS232 level data to TTL levels.

Do you think this should be ok when used with the MAX3232?
Yes

From the pump information I assumed I'd need to connect pin 9 to pin 8 ie 5V to RTS in order to fool the pump that it is constantly asserted?
RTS to CTS more likely.

dlloyd:

It looks like you need a crossover cable shown below

From what I understand, my shield crosses over the lines from Rx and Tx already:
Arduino RS232 Shield Wiki - DFRobot

So...
What I think seems like the best option is to hardwire RTS to 5V and then leave out checking CTS completely? Although it would be preferable to check it in someway, from what I've heard I don't think it's possible to do this with Arduino. Do you think this sounds like the best way to go?

They can be used/checked with Arduino, via MAX232 (those have two 232 inputs and two 232 outputs,) it's up to you to sense and assert as required.

dlloyd:

The device is configured for Data Circuit-terminating Equipment (DCE).

So does that mean that it is expecting a DCE?
Did they mean to say that it is DTE? [WTH?]
(I thought DCE meant Data Communications Eqpt., a/k/a "modem".)

What I think seems like the best option is to hardwire RTS to 5V and then leave out checking CTS completely? Although it would be preferable to check it in someway, from what I've heard I don't think it's possible to do this with Arduino. Do you think this sounds like the best way to go?

So the device has handshaking, but there's no handshaking available at the shield.
Yes, I think looping back the handshaking with jumper from pin 7 to pin 8 might fool the device.

As in "null modem with loop back handshaking" diagram here (ignore pins 1, 4 and 6):

dlloyd:
Yes exactly, so the shield has no handshake. Your argument is convincing, but I'm still not sure why a jumper from RTS (pin 8 ) => +5V (pin 9) wouldn't be the best solution.

Runaway Pancake
Thanks for the MAX232 suggestion, I can definitely keep this idea in mind for making improvements in the future.

Don't we need to fool the device into thinking that the host is asserting pin 8? And then the knock on effect of that would be the pump asserting CTS (pin 7). Wouldn't this mean that CTS is only active after RTS has already been brought high? I'm just going on the description given for this particular device (however weird) :P. I'll check this solution in the lab tomorrow.

The host asserts RTS (Request to Send) prior to sending a command. If
ready, the pump shall respond by asserting CTS (Clear to Send) within
20 milliseconds of RTS active. The host may keep RTS asserted
indefinitely. Unless there is a fault, the pump shall keep CTS asserted
as long as RTS is asserted.

Thanks! :smiley:

Just to let you know, it's working now! Thanks for your advice everyone. :wink:

Can you advise on what you did exactly to get it working. I seem to have precisely the same issue.!