Hello, everyone. I have a problem about Uart Interface, the Nano 33 BLE is connected with RFID reader for send and receive the Command. The problem is the Received Data will shift after it worked fine in several min. The situation is shown on below pic. In the pic, the byte in red should be appeared on Blue
I had tried use while(uart.read() != -1)
to flush it, but there are no data. And I also tried reset the client device, the problem isn't fixed, so i considered the problem may caused by Arduino, and the situation will same after reset the arduino.
Here is code
// Import Library
#include <Wire.h>
#include <Arduino.h>
#include <ArduinoBLE.h>
#include "wiring_private.h"
//Pin Declaration
//UUID Setting
//Global Var
bool isBLEconnected = false;
bool BLEnotBegin = false;
bool LEDState = false;
bool isNavOrSet_BLE = false;
bool flagSendCmd = false;
bool flagGetData = false;
bool flagData2BLE = false;
bool flagBLE = false;
bool flagNonReading = false;
bool flagFlush = false;
int FeedBackIndex = 0;
// uint8_t readbyte_flag = 0;
uint8_t CmdCounter = 0;
uint8_t FlushCounter = 0;
byte length = 0;
byte from_BLE[60] = {};
byte FeedBack[300] = {};
// Millis timer
unsigned long currentMillis = 0;
unsigned long previousMillis_LEDBlink = 0;
unsigned long previousMillis_checkSum = 0;
unsigned long previousMillis_cmd2reader = 0;
unsigned long previousMillis_Forward = 0;
unsigned long previousMillis_Flush = 0;
unsigned long previousMillis_NonReading = 0;
unsigned long previousMillis_readStart = 0;
// Micros timer
unsigned long currentMicros = 0;
unsigned long previousMicros_readFeedBack = 0;
// Uart communication
UART uart(digitalPinToPinName(3), digitalPinToPinName(2), NC, NC); // TX, RX
// BLE communication
BLEService BLE(service_uuid);
BLECharacteristic toReaderChar(toReaderChar_uuid, BLEWrite | BLEWriteWithoutResponse, 60);
BLECharacteristic fromReaderChar(fromReaderChar_uuid, BLERead | BLENotify, 400);
// BLEService Battery(battery_levelSer_uuid);
// BLEByteCharacteristic battery_leveChar(battery_levelSer_uuid, BLERead | BLENotify);
// Functions Declaration
void LEDBlink();
void UartFlush();
void ReadFeedBack();
void triggerReadbyte();
void sendnreveice(byte cmd[], uint8_t length);
void cmd2reader(byte cmd[], uint8_t cmd_size);
byte checksum(byte buffer[], uint8_t buffer_len);
void setup()
{
// put your setup code here, to run once:
// Start I2C
Wire.begin();
// Start Serail
Serial.begin(115200);
uart.begin(115200);
//Initializes the BLE device
if (!BLE.begin())
{
BLEnotBegin = true;
}
// set advertised local name and service UUID:
BLE.setLocalName(device_name);
BLE.setDeviceName(device_name);
BLE.setAdvertisedService(ble);
// add the characteristic to the service
ble.addCharacteristic(toReaderChar);
ble.addCharacteristic(fromReaderChar);
ble.addCharacteristic(geoPositionChar);
ble.addCharacteristic(motorChar);
ble.addCharacteristic(isNavOrSetChar);
// Battery.addCharacteristic(battery_leveChar);
// add service
BLE.addService(ble);
// start advertising
BLE.advertise();
}
void loop()
{
// Reload the WDTs RR[0] reload register
NRF_WDT->RR[0] = WDT_RR_RR_Reload;
currentMillis = millis();
currentMicros = micros();
// put your main code here, to run repeatedly:
LEDBlink();
// listen for BLE peripherals to connect:
BLEDevice central = BLE.central();
if (central)
{
// Only send data if we are connected to a central device.
isBLEconnected = (central.connected() ? true : false);
if (central.connected())
{
if (!flagBLE)
memset(from_BLE, 0, sizeof(from_BLE));
if (toReaderChar.written())
{ // revice the comand through BLE
length = toReaderChar.valueLength();
toReaderChar.readValue(from_BLE, length);
if (from_BLE[0] == (byte)0xA0 && from_BLE[2] == (byte)0xFE)
{
if (!flagSendCmd)
{
flagBLE = true;
flagSendCmd = true;
}
}
}
if (isNavOrSetChar.written())
{
isNavOrSet_BLE = (isNavOrSetChar.value() ? true : false);
}
if (motorChar.written())
{
}
if (!isNavOrSet_BLE)
sendnreveice(from_BLE, length);
}
}
if (!flagFlush)
triggerReadbyte();
}
void sendnreveice(byte cmd[], uint8_t length)
{
if (!flagFlush)
{
if (flagSendCmd)
cmd2reader(cmd, length);
if (flagGetData)
ReadFeedBack();
if (flagData2BLE)
{
if (isBLEconnected)
{
fromReaderChar.writeValue(FeedBack, FeedBackIndex, true);
flagData2BLE = false;
}
}
if (!flagGetData && !flagData2BLE)
{
memset(FeedBack, 0, sizeof(FeedBack));
FeedBackIndex = 0;
}
}
else
{
UartFlush();
}
}
void scranRoutine()
{
byte cmd[4][10] = {
{0xA0, 0x04, 0xFE, 0x80, 0xFF},
{0xA0, 0x03, 0xFE, 0x90},
{0xA0, 0x06, 0xFE, 0x81, 0x03, 0x00, 0x08},
{0xA0, 0x03, 0xFE, 0x93}};
}
void cmd2reader(byte cmd[], uint8_t cmd_size)
{
uint8_t buffer_len = cmd[1] + 2;
if (CmdCounter < 1)
{
if (cmd_size < buffer_len)
{
cmd[cmd_size] = checksum(cmd, cmd_size);
}
// Serial.println("****Send Cmd to Read****");
// for (int i = 0; i < buffer_len; i++)
// {
// String str = (cmd[i] > 15) ? "" : "0";
// Serial.print(str);
// Serial.print(cmd[i], HEX);
// Serial.print(" ");
// }
// Serial.print("\n");
}
//
if (currentMillis - previousMillis_cmd2reader >= 10)
{
uart.write(cmd, buffer_len);
previousMillis_cmd2reader = currentMillis;
if (cmd[3] != (byte)0x70)
{
CmdCounter += 1;
}
}
igitalWrite(reader_enable_pin, HIGH);
}
if (CmdCounter > 3 || cmd[3] == (byte)0x70 || flagGetData)
{
flagSendCmd = false;
flagBLE = false;
CmdCounter = 0;
}
}
void ReadFeedBack()
{
uint8_t interval = 5;
uint8_t Endinterval = 50;
if (!FeedBackIndex)
{
// Serial.print("****Cmd from Reader****\n");
previousMillis_readStart = currentMillis;
}
if (currentMicros - previousMicros_readFeedBack > (unsigned long)2)
{
if (uart.available())
{
flagNonReading = false;
FeedBack[FeedBackIndex] = uart.read();
FeedBackIndex += 1;
}
previousMicros_readFeedBack = currentMicros;
}
if (!uart.available())
{
if (!flagNonReading)
{
flagNonReading = true;
// previousMicros_NonReading = currentMicros;
previousMillis_NonReading = currentMillis;
}
}
if (FeedBackIndex > 3)
{
if (FeedBack[0] == (byte)0xA0 && FeedBack[2] == (byte)0xFE)
{
interval = (FeedBack[3] == (byte)0x90 || FeedBack[3] == (byte)0x81 ? 20 : 5);
Endinterval = (FeedBack[3] == (byte)0x81 ? 200 : FeedBack[3] == (byte)0x90 ? 150 : 100);
// Endinterval = (FeedBack[3] == (byte)0x81 || FeedBack[3] == (byte)0x90 ? 200 : 50);
}
}
if ((currentMillis - previousMillis_NonReading > interval && (!uart.available())))
{
// uint8_t num = 0;
// for (int i = 0; i < FeedBackIndex; i++)
// {
// if (FeedBack[i] == (byte)0xA0 && FeedBack[i + 2] == (byte)0xFE)
// {
// if (num)
// Serial.print("\n");
// num += 1;
// }
// String str = (FeedBack[i] > 15) ? "" : "0";
// Serial.print(str);
// Serial.print(FeedBack[i], HEX);
// Serial.print(" ");
// Reader_uart.read();
// }
// Serial.print("\n");
if (FeedBack[0] == (byte)0xA0 && FeedBack[2] == (byte)0xFE)
{
flagData2BLE = true;
}
else
{
flagFlush = true;
}
flagGetData = false;
flagNonReading = false;
}
if (currentMillis - previousMillis_readStart > Endinterval)
{
FeedBackIndex = 0;
flagGetData = false;
flagNonReading = false;
}
}
void LEDBlink()
{
if (BLEnotBegin)
{
if (currentMillis - previousMillis_LEDBlink >= 1)
{
LEDState = !LEDState;
digitalWrite(LEDR, LEDState);
previousMillis_LEDBlink = currentMillis;
}
}
else
{
unsigned long interval = (isBLEconnected ? 1000 : 100);
if (currentMillis - previousMillis_LEDBlink >= interval)
{
LEDState = !LEDState;
digitalWrite(LEDB, LEDState);
previousMillis_LEDBlink = currentMillis;
}
}
}
void triggerReadbyte()
{
if (uart.available() && !flagGetData)
{
flagGetData = true;
flagSendCmd = false;
flagBLE = false;
CmdCounter = 0;
}
}
byte checksum(byte buffer[], uint8_t buffer_len)
{
byte sum = 0;
for (uint8_t i = 0; i < buffer_len; i++)
{
sum = sum + buffer[i];
}
return 255 - sum + 1;
}
void UartFlush()
{
Serial.println(float(currentMillis / 1000));
while (true)
{
currentMillis = millis();
if (currentMillis - previousMillis_Flush >= 100)
{
while (uart.read() != -1)
Serial.print(uart.read());
FlushCounter++;
previousMillis_Flush = currentMillis;
}
if (FlushCounter > 20)
{
FlushCounter = 0;
flagFlush = false;
break;
}
}
}