SoftwareSerial with a CO2 Sensor (translating R.Pi Code to Arduino)

Hello,

Context
I am running into what I imagine is a fairly straightforward SoftwareSerial issue, but have so far been unsuccessful in resolving. I have a CO2 sensor (instructions sheet attached) that has a simple RX/TX connection. The example the supplier provided was for R.Pi, but translating to Arduino doesn't seem too hefty of a task (R.Pi and Arduino translation we made posted below). However, when we run this script, we have been running into the following list of errors:

avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_ReceiveMessage(): timeout
avrdude: stk500v2_getsync(): timeout communicating with programmer

In my attempts to troubleshoot, I've tried sending/receiving simple messages ("hello world") via RX/TX with the Arduino hooked up to itself (pin 0 --> pin 1). This resulted in the same error. To isolate the problem, I pulled up the SoftwareSerialExample and TwoPortReceive examples. While I no longer ran into the errors, I was not seeing the apparent messages that should be relayed to Serial.print (I was sifting through the appropriate Baud rates; only getting a static set of "?????"). I also noticed that I had a growing list of "COM3", which I couldn't clear, and temporarily resolved by just restarting my computer.

Ultimately, the plan is to have two of these sensors hooked up to the Arduino (MEGA). I mention that now in case that significantly affects how we move forward, but otherwise that seems like something we can address later. So, in summary...

The Ask
I'd greatly appreciate help with:
1). Identifying what we are doing wrong with our Serial Port management.
2). Checking over our translation of the R.Pi script to Arduino (below).

Raspberry Pi

#rpi serial connections
#Python app to run a S8 Sensor
import serial
import time

# RPi pin connextions:
#pin 6	GND
#pin 4	5v
#pin 8	TXD:  UART data to S8
#pin 10  RXD: UART data from S8

ser = serial.Serial("/dev/ttyS0",baudrate =9600,timeout = .5)
print "  AN-168: Raspberry Pi3 to S8 Via UART\n"
ser.flushInput()
time.sleep(1)


for i in range(1,21): # Print 20 readings from sensor
	
    
    ser.flushInput()
    ser.write("\xFE\x44\x00\x08\x02\x9F\x25")
    time.sleep(1.9)
    resp = ser.read(7)
    high = ord(resp[3])
    low = ord(resp[4])
    co2 = (high*256) + low
    print " CO2 = " +str(co2)
    time.sleep(.1)

Arduino

#include <SoftwareSerial.h>

#define rxPin1 0
#define txPin1 1

SoftwareSerial co21Ser(rxPin1, txPin1);

int co2;
char resp = '0';

void setup() {
  pinMode(rxPin1, INPUT);
  pinMode(txPin1, OUTPUT);
  Serial.begin(9600);
  co21Ser.begin(9600);
}

void loop() {
  if (co21Ser.available()){
    co21Ser.write("\xFE\x44\x00\x08\x02\x9F\x25");
    delay(1900)
    resp = co21Ser.read();
    Serial.print("resp = ");
    Serial.println(resp);
    int high = atoi(resp[3]);
    int low = atoi(resp[4]);
    co2 = (high*256) + low;
    Serial.print("CO2 = ");
    Serial.println(co2);
  }
  else{
    Serial.println("Nothing...");
  }
  delay(100);
}

Thank you.

All the best,
m3yre

CO2Meter_CO2Circuit_Instructions.pdf (423 KB)

Try using pins 2 and 3 for receive and transmit.

It will not work, you need to get past setup first. The following is your setup:
#define rxPin1 0 <-- Pin REserved for the debug terminal, not for typical application
#define txPin1 1 <-- Pin REserved for the debug terminal, not for typical application
SoftwareSerial co21Ser(rxPin1, txPin1); <--- Same Problem
pinMode(rxPin1, INPUT); <--- Same Problem
pinMode(txPin1, OUTPUT); <--- Same Problem
My suggestion is to slow down a bit, go on line and research each of the items you are trying to use. Get a copy of the Arduino Cookbook and read it, most of what you want to do is already there. Get a beginners book on electronics, This will help a lot with the terms etc. YouTube has tons of videos that will explain what is going on complete with examples. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

Thought I posted a reply here, looks like I didn't post it, my apologies for the delay:
I appreciate the "Arduino Cookbook" recommendation, this looks like a great read and reference for future troubleshooting! That said (and I'm sure you've heard this many times before), we are on a bit of a time crunch. Some assistance through this particular problem would be really appreciated as we build up our knowledge for future projects. If we can determine that the problem is beyond how we're using UART or SoftwareSerial, that will help us greatly with further troubleshooting.

From what you've mentioned, and some tutorials I've gone through since, this is what I've gleaned:
Pins 0 and 1 should not be used as the Arduino essentially uses these pins to communicate with the computer. Thus, we should either use the other UART pins on the MEGA, or use SoftwareSerial with certain compatible pins (10, 11, 12, 13, 50, 51... for the MEGA).

It looks like to use the additional UART pins on the MEGA, you simply call out "Serial#.____". That is, in using pints 18 and 19 for TX1 and RX1, respectively, we call out "Serial1._____". With the appropriate "while (Serial1.available() == 0)" we stay stuck in that loop, indicating that we aren't getting data via Serial1.

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop() {
  while (Serial1.available() == 0){
    Serial.println("Nothing");
  }
  Serial1.write("\xFE\x44\x00\x08\x02\x9F\x25");
  delay(1900);
  resp = Serial1.read();
  Serial.print("resp = ");
  Serial.println(resp);
  delay(100);
}

Does everything so far seem properly done? As mentioned in the first paragraph, if we can determine that this portion of our code is not correct, we can dive further into troubleshooting the sensor.

Thank you again for your time and assistance.

Best,
m3yre

mikb55, moving to pins 2 and 3 (or 10 and 11) unfortunately didn't work.

The sensor only sends data after your Arduino sends a request.

Currently it gets stuck in the while (Serial1.available() == 0) loop checking for a response that will never come because you haven't sent a request.