How to capture ascii character input from serial TX/RX [SOLVED]

In advance… thanks in advance.

I’m having trouble getting started with an Atlas Scientific Dissolved Oxygen sensor. Hoping for some coding startup help on this. I think my problem is figuring out how to properly address and initialize the TX from the sensor to the photon redboard. Documentation says Serial1 class is for use on D0 and D1. I think I’m not using it correctly.

Here are the specs that (I think) are relevant.
Sensor: UART mode, 9600 bps 8 bit no parity 1 stop bit. Output is string type
Connected to Photon Redboard. RX --> D0, TX --> D1

Note that I don’t have the sensor in my lab. It is in another lab 1500 miles away, and I’m remotely flashing it, so I don’t have direct serial connection (will get a local one soon)

Here is the error I get. It suggest to me that the code never gets into the second section to publish the variable. Probably Serial1.available is never true. Help?
{
“ok”: false,
“error”: “Variable not found”
}

Here is the code I’m using (though I’m fiddling around with it a lot).

String DOReading = "";
bool sensor_string_complete = false;
char incomingChar = 'A';

void setup() 
{
  pinMode(D0, OUTPUT); // Initialize D0 pin as output, photon communicating to sensor RX
  pinMode(D1, INPUT);  // Initialize D1 pin as input, sensor tx pin com to photon
  Serial1.begin(9600,SERIAL_8N1); // open serial port, set data rate to 9600 bps, 8 bits no parity 1 stop bit (8N1)
  DOReading.reserve(30);
}

void loop() {
  if (Serial1.available() > 0) {
    incomingChar = (char)Serial1.read();        // read next available byte, cast to char
    DOReading += incomingChar;                  //append to string
    if (incomingChar == '\r'){
        sensor_string_complete = true;
    }
  }

  if (sensor_string_complete== true) {
   Particle.variable("do_sensor", DOReading);
   sensor_string_complete = false;
   delay(60000);  // wait a minute before doing another reading
  }
}

For Serial1, you should be using the pins marked TX and RX. They’re in the position where Arduino D1 and D0 would be, next to D2.

The pins that are actually marked ~SCL/D1 and ~SDA/D0 are for I2C, not serial. You should not use those.

Also, you don’t need the pinMode D0/D1 calls, because from the point of view of Photon code, you’re actually using TX/RX, the hardware Serial1 port.

HA! SCORE!!! I love it when the answer is easy. Of course… must try it now. Stand by and thanks a bunch.

This is not the way you use Particle.variable().
You only register them once in setup() and after that only work on the this way exposed variable (DOReading).

You might also consider reading more than one byte per iteration of loop()
e.g. like this

  ...
  for( incomingChar = '\0'; Serial1.available() &&  incomingChar != '\r'; )
  {
    incomingChar = (char)Serial1.read();        // read next available byte, cast to char
    DOReading += incomingChar;                  //append to string
  }
  ...

And do you not need to trigger a fresh reading via Serial1.print() of some sort?
Or if you get a continous stream, you'd need to flush partly received data, wait for a start indicator (e.g. '\r' of a previous transmission) and only after that you can actually expect valid data.

2 Likes

@cestamper, since Serial is part of the Stream class, you can also use the readStringUntil() function:

sensorstring = Serial1.readStringUntil('\r');  // where sensorstring is declared as global String

:smile:

2 Likes

Thanks so much for the info about how to use Particle.variable, how to use rx/tx, how to simplify the serial string reading. Got it working after more fiddling. All we wanted initially was to be able to get readings from sensor. We succeeded.

SOLUTION!
Wiring: (using Sparkfun Photon RedBoard)

  1. Make sure power is properly run to sensor.
  2. Sensor TX to Photon Redboard RX
  3. Sensor RX to Photon Redboard TX
  4. Read instructions in sensor doc from Atlas Scientific, do things like remove protective cap from sensor, etc
  5. I did not do any configs on sensor, have not SENT it any commands. It’s in completely default settings.

Code. This would be good example code for anybody using the Atlas Scientific Dissolved Oxygen Sensor. There’s not much in the way of comments. Note that Serial1 class is already configured to use the RX/TX pins as described in wiring note above.

String sensorstring = "initial";

void setup() {
  Serial1.begin(9600); // open serial port 
  sensorstring.reserve(30);
  Particle.variable("sensorstring", sensorstring);
}

void loop() {
   sensorstring = Serial1.readStringUntil('\r');
   delay(10000); // leave sensorstring up for 10 secs
   sensorstring="inbetween readings, next reading in 2 secs";
   delay(2000); // just to verify code is running
}

How to see the variable value (if you read first post, I do not have the device in MY lab, it’s halfway across country).

  1. URL (note that I took out my DEVICE_ID and TOKEN specifics, put in your own. You will not get anything using this URL as it shows here)

https://api.particle.io/v1/devices/DEVICE_ID/sensorstring?access_token=TOKEN

  1. Typical output. Sensor is currently sitting in a bottle of tap water. The “result” is the value of sensorstring variable. Had been coming up empty as “”, now that it’s all working, we get numbers between 3 and 5. Yippee
{
  "cmd": "VarReturn",
  "name": "sensorstring",
  "result": "3.35",
  "coreInfo": {
    "last_app": "",
    "last_heard": "2016-06-21T19:43:26.911Z",
    "connected": true,
    "last_handshake_at": "2016-06-21T19:25:13.022Z",
    "deviceID": "29003a001247343431373336",
    "product_id": 8
  }
}
3 Likes