Pull one value from a data stream

Hi,

I have a question about coding. how is it possible to pull a single data value from a stream of data? I have a pressure transducer that is set to continuously output pressure readings at a frequency of 10Hz. I can successfully the data stream with my Arduino Pro Micro, but I lack the ability to read a single value and store it as a char variable. Here is the code I am using.
Below is an image of the data stream from the pressure transducer, read through the Arduino. How can I pull just one of those values like *000114.4929 out?

#include <SoftwareSerial.h>
#define pressureRX 8
#define pressureTX 9

SoftwareSerial pressureSerial(pressureRX, pressureTX);

void setup(){
  Serial.begin(9600);   //with computer
  pressureSerial.begin(9600);     //with pressure transducer
}

void loop(){
  char data = "";
  while(pressureSerial.available()){
    data = pressureSerial.read();
    Serial.write(data);
  }
}

I have a question about coding. how is it possible to pull a single data value from a stream of data?

How would you pick a single fish out of a stream? You’d have to detect when its snout passed by, and when its tail passed by, so you’d know when to collect fish, without collecting water.

  char data = "";

You can NOT store a string in a char.

Single quotes are for single characters. Double quotes are for strings.

Your “fish” obviously has a snout (’*’) and a tail ( or or both), so:

will make interesting reading.

Image from Original Post so we don't have to download it. See this Simple Image Guide

[|500x281/url]

...R](http://forum.arduino.cc/index.php?action=dlattach;topic=547755.0;attach=257948;image)

Please don't post pictures of text - as you can see it is unreadable. Just copy and paste the text.

Have a look at the 3rd example in Serial Input Basics. Try changing the start- and end-markers to '*' and '?'

...R

Thank you all for your help. I will take a look at the Serial Input Basics page.

If those are float values, you need 4 bytes each.

If they are text you have to read each byte and convert to float.

Hi again,

I want to say thanks again for the help. Robin2, your page Serial Input Basics was very helpful for me. I was able to get the Arduino to read the sensor data and store each in an array, then print them out to the Serial Monitor. I followed your example with the start and end markers. Now I am getting output like this:

000114.2927
000114.2928
000114.2926

And this is the code I am using:

#include <SoftwareSerial.h>
#define paroRX 8
#define paroTX 9

SoftwareSerial paroSerial(paroRX, paroTX);

const byte numChars = 16;
char paroChars[numChars];     //array to store received data
char paroToSend[numChars];      //array to transmit
boolean newParoData = false;

void setup(){
  Serial.begin(9600);     //with transmitter radio
  paroSerial.begin(9600);
}

void loop(){
  paroSerial.listen();
  readParo();      //read from Paro and store values in paroChars
  if(newParoData == true){
    for(int i=0; i<16; i++){
      paroToSend[i] = paroChars[i];
    }
    Serial.print(paroToSend); Serial.print('\n');     //transmit Paro data with a new line for each value
    newParoData = false;
  }
}

void readParo(){
  static boolean receiveInProgress = false;
  static byte index = 0;
  char startMarker = '*';
  char endMarker = '\n';
  char pd;
  while(paroSerial.available() && newParoData == false){
    pd = paroSerial.read();
    if(receiveInProgress == true){
      if(pd != endMarker){
        paroChars[index] = pd;
        index++;
        if(index >= numChars){
          index = numChars - 1;
        }
      }else{
        paroChars[index] = '\0';      //terminate string
        receiveInProgress = false;
        index = 0;
        newParoData = true;
      }
    }else if(pd == startMarker){
      receiveInProgress = true;
    }
  }
}

I have another related question. The sensor is programmed to continuously output data at a frequency of 10Hz. With my code, the Arduino seems also to read and print at 10Hz. How can I read and print a data value just once every second? The obvious choice to me was to put a delay in the loop, but after trying delay(1000) and using the millis() function, I get distorted readings. Although they do print at 1Hz to the Serial Monitor.

#include <SoftwareSerial.h>
#define paroRX 8
#define paroTX 9

SoftwareSerial paroSerial(paroRX, paroTX);

const byte numChars = 16;
char paroChars[numChars];     //array to store received data
char paroToSend[numChars];      //array to transmit
boolean newParoData = false;

void setup(){
  Serial.begin(9600);     //with transmitter radio
  paroSerial.begin(9600);
}

void loop(){
  paroSerial.listen();
  readParo();      //read from Paro and store values in paroChars
  if(newParoData == true){
    for(int i=0; i<16; i++){
      paroToSend[i] = paroChars[i];
    }
    Serial.print(paroToSend); Serial.print('\n');     //transmit Paro data with a new line for each value
    newParoData = false;
  }
   delay(1000);
}

void readParo(){
  static boolean receiveInProgress = false;
  static byte index = 0;
  char startMarker = '*';
  char endMarker = '\n';
  char pd;
  while(paroSerial.available() && newParoData == false){
    pd = paroSerial.read();
    if(receiveInProgress == true){
      if(pd != endMarker){
        paroChars[index] = pd;
        index++;
        if(index >= numChars){
          index = numChars - 1;
        }
      }else{
        paroChars[index] = '\0';      //terminate string
        receiveInProgress = false;
        index = 0;
        newParoData = true;
      }
    }else if(pd == startMarker){
      receiveInProgress = true;
    }
  }
}

With this code, I get this kind of output on the Serial Monitor:

000114.4927
***000114.4948
***000114
4947
*000114

What is my problem here? How can I read at a specified frequency of 1Hz when I have a continuous stream of data?

You need to create another function to display the data and only have that run at the intervals you want. Something like

void loop() {
  // other stuff
  showData();
}

void showData() {
   if (millis() - lastPrintMillis >= 1000) {
        lastPrintMillis += 1000;
        // code to display data
   }
}

You most certainly should NOT use delay() as that stops everything until the delay period is over.

...R

If the device outputs 10 values per second, and you only want to display/deal with every 10th value, it doesn't seem overly complicated to determine if this value is the 10th value, and so should be used (and the counter reset), or not.

bz26: What is my problem here? How can I read at a specified frequency of 1Hz when I have a continuous stream of data?

Read 10 times but either only use one of those or average the 10 but read to clear what gets sent.