Receiving strings on Arduino - problems - - string

I have a problem with my code when I receive a string from my app in Android.
I need to send some string from my App to Arduino (over bluetooth BLE), and get data in a SdCard (in Arduino).
The strings are two and the first string that I need to send is:
U\n
and the last one is:
0 20/11/25 18:18:46\n
The code in Arduino for process this strings is:
SoftwareSerial HM10(8, 9);
char appData = ' ';
String inData = "";
void loop() {
HM10.listen(); // listen the HM10 port
while (HM10.available() > 0){
appData = HM10.read();
delay(50);
inData = inData+appData;
if (appData == '\n'){
Serial.print("String:");
Serial.println(inData);
R_SdCard(inData);
inData="";
}
}
}
Ok, the output for Serial.print("String:"); print U (the result that I expect), but when I need to send the last one string I only receive trash...
But if I forward the last string again, now the string received it's Ok!!
I have also sent the first string (the string received is Ok) and next restart Arduino and finally send the last string and the string received ( the last one) is Ok!!
I tried to understand where is the problem but without results... maybe I need to put in blank to appData??
Thanks in advance!

Related

how to trim unknown first characters of string in code vision

I set a mega16 (16bit AVR microcontroller) to receive data from the serial port
which is connected to Bluetooth module HC-05 for attaining an acceptable number
sent by my android app and an android application sends a number in the form of a
string array whose maximum length is equal to 10 digits. The problem arrives
while receiving data such that one or two unknown characters(?) exist at the
beginning of the received string. I have to remove these unknown characters from
the beginning of the string in the case of existence.
this problem is just for HC-05. I mean I had no problem while sending numbers by
another microcontroller instead of android applications.
here is what I send by mobile:
"430102030405060\r"
and what is received in the serial port of microcontroller:
"??430102030405060\r"
or
"?430102030405060\r"
here is USART Receiver interrupt code:
//-------------------------------------------------------------------------
// USART Receiver interrupt service routine
interrupt [USART_RXC] void usart_rx_isr(void)
{
char status,data;
status=UCSRA;
data=UDR;
if (data==0x0D)
{
puts(ss);printf("\r")
a=0;
memset(ss, '\0', sizeof(ss));
}
else
{
ss[a]=data;
a+=1;
}
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
rx_buffer[rx_wr_index++]=data;
if RX_BUFFER_SIZE == 256
// special case for receiver buffer size=256
if (++rx_counter == 0) rx_buffer_overflow=1;
else
if (rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
if (++rx_counter == RX_BUFFER_SIZE)
{
rx_counter=0;
rx_buffer_overflow=1;
}
endif
}
}
//-------------------------------------------------------------------------
how can I remove extra characters (?) from the beginning of received data in codevision?
You do not need to remove them, just do not pass them to your processing.
You either may test the data character before putting it into your line buffer (ss) or after the complete line was received look for the first relevant character and only pass the string starting from this position to your processing functions.
Var 1:
BOOL isGarbage(char c){
return c<'0' || c > '9';
}
if (data==0x0D)
{
puts(ss);printf("\r")
a=0;
memset(ss, '\0', sizeof(ss));
} else {
if(!isGarbage(data))
{
ss[a]=data;
a+=1;
}
}
Var2:
if (data==0x0D)
{
const char* actualString = ss;
while(isGarbage(*actualString )){
actualString ++;
}
puts(actualString );printf("\r")
a=0;
memset(ss, '\0', sizeof(ss));
} else {
ss[a]=data;
a+=1;
}
However:
maybe you should try to solve the issue in contrast to just fix the symptoms (suppress '?' characters).
What is the exact value of the questionable characters? I suspect, that '?' is only used to represent non printable data.
Maybe your interface configuration is wrong and the sender uses software flow control on the line and the suspicious characters are XON/XOFF bytes
One additional note:
You may run into trouble if you use more complex functions or even peripheral devices from your interrupt service routine (ISR).
I would strongly suggest to only fill buffers there and do all other stuff in the main loop. triggered by some volatile flags data buffers.
Also I do not get why you are using an additional buffer (ss) in the ISR, since it seems that there already is a RX-Buffer. The implementation looks like that there is a good RX-receive buffer implementation that should have some functions/possibilities to get the buffer contents within the main loop, so that you do not need to add your own code to the ISR.
Additional additional notes:
string array whose maximum length is equal to 10 digits.
I count more than that, I hope your ss array is larger than that and you also should consider the fact that something may go wrong on transmission and you get a lot more characters before the next '\n'. Currently you overwrite all your ram.

How can I read and write to the serial buffer in the same Python script?

I'm having a problem understanding how serial works.
I am trying to write a looping script that generates a code in Python, reads the serial buffer for a six digit code entered into the Arduino keypad, sends it back to Python, checks it against a code in an postgreSQL database and returns a value (1 for match, and 0 for no match). I want to send the binary value to the Arduino and trigger a linear servo. When I run the Python loop that I wrote, it functions how I would expect, until I get to the value returned from the SQL database. The value does not seem to write to the serial buffer, and so the Arduino loop never triggers the linear servo. For simplicity of testing, I am generating a code for the keypad locally every time the loop runs.
At first, I was using the keypad.h function waitForKey(), which is blocking. I thought that the blocking was keeping the Arduino loop from registering the updated value and operating the servo. I changed it to getKey(), but the function is still not working. I have tried different encoding methods and writing different types of data (characters and numbers), but nothing seems to work.
Here is the most relevant section of the Python code:
if (txStage == '0'):
#genCode = search_ChatValue("access_code","demo") #Find the value in the database table
time.sleep(10)
while (ser.inWaiting() > 0):
codeDigit = ser.readline(9)
codeDigit = codeDigit.decode()
codeDigit = codeDigit[0:6]
ser.flush()
print(codeDigit)
attemptCode(codeDigit, "demo") #check the entered code against the database code
doorVer = codeResult("demo") #Check if the code was correct
print(doorVer)
if (doorVer == "Success! You may now access your SafeDrop."): #if the code is correct
lockVer = '1' #variable to be sent to the Arduino
print("lock status is: " + str(lockVer))
ser.flush() #flush the serial buffer to ensure it is empty
lockVer = lockVer.encode("utf-8")
ser.write(lockVer) #write to Arduino
time.sleep(10) #wait for lock to open
#time.sleep(5)
Here is the Arduino code:
void loop(){
char pass[6];
char lockVer = '0';
int sensorValue = analogRead(A0);
Door(sensorValue);
door = warning;
if (Serial.available() > 0){
lockVer = Serial.read();
}
if (lockVer == '0'){
while (door == 0){
while (i < 6){
char key = customKeypad.getKey();
if (key){
pass[i] = key;
lcd.write('*');
i++;
if (i == 6){
delay(500);
lcd.clear();
i = 0;
}
}
Serial.println(pass);
Serial.flush();
}
//delay(5000);
//scaleCheck;
}
}
else{
Lock(unlock);
delay(5000);
Lock(lock);
delay(5000);
}
}
My hope is that the variable lockVer would change from 0 to 1, and this change would be identified by the Arduino, causing the linear servo to activate and move into the unlock position, wait 5 seconds, and move back to the locked position. Instead, the Arduino code ignores the change, and keeps looking for keypad input. The keypad code is confirmed to work, and the variable lockVer does change from 0 to 1 in Python, just not in Arduino.
I can post the rest of the code if anyone needs more context, but I am running out of things to try, and I would really appreciate some help. Thanks!
looks like your arduino code is getting stuck in the "while(door == 0)" loop. Change that to an if condition and your code should work as intended

Arduino serial data manipulation - Sensors Serial Data, Read and parse to variables

I send 3 set of data from 3 sensors from Arduino 1 (router) to another Arduino(coordinator) to with wireless technology (xbee):
On coordinator, I receive wireless data from this 3 sensors(from the router) perfectly. The data stream is something like this(each sensor data on its line):
22.5624728451
944
8523
I want to have these 3 values as 3 variables that get updated constantly and then pass these values on to the rest of the program to make something like print on LCD or something else:
temperature=22. 5624728451
gas=944
smoke=8523
Initially, I had only 2 sensors and I send the data of these 2 sensors something like this:
22.5624728451944(22.5624728451 – temperature, 944 - gas) and I received both of them on the same line and divided everything into two variables(with readString.substring() ) with the code below. But now I have 3 sensors and I receive data on a separate line because I don't know which is the length of each data string … And I can't use the same technique (sending only one string that contain all sensor data on the same line and then divide them)
My old code:
#include <LiquidCrystal.h>
LiquidCrystal lcd(12,11,10,9,8,7);
String temperature;
String gas;
String readString;
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop() {
while (Serial.available() > 0)
{
char IncomingData = Serial.read();
readString += IncomingData ;
temperature = readString.substring(0, 13); //get the first 13 characters
gas = readString.substring(13, 16); //get the last 3 characters
Serial.print(IncomingData); //here I have my string: 20.1324325452924 wichs is updating properly when I have sensor values changes
// Process message when new line character is DatePrimite
if (IncomingData == '\n')
{
Serial.println(temperature);
lcd.setCursor(0,0);
lcd.write("T:");
lcd.print(temperature);
delay(500);
temperature = ""; // Clear DatePrimite buffer
Serial.println(gaz);
lcd.begin(16, 2);
lcd.setCursor(0,1);
lcd.write("G:");
lcd.print(gas);
delay(500);
gaz = ""; // Clear DatePrimite buffer
readString = "";
}
}
}
All I want to do now is to assign a variable for every sensor data (3 lines – 3 variables for each line) updated constantly and then pass these values on to the rest of the program. Does anyone have any idea how to modify the code tO work in this situation?
Thank you in advance!
I would recommend that you concatenate the values into the same line on the sending end and use a delimiter like a comma along with string.split() on the receiving end if you are committed to using string values. EDIT: It appears Arduino does not have the string.split() function. See this conversation for an example.
An alternative would be to set a standard byte length and send the numbers as binary instead of ASCII encoded strings representing numbers. See this post on the Arudino forum for a little background. I am recommending sending the number in raw byte notation rather than as ASCII characters. When you define a variable as in integer on the arduino it defaults to 16-bit signed integer value. A float is a 32-bit floating point number. If, for example, you send a float and two ints as binary values the float will always be the first 4 bytes, the first int, the next 2 and the last int the last 2. The order of the bytes (endianness, or most significant byte first (Big Endian, Motorolla style)/least significant bit first (Little Endian, Intel style)).

Why is my data converted to ASCII using Serial.print function in arduino?

I am coding a small software to send data with an RN2483 transciever, and I have realised that my data is converted to ASCII when I sent it through serial. It is to say, I have the following part in the sender, the data has to be HEX
String aux = String(message.charAt(i),HEX);
dataToBeTx = "radio tx " + aux+ "\r\n";
Serial1.print(dataToBeTx)
On the receiver I am reading Serial1 till I get the message, which I receive properly, however it is an ASCII representation of the HEX data, and I would like to have it HEX, I mean, I send HI that is converted to HEX (H I=>0x48 0x49) on the receiver if I translate that value to HEX again I got different things than my H or I , so I guess it is being encoded in ASCII, how can I ride off from that?
Thanks in advance,
regards
It is very unclear what you are trying to achieve. The first line in your code converts a single character into a string in hexadecimal. For example:
void setup ()
{
Serial.begin (115200);
Serial.println ();
String aux = String('A', HEX);
Serial.print ("aux = ");
Serial.println (aux);
} // end of setup
void loop ()
{
} // end of loop
Output:
aux = 41
So the 'A' in my code (internally represented as 0x41) has now become two ASCII characters: 4 and 1. That is, a string which is two bytes long.
So, in a sense, you can say it is already in hex.
if I translate that value to HEX again I got different things than my H or I
Well, yes, if you translate it "again" then you would get 0x34 and 0x31.
Do you want to send A in this case, 41 or something else?

Sending string using i2c commuication on two arduino micro-controller

i am using two arduino mcu to connect two lines of LED-matrix display. I tried using i2c communication to connect a master mcu (which controls the first line of the LED-matrix display) and slave mcu (which controls the second line of LED-matrix display). I need to pass a string data(consist of 300 characters) from the master to the slave, so that i can display the same string to the second line of the LED-matrix display.
The problem is, I can't pass a string variable using Wire.read() from master to slave. My solution to this, was to convert the string to character before using wire.read() to transmit the data, but the slave cannot receive the whole string, only the first few characters. I also had problem in the timing of the display, the second line of the LED-matrix(which is controlled by the slave), displays the string very late.
This is the sample code for the master mcu
//Master Code
String inData;
String LED_DATA;
char buf[300];
void Input(void){
while(Serial.available() > 0)
{
char received = Serial.read();
inData+=received;
if(received == '~')
{
LED_DATA = inData;
inData.toCharArray(buf,300);
Wire.beginTransmission(5);
Wire.write(buf);
Wire.endTransmission();
}
}
}
And this is the sample code for the slave
//slave
char LED_DATA[100];
void setup(){
Wire.begin(5);
Wire.onReceive(receiveEvent);
}
void receiveEvent(int howMany){
while(Wire.available()){
LED_DATA[300] = Wire.read();
}
}
I am new to arduino and microcontroller. What is the easiest way possible to solve my problem? Thank you very much.
You can pass string to Wire.write(), by passing the variable as a char * . So if String a = "test"; was the earlier declaration, try using Char* a = "test"; it will send the data through

Resources