xbee pro s2b receiving random data - arduino

I have a trouble with xbee s2b.
I try to receive two joystick values using only xbee placed on sparkfun regulated board (Coordinator API) and process these data on Arduino Uno connected to other xbee s2b placed on explorer board.(Router API). I configured xbees using X-CTU properly and I adjusted DIO0 and DIO1 to ADC[2] on Router Xbee. There is no problem when working with one joystick. But when I try to receive two joystick values at the same time, they are not working correctly. When I look the incoming data on serial monitor, I see;
https://lh3.googleusercontent.com/-20vjr0EchsQ/VqyZXgq84VI/AAAAAAAAA_0/WhEtoOU61vA/s1280-Ic42/Screenshot_3.jpg
My Arduino code is:
int packet[32];
void setup()
{
Serial.begin(9600);
}
void loop(){
if (Serial.available() > 0) {
if (Serial.read() == 0x7E) {
packet[0] = 0x7E; //start delimiter
packet[1] = readByte(); //MSB1
packet[2] = readByte(); //MSB2
int dataLength = (packet[1] << 8) | packet[2]; //between the length and the checksum
printPacket(dataLength+4);
Serial.println("");
}
}
delay(1000);
}
void printPacket(int k) {
for(int i=0; i < k; i++) {
Serial.print(packet, HEX);
Serial.print(" ");
delay(1000);
}
}
int readByte() {
while (true) {
if (Serial.available() > 0) {
return Serial.read();
}
}
}
What is the point I missed? Can you help me about this issue. Thank you in advance.

The delay(1000) statements may be causing you to lose characters from your serial buffer, and might not be necessary.
The code you shared appears incomplete. Where are you reading the dataLength bytes of the packet? How does printPacket() print the bytes?
Your inbound packet buffer should be larger -- I think the XBee S2B can have network payloads of up to 255 characters, in addition to the frame header and checksum.
You've created a blocking readByte() call, which isn't good program design. Consider something like this instead:
unsigned char packet[300];
int packet_index = 0;
int packet_length;
void loop() {
while (Serial.available() > 0) {
packet[packet_index++] = Serial.read();
if (packet_index == 3) {
packet_length = (packet[1] << 8) | packet[2];
}
if (packet_index > 2 && packet_index == packet_length) {
print_packet();
packet_index = 0;
}
}
}
void print_packet() {
int i;
for (i = 0; i < packet_length; ++i) {
Serial.print(packet[i], HEX);
Serial.print(" ");
}
Serial.println("");
}
If you have too much data to print and you're overflowing your outbound serial buffer, try increasing the speed of the console's serial port to 115200bps. Or print the bytes as you receive them instead of waiting until the packet is complete.

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;
}
}

Can I temporarily disable Arduino Serial data receive?

I am working on a project and I encountered some problems.
I am using a DHT11 temperature sensor, an Arduino Uno and a TFT LCD display 2.2-inch model ITDB02-2.2.
What I want my project to do is to use 2 functioning modes for the sensor that I can select from the keyboard at the beginning of the program(one which is normal and one which will be used on special occasions)(so I need serial communication).
I noticed that the screen does not function if I start a serial communication at any rate so I used Arduino Serial.begin(9600) and Serial.end() for the mode selecting part of the program.
THE PROBLEM: My Arduino is still sending data through serial port even if I ended the serial communication and is looking like this:
I found out that Serial.end() function does not shut off serial communication but just the rate of communication. I am curious if you have any idea that I can use in order to get rid of the extra data, to neglect it before the computer receives it.
I`m stuck. I thought that interruptions would be a solution but they are not as far as I researched on the internet.
My ARDUINO CODE:
#include <SimpleDHT.h>
#include <UTFT.h>
UTFT myGLCD(ITDB22,A5,A4,A3,A2);
SimpleDHT11 dht11;
// Declare which fonts we will be using
extern uint8_t BigFont[];
//dht sensor data pin
int dataPinSensor1 = 12;
char mode;
int del;
void setup()
{
Serial.begin(9600);
Serial.print("Select functioning mode");
mode=SensorModeSelect(mode);
Serial.end();
pinMode(12, INPUT);
}
void loop()
{
if(mode=='1') {
FirstFuncMode(dataPinSensor1);
}
if(mode=='2') {
SecondFuncMode(dataPinSensor1,del);
}
delay(10);
}
char SensorModeSelect(char in)
{
char mode='0';
while(mode=='0') {
if(Serial.available() > 0) {
mode=Serial.read();
}
}
if (mode == '1') {
Serial.print("\nMOD1 SELECTED: press t key to aquire data \n");
}
if (mode == '2') {
Serial.print("\nMOD2 SELECTED: press q if you want to quit auto mode \n");
Serial.print("Select the data aquisition period(not smaller than 1 second) \n");
}
return mode;
}
int DataAqPeriod()
{
int del=0;
while(del==0) {
while(Serial.available() > 0) {
//Get char and convert to int
char a = Serial.read();
int c = a-48;
del *= 10;
del += c;
delay(10);
}
}
del*=1000;
return del;
}
void FirstFuncMode(int dataPinSensor1)
{
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
bool DispCond=false;
Serial.begin(9600);
delay(1500);
if (Serial.read() == 't' ) {
DispCond=true;
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode");
}
byte f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(1500);
}
Serial.end();
if(DispCond==true) {
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
//print value on LCD
displayNoInit((int)temperature,(int)humidity);
}
}
void SecondFuncMode(int dataPinSensor1,int del)
{
bool q=false;
byte temperature = 0;
byte humidity = 0;
int err = SimpleDHTErrSuccess;
Serial.begin(9600);
del=DataAqPeriod();
Serial.end();
//Setup the LCD
myGLCD.InitLCD();
myGLCD.setFont(BigFont);
while(q==false) {
Serial.begin(9600);
//read temperature and compare it with an error value
if((err = dht11.read(dataPinSensor1, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
Serial.print("unreliable measurement or unselected functioning mode \n");
}
float f = temperature * 1.8 + 32;
Serial.print((int)temperature);
Serial.print(" *C, ");
Serial.print((int)f);
Serial.print(" *F, ");
Serial.print((int)humidity);
Serial.println(" H humidity");
delay(del);
if(Serial.read() == 'q')
q=true;
Serial.end();
displayNoInit((int)temperature,(int)humidity);
delay(10);
}
}
void displayNoInit(int temperature,int humidity)
{
//effective data display
myGLCD.clrScr();
myGLCD.setColor(255, 255, 0);
myGLCD.setBackColor(10,10,10);
myGLCD.print(" Temperature ", CENTER, 10);
myGLCD.setColor(254, 254, 254);
myGLCD.printNumI(temperature, CENTER, 45);
myGLCD.setColor(255, 255, 0);
myGLCD.print("C ", RIGHT, 45);
myGLCD.print("Relative Hum.", CENTER, 90);
myGLCD.setColor(204, 245, 250);
myGLCD.printNumI(humidity, CENTER, 120);
myGLCD.print("%", RIGHT, 120);
}
You are correct in the definition that Serial.end() does not disable the serial monitor, only the interrupts. After calling Serial.end() you can disable the serial monitor like so.
#include <avr/io.h>
// Save status register, disable interrupts
uint8_t oldSREG = SREG;
cli();
// Disable TX and RX
cbi(UCSRB, RXEN);
cbi(UCSRB, TXEN);
// Disable RX ISR
cbi(UCSRB, RXCIE);
// Flush the internal buffer
Serial.flush();
// Restore status register
SREG = oldSREG;

Can't send data through ESP8266

I working on project about seat occupancy in which I have used an Arduino, a piezoelectric sensor and an ESP8266. My problem is that I am not able to send data to my PC where an UDP server is running, written in Python.
My real problem is, that I am able to send data, when I use Arduino IDE's serial monitor. It sends and receives data perfectly, but code is not running and I am not able to point out my mistake.
Arduino code:
const int seat_no = 2;
const char *ssid = "";
const char *passwd = "";
const char *ip = "192.168.43.250";
const int port = 55056;
const int threshold = 100;
String op;
int i, a, data_size;
void setup() {
Serial.begin(9600);
Serial1.begin(115200);
Serial.println("Starting ESP8266");
Serial1.write("AT+CWJAP=\"");
Serial1.write(ssid);
Serial1.write("\",\"");
Serial1.write(passwd);
Serial1.write("\"\r\n");
Serial1.write("AT+CWMODE=1\r\n");
Serial1.write("AT+CIPMUX=0\r\n");
Serial1.write("AT+CIPSTART=\"UDP\",\"");
Serial1.write(ip);
Serial1.write("\",");
Serial1.write(port);
Serial1.write("\r\n");
}
void loop() {
op = "{\"seat_status\":[";
for (i = 0; i < seat_no; i++) {
a = analogRead(i);
if (a > threshold) {
op += "\"0\"";
Serial.println("0");
}
else {
op += "\"1\"";
Serial.println("1");
}
if (i < seat_no - 1)
op += ",";
}
op += "]}";
data_size = op.length();
Serial1.write("AT+CIPSEND=");
Serial1.write(data_size+2);
Serial1.write("\r\n");
delay(1000);
for (i = 0; i < data_size; i++)
Serial.write(op[i]);
Serial.println();
for (i = 0; i < data_size; i++)
Serial1.write(op[i]);
Serial1.write("\r\n");
delay(5000);
}
I think my Python code is correct as I am able to receive data from other sources as well (through Android app UDP sender) so help me to rectify this problem.
Circuit Diagram
The problem is with the use of Serial1.write. It's a lower level function. All it does is send bytes and doesn't convert numbers to their string representation.
When you are writing your port and length of your data to the serial, the write function is just sending a byte with that value and not a string.
If you would replace Serial1 with Serial and send the commands back to PC, you would see the mistake.
To actually solve your problem, you should replace all of your Serial1.write with Serial1.print.

ASCII reading with arduino

This is my first post, I know this theme could be very simple or obvious but I can't figure out how to solve it.
I have a capacitance meter from jyetech wiuch claims to have a 8-N-1 serial output, here is the link to the manual. I just want to read the output with my Arduino Uno, can anyone help me? Here is the code I have done, I'm getting some real data but also some strange characters.
#include <stdio.h>
void setup() {
Serial.begin(38400);
Serial.println("OK");
}
char command[1024];
char commandBuffer[128];
int commandBufferSize = 0;
void readCommandBuffer(int bytesToRead) {
int i = 0;
char c = 0;
while (i < 128 && (i < bytesToRead || bytesToRead <= 0)) {
while (!Serial.available())
;
c = Serial.read();
if (c == '\r' || c == '\n') {
break;
}
commandBuffer[i] = c;
i++;
}
commandBufferSize = i;
}
void readCommand() {
command[0] = '\0';
readCommandBuffer(0);
if (strncmp(commandBuffer, "RCV", 3) == 0) {
commandBuffer[commandBufferSize] = '\0';
int expectedSize = atoi(commandBuffer + 4);
if (expectedSize <= 0 || expectedSize > 1024) {
return;
}
Serial.println("RDY");
int bytesRead = 0;
while (bytesRead < expectedSize) {
readCommandBuffer(expectedSize - bytesRead);
memcpy(command + bytesRead, commandBuffer, commandBufferSize);
bytesRead += commandBufferSize;
Serial.print("ACK ");
Serial.println(commandBufferSize);
}
command[bytesRead] = '\0';
} else {
memcpy(command, commandBuffer, commandBufferSize);
command[commandBufferSize] = '\0';
}
}
void loop() {
if (Serial.available()) {
readCommand();
// "command" now contains the full command
Serial.println(command);
}}
You have to use two serial ports, one to talk to the PC (the usual Serial object), and the other to talk to the instrument.
If you have an Arduino UNO, which has only one hardware serial port, you have to use the software serial library. Mega boards have instead 4 hardware serial ports, which are available through the bulit-in objects Serial1, Serial2, etc.
BTW, just noticed a very similar question was asked awhile ago:
Serial Data communication Arduino

Arduino SoftwareSerial connection with LinkSprite Jpeg Camera

So we're having trouble connecting the Arduino Uno to the LinkSprite camera, we've been using the LinkSprite sample code with a few print statements added
#include < SoftwareSerial.h >
/* Linksprite */
byte incomingbyte;
SoftwareSerial mySerial(4, 5); //Configure pin 4 and 5 as soft serial port
long a = 0x0000, j = 0, k = 0, count = 0; //Read Starting address
uint8_t MH, ML;
boolean EndFlag = 0;
void SendResetCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();
void setup() {
Serial.begin(38400);
mySerial.begin(38400);
Serial.print("Serial began\n");
}
void loop() {
SendResetCmd();
Serial.print("Reset Command Sent\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print(incomingbyte, HEX);
} //After reset, wait 2-3 second to send take picture command
Serial.print("Delay Ended\n");
SendTakePhotoCmd();
Serial.print("Take Photo Command Sent\n");
while (mySerial.available() > 0) {
Serial.print("Checking Available Bytes\n");
incomingbyte = mySerial.read();
}
byte a[32];
Serial.print("Byte array intialized\n");
while (!EndFlag) {
Serial.print("Entering While loop\n");
j = 0;
k = 0;
count = 0;
SendReadDataCmd();
Serial.print("Read Command Sent\n");
delay(250);
Serial.print("Delay Ended\n");
Serial.print(mySerial.available());
Serial.print("\n");
while (mySerial.available() > 0) {
incomingbyte = mySerial.read();
Serial.print("Incoming Byte Read\n");
k++;
if ((k > 5) && (j < 32) && (!EndFlag)) {
Serial.print("Byte Added to Array\n");
a[j] = incomingbyte;
if ((a[j - 1] == 0xFF) && (a[j] == 0xD9)) { //Check if the picture is over
Serial.print("End Flag");
EndFlag = 1;
}
j++;
count++;
}
}
for (j = 0; j < count; j++) {
if (a[j] < 0x10)
Serial.print("0");
Serial.print("Picture Printing\n");
Serial.print(a[j], HEX);
Serial.print(" ");
} //Send jpeg picture over the serial port
Serial.println();
delay(10000);
}
Serial.print("Picture Complete");
while (1);
}
//Send Reset command
void SendResetCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x26);
mySerial.write(byte(0x00));
}
//void SetImageSizeCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x31);
//mySerial.write(0x05);
//mySerial.write(0x04);
//mySerial.write(0x01);
//mySerial.write(byte(0x00));
//mySerial.write(0x19);
//mySerial.write(0x22);
//}
//void SetBaudRateCmd()
//{
//mySerial.write(0x56);
//mySerial.write(byte(0x00));
//mySerial.write(0x24);
//mySerial.write(0x03);
//mySerial.write(0x01);
//mySerial.write(0xAE);
//mySerial.write(0xC8);
//
//}
//Send take picture command
void SendTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(byte(0x00));
}
//Read data
void SendReadDataCmd() {
MH = a / 0x100;
ML = a % 0x100;
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x32);
mySerial.write(0x0c);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(MH);
mySerial.write(ML);
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(byte(0x00));
mySerial.write(0x20);
mySerial.write(byte(0x00));
mySerial.write(0x0a);
a += 0x20; //address increases 32£¬set according to buffer size
}
void StopTakePhotoCmd() {
mySerial.write(0x56);
mySerial.write(byte(0x00));
mySerial.write(0x36);
mySerial.write(0x01);
mySerial.write(0x03);
}
`
The code basically sends a take picture command to the camera and then reads the HEX values that the camera sends and saves the values in an array. We know the camera works because we tested it on another device.
The problem initially was, the values that we were getting from the camera aren't correct. The EndFlag in the while loop is never toggled because the HEX values that indicate the end of a JPEG values (FF and D9) are never read so it never breaks from the while loop. Now, the terminal doesn't print anything until the camera is disconnected, then all the values seem to get flushed to the screen and the command mySerial.available() returns 0 meaning that there is nothing in the serial read buffer.
I compared your code with the example sketch provided from the manufacturer and figured out that your initialization procedure differs from the original. In the official sample code they first connect to the camera on 115200 serial baudrate, tells camera to change it's baudrate to 38400 and then they connect to camera again but with different speed - 38400 baud.
In your code I see that you are connecting on 38400 baud speed in the beginning. However, the camera is operating at a different speed and this explains why you get garbage instead of valid data. I recommend that you perform the correct initialization procedure, as described in the example:
void setup()
{
Serial.begin(38400);
mySerial.begin(115200);
delay(100);
SendResetCmd();
delay(2000);
SetBaudRateCmd(0x2A);
delay(500);
mySerial.begin(38400);
delay(100);
Serial.println("initialization done.");
}
Also, uncomment SetBaudRateCmd() function as it's used in the initialization procedure.

Resources