Hi all,
I'm attempting to write a fairly robust system for an eventual exhibition piece and am trying to write in some fail safes in the case of catastrophic manhandling.
I'm interfacing with the serial port through a C program which utilises the "libserialport" library which is working fine other than I'm struggling with handling the event of the arduino being yanked out and plugged back in. Ideally, I'd like to have this automated to avoid a technician having to restart the computer running the exhibition software. I'm early on in development, so there are quite a few unnecessary stages which I'll omit once I'm past testing.
So far, it works fairly efficiently and handles the C program being restarted and power remaining to the arduino, but I'm getting unexpected bytes through the serial when the arduino has been unplugged and plugged back in.
On the script start I initialise the connection between the software and
arduino using a handshake byte: 'A'.
Once it's mirrored by the software,
the system moves into a ready_to_send state, emitting 'B', which when
mirrored by the software triggers the writing of a series of values, followed
by the system moving into the third state.
The third state waits for confirmation of receipt 'C'. On success, the system
reverts back to the ready_to_send state.
void loop() {
reset = false;
startSerial();
state = 0;
while (!reset) {
switch (state) {
case 0:
// Establish connection;
// Emitting: 'A' || 65
state = establish_connection();
// returns 1 if send cmd 'A' || 65 is received
// returns 3 if received command is 'E' || 69
break;
case 1:
// Waiting for send command
// Emitting: 'B' || 66
state = checkToSend();
// returns 2 if send cmd 'B' || 66 is received
// returns 3 if received command is 'E' || 69
break;
case 2:
// Waiting for confirmation of receipt
// --- Will program in some timeout to return
// ---- back to connection state
// Emitting: 'C' || 67
state = checkReceived();
// returns 1 if send cmd 'C' || 67 is received
// returns 3 if received command is 'E' || 69
break;
case 3:
reset = true;
Serial.end();
delay(1000);
break;
}
}
}
int establish_connection() {
// Sends out #65 waits for #65
Serial.write('A');
sendVal++;
delay(500);
toggleLight();
for (i = 0; i < Serial.available(); i++) {
response = Serial.read();
if (response == 65 || response == 'A') {
return 1;
}
if(checkForError(response)) {
return 3;
}
}
return 0;
}
When the arduino is unplugged and plugged back in I thought the arduino
would reboot and return back to the first state and send 'A' but all I'm receiving
is '\x 1 \x 1f " or which equates to "Start of Heading" and "Unit Header".
It seems like no matter how I restart the serial on the software side of things,
it remains stuck sending these bytes. The only way I've found to get it working
again is to start the arduino Serial Monitor. It's definitely in the first state as I've
set light patterns to identify which state it's in. Is there something the Serial
Monitor does other than restarting the port which would result in this?
I've attached both files for your browsing.
Cheers in advance!
int serialTest_parse_serial(char *byte_buff, int byte_num) {
for (int i = 0; i < byte_num; i++) {
switch (byte_buff[i]) {
case READY_TO_CONNECT: {
printf("Ready_to_connect cmd received");
cmd2bSent[0] = 'A';
if (serialTest_sendMsg(cmd2bSent, 1, 0)) {
// Something went wrong
printf("Something went wrong... attempting to write to serial...");
}
previousReceivedCMD = READY_TO_CONNECT;
break;
}
case READY_TO_SEND:
//printf("Ready_to_send cmd received");
previousReceivedCMD = READY_TO_SEND;
cmd2bSent[0] = 'B';
serialTest_sendMsg(cmd2bSent, 1, 0);
break;
case CHECK_RECEIVED:
previousReceivedCMD = CHECK_RECEIVED;
//printf("check_received cmd received\n");
cmd2bSent[0] = 'C';
serialTest_sendMsg(cmd2bSent, 1, 0);
break;
case MSG_START:
//printf("MSG_Start cmd received\n");
previousReceivedCMD = MSG_START;
receivingData = 1;
break;
case MSG_END:
previousReceivedCMD = MSG_END;
receivingData = 0;
//for (int i = 0; i < 13; i++) {
// printf("%ld, ", receiveBuffer[i]);
//}
//printf("\n");
//printf("\nLast Receive Count: %ld\n", dataCount);
dataCount = 0;
break;
case CARRIAGE_R:
//printf("CARRIAGE_R Cmd Received\n");
// Restart Serial
return -1;
}
if (receivingData == 1 && byte_buff[i] != MSG_START) {
receiveBuffer[dataCount] = byte_buff[i];
dataCount++;
}
if (byte_buff[i] == 1 ) {
printf("Other received!");
printf("%ld", byte_buff[i]);
cmd2bSent[0] = 'E';
serialTest_sendMsg(cmd2bSent, 1, 1);
return -1;
}
return 1;
}
}
FinalBSMM_debug.ino (4.32 KB)
serialTest.c (5.01 KB)