Go Down

Topic: RS232 to control lab equipment (Read 2298 times) previous topic - next topic

Fillbe

Hi all,
I have some lab equipment that is run from (at the moment) from an old tower computer,and some matlab code, which is the dumbest thing as all it really does is send 3 lines of serial code to the device. (it's basically just a time synchronised trigger)

I'm trying to replicate this with the arduino but i've hit a stumbling block:  The RS 232 Tx doesn't seem to be working.

I'm running and Arduino uno R3 with a DF Robot RS232 shield (MAX3232 chip) and all I need to do is send a short string.

The TX light does blip when I send, but if I do a read from my PC I get nothing. I can get the same string to send over TTL no problem. I can also receive RS232 Rx no problem in the Arduino, so I think things are working and I've matched Baud rates ok.

I'm at the point of either giving up or ordering a different TTL-to-RS232 unit in the hope that it's just duff, but if anyone has any insights I'd really appreciate it.

Thanks!

CrossRoads

What code do you have running for the Arduino to send anything?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Fillbe

OK, a few bits in there to ignore, but basically I set it up to trigger on a push button and it looks something like this below.
I'm sure that the serial prints work fine for TTL, and what I've read suggests that the line from the MAX3232 should just convert that into RS232 compatible signal... and that's the limits of my knowledge (which is more than it was a day or so ago)

Code: [Select]

static FILE uartout = {0} ;
static int uart_putchar (char c, FILE *stream)

{
    Serial.write(c) ;
    return 0 ;
}

//constants used for pins
const int buttonPin1 = 2;     // the number of the pushbutton pin

const int ledPin =  12;      // the number of the LED pin

//declare variables
int buttonState = 0; 
int Frozen = 0; 

void setup()
{
  pinMode(ledPin,OUTPUT);
  pinMode(ledPin2,OUTPUT);
  digitalWrite(12,LOW);
   Serial.begin(9600) ;
}

void loop()

  // read the state of the pushbutton value:
int buttonState = digitalRead(buttonPin1);

  if (buttonState == HIGH) {     
    // turn LED on:   
    if (Frozen == 0){
      digitalWrite(ledPin, HIGH); 
      Serial.print("freeze");
      Frozen=1;
      delay(500); 
      }
    else {
      digitalWrite(ledPin, LOW); 
       printf("unfreeze");
      Frozen=0;
      delay(500);   
      }
  }
}

CrossRoads

Code looks ok - how is the MAX3232 wired?
Draw a picture.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

jremington

There are other aspects to RS232 data transmission than the baud rate, for example parity and number of stop bits and for scientific equipment those often need to be correctly specified. Among the possibilites are 8E2, 7N1, etc. You can attempt trial and error, or take a look at the bits involved in a successful transmission with an oscilloscope to see what is happening.

Fillbe

Crossroads: I'm actually running from this shield: http://www.ebay.co.uk/itm/321320153350?ssPageName=STRK:MEWNX:IT&_trksid=p3984.m1497.l2649

As far as I can see it's all correct, ad like i say, I can receive fine.

jremington: Ah, interesting, are these features that can be set? It's not just the lab kit mind you, I can't send and detect to my PC either.

Riva

#6
Feb 28, 2014, 12:48 pm Last Edit: Feb 28, 2014, 12:50 pm by Riva Reason: 1
How is the serial port defined on the PC and/or lab equipment. Is it using hardware handshaking, XON/XOFF or none and how is the serial cable wired between them?
What you describe sounds like protocol or either the equipment is expecting hardware handshake and/or the cable is not wired in a suitable fashion for your shield (crossover cable vs null modem cable wiring).

Fillbe

So the PC-to-lab kit config (which works) is:

PC -> TTL to RS232 adapter* -> lab kit

* adapter is similar to this (http://www.easysync-ltd.com/product/530/usb2-f-1001.html). I can't get this adapter to work with Arduino either, hence buying the shield.

BaudRate = 57600
DataBits = 8
DataTerminalReady = on
FlowControl = none
Parity = none
Port = COM4
ReadAsyncMode = continuous
RequestToSend = on
StopBits = 1

...as far as I can tell these settings are compatible with the default settings on the Arduino (please let me know if I'm wrong, I've read through the online docs as best I can)

The equipment itself is a black box, other people use it and so they don't want me opening it up to tinker. I use the exact same cabling from the arduino set up as from the RS232 adapter from the PC.

Thanks for all your suggestions guys, you're coming up with stuff I wasn't aware of so it's all useful.

Riva


BaudRate = 57600
DataBits = 8
DataTerminalReady = on
FlowControl = none
Parity = none
Port = COM4
ReadAsyncMode = continuous
RequestToSend = on
StopBits = 1

Okay it's looking to be standard serial protocol (57600,8N1). Despite FlowControl = none it could still mean the lab kit is expecting hardware flow control but the 9 pin cable has been wired in such a way to ignore it (Welcome to the standards world of RS232).
A better place to start is your code, the sketch you posted as an example does not compile and if it did then the baud rate (9600) is not set right.
Is the arduino (what model) replacing the PC tower or simulating the lab kit. How have you got the button and extra LED's connected up and after uploading a sketch to the arduino do you flick the switch on the shield to enable it's RS232 istead of the arduino USB serial?

Fillbe

HI,

So the code I put up had a few things taken out from the live version (there were multiple buttons each with their own output and I had added an LCD screen to error check what it was doing live  and had some different syntax for the serial print stuff but thought that might confuse the issue for you guys) so I'm not surprised it doesn't compile as it is. (Unfortunately I didn't keep my old version). I don't think the LEDs and switches are likely to be a problem, they're conventional resistor->LED->pin , same with the button switches for the inputs. I had been trying different Baud rates before I uploaded here, sorry to be confusing on that and thanks for pointing it out.

Arduino is an UNO R3 (genuine) and is there to replace the tower.  The RS232 shield has a switch on it that is 'off' during upload of the program (it won't upload otherwise), then I flick it 'on', then I unplug the arduino from the PC and reset with RS232 switch 'on'. When I've tested the receive side of things this works perfectly well (in fact I don't really need to reset or unplug).

for interest, here's the full code I have at the minute, But I think the problem is unlikely to be with any of the extra bits in there as more primitive versions of the code had the same problem and the stuff I've added has been attempted workarounds.

Code: [Select]

//LCD screen stuff
#include <LCD.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

#define I2C_ADDR    0x27
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

int n = 1;
LiquidCrystal_I2C   lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

//serial port stuff
static FILE uartout = {0} ;
static int uart_putchar (char c, FILE *stream)
{
    Serial.write(c) ;
    return 0 ;
}

//constants used for pins
const int buttonPin1 = 2;     // the number of the pushbutton pin
const int buttonPin2 = 3;
const int ledPin =  12;      // the number of the LED pin
const int ledPin2 =  11;
//declare variables
int buttonState = 0; 
int Frozen = 0; 
int Frozen2 = 0; 

void setup()
{
  //LCD stuff ============================================================
  lcd.begin (16,2);
   
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go home
lcd.print("Ready...");
LiquidCrystal_I2C   lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


//serial port stuff ============================================================
Serial.begin(57600);
pinMode(ledPin,OUTPUT);
  pinMode(buttonPin1, INPUT);
 
  pinMode(ledPin2,OUTPUT);
  pinMode(buttonPin2, INPUT);
 
  digitalWrite(12,LOW);
  digitalWrite(11,LOW);

   // fill in the UART file descriptor with pointer to writer.
   fdev_setup_stream (&uartout, uart_putchar, NULL, _FDEV_SETUP_WRITE);

   // The uart is the standard output device STDOUT.
   stdout = &uartout ;

}

void loop()

  // output any serial Rx input to tht LCD
 
  if (Serial.available()) {
    delay(100);
  lcd.setCursor (0,0);        // go to start of 2nd line
  lcd.clear();
    // read all the available characters
    while (Serial.available() > 0) {
      // display each character to the LCD
      lcd.write(Serial.read());
    }
  lcd.setCursor (0,0);
  //lcd.setBacklight(HIGH);     // Backlight on
  delay(3000);
}

// take any input from buttons and output to serial Tx
  // read the state of the pushbutton value:
int buttonState = digitalRead(buttonPin1);
int buttonState2 = digitalRead(buttonPin2);
//int n=0;
  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  buttonState = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
 
  if (buttonState == HIGH) {     
    // turn LED on:   
    if (Frozen == 0){
      digitalWrite(ledPin, HIGH); 
      //Serial.print("cine freeze");
      //printf("cine freeze");
      fprintf( &uartout, "cine freeze") ;
      Serial.println("");
      lcd.clear();
      lcd.setCursor (0,0);
      lcd.print("cine freeze");
      Frozen=1;
      delay(500); 
      }
    else {
      digitalWrite(ledPin, LOW); 
      //Serial.write("cine unfreeze");
      //printf("cine unfreeze");
          fprintf( &uartout, "cine unfreeze") ;
          Serial.println("");
          lcd.clear();
          lcd.setCursor (0,0);
          lcd.print("cine unfreeze");
      Frozen=0;
      delay(500);   
      }
  }
 
    if (buttonState2 == HIGH) {     
    // turn LED on:   
     
      //Serial.write('cine dump y:\test1 1 10 2');
     
      fprintf( &uartout, "cine dump y:\test1 1 10 2") ;
      Serial.println("");
      lcd.clear();
      lcd.setCursor (0,0);
      lcd.print("cine dump y:\test1 1 10 2");
     
       //flashy light while saving
      for (int n=0; n<20; n++){
        digitalWrite(ledPin2, HIGH); 
        delay(80);
        digitalWrite(ledPin2, LOW);
        delay(80);
        }     
      delay(500); 
      }
}

Fillbe

For extra clarity on the fault finding I've done:

These work:
PC Tx -> RS 232 adapter -> BlackBox
PC Tx -> RS232 adapter-> Arduino RS232 Sheild -> Arduino (verified by printing strings to LCD... different code to above)

These don't
Arduino -> Arduino RS232 Sheild -> RS232 adapter ->PC
Arduino -> Arduino RS232 Sheild -> Black Box

Riva


For extra clarity on the fault finding I've done:

These work:
PC Tx -> RS 232 adapter -> BlackBox
PC Tx -> RS232 adapter-> Arduino RS232 Sheild -> Arduino (verified by printing strings to LCD... different code to above)

These don't
Arduino -> Arduino RS232 Sheild -> RS232 adapter ->PC
Arduino -> Arduino RS232 Sheild -> Black Box

Okay this helps and reduces the number of questions some.
To confirm the TX on the RS232 Shield is working have you tried a loopback test by connecting pins 2 & 3 of the 9 pin D-SUB on the shield together and making a simple arduino sketch to send a string and display the result on the LCD.
If this works then my guess is hardware flow control problem with talking to the PC and blackbox if it does not then maybe a faulty shield TX pin.

Fillbe

Thanks for all your help guys, I learnt a lot.

Conclusion:  duff null modem cable. seems to be working now.

<deep sigh>

Hi - Sorry for the old post rebirth but this topic fits my question and before I go buy some hardware it would be great if some one could provide some insight please  :D ?

Objective - Send a single command via a Arduino Uno R3 & RS232 to a piece of lab equipment, which returns a string of data. Then print a truncated version of this string to an LCD connected to the arduino. 

Comm Setup:
Baud Rate  - 57600
Data Bits - 8
Parity - None
Stop Bits - 1
Flow Control (handshake) - None

This was verified working with:
PC > USB to RS232 adapter > DB9 cable > Lab Eq.
Using putty, and I was able to send the cmd "ch1:diag" and putty returned the following string:
lamp: XX.7% Light:X.XV Cont: XX.7% Gain: X.XX SNR: XXX.X Mono: XXX.X

My Questions based on this thread:
1. I need a MAX232 type shield to do this? like this unit 

2. If connected as follows Arduino > MAX232 type shield > DB9 cable > Lab Eq. During code development, how do I debug or monitor the RS232 response after I send my cmd to the equipment? Can i use Software.serial on pins 7,8? then pass the sting over to "Serial.print" on the USB D0, D1? just to verify my setup is working. Later I can add the LCD.

3. Is the expected return string too big? I remember looking at Software.serial and its limits are 64 byte serial buffer?

thanks in advance!









Go Up