External receiver

Hi guys after a few days of research I feel like I know a lot more , I want to personally thank everybody who replied to my post !

So I used Robin’s data receiving program , wich is a life saver.

I’m using pin 0 ( RX ) to receive data from an external receiver : Radiometrix - Radio Modules - RF Modules - Wireless Modules | RX2G

How can I use this code with using an external receiver instead of the PC ? Also I tried parsing data but parsing my receivedchars to integer won’t work. For example I tried to give “V,123” and it returned

Richting=V // This is right
Axis=0 // This isn’t right

It always gives back a “0” when it should be giving “123”.

Thanks for listening.

#define E1 10  // Enable Pin for motor 1
#define E2 11  // Enable Pin for motor 2

#define I1 8  // Control pin 1 for motor 1 for L293D it changes the direction of the motor
#define I2 9  // Control pin 2 for motor 1 for L293D it changes the direction of the motor
#define I3 12  // Control pin 1 for motor 2 for L293D it changes the direction of the motor
#define I4 13  // Control pin 2 for motor 2 for L293D it changes the direction of the motor
// #define RX 0 // Data in from the receiver

char Richting[32] = {0};  // Direction
int Axis;                 // Numbers (the speed I want to set on the motors)
const byte numChars = 50;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;

void setup() {
  Serial.begin(2400);
  //  pinMode(RX, INPUT);
  pinMode(E1, OUTPUT);
  pinMode(E2, OUTPUT);

  pinMode(I1, OUTPUT);
  pinMode(I2, OUTPUT);
  pinMode(I3, OUTPUT);
  pinMode(I4, OUTPUT);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvWithEndMarker();
  parseData();
  showNewData();
}

void recvWithEndMarker() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;


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

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

void showNewData() {
  if (newData == true) {
    Serial.print("De richting=");
    Serial.println(Richting);
    Serial.print("De snelheid=");
    Serial.println(Axis);
    newData = false;
  }
}

void parseData() {

  // split the data into its parts

  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(receivedChars, ",");     // get the first part - the string
  strcpy(Richting, strtokIndx); // copy it to Richting

  strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
  Axis = atoi(strtokIndx);   // convert this part to an integer DOES NOT WORK !


}

PS you can ignore the motor variables it for later when everything works.

This is really not an ideal start to working with functions.

Operating on anonymous global variables like your loop() sequence of function calls doesn’t indicate that (or which) functions have dependancies.

void loop() {
  recvWithEndMarker();
  parseData();
  showNewData();
}

functions generally should do something (to something) and return the result…

I think this better shows your real intent, though operating on global variables like this is still a bit sketchy (excuse the pun):

void loop() {
  if(recievedMessage())  // have the function return true if a valid message is recieved
  {
    parseMessage();  // then go on to this function that depends on an event in recievedMessage()
    showNewMessage();  // and this
  }
}

but that is another lesson!

for “V,123” you merely need to do this:

void parseData() 
{
  strtok(receivedChars, ",");
  strcpy(Richting, receivedChars);
  Axis = atoi(strtok(NULL, ","));    
}

here it is all together:

#define E1 10  // Enable Pin for motor 1
#define E2 11  // Enable Pin for motor 2

#define I1 8  // Control pin 1 for motor 1 for L293D it changes the direction of the motor
#define I2 9  // Control pin 2 for motor 1 for L293D it changes the direction of the motor
#define I3 12  // Control pin 1 for motor 2 for L293D it changes the direction of the motor
#define I4 13  // Control pin 2 for motor 2 for L293D it changes the direction of the motor
// #define RX 0 // Data in from the receiver

char Richting[32] = {0};  // Direction
int Axis;                 // Numbers (the speed I want to set on the motors)
const byte numChars = 50;
char receivedChars[numChars]; // an array to store the received data
boolean newData = false;

void setup() {
  Serial.begin(9600);
  //  pinMode(RX, INPUT);
  pinMode(E1, OUTPUT);
  pinMode(E2, OUTPUT);

  pinMode(I1, OUTPUT);
  pinMode(I2, OUTPUT);
  pinMode(I3, OUTPUT);
  pinMode(I4, OUTPUT);
  Serial.println("<Arduino is ready>");
}

void loop() {
  if(recievedMessage())
  {
    parseMessage();
    showNewMessage();
  }
}

bool recievedMessage() {
  static byte ndx = 0;
  char endMarker = '\n';
  char rc;


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

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

void showNewMessage() {
  if (newData == true) {
    Serial.print("De richting=");
    Serial.println(Richting);
    Serial.print("De snelheid=");
    Serial.println(Axis);
    newData = false;
  }
}

void parseMessage() 
{
  strtok(receivedChars, ",");
  strcpy(Richting, receivedChars);
  Axis = atoi(strtok(NULL, ","));   
}

Thank you so much for taking the time and rewriting the code ! It works great :smiley:

MrKrabs:
Thank you so much for taking the time and rewriting the code ! It works great :smiley:

great!

While Serial Input Basics gives some nice (cut and paste) examples of how to get data in/out over Serial, it really does fall flat on showing how to properly use functions and when and where to use global or local variables.

It misses the opportunity to teach any of that, and I get it... they are two or even three lessons. The reality is that you end up starting with a program framework that you wouldn't really see used by anyone but someone that just completed that lesson.

great to see you got to this point, and that lesson got you here!

BulldogLowell:
While Serial Input Basics gives some nice (cut and paste) examples of how to get data in/out over Serial, it really does fall flat on showing how to properly use functions and when and where to use global or local variables.

It misses the opportunity to teach any of that

That is quite deliberate. I don't think it helps a newbie to try to cover every aspect of programming in one lesson.

And I really don't think there is any problem using global variables and void functions in the small space on an Arduino - especially if I am developing a project on my own.

I would much prefer to focus the newbie's early learning on using functions and on using meaningful names.

...R

Robin2:
That is quite deliberate. I don't think it helps a newbie to try to cover every aspect of programming in one lesson.

Yes, as I acknowledged.

Robin2:
I would much prefer to focus the newbie's early learning on using functions and on using meaningful names.

Well then, if we are talking about function names then maybe the example should look more like this:

void loop() {
  waitToRecvCompleteMessageWithEndMarker();
  waitForCompleteMessageAndThenParseData();
  waitForCompleteMessageToBeParsedAndThenDisplayData();
}

as a way to designate those dependencies, which are not otherwise indicated in any passing of arguments or logic (as one may typically see in a more functional approach).

Robin2:
And I really don't think there is any problem using global variables and void functions in the small space on an Arduino - especially if I am developing a project on my own.

That is very much your prerogative, but let's not confuse that with good programming practice.

The problem with global variables is that since every function has access to these, it becomes increasingly hard to figure out which functions actually read and write to these variables.

To understand how the application works, you have to take into account every function which may modify the global state. That can be done, but as the application grows it will get harder.

Look at OP's next topic for a perfect example.

Plus, Arduino has plenty of space for functions. :wink:

BulldogLowell:
Well then, if we are talking about function names then maybe the example should look more like this:

Pedant :slight_smile:

Write a short tutorial that introduces newbies to the value of local variables and functions that return values and I will happily refer people to it.

...R

Robin2:
Pedant :slight_smile:

Write a short tutorial that introduces newbies to the value of local variables and functions that return values and I will happily refer people to it.

...R

Yes, but how could it possibly be better described than @econjack, with the use of prostitute analogies?

Absolutely Aristotelian!

BulldogLowell:
Yes, but how could it possibly be better described than @econjack, with the use of prostitute analogies?

I had forgotten about that.

That's fine if a newbie wants to learn about scope. But first he needs to know that he needs to know

I reckon I would refer someone to that Thread if he was having a problem with something not working because it was in a too-narrow scope. And I suspect many would read it and not take from it the lesson you would like them to learn. (Someone recently thanked me for Serial Input Basics after doing almost the opposite of what I recommended)

So i think there is still plenty of scope (sorry, couldn't resist) for you to write an introduction to the value of local variables and functions that return values. Maybe a simple example program that flashes some LEDs written in two different ways - with all-global variables and with local variables etc. The newbie could then read @econjack's Thread for the full story.

...R