Hello and Good day everyone! I would like to ask for some help on my project because i am having some problems. I have 2 xbees and 2 arduinos. I can transmit data from one xbee to the other xbee. the data transmitted is the reading from my ultrasonic that is connected to an arduino. What type of data is being sent between the two xbees? is it string? or int? and how can i use this data as an input for my motor using arduino? I can see the sensor reading in my serial monitor with this code
#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 12); // RX, TX
void setup()
{
XBee.begin(9600);
Serial.begin(9600);
}
void loop()
{
if (Serial.available())
{ // If data comes in from serial monitor, send it out to XBee
XBee.write(Serial.read());
}
if (XBee.available())
{ // If data comes in from XBee, send it out to serial monitor
Serial.write(XBee.read());
}
}
but how will i use the readings as an input for my arduino?
wvmarle:
You connect them using Serial.
You can send it as ASCII string or in binary format - up to you, whatever is most convenient for your specific data.
can you please elaborate? im a total newbie with arduino and dont know much about coding it. i can receive in my serial monitor readings like , 123, 342, 452, 54. i am receiving number but i am not sure if this is in int or string type. i would like to use this reading to trigger my motor. for example, the reading is below 100, the motor will not turn. and the reading is above 100, the motor will start. thank you!
If it's shown like that in the Serial monitor, it's ASCII characters.
You'll have to store that in a char array, and convert it to an int if you want to have it as int.
wvmarle:
If it's shown like that in the Serial monitor, it's ASCII characters.
You'll have to store that in a char array, and convert it to an int if you want to have it as int.
do you mind helping me with storing it? i really dont know how to. i've been searching everywhere in this forum but i cant understand what is happening in their codes. like give me some example for storing 123 and converting it to an int. Thank you so much!
char message[4]; // holds the C-string
for (i=0; i<3; i++) message[i] = Serial.read(); // read the characters from Serial
message[3] = '\0'; // null termination
int intValue = atoi(message); // convert to int
Now make sure to call this when you have Serial communication coming in, that it doesn't get stuck if it's less than three characters (are your numbers prepended with zeroes or simply shorter? Do you use any stop character?), that it ignores illegal characters, that the final int is in the range you expect. If your numbers may be longer than three characters increase the message length.
If you don't understand some piece of code, start studying harder. Look up every single function that you don't know, etc.
for (i=0; i<3; i++) message[i] = Serial.read(); // read the characters from Serial
message[3] = '\0'; // null termination
int intValue = atoi(message); // convert to int
Now make sure to call this when you have Serial communication coming in, that it doesn't get stuck if it's less than three characters (are your numbers prepended with zeroes or simply shorter? Do you use any stop character?), that it ignores illegal characters, that the final int is in the range you expect. If your numbers may be longer than three characters increase the message length.
If you don't understand some piece of code, start studying harder. Look up every single function that you don't know, etc.
i have not much zeros from the serial monitor coming in. i somehow get the code you shared.
my char is 123, so my int is also 123? i saw in some other forum that if you have 123, you will have 1 first, then 2, then 3. Thanks a lot sir!
Get rid of the atoi() call. Since you are using XBee.write() on the transmitter side, you are NOT sending ascii in the first place, just raw binary data. Your atoi() is returning a -1 as an error since your argument is never ascii.
wvmarle:
So what exact characters are actually received?
Make sure you receive what you expect to receive. Do a Serial.print(message) or so.
I really dont know what type of data am i getting from the xbee transmitter side. But i am getting numbers in my serial monitor which is my xbee receiver side. i tried to do Serial.print to see if i am getting the right thing but all i see is the -1.
Power_Broker:
Get rid of the atoi() call. Since you are using XBee.write() on the transmitter side, you are NOT sending ascii in the first place, just raw binary data. Your atoi() is returning a -1 as an error since your argument is never ascii.
so the numbers that the xbee transmitter side is sending are not in ascii? if those are just raw binary data (like 43, 456, 143, 69, 30?) how can i make it into something that i can use as an input for my motor to be triggered?
here's my full code with the motor
#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 11); // RX, TX
int stepPin = 5;
int dirPin = 6;
int enblPin = 7;
int ultra;
long Distance = 0;
void setup() {
XBee.begin(9600);
Serial.begin(9600);
pinMode (stepPin, OUTPUT);
pinMode (dirPin, OUTPUT);
pinMode (enblPin, OUTPUT);
digitalWrite(stepPin, LOW);
digitalWrite(dirPin, LOW);
digitalWrite(enblPin, HIGH);
}
void loop() {
{
if (XBee.available() > 0)
{ char message[5]; // holds the C-string
for (int i=0; i<3; i++)
message[i] = XBee.read(); // read the characters from Serial
message[3] = '\0'; // null termination
int intValue = atoi(message); // convert to int
}
}
for(long x=0; x<38400; x++)
{
digitalWrite(stepPin, HIGH);
delayMicroseconds(100);
digitalWrite(stepPin, LOW);
delayMicroseconds(100);
//Distance = Distance + 1;
}
// first rotation COUNTER CLOCKWISE
if (ultra < 3);
{
Distance == 38400;
}
{ if
(digitalRead(dirPin) == LOW)
{
digitalWrite(dirPin, HIGH);
}
// else
// {
// digitalWrite(dirPin, LOW);
// }
Distance = 0;
delay(2000);
}
}
i still dont know yet how to use the incoming readings from my sensor as an input for my motor.
Thank you everyone! really appreciate your replies
Hello! i got readings for now. And i can turn on LED with those readings. Sometimes its more than 40 but most of the time its just 10 and 13. I am using an ultrasonic sensor here.
#include <SoftwareSerial.h>
SoftwareSerial XBee(10, 11); // RX, TX
#define led 5
void setup()
{
pinMode(led, OUTPUT);
XBee.begin(9600);
Serial.begin(9600);
}
void loop()
{
{
if (XBee.available() > 0)
{ char message[5]; // holds the C-string
for (int i=0; i<3; i++)
message[i] = XBee.read(); // read the characters from Serial
message[3] = '\0'; // null termination
int intValue = atoi(message); // convert to int
}
}
{ // If data comes in from XBee, send it out to serial monitor
Serial.println(XBee.read());
}
if (XBee.read() >=50 )
{
digitalWrite(led, HIGH);
}
else
{
digitalWrite(led,LOW);
}
delay(3000);
}
it prints out -1 if there are no data coming in the xbee receiver side.
And i dont think i am getting the right readings from my ultrasonic sensor in my xbee receiver.
Based on observation, whenever i get a reading of 100+ it prints out 13 on the receiver side. and when the reading is lower than 100, it prints out 10. why is that so? anyone know? thanks!
Probably because the xbee doesn't send what you think it sends.
I asked you before and you admitted to having no clue what the xbee is actually trying to transmit. Without knowing that, it's useless to try and debug your Arduino side.
I did notice you didn't heed my advice to allow for messages shorter than three bytes.
wvmarle:
Probably because the xbee doesn't send what you think it sends.
I asked you before and you admitted to having no clue what the xbee is actually trying to transmit. Without knowing that, it's useless to try and debug your Arduino side.
I did notice you didn't heed my advice to allow for messages shorter than three bytes.
Hello again sir, I want to show you my code for the transmitter side
const int trigPin = 11;
const int echoPin = 10;
// defines variables
long duration;
int distance;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
Serial.begin(9600); // Starts the serial communication
}
void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculating the distance
distance = ((duration * 0.034 / 2) * 10);
// Prints the distance on the Serial Monitor
delay(3000);
Serial.println(distance);
}
the distance is in int. it is the value that is being sent via xbee.
Thanks!
This is the same as you use to print on your Serial monitor, so it will convert the int to char array, then print the separate chars. So you're sending your int in the form of ASCII characters. On the other end you then have to read these characters, put them in a char array, and convert that back to an int.
Actually you can do this much more efficiently.
What is the maximum value this distance can be? So far you're talking about values of 100-200. If no more than 255 ever, you can change the type to byte, and then send that using Serial.write(). Then you just have to read a single byte on the other side. If it can be larger than 255 but no more than 65535, you can use an unsigned int. That's two bytes on Arduino, I don't know about Teensy - so use uint16_t instead which is certain to be 16 bits or 2 bytes.
When using the Serial.write() function your receiving code becomes something like:
// In case of sending a single byte (0 <= distance <= 255):
byte distance;
if (Serial.available())
distance = Serial.read();
// In case of sending a 16-bit int (0 <= distance <= 65535):
byte i[2];
uint16_t distance;
if (Serial.available()) {
i[0] = Serial.read(); // Read the first byte
i[1] = Serial.read(); // Read the second byte
distance = uint16_t(i[0] << 8) | i[1]; // Reassemble the original value.
}
Please note: I don't know the order in which the two bytes of the int are sent; I guess it's high byte first, low byte second but it may be the other way around and then of course you have to swap the two in the "reassemble" line.