Hello everyone, I am writing a simple app which I will use to test my arduino project.
I have the receiving/sending of strings ready to go on the arduino side, but in my app I am facing an issue regarding responses from the arduino. Here is the situation:
Data sent from the app must be in a specific format to receive an ACK
response (everything is OK):
BP:<int>/<int>\n
Otherwise a RETRY
response will be sent by the arduino.
No problem, I have that set up correctly on the arduino side, and verified it works.
However, in my when Btn_BP_Send.Click
procedure after sending the data (which I can see from the serial monitor is received successfully) I need to wait for the response from the arduino (which I can also see is sending as it should). If an ACK string is received, all good proceed. If a RETRY string is received however, I want to do something else (e.g. notify the user that something went wrong and they should try sending again). Instead, I am receiving neither of these.
Here is my .aia file. Note: I have registered for receiving strings.
ThesisSimulationApp.aia (217.5 KB)
I initially tried adding a while loop after calling the send_data procedure, but that caused my app to crash.
I guess my question if how can I "wait" for a response from the arduino, and then according to the response continue with the code in the when Btn_BP_Send.Click
procedure without blocking the rest of the code (so that strings can actually be received)?
Edit:
In case they are helpful, here are 2 functions which are directly related to reading data:
When data is received while in the READING state, check it with validate_message, and send the appropriate response.
states state_reading() {
char input_buffer[64];
uint8_t index = 0;
static unsigned long last_high_time = 0;
const unsigned long disconnect_threshold = 2000; // 2 seconds of LOW before triggering
uint8_t bt_pin_state = digitalRead(BT_STATE);
if (bt_pin_state == HIGH) {
last_high_time = millis();
}
else {
if ((millis() - last_high_time) > disconnect_threshold) {
log_msg("WARN", "Bluetooth disconnected during READING");
return DISCONNECTED;
}
}
while (HM10_UART.available()) {
log_msg("DEBUG", "Reading data");
char incoming_byte = HM10_UART.read();
char debug_char[2] = {incoming_byte, '\0'};
log_msg("DEBUG", debug_char);
if (incoming_byte == '\n') {
input_buffer[index] = '\0';
size_t len = strlen(input_buffer);
if (len > 0 && input_buffer[len - 1] == '\r') {
input_buffer[len - 1] = '\0';
log_msg("DEBUG", "Stripped trailing \\r from input_buffer");
}
log_msg("DEBUG", "Received string: ");
log_msg("DEBUG", input_buffer);
if (validate_message(input_buffer)) {
HM10_UART.println("ACK");
log_msg("INFO", "Valid data received. ACK sent.");
strncpy(g_received_data_buffer, input_buffer, sizeof(g_received_data_buffer));
g_received_data_buffer[sizeof(g_received_data_buffer) - 1] = '\0'; // ensure that the last character is the null terminator no matter what
return PROCESSING;
}
else {
HM10_UART.println("RETRY");
log_msg("INFO", "Invalid data received. Retry request sent.");
}
index = 0;
}
else if (index < sizeof(input_buffer) - 1) {
input_buffer[index++] = incoming_byte;
}
else { // Buffer overflow
index = 0;
log_msg("WARN", "Input buffer overflow. Resetting.");
}
}
return READING;
}
validate_message checks that the received data is in the correct format
bool validate_message(const char *msg) {
if (strncmp(msg, "BP:", 3) == 0) {
log_msg("DEBUG", "Received data is from a BP device.");
const char* data = msg + 3;
int systolic, diastolic, consumed = 0;
if (sscanf(data, "%d/%d%n", &systolic, &diastolic, &consumed) == 2) {
if (data[consumed] == '\0') {
return true;
}
}
}
else if (strncmp(msg, "TEMP:", 5) == 0) {
log_msg("DEBUG", "Received data is from a TEMP device.");
const char* data = msg + 5;
char* endptr;
strtod(data, &endptr);
if (endptr != data && *endptr == '\0') {
return true;
}
}
else if (strncmp(msg, "HR:", 3) == 0) {
log_msg("DEBUG", "Received data is from a HR device.");
const char* data = msg + 3;
char* endptr;
strtol(data, &endptr, 10);
if (endptr != data && *endptr == '\0') {
return true;
}
}
return false;
}