Arduino Xbee Data parsing - serial-port

Im sorry to make a post like this but i have tried everything and i cant get this working!
I have two arduinos hooked up with xbee's.
One is connected to my computer recieving data and the other is bettery powered and has a Wii nunchuck attached.
I know im getting good data from the nunchcuck cause i tested it without the xbee.
But i want to send the data over serial and recieve on the other to use for something else but doesnt seem to be working. Here is the code:
Arduino with wii:
#include <Wire.h>
#include <Servo.h>
const int vccPin = A3;
const int gndPin = A2;
Servo servo;
const int dataLength = 6; // Number of bytes to request
static byte rawData[dataLength];
enum nunchuckItems {
JoyX, JoyY, accelX, accelY, accelZ, btnZ, btnC};
void setup()
{
pinMode(gndPin, OUTPUT);
pinMode(vccPin, OUTPUT);
digitalWrite(gndPin, LOW);
digitalWrite(vccPin, HIGH);
servo.attach(9);
delay(1000);
Serial.begin(9600);
nunchuckInit();
}
void loop()
{
nunchuckRead();
int joyX = getValue(JoyX);
int joyY = getValue(JoyY);
Serial.print(joyX);
Serial.print(",");
Serial.print(joyY);
Serial.println();
}
void nunchuckInit(){
Wire.begin();
Wire.beginTransmission(0x52);
Wire.write((byte)0x40);
Wire.write((byte)0x00);
Wire.endTransmission();
}
static void nunchuckRequest(){
Wire.beginTransmission(0x52);
Wire.write((byte)0x00);
Wire.endTransmission();
}
boolean nunchuckRead(){
int cnt = 0;
Wire.requestFrom(0x52, dataLength);
while (Wire.available()){
rawData[cnt] = nunchuckDecode(Wire.read());
cnt++;
}
nunchuckRequest();
if (cnt >= dataLength)
return true;
else
return false;
}
static char nunchuckDecode(byte x){
return (x ^ 0x17) + 0x17;
}
int getValue(int item){
if (item <= accelZ)
return (int)rawData[item];
else if (item == btnZ)
return bitRead(rawData[5], 0) ? 0: 1;
else if (item == btnC)
return bitRead(rawData[5], 1) ? 0: 1;
}
How could i recieve this data on the recieving arduino?
Please help its for my school project!
Thank you!!

When you read the terminal (without the Xbee) do you see line with X,Y appear ? Because if your arduino terminal see it, the problem comes from the Xbee.
If your terminal see the line, look at your Xbee with Xctu. You must set the panID on both Xbee to see them communicate. you must also make the SL address of the sender equal to the DL address of the receiver (and same for the SH/DH).
Can you say us which Arduino, Xbee, shield you use. It can help us to have more details

Related

Xbee Serial.read is not clearing buffer

I wrote a example program to test Serial read from xbee. I was expecting a message passed from transmitter to receiver every 5 sec's but in serial monitor of receiver I am observing a continuous stream of repeat messages. Can anyone what I am missing. FYI: Also attached link to serial monitor screenshot.
[1]: https://i.stack.imgur.com/Lgxx5.png
/* ~ Simple Arduino - xBee Transmitter sketch ~ Router
*/
int count = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
//Send the message:
count ++;
Serial.println(String("Hello World : " + String(count)));
delay(5000);
}
/* ~ Simple Arduino - xBee Receiver sketch ~ Coordinator
*/
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0){
Serial.write(Serial.read());
}
}
For the receiver, don't you just want to pass Serial.read() to print() instead of Serial.write()? If you have two serial ports, one to the console and one to the XBee, they should have different names.
Could you provide some more details on your serial connections? What are COM3 and COM6 attached to? Are you sharing serial port pins with the XBee and your console? it seems like that could be part of your problem, if either the Arduino or XBee can drive the RX pin of your receiver's serial port, you'd end up echoing your characters back to yourself.
Figured out a work around to address the issue. Here are the details:
https://i.stack.imgur.com/3qZMi.png
Circuit connections from Arduino to XBEE Shield:
D0/RX to TX
D1/TX to RX
5V to 5V
GND to GND
/* ~ Simple Arduino - xBee Transmitter sketch ~ Router
*/
void setup() {
Serial.begin(9600);
}
void loop() {
//Send the message:
Serial.print('<');
Serial.print("Hello World");
Serial.println('>');
delay(1000);
}
/* ~ Simple Arduino - xBee Receiver sketch ~ Coordinator
*/
bool started = false; //True: Message is strated
bool ended = false; //True: Message is finished
byte index; //Index of array
char character; //Variable to store the incoming byte
char msg[13]; //Message - array
void setup()
{
Serial.begin(9600);
}
void loop()
{
while (Serial.available())
{
character = Serial.read();
if (character == '<')
{
started = true;
index = 0;
msg[index] = '\0'; // Throw away any incomplete packet
}
//End the message when the '>' symbol is received
else if (character == '>')
{
ended = true;
break; // Done reading - exit from while loop!
}
//Read the message!
else
{
if (index < 11)
{ // Make sure there is room
msg[index] = character; // Add char to array
index++;
msg[index] = '\0'; // Add NULL to end
}
}
}
if (started && ended)
{
Serial.print("Message: ");
Serial.println(msg);
index = 0;
msg[index] = '\0';
started = false;
ended = false;
}
}

vw_get_message return false when running motors

I am using Arduino for the first time, my project consists of RF transmitter connected with arduino UNO and a RF receiver connected to Arduino Mega.
I'm try to send data from transmitter and print it on receiver serial using VirtualWire library and every thing is okey for this receiver code:
#include <VirtualWire.h>
int x=9;
int y=8;
int z=10;
int r=7;
void setup()
{
Serial.begin(9600);
pinMode(x,OUTPUT);
pinMode(y,OUTPUT);
pinMode(z,OUTPUT);
pinMode(r,OUTPUT);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received, print it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
Serial.print(buf[i], HEX);
Serial.print(' ');
}
Serial.println();
}
}
Then i add some if statments to run 2 motors (connected to x,y,z,r pins) based on recrived values :
#include <VirtualWire.h>
int x=9;
int y=8;
int z=10;
int r=7;
void setup()
{
Serial.begin(9600);
pinMode(x,OUTPUT);
pinMode(y,OUTPUT);
pinMode(z,OUTPUT);
pinMode(r,OUTPUT);
vw_setup(2000);
vw_rx_start();
}
void loop()
{
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) // Non-blocking
{
int i;
// Message with a good checksum received, print it.
Serial.print("Got: ");
for (i = 0; i < buflen; i++)
{
if (buf[i]==0x77)//Stop motors
{
digitalWrite(x,LOW);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
digitalWrite(r,LOW);
}
else
{
if(buf[i]==0x80)//2 motors clockwise
{
digitalWrite(x,LOW);
digitalWrite(y,HIGH);
digitalWrite(z,HIGH);
digitalWrite(r,LOW);
}
if (buf[i]==0x90)//counter clockwise
{
digitalWrite(x,HIGH);
digitalWrite(y,LOW);
digitalWrite(z,LOW);
digitalWrite(r,HIGH);
}
}
}
Now the problem is that when motors is stop working and I am sending the values that will run it either with or counterclockwise the motor works in the right direction but then does not respond to any data sent.
In short, when the motor stops working and I send data, the receiver receives the values and runs the motor violin is required, but then for example if the motor was working clockwise and sent the order which is running counterclockwise or even stop work, it does not respond and continues to move It was.
I noticed that this bacause when motors runs this function returns false
vw_get_message(buf, &buflen)
But i don't no why!
In VirtualWire library every time you send a new character or a set of characters your buffer will be overwritten. So the problem in this program is with your for loop checking. It will work fine if you just use the following
For example if you are sending characters like 'A', 'B' etc then
if (vw_get_message(buf, &buflen))
{
if(buf[0]=='A')
{
//move forward
}
if(buf[0]=='B')
{
//move backward
}
.... and so on
Hope this helps

Call of overloaded 'println(char [4], int)' is ambiguous

I've two Arduinos and I want to make them communicate via TX/RX. Arduino one as a sender, and Arduino two as a receiver. But I have a problem with the receiver code and get this error:
call of overloaded 'println(char [4], int)' is ambiguous
Can anyone help me? Thank you.
This is my receiver code:
char str[4];
void setup(){
Serial.begin(9600);
Serial.begin(9600);
}
void loop() {
int i=0;
if (Serial.available()){
delay(100); //allows all serial sent to be received together
while(Serial.available() && i<4){
str[i++] = Serial.read();
}
str[i++]='\0';
}
if(i>0){
Serial.println(str, 4);
}
}
Why do you have two Serial.begin(9600) in the setup?
After the while loop, the i var is equal to 4. Your biggest index in str array is str[3] (0-3), so you are accesing the 4th index which doesn't exist.You should remove that str[i++] = '\0', and if you want to make communication you should do something like :
if (i > 0) {
for (int j=0; j<4; j++) {
Serial.print(str[j]);
}
Serial.println("");
}

Arduino control with serial input more then 1 character

I have the script below and it works.
But I want to control it with a word like on or off instead of one character.
I tried and searched a lot but without success.
/*
Simple LED sketch
*/
int led = 13; // Pin 13
void setup()
{
pinMode(led, OUTPUT); // Set pin 13 as digital out
// Start up serial connection
Serial.begin(115200); // baud rate
}
void loop()
{
if (Serial.available()) {
int ser = Serial.read(); //read serial as ascii integer
if (ser == 'a') { //is this serial byte the ASCII equivalent of 0 through 9?
digitalWrite(led, HIGH); // on
Serial.println("aan");
}
else if (ser == 'u') {
digitalWrite(led, LOW); // off
Serial.println("uit");
}
}
}
Use Serial.readStringUntil(terminator) to read a string from the serial.
The sent string needs to be terminated with a newline character.
Chose Newline in the Arduino IDE's Serial Monitor.
String cmd = "";
void loop()
{
if (Serial.available()) {
cmd = Serial.readStringUntil('\n');
if (cmd == "on") {
digitalWrite(led, HIGH); // on
Serial.println("aan");
}
else if (cmd == "off") {
digitalWrite(led, LOW); // off
Serial.println("uit");
}
}
}
Your problem is that you are using a char you need to declare a string so you can compare that string to the input, the guy above gave a ok/very slacky/too complex for you answer (sorry no offense I am just trying to show contrast between a complex and a easy answer not trying to offend you) and partially is because he did not explain what he is doing and because he is doing unnecessary/useless work. There is a function in c++ called Serial.readString(), much easier then the stuff up there. Assuming your level of programming (no offense) from your question here is a quick review on data types:
String = ""
int = integer number {1,2,3,4,5,6,...}
char = '' <- Notice the difference from String = ""
float = floating point number {1.2,4.5,...}
(These are not all of them, there is more like byte and so on but just make sure you know how to use the above first)
/*
Simple LED sketch
*/
int led = 7; // Pin 13
String ser; //Declare the string that is going to store what your are going to
//write in the serial
void setup(){
// Start up serial connection
//It's good convention to start the serial before pinMode or any other thing
//in setup
Serial.begin(9600); //I don't know why you need such an high baud rate in
//your thing, 9600 for what you have to do is more than fine, this is just at
//what speed the serial is read (in a very general explanation)
pinMode(led, OUTPUT); // Set pin 13 as digital out
//make sure you put in here wheter you want to start the led "on" or "off"
//Eg you want it to start on, then digitalWrite(led, HIGH);
}
void loop(){
ser = Serial.readString();
if(Serial.available() == 0) { //You can also use a while loop if you want to
//This is telling the arduino: if there is something in the serial, then do...
if(ser == "on"){
Serial.println("on");
digitalWrite(led, HIGH);
}else if(ser == "off"){
Serial.println("off");
digitalWrite(led, LOW);
}
}
}
Hope it helped!
Also notice how the above code with
if(Serial.available())
This is a quite WEIRD and SHADY statement and might not work. That's because you are not really telling the int value into the function Serial.available
As the arduino guidelines specify:
int incomingByte = 0; // for incoming serial data
void setup() {
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}
void loop() {
// send data only when you receive data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
// say what you got:
Serial.print("I received: ");
Serial.println(incomingByte, DEC);
}
}
viewable here

Global variable arduino

I'm using I2C to communicate a Master Arduino to 4 Slaves Arduinos, and an Shield (OULIMEX Shield LCD 16x2) on every Arduino slave.
I send Data from the master to slaves using I2C. So I use this code in the master :
#include <Wire.h>
#include <math.h>
#include <floatToString.h>
double incomingData;
void setup()
{
Wire.begin();
Serial.begin(9600);
incomingData = Serial.parseFloat(); //read incoming data
}
void loop()
{
delay (1000);
if (Serial.available())
{
incomingData = Serial.parseFloat(); //read incoming data
Wire.beginTransmission(8); // transmit to device #8
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8 *****************************************************************
else
Wire.beginTransmission(7); // transmit to device #7 *****************************************************************
M++;
if (M==5)
M=0;
String a = "";
a = floatToString(test,incomingData,3,5,true);
for(i=0; a[i]!='\0'; ++i); // length of the string
Wire.write(i);
Wire.write(floatToString(test,incomingData,3,5,true)); // sends one byte
Wire.endTransmission(); // stop transmitting
}
}
I wanted the Data to be printed on the Shield, but I'm connecting all slaves with the same way with the master. For that I have two problems :
1- The global data I'm using to print value is always printed as 0, and not giving the real value;
2- All Shields print the same thing : For exemple, I print "hello" in the first Shield, and I print "hi" in the second Shield, but bouth are printing the same thing (hello or hi).
The code using for the first slave is :
#include <LCD16x2.h>
#include <Wire.h>
LCD16x2 lcd;
int buttons;
int sensorPin = A0; // select the input pin for the potentiometer
int sensorValue = 0; // variable to store the value coming from the sensor
float numOut;
int comp=1 ;
String wordd = "";
int M =0;
void setup()
{
Wire.begin(8); // join i2c bus with address #8
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
}
void loop()
{
delay(500);
}
// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany) {
wordd = "";
int x = Wire.read();
for (int i=0; i<=x; i++)
{
char c = Wire.read();
wordd += c;
}
numOut = wordd.toFloat();
Serial.println(numOut,3); // print the integer
}
Thank you in advance !!
I think it's due to a poor program structure in master shield.
This block selects the slave but on the first line you already select #8
I think this is confusing for the slaves.
Wire.beginTransmission(8); // transmit to device #8
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8
else
Wire.beginTransmission(7); // transmit to device #7
This block should be at the end of the function
M++;
if (M==5)
M=0;
Then you parse the value in a string.
But leave out the first char because you write ++i instead of i++
Moreover you close the loop with ; so it does nothing
String a = "";
a = floatToString(test,incomingData,3,5,true);
for(i=0; a[i]!='\0'; ++i); // length of the string
Finally you write the ordinal number of the byte
And then again the Whole string
So you should get "0" (or "1" because of ++i)
followed by your number if Wire.write() supports it
Wire.write(i);
Wire.write(floatToString(test,incomingData,3,5,true)); // sends one byte
Wire.endTransmission(); // stop transmitting
}
Your sketch should be:
if (Serial.available())
{
incomingData = Serial.parseFloat(); //read incoming data
String a = "";
a = floatToString(test,incomingData,3,5,true);
if ((M==0) || (M==1) || (M==2))
Wire.beginTransmission(8); // transmit to device #8
else
Wire.beginTransmission(7); // transmit to device #7
for(i=0; a[i]!='\0'; ++i) // length of the string
Wire.write(a[i]); // write one byte
Wire.endTransmission(); // stop transmitting
M++;
if (M==5) M=0;
}
Let me know if this works.
I already ask this question but I think I have the answer of it. A global variable have to be diclared befor the void setup, and the void loop too, like that :
type YourGlobalVariable;
void setup()
{
}
void loop()
{
}
So, it is exactly how I did already. The reason it didn't work for me, it was cause of I used this function :
void receiveEvent(int howMany) {}
I don't really know what are the properties of it that let it not work for a global variables, but It works like I sayd already.
Thank you all

Resources