Software Serial Program

Hi guys!

I have a gas sensor with 5 pins (GND,VCC,VIN,TXD,RXD). My UNO board is connected using USB cable and external 9V power adaptor. I'm trying to run a software serial program and in the serial monitor if I change the baud rate to 9600, my serial monitor response is random characters .
Any reason why it happening?
Thank you.

SoftwareSerialExample.ino (1.35 KB)

Rishi_me:
How can I get the RX part working?

It's probably not relevant to your problem. The LEDs reflect hardware serial operations. The monitor baud rate must match whatever you set the Serial rate to.

Please provide a link to the gas sensor being used

I can see TX LED blinking on the Arduino but not RX.

Those LEDs are irrelevant when using SoftSerial. I assume that you have connected the sensor to the pins defined for the SS object and not the pins marked Rx and Tx on the board.

Rishi_me:
Hi guys!

I have a gas sensor with 5 pins (GND,VCC,VIN,TXD,RXD) and connected it to UNO board with USB cable

How could you connect it with a USB cable?

Make a drawing showing all the connections and post a photo of the drawing.

Also post a photo of the connected cable.

...R

Thanks for your information guys. My bad for telling you that sensor is connected using USB. It has been modified.

Please see the picture to get an idea of my connection in the attachment-1.

I wanted to check the communication between sensor and Arduino. Can you please suggest a better way to do that ?

Can you please tell me whether I can/can't connect the sensor with TxD and RxD directly to Pin 0 (Rx) and Pin 1 (Tx) on Arduino UNO to check the output?

SoftwareSerialExample.ino (1.35 KB)

I'm using Pin-10(Rx) and Pin-11(Tx) and I have used the sample Software Serial program, how do I know that the sensor is Sending or Receiving data? Do I need to tweak the code a bit?
Thank u

CO gas sensor- Pin Image.PNG

schematic. Please have a look

You layout looks kosher, something it would have smart to do in the first place.

At least the wiring is sensible, but there are no details about the sensor. The sensor is a serial output device but you need to be sure

  1. the output levels are OK for use with Arduino
  2. Arduino's voltage output is sufficient
  3. the baud rate matches Arduino

I imagine all if these will be apparent in the data sheet.

the sensor information has been attached. I am having trouble with the communication protocol in the data sheet especially commands section(pg.5). Stuck understanding the output.

I tried programming by comparing with another similar program. Sorry if the coding doesn't make any sense but I'm still learning. Your time and help much appreciated.

Thank u.
Serial Monitor response: Without Sensor connected

CO ppm = 4294967295
CO ppm = 4294967295

Serial Monitor response: With Sensor connected

CO ppm = 4294967295
CO ppm = 4294938112
CO ppm = 654
CO ppm = 4294936066
CO ppm = 4294967174
CO ppm = 4294961919
CO ppm = 235
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 4294938112
CO ppm = 654
CO ppm = 4294936066
CO ppm = 4294967174
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 0

ZE03 Electrochemical Module V2.4.pdf (472 KB)

sketch_jul19a.ino (1.77 KB)

Hi,

I had a look at the pdf you attached. Since you are currently getting getting probs with the serial COMs with your CO sensor why not try using the analog output of the sensor with one of the Analog inputs of the UNO and print it out to the serial monitor?

At least then you could establish if your sensor is working OK for starters...

Sorry just to confirm, the analog output you mean Pin 11 (Tx)?or Sensor Analog voltage pin VO? Can you please tell me how to achieve "using the analog output of the sensor with one of the Analog inputs of the UNO and print it out to the serial monitor?"

thank you.

It would appear that the device simply sends TTL serial signals every second @9600 baud. I think you just need to read that via software serial, analyse it, and send results to monitor.

The device is 5v but serial is 3v. Arduino should read it OK but, if you want to send signals to it, you should use a 1.2k/2k voltage divider on the Arduino Tx. You might not need to send commands anyway.

http://forum.arduino.cc/index.php?topic=396450.0

I have managed to check the analog voltage of the sensor (VO pin) using AnalogRead program and its 0.6 V mentioned in the data sheet.

At the moment I'm not worried about sending data to the sensor. I'm trying to figure how to use the expressions like:
FF 01 86 00 00 00 00 00 79- active upload

FF 86 00 00 00 00 00 00 7A (concentration value is 0)- receive

I used:

byte readCO[] = {0xFF, 0X86, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X7A}; //Command packet to read CO
byte response[] = {0,0,0,0,0,0,0, 0, 0};

Is this the correct way to approach reading ppm?

Nick_Pyner:
The device is 5v but serial is 3v. Arduino should read it OK but, if you want to send signals to it, you should use a 1.2k/2k voltage divider on the Arduino Tx. You might not need to send commands anyway.

Serial Input Basics - updated - Introductory Tutorials - Arduino Forum

I have gone through the link you posted and in the example- 2 there was a mention about "Receiving several characters from the Serial Monitor". If you can modify that code in terms of the above expressions in HEX form that would be great. Just few line of program will do
Thank u.

I'm afraid that is beyond me. I don't think you need to "modify the code", you just to break up the HEX received to the data you want, which is probably just a little bit of it. I guess this is one for Robin2.

since u got everything in an array, I guess what you want is a for loop to send you hex data using the software serial "write" function

then check for when the sensor reply back to pick up the 8 reply bytes using software serial "available" and "read" functions.

Should be easy enough for you to give it a try and code it in! :slight_smile:

sherzaad:
since u got everything in an array, I guess what you want is a for loop to send you hex data using the software serial "write" function

then check for when the sensor reply back to pick up the 8 reply bytes using software serial "available" and "read" functions.

I know it's too much to ask for. But can you please try and write for me those few lines of code? I don't have much programming experience but please correct me if I'm wrong

According to this code, I'm sending a request (byte packet) as you mentioned

void sendRequest(byte packet[])
{
while(!softSerial.available()) //keep sending request until we start to get a response
{
softSerial.write(readCO,9);
delay(50);
}

waiting until I get a response

int timeout=0; //set a timeoute counter
while(softSerial.available() < 10 ) //Wait to get a 9 byte response
{
timeout++;
if(timeout > 10) //if it takes to long there was probably an error
{
while(softSerial.available()) //flush whatever we have
softSerial.read();

break; //exit and try again
}
delay(50);
}

And if I have the response, then I'm reading the packets.

I think the code needs some tweaks and if you can change it that would be great.

In response to a PM from the OP (don't ya just love acronyms) I looked at the datasheet PDF.

It seems the default mode is that it sends a message every second. Also the messages contain bytes rather chars

So start with a program that prints every byte as it arrives in HEX (so as to be the match the datasheet)

Something like this

void loop() {
   if (mySerial.available) {
      byte inByte = mySerial.read();
      Serial.println(inByte, HEX);
   }
}

...R

But before trying that can you please tell me whether it's correct to declare or read bytes like this in the code?

byte readCO[] = {0xFF, 0X86, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X7A}; //Command packet to read CO
byte response[] = {0,0,0,0,0,0,0,0,0}; //create an array to store the response

#include <SoftwareSerial.h>

#define RxPin 10
#define TxPin 11

SoftwareSerial softSerial =  SoftwareSerial(RxPin, TxPin); //this is my virtual serial port

byte readCO[] = {0xFF, 0X86, 0X00, 0X08, 0X00, 0X00, 0X00, 0X00, 0X7A};  //Command packet to read CO
byte response[] = {0,0,0,0,0,0,0, 0, 0};  //create an array to store the response

int valMultiplier = 1;

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);
//}

void loop() 
{
  sendRequest(readCO);
  unsigned long valCO = getValue(response);
  Serial.print("CO ppm = ");
  Serial.println(valCO);
  delay(2000);
  
}

void sendRequest(byte packet[])
{
  while(!softSerial.available())  //keep sending request until we start to get a response
  {
    softSerial.write(readCO,9);
    delay(50);
  }
  
  int timeout=0;  //set a timeoute counter
  while(softSerial.available() < 10 ) //Wait to get a 9 byte response
  {
    timeout++;  
    if(timeout > 10)    //if it takes to long there was probably an error
      {
        while(softSerial.available())  //flush whatever we have
          softSerial.read();
          
          break;                        //exit and try again
      }
      delay(50);
  }
  
  for (int i=0; i < 8; i++)
  {
    response[i] = softSerial.read();
  }  
}

unsigned long getValue(byte packet[])
{
    int high = packet[2];                        //high byte for value is 4th byte in packet in the packet
    int low = packet[3];                         //low byte for value is 5th byte in the packet

  
    unsigned long val = high*256 + low;                //Combine high byte and low byte with this formula to get value
    return val* valMultiplier;
}

output:

CO ppm = 4294935296
CO ppm = 4294935552
CO ppm = 4294935552
CO ppm = 4294935552
CO ppm = 4294935552
CO ppm = 4294935552
CO ppm = 4294967295
CO ppm = 644
CO ppm = 4294936066
CO ppm = 4294967174
CO ppm = 4294964479
CO ppm = 244
CO ppm = 0
CO ppm = 0
CO ppm = 0
CO ppm = 4294935296
CO ppm = 644
CO ppm = 4294936066
CO ppm = 4294967174
CO ppm = 4294964479
CO ppm = 4294935552

Confused why I'm getting number like these?

I got the conversion part working but still can't figure out the expected output which should be in the range 0-1000 (decimal value).

My wild guess is that you are not using the correct elements of the response.

You have nothing in your program to detect the start byte nor to verify the data with the checksum.

Rather than try to go straight to the top spot on the podium, content yourself with finishing the race. Just print out the message values as I suggested in Reply #20 and let's see what is actually happening.

Another suggestion (for AFTER you have tried the previous one) is to modify the 2nd example in Serial Input Basics so that it receives bytes rather than chars and change the end marker to 0xFF. I know that is the value of the start marker but it should probably work - you will just miss the very first message.

...R