Code optimization

A project log for R'lieh - Aquarium/ closed ecosystem management

An automated and connected aquarium management system

Audrey RobinelAudrey Robinel 05/14/2015 at 12:430 Comments

I had issues with the code. it turns out that i was using too much ram on the *duino..

Indeed, each string is counted as global variable, and space is sparse on an Atmega328p : you have 2048 Bytes of RAM. The device is meant to answer to simple commands (such as getWaterTemp), and returns XML like strings. Those strings among other things was taking too much space. Furthermore, writing Serial.println("blablabla") two times takes twice as many ram, the system doesn't free the ram after the first call.

I hence had to clean the code. In order to do that, i declared strings containing all the text that was repeated more than once, or that is likely to be so in the future. I also compacted messages, reducing all unnecessarily long error messages.

All those changes reduced the RAM taken from more than 2048 Bytes to 1356 Bytes.

With this change, all bugs have disappeared, and now all functions are properly working. One good side effect is that messages are coherent : when something is on, the status will be reported as "ON" everywhere, rather than "On", "on", or "ON" in various locations.

As of now, the system controls two relays (on, off, and returning status of the relay), two TIP120 transistors (on, off, set to PWM level, and status), one of which is used to control the lighting described in a previous post. The second one will be used to cool the water (as of now, fans blowing towards the surface, but later on maybe a pelletier chilling the water). Two DS18B20 temperature probes are also accessible (one for air, another for water).

The cooling is set to turn on when a threshold temperature is reached, and shuts down when another lower temperature is obtained. I used two values (24 for low, 24.5 for high) so that the cooling doesn't turns on and off all the time around the target value.

Multiple functions are also available for lighting, but i already covered that in a previous post. It is also possible to set a number of variables trough the serial commands, such as low and high temperature thresholds, lights fade time, etc.

Every function described here can be activated by serial, but the state of each subsystem can be obtained in the same way at any time.

The code has been written entirely without delays, so the device never "hangs" waiting for something. This makes the board quite responsive.

In order to improve this aspect, i did set the Serial.timeout to 100ms, wich is enough at 9600 bauds fo all commands. Thus, when a command is sent, it is executed in 100ms, and a response is sent after this delay. By default, the timeout is set to 1000ms.