Go Down

Topic: Help with Design: Using processor time efficiently when dealing with serial (Read 1 time) previous topic - next topic


Hi everyone,

I'm currently working on developing what is essentially a temperature controller with a few other bells and whistles attached. I have a few questions about how I should approach the code design in terms of using the microprocessor efficiently (I don't want to be blocking other things from happening while waiting around for a serial reponse). The basics of my system are as follows

            USB Slave Device -----(USB)------Arduino Mega ADK-----------------RS485Bus
                                                        Temp monitor

There are a few other things attached but I think this is all I need to consider at this point in time. The arduino has a few tasks that need to be done often such as PID control for a heater (which is connected to a digital pin via a motor driver) and a rather large state machine function. It also needs to be able to receive commands/queries from the display and act accordingly for, example the display could ask the arduino for some propery of the USB slave device to display on screen.

The Arduino has a lot of things it needs to do so I want to minimise the time spent waiting for things e.g. a response over USB. How should I organise my code?

My thoughts so far are to have the PID function on a timer interrupt as it is a short method and needs to be regular (i guess this means I would need to query the temp monitor just as regularly and somehow ensure I don't read and write from the buffer at the same time). I think the state machine function can just be in the main loop. But, I am unsure how to handle the requests from the display. If I receive a query, should I use Serial.Event() and have code in there to send the USB device for the query and wait for a response? This seems a bit wasteful of resources. Ideally, once the query is received from the display, my code would send the query to the usb device and continue doing normal things until a response is received on which it would act (forward to the display or do some other necessay processing). How could i achieve this??

Any other comments and thoughts would be appreciated too,

Thanks a lot for your help


It's hard to tell what your timing need is from those details, but generally, the arduino is plenty fast enough to deal with serial data and other operations without the need for interrupts. Just steer clear of delay. What are you measuring the temperature of that you need such frequent updates?


Separating the two communications accomplishes what you want.
Your main loop periodically sends a serial message to read the temperature and stores it in a variable.
The loop also checks for a touch screen request.  If it is a request for temperature it immediately sends the variable value.
(there is no additional transmission and wait).  It processes any other type of request.
Then it begins the loop again.  The only trick is to perhaps snap the time (millis()) when you last read the temperature, so that you can compare it to the current time and not read it too quickly.
This way, no delay is used.  You get instant response to your touch, except if it happens to be in the middle of a temperature measurement communication.


It might be worth breaking your project up into multiple chips.  For e.g., reading 1-wire digital thermometer ICs is a blocking event, so your code stops running while that's happening.  It's long enough to make the UI feel sluggish and unresponsive.

You could use an ATtiny or something to poll your sensor and send the temp back to your main controller.  The rest of what you want to do is all fairly cooperative.  For instance, serial I/O takes some time, but not that much.  You're not going to miss the (less than a) millisecond it takes to transfer some data over serial before a touch is registered.  Your PID routine probably won't miss the stolen ticks either.

Some code is forgiving of being interrupted, some isn't.  If you do schedule events on interrupts, make sure your ISR doesn't affect critical timing loops or change the contents of any variables or ports that might need to be consistent during some other unrelated operation that could be happening concurrently.


What you want to do is simple if you go about it in the correct way. I would implement a finite state machine. It is a lot simpler than it sounds, google for more info.

Go Up