Reading values from mySQL (located on a Pi) to arduino mega using python?

Then write some string parsing on the arduino (many examples in the forums) and work the relays.

Here's some code to capture that string:

#define SOP '<'
#define EOP '>'

bool started = false;
bool ended = false;

char inData[80];
byte index;

void setup()
{
   Serial.begin(57600);
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Where it says "Process the packet", strtok() would be useful. Both commas and colons are delimiters.

Thanks PaulS and wildbill

Yes thats exactly what I was after, a simple example of putting it all together. I did see posts with ser.write() and while(Serial.available() > 0) but had no clue how they meshed together. With that said ill be working on getting the rest to work.

I'm so frustrated with myself because for a long time I just wasn't seeing anything through the serial monitor. Turns out the serial monitor was reading from my debian laptop rather than the raspberry pi serial. As I don't know a way around this, I just copied over the scripts to my laptop for testing and works perfect!

Cheers,
Damo

How do you have the Pi connected to the Mega?

SurferTim:
How do you have the Pi connected to the Mega?

Through the TX0 and RX0 pins on the mega

And you are not using the usb port on the Mega? The tx and rx pins are also connected to the usb port.

Are you connected to a TTL serial port on the Pi and not a RS-232 port, or are you using a device like the MAX232 to convert the signal levels from TTL to RS232?

SurferTim:
And you are not using the usb port on the Mega? The tx and rx pins are also connected to the usb port.

Are you connected to a TTL serial port on the Pi and not a RS-232 port, or are you using a device like the MAX232 to convert the signal levels from TTL to RS232?

I've taken this up as a hobby for a few months so don't take my word for it but I'm really new to all this.

The mega-pi matchup is solely connected to one another through RX and TX, I only use the mega USB when I'm uploading sketches. I do however use a logic converter between the two.

Does that answer your question?

Does that answer your question?

Some of them. So you are powering the Mega with an external power supply and you disconnect the usb when you run the sketch with the Pi connected?

I usually don't do that. I use the usb port for debugging and another hardware port for additional serial comm. I use D18 and D19 for TTL serial, and access that port with Serial1 rather than Serial.

void setup() {
  Serial.begin(9600); // usb
  Serial1.begin(9600); // Serial1

  Serial.println("This prints to the usb port");
  Serial.read(); // This reads from the usb port

  Serial1.println("This prints to D18");
  Serial1.read(); // This reads from D19
}

At this stage the Mega and Pi are powered separately but I intend to use a common power supply in the future. The USB is connected to my laptop for debugging I guess and communication between the Pi and Mega uses RX0 and TX0.
When the python script works on my laptop Ill copy it over to the Pi and change the port name. In the past I didn't notice the serial communication problem because I wasn't reading data into the mega. I was simply using Putty and saw data populating mySQL and then onto apache from the Mega. I find sending data the opposite direction way more involved.

void setup() {
  Serial.begin(9600); // usb
  Serial1.begin(9600); // Serial1

  Serial.println("This prints to the usb port");
  Serial.read(); // This reads from the usb port

  Serial1.println("This prints to D18");
  Serial1.read(); // This reads from D19
}

Good idea, wildbill also mentioned that. I really need to fix that before I forget!!!

Thanks for the feedback!

#include <Wire.h>
#define SOP '<'
#define EOP '>'

bool started, started1 = false;
bool ended, ended1 = false;

char inData[80];
int var1,var2;
byte index, index1;

void setup()
{
   Serial.begin(115200);
   Wire.begin();
   // Other stuff...
}

void loop()
{
  // Read all serial data available, as fast as possible
  while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

  // We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?

  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet
    
    char *token = strtok(inData, ",");
    
    
    if (*token != NULL)
    {
      index1 = 0;
      var[index1] = token; // **I know this wont work**
      started1 = true;
      ended1 = false;       
    }
    
    else if(*token == NULL)
    {
       ended1 = true;
       break;
    }
    
    else
    {
      index= index++
    }
    
          
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

I manged to get the string of values read to the serial port. If I understand correctly the strtok() splits a string into tokens and then atoi() converts the tokens into integers? How could I take the first token and store as say var1, and then store the second token as var2, etc?

I know the above code won't work but its the concept that I'm trying to figure out.

if (*token != NULL)
{
index1 = 0;
var[index1] = token; // I know this wont work

If you are trying to store the value in a variable named var0, you can't. If you create an array, called var, you can save the value in the 0th element of the array.

What possible use is there for started1 and ended1?

      index= index++

Since i++ is equivalent to i = i + 1, this code is equivalent to
index = index = index + 1;
Looks kind of stupid that way, doesn't it?

I've finally got some time to work further on this project.

I have this so far

if(started && ended)
  {
    // The end of packet marker arrived. Process the packet
        
    if (inData != NULL){
      index = 0;
      array[index] = strtok(inData, ",");
      started = true;
      ended = false;
    }
    
    else if (inData == NULL){
      ended =true;
    }
    
    else {
      index++;
    }
    
    // Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }

What I'm trying to accomplish here is to break up inData into an array, separated by a delimiter (comma in this case). The array position is incremented by index.

I receive an error saying "invalid conversion from "char* to int". Any suggestions as what I'm missing?

Is this the line throwing the error?

      array[index] = strtok(inData, ",");

If array[] is an integer array, then that would be the error I would expect. strtok returns a character pointer, not an integer index to the array.

strtok returns a character pointer

If the token being pointed to represents an integer, you can use atoi() to convert the token to an int, to store in the array.

Thanks for the help!!

if (inData != NULL){
      index = 0;
      array[index] = atoi(strtok(inData, ","));
      started = true;
      ended = false;
    }
    
    else if (inData == NULL){
      ended =true;
    }
    
    else {
      index++;
    }

When I use this code, array[0] position works but anything after that gives me a 5 digit number which makes me think Im not splitting the string correctly. I think it has to do with the way I handle NULL.

array[index] = atoi(strtok(inData, ","));

Is this correct. The way I see it; I point to the token with strtok() then convert to int with atoi(). Do I need a line under that that handles NULL? This is so confusing, or do I need a nested if statement in there somewhere, and what would it say?

When I use this code, array[0] position works but anything after that gives me a 5 digit number which makes me think Im not splitting the string correctly. I think it has to do with the way I handle NULL.

You are only populating the 1st element of the array. Any other element that you print will not be meaningful.

It's generally a good idea to make sure that strtok() returned a valid pointer before trying to dereference it (that it what atoi() does).

I don't understand. The 0th element is fine, but the following element is populating and so on...
How do I check that strtok () is infact pointing correctly as you suggest?
The arduino mountain is getting steeper :0

but the following element is populating and so on...

Where? There is only ONE call like this:

      array[index] = atoi(strtok(inData, ","));

That gets just the first token and stores it in just the 1st element of the array.

To get additional tokens, and store them in the rest of the array, you need something like:

   if (strlen(inData) > 0)
   {
      char *token = strtok(inData, ",");
      if(token)
      {
         index = 0;
         array[index] = atoi(token);

         while(token = strtok(NULL, ",")
         {
            array[index++] = atoi(token);
         }
      }

      started = true;
      ended = false;
    }

Thanks PaulS

Turns out that code works perfectly as it is. Im not particularly interested in the 1st token anyway (i.e. the id).

Regards,
Damian

Hi, my project is coming along well. I recently encountered a problem with serial communication. The below code works great and does exactly what I want, receiving data from python. I have a problem with sending data from arduino to python, I find that bytes are being lost along the way, not consistently but ever so often, Communicating from python to arduino works great but communicating from arduino to python is buggy. Am I correct in thinking its a python code problem? I do understand this is an arduino forum and Not python, I just want to make sure it is actually a python problem and not an arduino send communication issue. I feel I need an equivalent of the below code from PaulS on the python??? How I don't know, can't find much info

This code works perfectly receiving data from python, thanks PaulS :slight_smile:

PaulS:

  // Read all serial data available, as fast as possible

while(Serial.available() > 0)
  {
    char inChar = Serial.read();
    if(inChar == SOP)
    {
       index = 0;
       inData[index] = '\0';
       started = true;
       ended = false;
    }
    else if(inChar == EOP)
    {
       ended = true;
       break;
    }
    else
    {
      if(index < 79)
      {
        inData[index] = inChar;
        index++;
        inData[index] = '\0';
      }
    }
  }

// We are here either because all pending serial
  // data has been read OR because an end of
  // packet marker arrived. Which is it?
  if(started && ended)
  {
    // The end of packet marker arrived. Process the packet

// Reset for the next packet
    started = false;
    ended = false;
    index = 0;
    inData[index] = '\0';
  }
}

Here is the arduino code which sends out to python which I'm not sure is correct for my purpose

/----( SENSORS: READS SENSOR INPUTS )----/
void Sensors()
{
sensor1.requestTemperatures(); //Get TEMPERATURE from probe
DHT.read22(DHT22); //Get TEMP/HUMIDITY from DHT22
setTime(hour(), minute(), second(), day(), month(), year());
Serial.print(year());
Serial.print('/');
Serial.print(month());
Serial.print('/');
Serial.print(day());
Serial.print(",");
Serial.print(hour());
Serial.print(':');
Serial.print(minute());
Serial.print(':');
Serial.print(second());
Serial.print(",");
Serial.print(analogRead(photopin));
Serial.print(",");
Serial.print(sensor1.getTempCByIndex(0));
Serial.print(",");
Serial.print(DHT.humidity, 1);
Serial.print(",");
Serial.println(DHT.temperature, 1);
}