Hi friends!
I'm developing a system that relays on communication between an arduino(mega2560) and an Android Tablet, connected by an USB cable, using Serial.
The Android will send simple messages and the Arduino should take actions:
Receive "1Lz" -> Digital pin 8 to HIGH
Receive "1Dz" -> Digital pin 8 to LOW
Receive "2Lz" -> Digital pin 9 to HIGH
Receive "2Dz" -> Digital pin 9 to LOW
Receive "ADz" -> Digital pins 8 and 9 to LOW
*Character "z"(122) is the character that tells the Arduino to take an action... If there's no "z", there's nothing to be done
Here's a code that works:
char inByte[10];
int i = 0;
int y = 0;
String text;
boolean haveaction = false;
void setup() {
Serial.begin(9600);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop() {
i=0;
text = "";
while (Serial.available()) {
inByte[i] = Serial.read();
if (inByte[i] == 10){
inByte[i] = 0;
} else if (inByte[i] == 122){
inByte[i] = 0;
haveaction = true;
}
i++;
}
text = inByte;
Serial.println("Actual text:" + text);
if (haveaction == true){
action();
haveaction = false;
}
}
void action(){
if (text == "1L"){
digitalWrite(8, HIGH);
} else if (text == "2L"){
digitalWrite(9, HIGH);
} else if (text == "1D"){
digitalWrite(8, LOW);
} else if (text == "2D"){
digitalWrite(9, LOW);
} else if (text == "AD"){
digitalWrite(8, LOW);
digitalWrite(9, LOW);
}
}
The problem is I don't want the Serial to be flooded with "Text: ____" messages... Then I tried to put the "Serial.print" inside the "if" statement.
Like this:
if (haveaction == true){
text = inByte;
Serial.println("Actual text:" + text);
action();
haveaction = false;
}
After that, the Arduino simply stopped taking any actions, because the text that is shown in this step is always empty...
I tried then simply commenting the print line, like this:
text = inByte;
//Serial.println("Actual text:" + text);
if (haveaction == true){
action();
haveaction = false;
}
And the Arduino won't still take any actions, but I don't know why.
Anyone could give any help on why is this happening?
It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).
Have a look at the examples in Serial Input Basics - simple reliable non-blocking ways to receive data.
The technique in the 3rd example will be the most reliable. It is what I use for Arduino to Arduino and Arduino to PC communication.
You can send data in a compatible format with code like this (or the equivalent in any other programming language)
Explaining a bit more of my project: I'm designing a Self Service Beer Tap...
The interface of the tap will be an Android Tablet and the action(valves/relays/RFID reading) will be done on the Arduino side.
I tested the example 3 logic on the simple test code I wrote on the post above and it worked fine, but I'm facing more problems after incorporating the RFID reader on my project.
My code:
//Serial Reading Variables
const byte numChars = 32;
char receivedChars[numChars];
boolean newData = false;
//RFID Variables
#include <SPI.h>
#include <MFRC522.h>
constexpr uint8_t RST_PIN = 5; // Configurable, see typical pin layout above
constexpr uint8_t SS_PIN = 53; // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
byte nuidPICC[4];
void setup() {
Serial.begin(230400); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
}
void loop() {
MFRC522::MIFARE_Key key;
MFRC522::StatusCode status;
for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;
// Look for new cards
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Verify if the NUID has been readed
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Check if the token is compatible
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
if (piccType != MFRC522::PICC_TYPE_MIFARE_MINI &&
piccType != MFRC522::PICC_TYPE_MIFARE_1K &&
piccType != MFRC522::PICC_TYPE_MIFARE_4K) {
Serial.println(F("INCOMP_TOKEN"));
return;
}
Serial.print("ID<");
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = mfrc522.uid.uidByte[i];
Serial.print(nuidPICC[i]);
if(i!=3){
Serial.print(":");
}else{
Serial.print(">");
}
}
byte block;
byte len;
byte Name[18];
block = 4;
len = 18;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 4, &key, &(mfrc522.uid)); //line 834 of MFRC522.cpp file
if (status != MFRC522::STATUS_OK) {
Serial.print(F("<NAME_AUTH_FAIL>"));
return;
}
status = mfrc522.MIFARE_Read(block, Name, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("<NAME_READ_FAIL>"));
return;
}
byte DOC[18];
block = 1;
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, 1, &key, &(mfrc522.uid)); //line 834
if (status != MFRC522::STATUS_OK) {
Serial.print(F("<DOC_AUTH_FAIL>"));
return;
}
status = mfrc522.MIFARE_Read(block, DOC, &len);
if (status != MFRC522::STATUS_OK) {
Serial.print(F("<DOC_READ_FAIL>"));
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// Halt PICC
mfrc522.PICC_HaltA();
// Stop encryption on PCD
mfrc522.PCD_StopCrypto1();
Serial.println("Waiting for Serial Input.");
while(Serial.available() == 0){ //Waiting for authentication
}
Serial.println("Serial Input Received.");
recvWithStartEndMarkers();
showNewData();
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
Serial.print("Received Char: <");
Serial.print(rc);
Serial.println(">");
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void showNewData() {
if (newData == true) {
Serial.print("This just in ... ");
Serial.println(receivedChars);
newData = false;
}
}
Arduino is getting scrambled data from serial, not the characters I write:
It stops at "Waiting for Serial Input." after I show an RFID tag.
Then I write something into Serial, like .
It detects that the serial is available and prompts "Serial Input Received." //Everything OK by now
Then it starts strange chars, not what I wrote to it.
Serial log:
ID<155:228:220:62>
Waiting for Serial Input.
Serial Input Received.
Received Char: <<>
Received Char: <⸮>
Received Char: <.>
Received Char: <⸮>
Received Char: <⸮>
What may be happening here?
The serial code works on it's own with no problem at all... But with the RFID reader it's freaking out.
I had not... The code worked fine at 9600 bauds...
I tried the reading code alone and it was reading fine at that baud rate... I had increased it so much because I read somewhere that the RFID reading speed would be higher...
Thank you for the help.
EDIT: Thank you very much for the precious information Robin2! The code worked fine at 250000 bauds... The best of both worlds: Serial reading reliability and RFID reading speed.