How to properly track data?

Through serial I am sending my arduino some data. I want to store this data to show on a display or change it through user input. I am sending the name of the thing that needs to be tracked and a number between 0 and 1 belonging to this.

Usually (in webdevelopment) I would create an object with a few properties (name, value, etc.) that would contain all the data, but I don't think thats the Arduino way.

Hopefully someone can point me in the right direction to properly do this, thank you very much!

Usually (in webdevelopment) I would create an object with a few properties (name, value, etc.) that would contain all the data, but I don't think thats the Arduino way.

Why not ?
Th Arduino is, after all, programmed in C++ and OOP is fully supported

Would be wonderful to do it in a familiar way, but I cannot get it to work. Could you maybe help me with an example?

My intentions with serial is just sending one string with all the names and then one string witha ll the values. Seperated by a | (could be anything)

Something like:
N name1|name2|name3
V value1|value2|value3

vhofstede:
Would be wonderful to do it in a familiar way, but I cannot get it to work. Could you maybe help me with an example?

It will be much easier to help if you post the program that represents your best attempt and tell us in detail what it actually does and what you want it to do that is different. That way we can focus on the parts you need help with rather than wasting time on things that you can do.

I can't see how anyone could give you an example as you have provided no info on the data that is being sent to the Arduino - not even about what is sending it, how it is being sent or what Arduino board you are using.

...R

Okay so the code I've got is

#include <SPI.h>
#include <TFT_eSPI.h>
TFT_eSPI tft = TFT_eSPI();

const byte numChars = 255;
char receivedChars[numChars];

char* sessions[20]= {};

boolean newData = false;

boolean pcReady = false;

int buttonPin = 18;
int buttonState = 0;
int lastButtonState = 0;

int potPin = 27;
float potVal = 0;
float measuredValue = 0;
float measurementRange = .05;

int currentSession = 0;

int counter = 1;

unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 100;    // the debounce time; increase if the output flickers

void setup() {
  Serial.begin(115200);
  
  tft.init();

  tft.setRotation(3);
  
  tft.fillScreen(TFT_BLACK);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE);
  tft.setCursor(0, 0);
  tft.setTextWrap(false);
  
  pinMode(buttonPin, INPUT);
  potVal = getPotValue();

  while(!pcReady){
    recvWithStartEndMarkers();
    
    if (newData && strcmp(receivedChars,"PCREADY") == 0) {
      tft.fillScreen(TFT_BLACK);
      tft.setCursor(0,0);
      pcReady = true;
    }
  }
}

void loop() {

  recvWithStartEndMarkers();
  if (newData) {
    
    tft.println(receivedChars);

    if(receivedChars[0] == 'S'){
      char * pch;
      pch = strtok (receivedChars,"|");
      while (pch != NULL)
      {
        //TODO: Add first session name to sessions
        pch = strtok (NULL, "|");
      }
    }
    
    newData = false;
  }

}

void setMessageDebounce() {
  lastDebounceTime = millis();
}

bool getMessageDebounce() {
  return ((millis() - lastDebounceTime) > debounceDelay);
}

double getPotValue() {
  return map(analogRead(potPin), 0, 4095, 0, 100)/100.0f;
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

In my setup I initialize stuff for a tft display and wait for a message from a python script on my PC that says PCREADY. This all works fine (although if you see improvements please let me know, trying to learn).

Then in the loop it checks for new received messages, is the first character of the received message is 'S', I want to split the incoming message, add each item to variable sessions.

So in javascript a sessions.push(pch) ? I tried to look around how to do something like that in my arduino code.

sessions is an array so once you have decoded a value from the input you can add it to the array by direct reference to the array index

sessions[index] = value;
index++;  //ready for the next value

What is the value in sending the names ? Just send the values

If you want the values to have names that you can refer to rather then just an array index, then consider using a struct to hold the values in named variables

Have a look at this Simple Python - Arduino demo . The Python code should work on Windows if you edit it to use the Windows style of COM ports. I believe you also have to change the line where it says rtscts = True to rtscts = False

Also have a look at the parse example in Serial Input Basics

...R

@UKHeliBob I want to show the names and values together on a small LCD screen. Then the user can change the values and those are sent back to the PC through serial. The number of sessions (and values ofcourse) is dynamic and will be no more than 15. So I want to connect the names of sessions and their corresponding values and have them easy accessible and usable

@Robin2 I did use the old post you made, haven't seen this update yet but I will check it out. The serial to python works fine however. It is the actually using the received data on the arduino that is the problem

EDIT: Sorry this comment does not actually progress my question so: I am looking for some example on what is the best way to put the received data in an object (or something more useful) and examples (like a print, or tft.println() in my case) on how to use the stored data.

I want to show the names and values together on a small LCD screen

I would advise sending the names and values as pairs and storing them both in an array of structs each with a name/value pair of data items. Sending the names and values separately is more likely to go wrong

This is exactly the kind of advice I needed! I will try tomorrow if I can get that to work (since I am not too familiar with structs). I'll post my findings and other problems I run into in case that happens!

vhofstede:
I am looking for some example on what is the best way to put the received data in an object (or something more useful) and examples (like a print, or tft.println() in my case) on how to use the stored data.

Have you considered the second link I gave you?

You could send a name and value as "<name, value>". However IMHO a better idea is to send all the values every time even if they have not changed. If you always send the values in the same order there would be no need for the names.

For example "<value1, value2, value3>"

...R

CSV input is a common data format as in
name, value, name2, value 2, ... NEWLINE

Check out my tutorial on Text I/O for the Real World that includes a detailed example of reading and parsing CSV GPS data using my SaftString library.

SafeString also provides tokenizing readers that you could use if you want to have a more free form input and use a simple parser to pick out commands and the values that follow them.
But CSV looks easier

You could use this CSV format
name=value,name2=value2, ...
then parse the CSV for the 'fields' name=value and the use SafeString stoken or indexOf to extract the name and value

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.