Cannot read from serial device

Hello All,

I'm trying to use an Arduino Uno R3 to read data from a serial connection. I'm using softwareserial on pins 9(Rx) and 8(Tx), and I have an RS232 TTL device connected to my Uno.

The device coonected on the other end has the follwing capabilites:

Asynchronous, bi-directional, half-duplex
Data format Baud rate: 1200, 2400, 4800, 9600 bps
Data: 7 bits + parity 1bit (even or odd) or 8 bits (non-parity)
Start bit: 1 bit
Stop bit: 1 bit
Code: ASCII
Terminator: CRLF (CR: 0Dh, LF: 0Ah)

This is a sample of the string generated:

S T , + 0 0 1 2 . 3 4 5 gCR LF

If I open excel or notepad, data is continuosly written to application.

This is a sample of how the data is outputted:
ST,+0012.345g
ST,+0012.345g
ST,+0012.345g
ST,+0012.345g
ST,+0012.345g
ST,+0012.345g

The data is outputted about every 100ms

If I open a terminal emulator such as putty and connect at with the same vaules I'm attempting to use with my code, I see the same output.

I'm using the example code found in the arduino library.


// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 9
#define txPin 8

// set up a new serial port
SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup()  {
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  Serial.begin(9600);
  mySerial.begin(2400);
}

void loop() 
{
 Serial.println("this is a test"); // making code is working
 Serial.println(mySerial.read());
 delay(100);
}

I removed the if(mySerial.available()); statement since there was no output, and it returns a -1, which I assume is telling me there is no data.

Note: I am using a straight through cable. I have also tried a null modem. The TTL converter supports both 3.3v and 5v.

My issue is mst likely due to my lack of uderstanding of how the serial function works, or serial communication in general. I have tried many different versions of this code such as using pins 2 and 3 for Rx and Tx, as well as other snippets I have found while researching my issue. After a few weeks, I thought I would see if someone much smarter than me could shed some light on things for me.

Thanks!

Here is something you may want to try as a test for both serial ports
Yes, I cannot spell avaiable, so sue me .

void loop()
{
delay(2000);                        // just pause and some verification for serial monitor 
  Serial.println(__FILE__);             // double check the x.ino file 
  Serial.println(__TIMESTAMP__); // time of compile 

 Serial.println("this is a test"); // making code is working - prints to serial monitor right?

// now test "manual " input to Serial 

 while(!Serial.available());      // wait for your input  FROM serial monitor "window"
 
//input some text in serial monitor and push Enter -example "Hello"  Enter 

 while(Serial.avaiable())
{
 Serial.println(Serial.read());   // this will echo your entry - read the serial buffer, format is immaterial , just looking for response    
} 

Now ready to do same for your other input , assuming it outputs the data you indicated 

while(1)                                // just an infinite data read  test loop 
{                                          
while(!mySerial.available());      // wait for input  FROM mySerial - should be quick 
 while(mySerial.available())
{
 Serial.println(mySerial.read());   // this will echo your data  to serial monitor again
// again the format is immaterial , just looking for response for now   
} 
}                                         // keep reading the mySerial port 



 Serial.println(mySerial.read());
 delay(100);
}

Try using the second example in Serial Input Basics

You just need to change it so that it reads from your SoftwareSerial instance. As written it takes input from the Serial Monitor.

...R

Excellent. I will give both a try once I get back to my workstation.

Thanks!

Robin2:
Try using the second example in Serial Input Basics

You just need to change it so that it reads from your SoftwareSerial instance. As written it takes input from the Serial Monitor.

...R

Robin2:
Try using the second example in Serial Input Basics

You just need to change it so that it reads from your SoftwareSerial instance. As written it takes input from the Serial Monitor.

...R

R
just read your tutorial sample code # 2.

I am not sure why such simple task is so convoluted.
You apparently have no clue how "available" method works.
Otherwise your code would not need all that superfluous checking for "marker".

I won't touch your "binary" code "samples".

From this encounter and judging from many others of your posts I would suggest you brush-up on serial communication protocol ( start / stop bits , data bits , parity etc.) and how it is formatted and transmitted / used in Arduino ( software and hardware).
Or just continue as usual.

Well I've tried both suggestions. Neither seem to be able to read the device.

I tried this code:

#include <SoftwareSerial.h>

#define rxPin 8
#define txPin 9

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

const byte numChars = 32;
char receivedChars[numChars];	// an array to store the received data

boolean newData = false;

void setup() {
        pinMode(rxPin, INPUT);
        pinMode(txPin, OUTPUT);
	Serial.begin(9600);
        mySerial.begin(2400);
	Serial.println("<Arduino is ready>");
}

void loop() {
Serial.println("<Start Loop>");
delay(100);
	recvWithEndMarker();
	showNewData();
}

void recvWithEndMarker() {
	static byte ndx = 0;
	char endMarker = '\n';
	char rc;
	
	// if (mySerial.available() > 0) {
           while (mySerial.available() > 0 && newData == false) {
		rc = mySerial.read();

		if (rc != endMarker) {
			receivedChars[ndx] = rc;
			ndx++;
			if (ndx >= numChars) {
				ndx = numChars - 1;
			}
		}
		else {
			receivedChars[ndx] = '\0'; // terminate the string
			ndx = 0;
			newData = true;
		}
	}
}

void showNewData() {
	if (newData == true) {
		Serial.print("This just in ... ");
		Serial.println(receivedChars);
		newData = false;
	}
}

And this code:

#include <SoftwareSerial.h>

#define rxPin 8
#define txPin 9

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

void setup() {
        pinMode(rxPin, INPUT);
        pinMode(txPin, OUTPUT);
	Serial.begin(9600);
        mySerial.begin(2400);
	Serial.println("<Arduino is ready>");
}



void loop()
{
delay(2000);                        // just pause and some verification for serial monitor
  Serial.println(__FILE__);             // double check the x.ino file
  Serial.println(__TIMESTAMP__); // time of compile

 Serial.println("this is a test"); // making code is working - prints to serial monitor right?

// now test "manual " input to Serial

 while(!Serial.available());      // wait for your input  FROM serial monitor "window"
 
//input some text in serial monitor and push Enter -example "Hello"  Enter

 //while(Serial.avaiable())
{
 Serial.println(Serial.read());   // this will echo your entry - read the serial buffer, format is immaterial , just looking for response   
}

//Now ready to do same for your other input , assuming it outputs the data you indicated

while(1)                                // just an infinite data read  test loop
{                                         
while(!mySerial.available());      // wait for input  FROM mySerial - should be quick
 while(mySerial.available())
{
 Serial.println(mySerial.read());   // this will echo your data  to serial monitor again
// again the format is immaterial , just looking for response for now   
}
}                                         // keep reading the mySerial port



 Serial.println(mySerial.read());
 delay(100);
}

I know my device sending the data works, as I can read the data with a PC. I've tried multiple serial cables, multiple TTL converters, and multiple Arduino's with the same result. :confused:

Is there something else I'm missing in the code?

Is there something else I'm missing in the code?

Are your rs232 to TTL inverters working as expected? You should be able to connect the TTL tx/rx together on the converters in a loop back fashion to test with a pc terminal program. Is your serial device out putting at the same baud rate as the arduino is receiving? Try connecting the serial converter tx to the arduino tx, and connect the arduino and converter grounds together. Then open the serial monitor and see if anything is being received by the serial monitor.

zoomkat:
Are your rs232 to TTL inverters working as expected? You should be able to connect the TTL tx/rx together on the converters in a loop back fashion to test with a pc terminal program. Is your serial device out putting at the same baud rate as the arduino is receiving? Try connecting the serial converter tx to the arduino tx, and connect the arduino and converter grounds together. Then open the serial monitor and see if anything is being received by the serial monitor.

I think I understand what you suggest. When I connect to the hardware Rx/Tx (pins 1 and 0), I see the same data that I saw in the serial monitor as I did before, however, there are Tx and Rx lights on the TTL converter that now illuminate and sync when connected to those pins.

The serial device is outputting at 2400 and I have the Softwareserial setting at 2400 in the code.

I see that you are powering the unit from 3.3V. But the I/O pins on the Arduino are 5V. That could be a problem.

aarg:
I see that you are powering the unit from 3.3V. But the I/O pins on the Arduino are 5V. That could be a problem.

I didn't mention how it it was powered, nor did I depict it in the diagram (which I should have done).

Although the R3 is plugged into the USB port for 3.3v power, it is also connected to a 5v external power supply.

Referring to Reply #5 ...

I would expect the first piece of code you posted to work properly (the code using the function recvWithEndMarker() ).

What does it actually do?

Is there any chance that you have the Tx and Rx connections back to front ?
I presume you have a GND connection as well as Rx and Tx ?

...R

Robin2:
Referring to Reply #5 ...

I would expect the first piece of code you posted to work properly (the code using the function recvWithEndMarker() ).

What does it actually do?

Is there any chance that you have the Tx and Rx connections back to front ?
I presume you have a GND connection as well as Rx and Tx ?

...R

Yes, ground is connected as well. I tried reversing the Rx and Tx just to make sure, but I get the same result.

I used the code you suggested, but modified it for the Softwareserial, and tried it on different pins

#include <SoftwareSerial.h>

#define rxPin 10
#define txPin 11

SoftwareSerial mySerial = SoftwareSerial(rxPin, txPin);

const byte numChars = 32;
char receivedChars[numChars];	// an array to store the received data

boolean newData = false;

void setup() {
        pinMode(rxPin, INPUT);
        pinMode(txPin, OUTPUT);
	Serial.begin(9600);
        mySerial.begin(9600);
	Serial.println("<Arduino is ready>");
}

void loop() {
Serial.println("<Start Loop>");
delay(100);
	recvWithEndMarker();
	showNewData();
}

void recvWithEndMarker() {
	static byte ndx = 0;
	char endMarker = '\n';
	char rc;
	
	// if (mySerial.available() > 0) {
           while (mySerial.available() > 0 && newData == false) {
		rc = mySerial.read();

		if (rc != endMarker) {
			receivedChars[ndx] = rc;
			ndx++;
			if (ndx >= numChars) {
				ndx = numChars - 1;
			}
		}
		else {
			receivedChars[ndx] = '\0'; // terminate the string
			ndx = 0;
			newData = true;
		}
	}
}

void showNewData() {
	if (newData == true) {
		Serial.print("This just in ... ");
		Serial.println(receivedChars);
		newData = false;
	}
}

When I run this code and open the serial monitor, I see , then repeatedly.

I think the code is just skipping everything else since the condition of mySerial.available returns with a -1.

My first thought, as stated before is that the RX/TX are backwards. (ETA: Your ARduino is a DTE, while the computer is a DTE, so you need to swap the RX ands TX on the device side, not the ARduino side) But, could the PC be setting/honoring things like the DTR and CTS pins telling the unit to send data?

shakezoola:
I think I understand what you suggest. When I connect to the hardware Rx/Tx (pins 1 and 0), I see the same data that I saw in the serial monitor as I did before, however, there are Tx and Rx lights on the TTL converter that now illuminate and sync when connected to those pins.

The serial device is outputting at 2400 and I have the Softwareserial setting at 2400 in the code.

...and the yellow RX LED on Uno was flashing too, right?
The LED is connected to an external processor - UART function - and flashing indicates the data is being processed by the external processor, NOT Uno.

Now it works on hardware serial and not on software serial - so where is the "problem"?
The baud rate in not the ONLY parameter for serial communication.
How about just reading RX as incoming bit stream and NOT as serial data?

Vaclav:
...and the yellow RX LED on Uno was flashing too, right?
The LED is connected to an external processor - UART function - and flashing indicates the data is being processed by the external processor, NOT Uno.

Now it works on hardware serial and not on software serial - so where is the "problem"?
The baud rate in not the ONLY parameter for serial communication.
How about just reading RX as incoming bit stream and NOT as serial data?

When I connect to the hardware pins, the light on the TTL device lights up, but that's about the only change. It's not reading from the Serial device. I still only see data written to the serial monitor that comes from the serial.println command. Still no data from the serial device.

shakezoola:
When I connect to the hardware pins, the light on the TTL device lights up, but that's about the only change. It's not reading from the Serial device. I still only see data written to the serial monitor that comes from the serial.println command. Still no data from the serial device.
[/quote
I still only see data written to the serial monitor that comes from the serial.println command. Still no data from the serial device.

...and the TX/RX LED's on Uno follow the data stream ... ( you did not answer that )

So the serial protocol - baud rate , start / stop parity etc does not match the data protocol from your device and /or the signal level expected by Uno ( 0 - +5V) is incorrect and / or you are missing (common) ground reference.
( or the pinMode is incorrect ??)

shakezoola:
Yes, ground is connected as well. I tried reversing the Rx and Tx just to make sure, but I get the same result.

I used the code you suggested, but modified it for the Softwareserial, and tried it on different pins

Add these two lines so you can see if anything is being received

          while (mySerial.available() > 0 && newData == false) {
 rc = mySerial.read();
 Serial,print("RC ");              // <========New
 Serial.println(rc);                 // <========New

...R

shakezoola:
Yes, ground is connected as well. I tried reversing the Rx and Tx just to make sure, but I get the same result.

We need to be very careful with nomenclature here because there are two RX and TX's.

Which did you switch? between the arduino and the RS232 board or the RS232 board and the device? If it is a DCE/DTE problem it is the ones from the device to the RS232 board that matter.

Vaclav:
...and the TX/RX LED's on Uno follow the data stream ... ( you did not answer that )

So the serial protocol - baud rate , start / stop parity etc does not match the data protocol from your device and /or the signal level expected by Uno ( 0 - +5V) is incorrect and / or you are missing (common) ground reference.
( or the pinMode is incorrect ??)

The protocol on the device is set to match the Arduino default 8N1, and matches the baud rate set when the software serial is defined.

I provided a diagram in my first post of how the TTL is connected to the Arduino. 2 wires for Rx/Tx, one for ground, and another for VCC. The Arduino is also connected to external 5v power. As far as I know, the Tx/Rx wires follow the data stream. I also reversed them to make sure I did not have them backward. Currently, I am using a straight through serial cable, but I have tried a null modem cable to see if reversing the connection before it hit the TTL would work, It did not.

As for pinMode, the Rx pin is set to input, and the Tx pin is set for output.

Should only the 4 connections be necessary? Tx, Rx, VCC, and Ground? Is CTS and RTS not used?

KeithRB:
We need to be very careful with nomenclature here because there are two RX and TX's.

Which did you switch? between the arduino and the RS232 board or the RS232 board and the device? If it is a DCE/DTE problem it is the ones from the device to the RS232 board that matter.

Understood. I reversed the Tx/Rx from the Arduino to the RS232 board. I can reverse them between the device and RS232 board with a Null Modem cable, correct? if so, I have tried that, but I may give it another try. With all of the different pieces of code I have tried, and all of the the different configurations, I may have missed something.