Sharing text through XBee on Arduino - xbee

How do I share text through an XBee module?
I tried, but instead of a word, I am getting some numbers every time. I want to exchange text data from both sides. I am using an Arduino for communication. How can I fix this problem?

I've been through a similar problem and was able to work around it. I assume you're using a MEGA 2560 and have a set of XBEE modules connected to two computers through the SPARKFUN XBEE USB explorer.
I've included my code that you can upload to both of the XBEEs and use them as a simple walkie-talkie pair. The program is meant to read an entire incoming word/string terminated with a defined character.
//xbee walkie-talkies
#define EndOfInput '#'//define a terminating character
void setup() {
Serial1.begin(9600); //serial thru pin 19
Serial.begin(9600); //Serial monitor
}
String incomingWord=""; //initialize to NULL
char input; //to read the incoming character
void loop() {
if (Serial.available()>0) {
// send out whatever is typed at the serial
//monitor thru the XBEE
Serial1.write(Serial.read());
}
//read the entire incoming word
while(Serial1.available()>0){
input = Serial1.read();
if (input != EndOfInput) incomingWord+=input;
else break;
}
//print out the word received on the serial monitor
Serial.println(incomingWord);
incomingWord = ""; //reset the string
}
It should be pretty self-explanatory.

Related

Can't send data to ESP8266 via arduino

I have an ESP8266-01 and I want to send sensor data from Arduino to ESP8266 via serial communication but the data I receive is not correct, I tried changing baud rates but no luck, here is the code
Code for ESP8266:
#include <SoftwareSerial.h>
void setup() {
// put your setup code here, to run once:
Serial.begin(38400);
}
void loop() {
// put your main code here, to run repeatedly:
while(Serial.available()) {
Serial.println("yes");
Serial.println(Serial.read());
}
delay(5);
}
Code for Arduino
#include <SoftwareSerial.h>
SoftwareSerial esp(1, 0);
String str;
void setup(){
Serial.begin(38400);
esp.begin(38400);
delay(2000);
}
void loop() {
// put your main code here, to run repeatedly:
str = String("Hi there");
esp.println(str);
esp.println("hi there");
delay(1000);
}
Here is the serial monitor:
Serial monitor showing numbers instead of "hi there"
The wiring connections are correct.
if you are using simple wires for the connection you might need to reduce the baud rate at 9600 or lower.
For higher speed you will need coaxial cables to get a decent communication distance. Moreover I am sure that you have checked the electrical connection obvously.
On the programming side, Serial.read() returns the first byte of incoming serial data available (or -1 if no data is available). Data type: int. This is why you are getting a single number instead of your string.
I would suggest to use Serial.readString() instead.
Please see the proper documentation here:
https://www.arduino.cc/reference/en/language/functions/communication/serial/
All the best

Why does this code clear the screen on the SparkFun 16x2 SerLCD

I have been playing around with SparkFun 16x2 SerLCD LCD from SparkFun and controlling it via the Tiva C EK-TM4C123GXL board. I have managed to connect the LCD via SPI communication and written code to display strings on the board. However I was having trouble writing code that would clear the screen for me until I came across this code online:
#include <stdint.h>
#include <stdlib.h>
#include "inc/tm4c123gh6pm.h"
void spi_master_ini(void){ //Setup SPI
SYSCTL_RCGCSSI_R|=(1<<2);
//SYSCTL_RCGCGPIO_R |=(1<<1);
SYSCTL_RCGC2_R |=(1<<1);
GPIO_PORTB_AFSEL_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PCTL_R=0x22220000;
GPIO_PORTB_DEN_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
GPIO_PORTB_PUR_R|=(1<<4)|(1<<5)|(1<<6)|(1<<7);
SSI2_CR1_R=0;
SSI2_CC_R=0;
SSI2_CR1_R=64;
SSI2_CR0_R=0x7;
SSI2_CR1_R|=(1<<1);
}
void send_byte(char data){
SSI2_DR_R=data;
while((SSI2_SR_R&(1<<0))==0);
}
void send_str(char *buffer){
while(*buffer!=0){
send_byte(*buffer);
buffer++;
}
}
int main(){
spi_master_ini();
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
send_str("Testing");
}
Specifically the 2 lines of code that are puzzling me:
SSI2_DR_R=0x7C; //Put into setting mode.
SSI2_DR_R=0x2D; //Clear screen, move cursor to home position.
After reading through the HD44780U datasheet I wasn't able to see how sending those HEX values to the data lines would do anything other than print "|" and "-" to the LCD. However, to my surprise when I ran the code it works and clears my LCD screen.
The data sheet for the HD44780U is irrelevant - you are not talking directly to the display controller. On the SparkFun 16x2 SerLCD, the SPI communication is with the ATmega328P which in turn communicates with the display controller.
This simplifies the interface to the display, since you only need an SPI or I2C link and do not need a 4/8 bit data bus and additional control lines required by the display controller.
The software running on the ATMega328P interprets and translates commands independently of the display controller. The source code at https://github.com/sparkfun/OpenLCD applies.
settings.h has:
#define SPECIAL_SETTING '|' //124, 0x7C, the pipe character: The command to do special settings: baud, lines, width, backlight, splash, etc
Then in OpenLCD.ino void updateDisplay() there is:
//Check to see if the incoming byte is special
if (incoming == SPECIAL_SETTING) //SPECIAL_SETTING is 127
{
currentMode = MODE_SETTING;
}
...
note the comment is erroneous, it is 124 not 127 (perhaps says something about the quality of this code).
Then later:
else if (currentMode == MODE_SETTING)
{
currentMode = MODE_NORMAL; //In general, return to normal mode
...
//Clear screen and buffer
else if (incoming == 45) //- character
{
SerLCD.clear();
SerLCD.setCursor(0, 0);
clearFrameBuffer(); //Get rid of all characters in our buffer
}
...
Then clearFrameBuffer() simply fills the buffer with spaces rather then using the HD44780 "Clear Display" instruction:
//Flushes all characters from the frame buffer
void clearFrameBuffer()
{
//Clear the frame buffer
characterCount = 0;
for (byte x = 0 ; x < (settingLCDwidth * settingLCDlines) ; x++)
currentFrame[x] = ' ';
}
Much of the documentaton is for Arduino, but the command table at https://learn.sparkfun.com/tutorials/avr-based-serial-enabled-lcds-hookup-guide/firmware-overview is valid regardless. It is interms of characters rather then integer codes so has:
...
...
And many more commands you might find useful.

Serial Communication between 2 Arduino Uno using just Registers

I need to transfer a string between 2 Arduino Uno, using serial communication without functions(just manipulating registers, such as UDR0).
I am able to send a string using
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
void USART_Init(unsigned int ubrr)
{
UBRR0H=(unsigned char)(ubrr>>8);
UBRR0L=(unsigned char)ubrr;
UCSR0B=(1<<RXEN0)|(1<<TXEN0);
UCSR0C=(1<<USBS0)|(3<<UCSZ00);
}
void USART_Transmit(unsigned char data)
{
while(!(UCSR0A&(1<<UDRE0)));
UDR0=data;
}
void SendString(char *StringPtr)
{
while(*StringPtr !=0x00)
{
USART_Transmit(*StringPtr);
StringPtr++;
}
}
void setup()
{
USART_Init(MYUBRR);
}
void loop()
{
SendString("123456");
delay(1000);
}
but I have no idea how to copy the content of the UDR0 register at the other end. The function should be something like:
unsigned char USART_Receive(void)
{
while(!(UCSR0A&(1<<RXC0)))
return UDR0;
}
But I don't know how to actually use it; I need to save all those chars from the serial to a string, then show the string on a LCD connected to the second Arduino Uno, but every time when I attempt to receive more that one char it's all working very bad(blank spaces, a lot of zeros, invalid characters).
I read that if I have an LCD connected to the second arduino, it's much better to not use the USART_Receive() function, and implement it as an interrupt, but I don't know how to do that either.
Do you have any idea how to transfer the string to the other Arduino?
Perhaps try to put all the chars in an big array and then send that array to your LCD. That way, the time between reading one char and the next one is minimized. (UART is asynchronous, so if you're too slow, you miss the requested data).

Store the data collected in the interrupt handler esp8266

The main idea is to receive the TLS key, SSID and password to esp8266 by light.
I implemented some simple protocol with a clock signal and data signal.
I can read the data and write it to serial to see what is going on.
But the main problem is that data can be the different length and my C lang knowledge is not enough to provide the storing this data in the variable. The data will be the JSON string.
LOCAL void ICACHE_FLASH_ATTR beam_intr_handler(void)
{
if (GPIO_REG_READ(GPIO_STATUS_ADDRESS) & BIT(BUTTON_PIN))
{
//disable interrupt
gpio_pin_intr_state_set(GPIO_ID_PIN(BUTTON_PIN), GPIO_PIN_INTR_DISABLE);
//clear interrupt status
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, GPIO_REG_READ(GPIO_STATUS_ADDRESS) & BIT(BUTTON_PIN));
os_printf("tick %d \r\n", system_get_time());
os_printf("sensor states %d\r\n", ((GPIO_REG_READ(GPIO_IN_ADDRESS) & (BIT(SENSOR_PIN1))) != 0));
}
}

Arduino Not Receiving Serial Data When Shield Attached

I have nexus duino 3WD and tried to do serial comm to move the robot. I have to remove shield to upload sketch code. This is my sketch:
#include <fuzzy_table.h>
#include <PID_Beta6.h>
#include <PinChangeInt.h>
#include <PinChangeIntConfig.h>
#include <MotorWheel.h>
#include <Omni3WD.h>
#include <EEPROM.h>
#define _NAMIKI_MOTOR //for Namiki 22CL-103501PG80:1
/*******************************************/
int incoming = 0;
int speed = 100;
// Motors
irqISR(irq1,isr1);
MotorWheel wheel1(9,8,6,7,&irq1); // Pin9:PWM, Pin8:DIR, Pin6:PhaseA, Pin7:PhaseB
irqISR(irq2,isr2);
MotorWheel wheel2(10,11,14,15,&irq2); // Pin10:PWM, Pin11:DIR, Pin14:PhaseA, Pin15:PhaseB
irqISR(irq3,isr3);
MotorWheel wheel3(3,2,4,5,&irq3); // Pin3:PWM, Pin2:DIR, Pin4:PhaseA, Pin5:PhaseB
Omni3WD Omni(&wheel1,&wheel2,&wheel3);
/******************************************/
void setup() {
Serial.begin(38400);
Serial.println("setup");
TCCR1B=TCCR1B&0xf8|0x01; // Pin9,Pin10 PWM 31250Hz
TCCR2B=TCCR2B&0xf8|0x01; // Pin3,Pin11 PWM 31250Hz
Omni.PIDEnable(0.26,0.02,0,10);
}
/****************************************/
void loop() {
if(Serial.available() > 0) {
incoming = Serial.read();
Serial.print(incoming);
if(incoming==0) {
Omni.setCarStop();
} else if(incoming==1) {
Omni.setCarAdvance(speed);
} else if(incoming==2) {
Omni.setCarRotateLeft(speed);
} else if(incoming==3) {
Omni.setCarRotateRight(speed);
}
}
Omni.PIDRegulate();
}
I tried to send data both from Serial Monitor and also PC app with USB cable. When shield is not attached I can send data and receive feedback from arduino. But when shield is attached it seem arduino not receiving data, the RX led flash but not the TX led, got 'setup' text output so arduino can send data to PC. Other thing is I can only use 38400 baud rate, otherwise the output will be garbagish.
I'm not sure if I do wrong in the code? Probably device power issues?
If you change the jumpers from RS-485 to Bluetooth like what it says here http://www.dfrobot.com/wiki/index.php/Arduino_I/O_Expansion_Shield_(SKU:_DFR0014)
then everything will work fine. uploading to the board without removing the shield might still be an issue, and sonars probably will not work, but at least you'll be able to read serial through the board.

Resources