Notifications
Clear all

433 MHZ Transmit more than two numbers?

7 Posts
3 Users
0 Likes
1,341 Views
(@arduinonoob2003)
Member
Joined: 3 years ago
Posts: 3
Topic starter  

In the DroneBot video about the 433 mhz transmitter and receivers it shows how to transmit two numbers using a for loop to parse the incoming string. (Video link:

 

I have tried to write some code to try and transmit three numbers, two potentiometers values and one button state. To do this, on the transmitting end I put them all together in one string. On the receiving end, I have to parse this string to separate the values into individual values for two servo positions and one direction state. I have the transmitting code, and only need to know how to split an incoming string into 3 different strings. Is there a way of doing this without the strtok function? The thing is that the values are constantly changing, so I don't know if converting the string into a char value would be any good... If anyone knows of a solution I would greatly appreciate it! 

Receiving code that I need help with:

#include <ServoTimer2.h>

#include <RH_ASK.h>

#include <SPI.h>

 

RH_ASK rf_driver;

int xservopos;

int yservopos;

int motordirection;

int motorspeed;

 

String xpos;

String ypos;

String motordir;

String str_out;

ServoTimer2 servo1;

 

void setup() {

  // put your setup code here, to run once:

rf_driver.init();

Serial.begin(9600);

servo1.attach(9);

 

pinMode(6, OUTPUT);

pinMode(5, OUTPUT);

pinMode(4, OUTPUT);

 

}

 

void loop() {

  // put your main code here, to run repeatedly:

 

uint8_t buf [RH_ASK_MAX_MESSAGE_LEN];

uint8_t buflen = sizeof(buf);

 

if (rf_driver.recv(buf, &buflen))

{

  str_out = String((char*)buf);

for (int i = 0; i < str_out.length(); i++)

{

  if (str_out.substring(i, i+1) == ",")

  {

    xpos = str_out.substring(0, i);

    ypos = str_out.substring(i+1);

   motordir = str_out.substring(1, i);

   break;

  }

}

Serial.println("X_position:");

Serial.println(xservopos);

Serial.println("Y_position:");

Serial.println(yservopos);

Serial.println("Motor_Direction:");

Serial.println(motordir);

 

xservopos = xpos.toInt();

yservopos = ypos.toInt();

motordirection = motordir.toInt();

motorspeed = map(yservopos,0,1023,0,255);

servo1.write(xservopos);

if (motordirection == 0)

{

  digitalWrite(4, LOW);

digitalWrite(5, HIGH);

}

else if (motordirection == 1)

{

  digitalWrite(5, LOW);

digitalWrite(4, HIGH);

}

 

analogWrite(6, motorspeed);

}

}

 

The main issue is in the for loop, I understand the rest of the code except for that small part. If I can replace it with a way to parse the code into three different parts the rest will work.. I have tried numerous things, and none have worked. Thank you for your help!

 

(Just realised I had first put this in the wrong area... oops)


   
Quote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

Take a look at < https://forum.arduino.cc/t/sending-data-via-rf-433mhz/529730>

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
(@arduinonoob2003)
Member
Joined: 3 years ago
Posts: 3
Topic starter  

@will Sorry, but the link does not appear to work..


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@arduinonoob2003

 

Sorry, I seem to have screwed up the formatting

 

try https://forum.arduino.cc/t/sending-data-via-rf-433mhz/529730

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
(@arduinonoob2003)
Member
Joined: 3 years ago
Posts: 3
Topic starter  

@will Not sure that is what I am looking for.. I'm trying to separate an incoming string into three separate parts, and when I try to do a Serial.println of the str_out (string that is being transmitted), tons of ??? appear on the Serial Monitor. I don't know how to separate this kind of incoming string, and was wondering if there was a direct way of decoding it


   
ReplyQuote
Will
 Will
(@will)
Member
Joined: 3 years ago
Posts: 2504
 

@arduinonoob2003

 

Here's some code for you to try. I can't seem to get it into proper format using the supplied description, but if you copy and past it into the IDE it should work.

The function GetNextInteger uses the original buffer (NOT THE STRING) and the buffer length as the container for the values to be read. You must declare an int value (called "location") which is used in the function to move along the contents of the buffer. 

Each call will start from 1 byte past the end of the last extracted value and will read and accumulate the sign and all digits of the integer. When it reaches a non-valid character (i.e not a digit or '-') it then returns the string value of the number just read from the buffer.

I'll leave the extraction of the direction to you 🙂

uint8_t buflen = 50;
uint8_t buf[50] = {" 123, 456, -78 "};

void setup() {
Serial.begin(9600);
while (!Serial) ;
// put your setup code here, to run once:
int location = 0;
Serial.println("");
Serial.print("Location = ");
Serial.print(location);
Serial.print(", X = ");
Serial.println( GetNextInteger(buf,buflen,location));
Serial.print("Location = ");
Serial.print(location);
Serial.print(", Y = ");
Serial.println( GetNextInteger(buf,buflen,location));
Serial.print("Location = ");
Serial.print(location);
Serial.print(", Z = ");
Serial.println( GetNextInteger(buf,buflen,location));
}

void loop() {
// put your main code here, to run repeatedly:

}

String GetNextInteger( const uint8_t *buf, const uint8_t buflen, int &at) {
//
int from=at; // Store starting location
bool isNeg = false; // Non-negative
int value; // Value read
//
// Skip controls and blanks
//
while (at<buflen && buf[at]<33)
at++; // Skip controls and blanks
if (at<buflen) {
value = 0; // Start from nothing
//
// Parse the first byte to determine sign
//
if (buf[at]=='-') { // Minus sign found
at++; // Move past it
isNeg = true; // Set neg indicator
}
if (buf[at]=='+') // Plus sign found
at++; // Ignore it (assumed non-neg)
//
while (at<buflen) {
if (buf[at]>='0' && buf[at]<='9') { // If a valid digit
value = 10*value+buf[at++]-'0'; // Accumulate it
} else {
at++; // Move past it
break; // Exit while loop
}
}
}
//
return (isNeg) ? String(-value) : String(value); // Tell caller waht we got
}

 

Hope this helps.

Anything seems possible when you don't know what you're talking about.


   
ReplyQuote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 
Posted by: @arduinonoob2003

Is there a way of doing this without the strtok function? The thing is that the values are constantly changing, so I don't know if converting the string into a char value would be any good... If anyone knows of a solution I would greatly appreciate it!

strtok and tokenizing it would be the straight forward method. I assume you are treating it like an API response.

If you want to avoid that then look into the sscanf function. Google it and pick our favorite tutorial website.

You could also use Arduino Parser library.


   
ReplyQuote