Close

January 27, 2015

A project log for AquaPic - Aquarium Controller

Reef tank controller used to monitor various parameters such as temp and pH, and also control equipment such as pump and lights.

skyler-brandtSkyler Brandt 02/14/2015 at 00:550 Comments

I have successfully made the changes I wanted to make to the serial communication protocol after a lot of pain, frustration, confusion, screaming, yelling, headache, and about 8 hours of my time. The way the protocol works now is messages are queued up, FIFO stack, and then a separate thread dequeues the top message and sends that to the slave. It then calls a callback function if a response beyond the generic response is received. I also added a byte count to the message to indicate length. I almost did a complete re-write of the master code and a few small changes to the slave, so it inevitable didn't work right off the bat. There were a few run-time errors but the most frustrating one and the bug that gave me the most grief was due to a forgotten break keyword in a switch statement.

case FUNCTION_RECIEVED:
    inst->message_length = byte_received;
    inst->message[2] = inst->message_length;
    inst->message_count = 3;
    inst->apb_status = MESSAGE_LENGTH_RECIEVED;
    break; // <----- 8 hours of my life I'll never see back
case MESSAGE_LENGTH_RECIEVED:
    inst->message[inst->message_count++] = byte_received;
    if (inst->message_count == inst->message_length) {
        if (apb_check_crc(inst->message, inst->message_count)) {
            inst->message_handler();
        }
        //more processing
    }
In the code segment the switch statement is switched by status of the message, and case FUNCTION_RECIEVED basically falls into case MESSAGE_LENGTH_RECEIVED. That resulted in inst->message[2] and inst->message[3] to be the same value and the crc check would fail. The slave would then think the communication was faulted and never send a response. That took me about 8 hours to find and so much headache. The other issues I ran into was threading related. The Gtk library crashes and does funny things if you call a function or update a property from a thread that didn't start the Gtk application. The fix for that was a Google search away, so that wasn't to bad to fix, and was as simple as calling an invoke to add a delegate to the event system of the Gtk run time.

Full code at my build log.

Discussions