sending variables over serial

Hi there, I just bought my arduino and managed to make an led blink and even receive some data from my mac so I’m on a roll but I need some advice. I’m not fully grasping the Serial communication process and wonder if anyone has some pointers.

I’d really like to be able to send arduino variables but I’m not sure whats the best way. Is it crazy to send a string like “foo1024” and have arduino use the first three letters to test which variable to assign a value and then assign the numbers after the first letter as the value. I predict this is a crazy way to do this but i don’t know how I would do it otherwise. Does anyone have any advice on how to do this. Essentially I want to drive 3 outputs from the arduino, a motor and some lights etc and want to send variables to the arduino like position of the motor and brightness of lights but don’t know how.

Any ideas or pointers on what i could read.

thanks Arduino:)

You have the right idea, but it isn't complete. You can't send the name of a variable that the Arduino is to store data in. You can send something like S1:180 to position servo 1 to 180, but, the Arduino is doing all the work, understanding that S means servo, 1 means which one, and 180 is the new position.

When sending data to the Arduino, it is best to use start and end of packet markers, so the Arduino knows when it has received a complete packet.

Search the forum for "started && ended" for an example I posted on how to receive and use a string with start and end markers.

so i should loop through the package and store each character in to an array then use that array to play with. In that case how would i convert an array of 3 numbers, say 2, 4 & 9 for example into the single int 249.

thanks so much!

Hi again, Ive been playing with the code you mentioned but i cant get any meaningful output, all i am trying to do is rad the serial port and then have it echo what has been read but i cant get it going, heres the code…

void setup() {
  Serial.begin(9600); 
}

byte usefulData[11];   // Space to store the Bytes read
byte index;   // Index into array; where to store the Bytes
byte someByte;
byte prevByte = 0;

#define SEOP 0x7E

boolean started = false;
boolean ended = false;

void loop()
{
   while(Serial.available() > 0)
   {
      byte someByte = Serial.read(); // Read the next byte
      if(started && !ended) // We've got a start-of-packet, but no end-of-packet
      {
         index++;
         usefulData[index] = someByte;
      }
      else if(someByte == SEOP) // It's either a start or end marker
      {
         if(!started || prevByte == SEOP) // Then this is the start marker
         {
            index = 0;
            usefulData[index] = someByte;

            started = true;
         }
         else
         {
            index++;
            usefulData[index] = someByte;

            ended = true;
            break;
         }
      }

      prevByte = someByte;
   }

   if(started && ended) // We've got both markers
   {
       int i;
         Serial.print("echo");
         for (i=0; i<11; i = i+1) {
           Serial.println(usefulData[i]); 
         }
         
       started = false; //reset the serial loop
       ended = false;
   }
}

Thank you thank you

Your Arduino is now acting like a radio receiver, except that rather than broadcast data, it's getting serial data. So, what is sending the data?

What is a 0x7E?

index++;
         usefulData[index] = someByte

Is there a reason you don’t like using “usefulData [0]”?

Im reaching the limit of my knowledge here. Right now I'm sending date from the serial monitor but eventually i want to send it from python. For me it would be easiest to send a string from python like "pos_X_1024" but i can send it in whatever format is best. I was expecting to be able to type anything and have it echoed back, but to no avail. if i send "0x7E" with the serial monitor will it be interpreted as four characters, or a hex number... its all very confusing to me right now, i think I'm beyond my depth.

Sorry for the rambling response, I'm very much still learning

j

If you type 0x7E in the Serial Monitor, it will be sent as 4 characters.

The code you are using expects that you will send something like , where < is the start of packet marker (SOP), > is the end of packet marker (EOP), and X1024 is the packet.

You could send something like ;X1024; where ; is the start and end of packet marker (SEOP). The problem with doing this becomes apparent when the sent stream looks like this:

;X1024;X1020;X1007;X998;X950;

and the received stream looks like this:

;X1024;X102;1007;X998;X950;

With the same start and end of packet markers, you can’t tell which end of the packet was lost, so you don’t know which packet(s) is(are) bad.

if i send "0x7E" with the serial monitor will it be interpreted as four characters, or a hex number

The serial monitor is a dumb terminal; it will send whatever characters you type in without interpretations. So, if you type "0x7E", is sends the four ASCII codes 0x30 ('0' 0x78 ('x') 0x37 ('3') and 0x65 ('e'). It is up to your sketch to interpret as a hex number.

Do you know how I set how the arduino to interprets an input, if i send how do i interpret the 1024 as an integer and assign it to my variable int X;

This is really helping, thanks

Also can i clarify what this is doing:

#define SEOP 0x7E

is SEOP a built in variable that defines the start of package character, in that case do i need to define an end of package character, also could I use something like

#define SEOP "<";

You’v just made SEOP a string.
You need to understand the difference between ‘’ and “”

AAh ok, so if my thinking is right if you define a variable as an int you can display it as hex, dec, etc, "" stores a string and '' stores a character as an int?

That ; on the end of the #define line IS part of the symbol definition. It will bite you in the posterior.

What does the define line do, ive not come across #define before?

J

I am also trying to figure out the same thing, except the communication is done with a pair of transceivers. I also just want to send something like X1046 with X as the sensor identifier, and 1046 as the reading. I have to convert between (uint8_t) and (int) in arduino, which I also have not been able to figure out. :(

#define is a pre-processor directive. It tells the pre-processor to replace all occurrences, in the rest of the file, of the first term with the rest of the data on the line.

#define LEDPIN 13

will change LEDPIN to 13 wherever it appears

digitalWrite(LEDPIN, HIGH); will become digitalWrite(13, HIGH);

#define SEOP "<";

will change

      else if(someByte == "<"[glow];[/glow]) // It's either a start or end marker
      {
         if(!started || prevByte == "<"[glow];[/glow]) // Then this is the start

marker
to

      else if(someByte == SEOP) // It's either a start or end marker
      {
         if(!started || prevByte == SEOP) // Then this is the start marker

which will introduce difficult to trace syntax errors.

I have to convert between (uint8_t) and (int) in arduino, which I also have not been able to figure out.

Some questions. What is returning the uint8_t value? Why are you having trouble converting this to an int? How are you trying?

A uint8_t is a typedef (defined type) rather than a native type. Somewhere, there is a statement that says that the name uint8_t is an alias for some native type. The u means that the value is most likely unsigned. The int means that the native type is most likely an integer type. The 8 gives a clue as to the size of the native type.

So, converting an 8 bit, unsigned integer value to a typed 16 bit signed value is trivial.

int someInt = someOtherVal; where someOtherVal's type is uint8_t.

yes, uint8_t is a marker to an unsigned int, i thought that it will be pretty easy too. I am sending something wireless using the HopeRF library. and messages have to be sent in uint8_t i think. So for example, the transmitter does this:

void loop()
{
  // Send a message to the server at most once a second
  server.send((uint8_t*)"11", 2);

  delay(1000);

  server.send((uint8_t*)"22", 2);

  delay(1000);
}

and the receiver does this

  if (client.recv((uint8_t*)&buf, &len))
  {
    //    for (int i = 0; i<len; i++){
    //   buff[1] = buf[1];    
    //    }
    //    strcat(bufff,buff);
    //   msg = atoi(bufff);
    //   msg = ((int)buf[0])*10+((int)buf[1]);
    msg = (int)buf;
  }
  switch(msg)
  {
  case 11:
    digitalWrite(4, HIGH);
    break;
  case 22:
    digitalWrite(4, LOW);
    break;
  }

but it doesn’t work :frowning:

It isn't surprising it isn't working - you appear to be sending a string consisting of two ASCII characters (0x32) and without any form of conversion, expecting them to morph into the decimal value 22