Pages: [1] 2 3   Go Down
Author Topic: Serial read from sensor  (Read 3983 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,  Sorry, this is a very basic question.  I am trying to pickup 10 ASCII characters being output from a sensor but not making much progress!!!  I have plugged the sensor TTL TXD into Arduino RX pin and using simple Serial.read() to try and get the string of 10 bytes output at 9600 and Serial.println to output - I guess my code is way off - what would be the best way to do this?
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Post your code (use the "#" button above) and we can give you some help.
Logged

.andy

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks Andy,

Here is one try :

Code:
void setup()
{  
  Serial.begin(9600);
}

void loop()
{  
  int data = Serial.read();
  Serial.println(data);
  delay (1000);
}

And another using SoftwareSerial:


Code:
#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4

SoftwareSerial softSerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
  
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  softSerial.begin(9600);

  Serial.begin(9600);
}

void loop() {
  
  int data = softSerial.read();
  Serial.println(data);
  
  delay (1000);
}
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 299
Posts: 26196
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Does it print anything?
Just the first character?
That one second delay in the loop isn't going to help in the soft serial case.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

The output looks like below - I guess I need to somehow group these bytes into 10 and convert to ASSCI?

-1
161
255
49
33
213
49
33
213
49
233
244
49
233
244
49
161
244
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 299
Posts: 26196
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, 49 is "1", and 33 is "!".
Do you have any idea what the sensor is supposed to produce?
Help us to help you!

The higher numbers (>128) could be ASCII with parity (eg 161 = 0xA1, minus 0x80 = 0x21 = "!"), or you could have a speed mismatch.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Copenhagen / Denmark
Offline Offline
Edison Member
*
Karma: 6
Posts: 2360
Do it !
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can just wait with the reading until enough bytes are in the buffer.

use something like:

if (serial.available >= 10) {

read the 10 bytes

}
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The output looks like below - I guess I need to somehow group these bytes into 10 and convert to ASSCI?
As AWOL said, you are probably seeing the ASCII values of the characters the program is receiving in your output. Each character is represented internally as a decimal number. See this chart for the numeric codes of each letter.

But, to force Serial.println () to output the letter instead of the ASCII code for the character, you can just say:

Code:
Serial.println(data, BYTE);
And if you use Serial.print () instead of Serial.println (), they will all appear on the same output line. Of course, at some point, you have to issue a Serial.println () call, otherwise the output will go way off the right side of the window.

And, as MikMo said, instead of putting an arbitrary delay in your program to try to wait for new characters to come along, you should check to see when one is ready to be read. Use Serial.available () for that.

There are examples of all of this on the Arduino site. Try here.
« Last Edit: October 28, 2009, 08:59:34 am by ahdavidson » Logged

.andy

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the help folks - the codes don't infact resemble the desired ASCII output !!!

If I take out the ATMEGA328 chip - connect the sensor to pin 1 (TX) - open the serial port at BAUD 38400 - I can see the expected data delivered every 3 seconds as documented - this is the format:

  857 ppm
  853 ppm
  850 ppm
  851 ppm
  850 ppm

I have no idea how to access this data via C however - I understand the suggestions made and have tried them - the only one I'm not sure about is how to ask for 10bytes and then print them out in the correct format?  I guess the 10 byte output for 857 ppm in decimal would be:
32 56 53 55 32 112 112 109 13 10 (last two being carriage return and linefeed) - this is nothing like the output I'm getting?
Logged

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's hard to diagnose what might be going on from the limited picture you've given us. But your translation of the expected data from byte to decimal looks right.

If you are not receiving what you expect, I would suggest a simple test program to track down what you are getting. Then you can figure out how to read it properly in your real application.

If you have an Arduino Mega, by some chance, which has more than one serial connection easily used by the Serial library, you could connect your sensor to one of them and use the Arduino IDE serial window on another. Then use a very simple Arduino program that loops like this pseudo-code:

loop:
  wait for byte on input serial port to be available
  read byte from input serial port
  write byte back to output serial port


This should simply echo back to the serial window whatever you are receiving from the sensor.

If you only have an Arduino 2009 with one real serial port, then perhaps you can use the software serial library for the input and the regular USB channel to your computer for the output to the serial monitor window.

Make sense?

You need a narrower test case to ferret out what is going on, I think.
Logged

.andy

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Andy,

Thanks for your reply.  Part of the problem is that I am very new to Arduino/MCU's - I'm kinda feeling my way slowly :-)

I am using a Duemilanove which I guess has just one real serial port which I was hoping to use but it sounds like a software serial is required for this board?

I'm rubbish at coding a the mo - learning slowly.  Would you be up for showing me, based on the code below, how to ask for 10 bytes and then printing them to a serial window?  Any help is appreciated as I have been on this for days now - failed to get I2C working and now failing at serial too !

Code:
#include <SoftwareSerial.h>

#define rxPin 3
#define txPin 4

SoftwareSerial softSerial =  SoftwareSerial(rxPin, txPin);

void setup()  {

  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  softSerial.begin(9600);

  Serial.begin(9600);
}

void loop() {

  int data = softSerial.read();
  Serial.println(data);

}
 
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
- open the serial port at BAUD 38400

Code:
softSerial.begin(9600);

Well, could just be...

Bad news is, I don't think softserial will manage 38400.
Logged

Per Arduino ad Astra

Seattle, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 248
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, first let's be clear about what you are trying to do.

You have a sensor that sends serial data that you would like to read on the Arduino, and then do something with that data on the Arduino, right?

Do you have a link to a datasheet for the sensor?

Now, you want to keep the standard serial port on the Duemilanove separate from your sensor. The standard serial port (digital pins 0 & 1) is used to a) upload your sketch to the Arduino and b) allow serial port traffic to/from the Arduino IDE serial monitor window. b) is invaluable and necessary for debugging.

So that means you need a different set of pins for your sensor input. If that sensor emits serial data, you need to use SoftwareSerial on pins other than 0 & 1 for receiving that data on the Arduino.

Right so far?
Logged

.andy

UK
Offline Offline
Sr. Member
****
Karma: 1
Posts: 278
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmmm, you could be right - I looked at this too: http://arduiniana.org/libraries/NewSoftSerial/ max BAUD being 28800 - does it have to be exactly the same to work?

The data sheet say this:

UART
38400bps, 8bit, No parity, 1 stop bit
TTL Level Voltage 3.0~4.5V
Logged

UK
Offline Offline
Faraday Member
**
Karma: 17
Posts: 2884
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
does it have to be exactly the same to work?
Absolutely!

 28800 / 38400 = 75%

AWOL spotted it in reply #5
« Last Edit: October 28, 2009, 04:32:48 pm by GrooveFlotilla » Logged

Per Arduino ad Astra

Pages: [1] 2 3   Go Up
Jump to: