Data Manipulation

Hello i have a case with 2 Arduinos one Nano and one Mega.
I need the setup to work like this:

The Arduino Nano has 10 push buttons and 2 joystick modules connected to it and it is powered by the Vin pin from the Mega
Digital Pins : 2-13 are taken up by the push buttons and the 2 buttons on the joysticks
Analog Pins : A0-A3 are taken up by the joystick axis (X1,Y1,X2,Y2)

The Arduino Mega has and I2C PWM controlller hooked up and an I2C LCD but that is pretty irrelevant to my question

The thing i need is for the Mega to ask for the Nano to read the inputs and the Nano to report back the input states.

I could do this via I2C or Serial it does not seem a problem for me . The problem comes with the data manipulation

I need a way to compress the input readings and send them in one large packet and have the Mega Decode the packet so it can use the data.

Example
Nano Sends something like this
102030405060708191100111121X1560X2670Y1569Y21023

And the Mega decodes it to
Buttons 1-7 Are 0 , 8-9 Are 1 , 10 is 0 , 11 12 is one ,X1 value is 560 X2 value is 670 Y1 value is 569 and Y2 value is 1023

I basically need when the mega asks for the state of the inputs to get them and be able to use them independently.

Thanks in advance.

Have a look at how the data is organized in the parse example in Serial Input Basics. That system is easy to create (just a series of Serial.print() statements) and easy to parse.

...R

struct for storing the state. union over that struct so each byte can be accessed. Convert each byte to hexadecimal for transmission. Include a reasonable head / tail over the transmission. Reverse on the receiver. The compiler does all the decoding.

Thank you very much for your answers gentlemen.

First of all i want to thank you Robin for awesome guide and for your help i will probably be using that guide since it implements everything Coding Badly has referred to pretty well i think :smiley: i am just a bit overwhelmed when it comes to coding MCUs that is why i asked for helped i have stumbled upon Robins guide once a few weeks back when researching the same thing but could not understand the code easily so i gave up pretty quickly.I will give it a second shot and create a function to automate the whole procedure if possible :wink: Thank you!

Nano Sends something like this

Whytheheckwouldyoudothat?Includingdelimitersmakesitordersofmagnitudeeasiertoparsedata.

Well my plan now is to use a comma to get the values streamed like this

1,0,1,0,1,1,1,1,0,0,580,940,586,640

if i use the fifth examples start and end marks then the mega would know which value corresponds to which button , switch , axis

The problem i have is i tried using the example and modifying it a bit but the code and the way it works is a bit hard for me to grasp :confused:

I get how the marker communication works but the example that expects characters and floats really confuses me :o

I get how the marker communication works but the example that expects characters and floats really confuses me

Show the code that you don't fully understand. We'll happily pound some understanding into your thick skull. 8)

hahah thanks for your help :smiley:
The code below is copied from the fifth example of robins guide.
My questions are being written as comments besides every line i do not understand :stuck_out_tongue:

In the Start
1) const byte numChars = 32; 
2) char receivedChars[numChars]; // The received data is in form or characters or string ?
3) char tempChars[numChars];  

In void recvWithStartEndMarkers()
1) receivedChars[ndx] = rc; // this is basically the same question as above if it receives characters it stores the received character in the receivedChars array on the ndx number

2) if (ndx >= numChars) {  
                    ndx = numChars - 1; // if the ndx is 33 that means it is larger than 32 why assign it the value of 31?
                }



In void parseData()

1) char * strtokIndx; // I have really no idea what this line is doing i searched about the strtok but i cant figure out what it does here.

2) strtokIndx = strtok(NULL, ","); // I am completely lost here too 
3) integerFromPC = atoi(strtokIndx);     //After searching a bit i figured out what atiod did but i do not understand how can i use it in my case that i need multiple values being saved.
2) char receivedChars[numChars]; // The received data is in form or characters or string ?

The characters are characters. They are stored in a char array. When the char array is NULL terminated, it becomes a string.

1) receivedChars[ndx] = rc; // this is basically the same question as above if it receives characters it stores the received character in the receivedChars array on the ndx number

One character was read, and store in rc. That character is added to the array, at the position defined in ndx.

2) if (ndx >= numChars) { 
                    ndx = numChars - 1; // if the ndx is 33 that means it is larger than 32 why assign it the value of 31?
                }

What would YOU do if you expected a user to send you up to 32 characters, and the user hunted and pecked out 114 characters? Which 32 would you save? The first 32? The first 31 and the last one? Robin2 made one choice. You can make a different choice.

[/code]
One character was read, and store in rc. That character is added to the array, at the position defined in ndx.

2) if (ndx >= numChars) { 
                    ndx = numChars - 1; // if the ndx is 33 that means it is larger than 32 why assign it the value of 31?
                }

What would YOU do if you expected a user to send you up to 32 characters, and the user hunted and pecked out 114 characters? Which 32 would you save? The first 32? The first 31 and the last one? Robin2 made one choice. You can make a different choice.
[/quote]
I would keep the first 32 but the thing that confuses me is why set ndx to 31 since the code can receive 32 chars. (does the code do 31 chars and the NULL at the end ? )

ChristosS:
why set ndx to 31 since the code can receive 32 chars.

Computers start counting from 0 so the index position 31 is actually the 32nd position.

...R

Well i feel pretty dump now :stuck_out_tongue: I knew that but my mind feels like its broken now… Thank you very much for your help i will now get to coding :smiley:

After a bit of modification this is the code i came up with.

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
int Values[numChars];
boolean newData = false;
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempChars, receivedChars);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
    }
}
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;
        }
    }
}
void parseData() 
{      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index
    
    strtokIndx = strtok(tempChars,",");      // get the first part - the string
    Values[0]= atoi(strtokIndx);
    for(int i=1;i<=31;i++)
    {
      strtokIndx = strtok(NULL,",");      
    Values[i]== atoi(strtokIndx);
    }
}
void showParsedData()
{
  for(int i=0;i<=31;i++)
  {
    Serial.print("DATA PIECE  ");
    Serial.print(i);
    Serial.println(Values[i]);
  }
}

EDIT : some code changes (in for loops) that caused the code to fail to compile
UPDATE: The code compiles but does not work … i do not know why ill have it print some debugging info and reply.

ChristosS:
Well i feel pretty dump now :stuck_out_tongue:

You mean "dumb"?

aarg:
You mean "dumb"?

hahahah yes i did not notice that mistake.

    Values[i]== atoi(strtokIndx);

Time to REALLY learn the difference between the = operator and the == operator.

I would post right now to ask why it did not work.When i put it data i was getting 0 , the operator was the problem
The refined working code for the parseData() void.

void parseData() 
{      // split the data into its parts

        char * strtokIndx; // this is used by strtok() as an index
        Serial.println("Parsing Data");
        for(int i=0;i<=31;i++)
        {
          Serial.println("FOR LOOP");
          if(i==0)
          {
            Serial.println("i=0");
            strtokIndx = strtok(tempChars,",");      // get the first part - the string
            Values[i]== atoi(strtokIndx);
          }
          else
          {
            Serial.println(i);
            strtokIndx = strtok(NULL,",");
            Values[i]== atoi(strtokIndx);
          }
        }   
}

Another problem came up and i have no idea how to solve it regarding the 2 MCUs talking to each other.

Arduino Mega Code

--------------------------Tab1-------------------
#include "VARIABLES.h"
void setup()
{
  Serial.begin(9600);
  Serial1.begin(9600);
}
void loop()
{
  while(Serial.available()>0)
  {
    char ready_to_send = Serial.read();
    if(ready_to_send==send_data)
    {
      get_inputs();
    }
  }
  
}


-------------------Tab 2------------------------
void get_inputs()
{
  Serial1.print('!');
  received_with_markers();
  if (newData == true) 
  {
        strcpy(tempChars, receivedChars);
        parse_data();
        newData = false;
   }
  for(int i=0;i<=31;i++)
  {
    Serial.println(data[i]);
  }
}
----------------------------------TAB 3-------------------
void parse_data()
{
  char * strtokIndx;
        for(int i=0;i<=31;i++)
        {
          if(i==0)
          {
            strtokIndx = strtok(tempChars,",");
            data[i]== atoi(strtokIndx);
          }
          else
          {
            strtokIndx = strtok(NULL,",");
            data[i]== atoi(strtokIndx);
          }
        }
}
-------------------------------------TAB 4 ----------------------- 
void received_with_markers()
{
  while (Serial1.available() > 0 && newData == false) 
  {

        rc = Serial1.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;
        }
    }
}
-------------------------------------TAB 5----------------------------------
#ifndef VARIABLES_H
#define VARIABLES_H

char dataReceive='!';
char dataSend='@';
char dataReceived='#';
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
int  data[numChars];
boolean newData = false;


//DB
char send_data='2';
#endif

Arduino NANO only sends this stream of data 

DATA : <0,0,0,0,0,0,0,0,0,0,0,0,521,522,537,526>

The problem is that the mega gets the data
rc is updating and getting the data
tempChars and receivedChars seem fine but after parsing the data the data[32] variables are empty

(I am sorry for all the tabs but it helps me work organize my code also i would normally have just one tab for getting the data (get_inputs tab) but due to me trying to figure out the issue i have split the code in many tabs)

(I used number 2 as the send data command to avoid bashing the nano with exclamation points)
Thank you in advance again

I would love your help because i have not figured it out yet … i have been trying to for the past couple of hours.

ChristosS:
I would love your help because i have not figured it out yet … i have been trying to for the past couple of hours.

Make life easy for everyone - just put all the code into a single .ino file.

…R