Skip to main content


Showing posts from September, 2018

ESPCLOCK2, Part 3 - Reading VCC using interrupt

In this post, I read the VCC voltage level to the ATtiny85 and save certain state values to the EEPROM if the voltage level is found to fall below a certain value. But this way of reading the VCC uses delay() and is found to interfere with I2C communication. So a better way needs to be found. After much experimentation, I found the following code to work reliably: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 volatile byte adc_countdown = 5 ; volatile bool adc_ready = false ; // adc_countdown is decremented elsewhere every second if (adc_ready) { adc_ready = false ; vcc = 1125300L / ADC; // Calculate VCC (in mV); 1125300 = 1.1*1023*1000 adc_countdown = 5 ; } else if ( ! bit_is_set(ADCSRA, ADSC) && adc_countdown == 0 ) { ADMUX = bit(MUX3) | bit(MUX2); // Measure VCC using internal bandgap as reference ADCSRA = bit(ADEN) | bit(ADSC) | bit(ADIE) | bit(ADPS2) | bit(ADPS1) | bit(ADPS0); // Start conversion } ISR(ADC_vect) { adc_r

ESPCLOCK2, Part 2 - Interrupt-driven time keeping

Due to the time sensitive nature of I2C, everything we do in the ATtiny85 has to be interrupt-driven. We cannot use any delay() in the code. The ATtiny85 has two timers, Timer0 and Timer1. We will use Timer0 to drive the clock pins, and Timer1 to keep time. First we configure Timer1 to interrupt every second: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #define TIMER1_PRESCALER 4096 #define OCR1A_DEFVAL ((byte)(F_CPU / (float)TIMER1_PRESCALER * 1.0) - 1) // Reset prescalers for Timer1 GTCCR |= bit(PSR1); // Setup Timer1 TCCR1 = 0 ; TCNT1 = 0 ; OCR1A = OCR1A_DEFVAL; OCR1C = OCR1A_DEFVAL; TCCR1 = bit(CTC1) | bit(CS13) | bit(CS12) | bit(CS10); // Start Timer1 in CTC mode; prescaler = 4096; // Interrupt on compare match with OCR1A TIMSK |= bit(OCIE1A); Then in the ISR for Timer1, we simply keep track of the actual time (we call this nettime , or actual time from the network that we are trying to get the clock face to match). 1 2 3 4 5 6 7 8 9

ESPCLOCK2, Part 1 - Getting timezone and local time

I am almost done with the implementation of ESPCLOCK2, so I will start a series of posts detailing the obstacles encountered and lessons learnt from the project. The original ESPCLOCK obtains the geolocation of the clock during setup from the user's browser, and use the geolocation to convert to local time using Google's Timezone API. As noted here , this approach hits a major snag as recent browsers started to restrict the use of  navigator.geolocation.getCurrentPosition()   to Javascript running from SSL-secured websites. Since it would be extremely unlikely for WifiManager to support SSL hosting, another approach is needed. After considering the alternatives, I think the simplest approach will be to host a simple PHP script on a server. This has several advantages: 1) There are no API keys to muck with. All timezone APIs I looked at require you to register for some kind of API key. 2) You won't be affected by API changes, or the service shutting down. You can run t

Link dump for information regarding Lavet motor control in analog clocks

Wall Clock Accurate Oscillator Hack GPS Synchronised Clock A Networked Analog Clock Controlling a clock with an Arduino 24-hour Analog Clock SynchroClock Lavet Motor Clock Library TurrisClock Clockwork Clockwork, Part 2 ESP8266 WiFi Analog Clock Crazy-Clock 29 July 2021: Making a clock spin faster Analog Clocks with NTP Programming the PCA200x Family of Watch ICs Turning analog clock in reverse using Arduino (Japanese) How fast can a quartz clock spin? (YouTube video with useful comments) 19 Aug 2021: Quartz Understanding a quartz analog mechanical clock Synchronized Fast Clocks ESPCLOCK1  /  ESPCLOCK2  /  ESPCLOCK3  /  ESPCLOCK4

Experiments with Circadian Rhythm Fasting (Update)

After my 30-day normal diet brought my weight up to the 74+kg territory, I went on the  Circadian Rhythm Fasting diet for 60 days. Here are the results: There is the same downward trend that I saw in the original 30-day experiment , But it seems to hit a floor in the 71kg territory. Maybe if this goes on long enough, I will be able to push through the barrier, but at the time of writing this up, I have actually gone through another 30 days or so of the diet, and my weight has stayed around the 71kg range. With the 5-2 Fast Diet, I have seen small but persistent weight loss all the way down to the 65kg territory at one point (took about 9 months). So in summary, I think the CRF diet is an easy and pain-free way of maintaining one's weight, but if the main objective is weight loss, the 5-2 Fast Diet might be more effective, albeit more painful way of achieving one's goal.

Switching ATtiny core

I was not getting reliable I2C communication between the D1 mini and the ATtiny85, starting with TinyWireS , then moving on to the more developed  TinyWire . I would send out 5 bytes from the D1 mini, then try to get 16 bytes back. It will start off well, but a few hours later, something will break and the D1 mini will start getting 0xFFs from the ATtiny85. Then I found "ATtinyCore" by Spence Konde (V1.1.5), which appears to be a more mature ATtiny core compared to the "attiny" core by David Mellis (V1.0.2). It has integrated I2C support that manifests as the familiar "Wire" library. The installation instructions are here . I did a manual upgrade to the latest git version as some I2C issues have been fixed in the V1.1.6 milestone but have not been officially released. As recommended by the instructions, I bumped up the Arduino version to 1.8.6. Finally, happy to see reliable I2C communication between the 2 components! The communication has been going n