In Part 2 I promised to build a very stylish finished product, that could be displayed with pride. Well, I don’t think I’ve quite achieved that. But, at least now I consider the project finished, and now have the confidence to get on with other projects.
I have mounted some tiny servos, the funky white on blue LCD display, and the Freetronics 2010 board on some Craftwood. Cutting the hole for the LCD was a bit hit & miss, using a carving knife to shape the hole, and managing not to loose any fingers in the process.
The hour servo is mounted at the bottom of the board, and travels clockwise from midnight, with noon vertical, until it re-tours to 0 on the stroke of midnight. The hour hand travels clockwise from 0 minutes at the bottom, over 30 minutes horizontal, to 59 minutes at the top of the stroke. At 0 minutes, the minute hand re-tours to 0 at the bottom. I find the movement of the servos on the stroke of the hour somewhat like a chime. Not too oppressive, but enough to draw my attention to the passing of another hour.
As the 4 line LCD has so much screen real estate, I have added the maximum and minimum temperature display, with hour, day and month when each extreme was reached.
Adding the LM335Z Temperature IC was discussed in Part 2. I found that the accuracy of the LM335Z IC could be improved by firstly knowing exactly what the Vcc was for operating the AVR device. Measuring this, and putting it in the calculation enabled enough accuracy to be found. Using the 5V regulator on the Freetronics 2010 delivered 4.97V for me, and this value is hard coded into the code. I have several LM335Z devices and they have different offsets, which is adjusted by modifying the subtraction in the Kelvin to Celsius calculation. As the LM335Z is accurate once the offset is established, there is no need to operate it in the “accurate” mode, IMHO, given we have software to make the adjustments it needs.
The instability in the temperature readings discussed in Part 2 was caused by the long wires to the sensor. Once the device was fixed into the prototyping area on the 2010, together with bypass capacitor, the stability of readings improved greatly. However, during testing, I noted that the maximum values were reading very high. These false high maximum values were caused because the ADC process was sampling during a servo move. The servos consume a lot of power, and this causes voltage drop on Vcc. Hence the reference voltage for the ADC is no longer accurate.
To prevent the ADC from operating during the servo moves, I simply used one of the freeRTOS semaphores I established previously. I use semaphores to control access to the LCD, the I2C and to the ADC. Use of a semaphore enables independent processes to share a single hardware resource without conflicts developing. The fix for the erroneous high maximums was done simply by taking the ADC semaphore (to prevent the ADC reading process from starting) during times when the servos are being instructed to move. Simple, with freeRTOS to manage the process interaction for me.
ERRATA
The code included in the updated source does not properly fix the issue of false maximum temperatures. It incorrectly releases the ADC semaphore immediately following resetting the PWM values. This means that the hands can still be moving when the ADC process gets unblocked which causes false maximums, because of voltage droop in Vcc, typically at midnight when both hands are in motion.
The fix is to move the vTaskDelay call between the set_PWM_hardware and xSemaphoreGive calls. I also increased it to 2000 milli Seconds too, to ensure the hands are really stopped before the ADC process gets unblocked.
set_PWM_hardware( servoHours_uS, servoMinutes_uS );
vTaskDelay( 2000 / portTICK_RATE_MS ); // a 2 second delay to ensure the hands have properly stopped.
xSemaphoreGive( xADCSemaphore );
END ERRATA
Another piece of code added since Part 2 is to write the maximum and minimum temperatures and the times the extremes occurred into the EEPROM available on the 2010. The functions to use the EEPROM are available in the AVR library and are very straightforward to use. Having a permanent record of temperature extremes is perhaps one thing this clock does, that other clocks in my house can’t do.
There are a lot of comments in the updated freeRTOS Retrograde Clock code, now hosted at Practical Arduino. As a reminder the code uses the AVR and Pololu Libraries, so these both need to be installed before you compile.