noob trying to store and save data from a sensor (help needed ASAP)

Hey all you lovely knowledgeable folk,

I need a code that logs and saves the data coming from a sensor I have connected to my arduino (a conductivity probe).

Info about the data:

The data comes as a string, and to the best of my limited knowledge cannot be converted to an integer

Reading it from the serial monitor MIGHT be a bit of a problem because it started outputing with a weird character in front of it... (I don't know why) after I added some code to send it to a program that would graph it in real time. this goes away if I mute the line that says " plot(Splot); "

I'm working with a pretty hectic deadline and would be incredibly grateful for help asap! :grinning:

I would prefer to save it to a computer (no an SD card) as our project has a budget that we have already surpassed).

Thanks!!

-Olive

#include <Servo.h>

#include <SoftwareSerial.h>                        // add the soft serial library
#define rxpin 2                                    // set the RX pin to pin 0
#define txpin 3                                    // set the TX pin to pin 

int N = 50;                                        // number of beads to dispense <----- DEFINE N HERE
int X = 5000;    // 500mL in 32 seconds (with container filled to 48 oz     // time which solenoid valve will be open for <----- DEFINE X HERE
int t = 1;                                         // time
int buffer[20];

Servo servo;
SoftwareSerial myserial(rxpin, txpin);             // enable the soft serial port

String Sstring = "";

String inputstring = "";                           // a string to hold incoming data from the PC
String sensorstring = "";                          // a string to hold the data from the EC probe
boolean input_stringcomplete = false;              // has all data from the PC been recieved?
boolean sensor_stringcomplete = false;             // has all data from the EC probe been recieved? 
boolean S_stringcomplete = false;

void setup(){
  pinMode(13, OUTPUT);                               // set the pin holding the solenoid's resistor to
  servo.attach(9);                                   // let the arduino know a servo is connect to pin
  Serial.begin(9600);                                // set the baud rate for the hardware serial port
  myserial.begin(9600);                              // set the baud rate for the software serial port
  inputstring.reserve(50);                            // set aside some bytes for PC data
  sensorstring.reserve(50);                          // set aside some bytes for EC probe data
}

void serialEvent(){                                // if the hardware port recives a character
  char inchar = (char)Serial.read();                 // get the character recieved
  inputstring += inchar;                             // add it to the inputString
  if(inchar == '\r'){                                // if the incoming character is a <CR>, set the flag
    input_stringcomplete = true;
  }
}


void loop(){

   /*for( int n = 0; n < 1; n++){
   delay(5000);                                       // wait 5 seconds
   digitalWrite(13, HIGH);                            // open solenoid valve
   delay(X);                                     // keep open for X number of MILIseconds
   digitalWrite(13, LOW);                             // close solenod valve
   
   for( n; n < (N/2); n++){                             //  N/2 number of 360 degree (+180,-180) servo sweeps 
   Serial.print(n);
   for(int angle = 0; angle <= 180; angle++){         // turn bead mover from 0 to 180 degrees...from collecting the SAP to dropping it
   servo.write(angle);
   delay(15);
   }
   for(int angle = 180; angle >= 0; angle--){         // turn bead mover from 180 to 0 degrees...from dropping the SAP to collecting another
   servo.write(angle);
   delay(15);
   }
   }
   delay(10800000);
   }
   }
   //*/

  if(input_stringcomplete){                          // if all of a string from the PC has been recieved
    myserial.print(inputstring);                       // send the string to the EC probe
    inputstring = "";                                  // clear the string
    input_stringcomplete = false;                      // reset the flag used to indicate whether a completed string has been recieved from the PC
  }
  while(myserial.available()){                       // while a character is holding in the serial buffer
    char inchar = (char)myserial.read();               // get the new character
    sensorstring += inchar;                            // add it to the sensorString
    if(inchar == '\r'){                                // if the incoming character is a <CR>, set the flag
      sensor_stringcomplete = true;
      char S1 = sensorstring[0];
      int S11 = S1 - '0';
      char S2 = sensorstring[1];
      int S22 = S2 - '0';
      char S3 = sensorstring[2];
      int S33 = S3 - '0';
      char S4 = sensorstring[3];
      int S44 = S4 - '0';
      if(S2 == '.'){
        if(S33 >= 5){
          S11 += 1;
          int Splot = S11;
          Serial.println(Splot);
          plot(Splot);
        }
        else{
          int Splot = S11;
          Serial.println(Splot);
          plot(Splot);
        }
      }
      else{
        if(S44 >= 5){
          S22 += 1;
          S2 = S22 + '0';
          Sstring += S1;
          Sstring += S2;
          int Splot = Sstring.toInt();
          Serial.println(Splot);
          plot(Splot);
        }
        else{
          Sstring += S1;
          Sstring += S2;
          int Splot = Sstring.toInt();
          Serial.println(Splot);
          plot(Splot);
        }
      }
    }
  }
  if(sensor_stringcomplete){                         // if all of a string from the EC probe has been recieved
    Serial.println(sensorstring);                      // use the hardware serial port to send the data to the PC

    sensorstring = "";                                 // clear the string
    sensor_stringcomplete = false;                     // reset the flag used to indicate whether a completed string has been recieved from the EC probe
    Sstring = "";   
}
}


void plot(int Splot){
  int pktSize;
  buffer[0] = 0xCDAB;
  buffer[1] = 1*sizeof(int);
  buffer[2] = Splot;

  pktSize = 2 + 2 + (1*sizeof(int));

  Serial.write((uint8_t * )buffer, pktSize);
}
//*/

You may not use an index with a String Object. The index buffer [ 2 ] is only valid if that buffer is an character array.

Some serial terminal programs are capable to create a log file. If the Arduino would send sensor data, it can be logged into a file. You can use that file to make a graph and analyze the data.

But I don't understand very well what you wrote and I don't understand the sketch. You delay for a few hours, is that okay ?

well I'm not sure quite what to say about the buffer[2] only being valid for a character array...it was part of a prewritten code used to send the data to a program which graphs it in real time (simplot) and it works...so I suppose I have no complaints there...even if I don't truly understand what's happening.

I have the hour delay because I will run the first two "parts" of the code once (the solenoid valve opening and bead mover rotating (see annotations)) then mute those two parts and run only the code that collects conductivity data and graphs it (as well as logs and saves it...once I figure that out)...so that's why that's in there. I could do this with a for loop I understand, but for some reason that stopped me from being able to communicate with the conductivity sensor circuit (change K values, temperature values etc.) for some reason.

I really don't understand what you mean by "serial terminal programs" (tOTAL noob) how do I do this, could you direct me to some code examples? I'm trying to save the data labeled "sensorstring. it is a charachter array that comes out of the format "[Electrical Conductivity Value],[Total Dissolved Solids Value],[Salinity Value],[Specific Gravity Value]" although right now I have it set that that if it prints to the serial monitor it only prints the Salinity value and a carraige return...I'm not sure where this happens though (I was able to set it to this through the instructions that came with the conductivity measurement kit).

It might help if you can supply samples of the raw data coming from the sensor and maybe even link to a datasheet/manual for the sensor your using.

I'm on my tablet now, so I can't insert all the links easily.

A serial terminal program can send and receive message to a serial port. The serial monitor of the Arduino is a build-in serial terminal program. I think "Q Serial Terminal" on sourceforge.net can log to a file.

There is a big difference between a character array and a String object. You should do some reading on that, since it is not allowed to mix them.

Unforunately I can't supply samples of raw data at this time...but it comes out on the serial monitor like this (after I change it to ouput only salinity)

42.1
42.1
42.1
42.2
42.3
etc...

when I add in the command, plot(Splot), then it comes out like this (data preceded by a weird or multiple unfamiliar characters):

42.1
42.1
42.1
42.2
42.3
etc...

this is from the command "Serial.println(sensorstring);" and again, sensorstring is a character array which if not adjusted will output on the serial monitor as follows:

[EC],[TDS],[S ],[SG]

or to fill in some typical values

12880,6320,7.2,1.004
13109,5881,7.1,1.004
etc.

(number of significant figures varies for the different values, depending on size)

The data sheet for the sensor is provided in a link at the bottom of this page:

Peter_n: I guess I'm not quite sure why that part of the code concerns you so much as it seems to be working perfectly fine (the data is graphed in real time successfully)...maybe I'm missing something?

I'm checking into the "Q Serial Terminal" as we speak :slight_smile:

When you type this: [pre]String sensorstring = "";[/pre]
you declare a String object called "sensorstring".
It is not an character array, but a String object.

When you need the third character of a string object, you need to use the function CharAt().

A String Object is a C++ class with many functions to manipulate the string. The code in the sketch is often easier, but below the surface the class functions do the hard work.

An array of data (integers or characters or something else) is something that you can manipulate yourself.

Sorry for the delay in replying, this site sux without reply notifications...

I would suggest you ditch using Strings and instead use a char[50] buffer as strings tend to fragment memory and will maybe eventually crash the code.

Converting a comma delimited char string is pretty simple and below is a sample sketch to do what you want.

char inString[] = {"12880,6320,7.5,1.004"};     // Character string read from sensor
float s;                                        // Used for floating point conversion

void setup(){
  Serial.begin(115200);
  Serial.println(inString);                     // Show the RAW string
  
  s = atof(inString + 0);                       // Convert first value (12880) to float
  Serial.println(s,0);                          // Print it without decimal point (round to nearest whole integer)
  
  for (byte x = 0; x < sizeof(inString); x++){  // Step through buffer
    if (inString[x] == ','){                    // Looking for commas
      inString[x] = ' ';                        // Replace with a space (atof ignores leading spaces but does not ignore commas)
      s = atof(inString + x);                   // Convert to float
      Serial.println(s,0);                      // Print value rounded to integer
    }
  }
  Serial.println(inString);                     // Show the string after commas have been converted to spaces
}


void loop(){
}

The funny characters your getting when you print are markers used by Simplot to determine data it needs to decode to graph. I'm not sure if you can use Serial.print for normal text while using it to feed data to simplot.