Skip to main content

Posts

Showing posts from 2017

ATtiny85 - Using capacitor for backup power to persist clock time to EEPROM

As discussed in the initial design post , the idea is to connect a 0.47F capacitor to the VCC and GND pins of the ATtiny85. Then when we lose power, the capacitor will provide the ATtiny85 with enough juice to store the current clock time to its EEPROM. When we gain power again, the ATtiny85 will read the clock time back from the EEPROM and start over. In this way, we avoid killing the EEPROM of the ATtiny85 with too many write operations. To that end, I purchased something like this over EBay (2 for $3, so works out to about $1.50 each). The code to check for supply voltage drop looks like this: void loop () { // Execute loop() every second if ( ! timer1) return ; else timer1 = false ; // Measure supply voltage // Source: http://digistump.com/wiki/digispark/quickref adc_enable(); ADMUX = _BV(MUX3) | _BV(MUX2); // VCC as reference, band gap voltage (~1.1V) as input _delay_us( 250 ); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversio

ESP-12E calling Google Timezone API

The ESP-12E module of the ESPCLOCK V2.0 project is done. All the clock control logic has been shifted to the ATtiny85 module, so the ESP-12E is only in-charged of periodically getting the NTP time, converting to local time, and sending it via I2C to the ATtiny85. One of the unresolved problems in the original ESPCLOCK project is calling the Google Timezone API via HTTPS. Because Google's HTTPS cert is different for servers in different geographical locations, this presents a problem for the original code: const String GOOGLE_API_URL = "https://maps.googleapis.com/maps/api/timezone/json?location=[loc]&timestamp=[ts]" ; const char * GOOGLE_API_CERT = "AD:B8:13:99:64:F5:75:F5:78:5C:FA:43:19:EA:8F:AF:2B:AE:54:FE" ; ... HTTPClient http; http.begin(url.c_str(), GOOGLE_API_CERT); int rc = http.GET(); The solution I used is the one outlined in this comment . const String GOOGLE_API_URL = "https://maps.googleapis.com/maps/api/timezone/json?lo

ESP-12E I2C test communication with ATtiny85

I ran a little test to make sure the ESP-12E is able to communicate with the ATtiny85 via I2C. These are the connections required: D1 and D2 are both pulled up to 3V3 on the ESP-12E with 10K resistors. The ESP-12E and the ATtiny85 are connected via different USB cables (ATtiny85 via the Arduino Uno) to the same USB hub. The sketch for the ESP-12E (I2C master): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 #include <stdint.h> #include <Wire.h> byte tx = 0 ; void debug ( const char * format, ...) { char buf[ 256 ]; va_list ap; va_start(ap, format); vsnprintf(buf, sizeof (buf), format, ap); va_end(ap); Serial.println(buf); } void setup () { Serial.begin( 115200 ); Wire.begin(); Wire.setClockStretchLimit( 1500 ); } void loop () { Wire.beginTransmission( 0x26 ); Wire.write( ++ tx); Wire.endTransmission(); debug( "tx = %d" , tx); Wire.requestFrom

Attiny85 timer programming using Timer1

This Arduino sketch uses Timer1 to drive the LED blinker: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 /* * Program ATTiny85 to blink LED connected to PB1 at 1s interval. * Assumes ATTiny85 is running at 1MHz internal clock speed. */ #include <avr/io.h> #include <avr/wdt.h> #include <avr/sleep.h> #include <avr/interrupt.h> bool timer1 = false , led = true ; // Interrupt service routine for timer1 ISR(TIMER1_COMPA_vect) { timer1 = true ; } void setup() { // Setup output pins pinMode( 1 , OUTPUT); digitalWrite( 1 , led); set_sleep_mode(SLEEP_MODE_IDLE); // Setup timer1 to interrupt every second TCCR1 = 0 ; // Stop timer TCNT1 = 0 ; // Zero timer GTCCR = _BV(PSR1); // Reset prescaler OCR1A = 243 ; // T = prescaler / 1MHz = 0.004096s; OCR1A = (1s/T) - 1 = 243 OCR1C = 243 ; // Set to same value to reset timer1 to

ATtiny85 timer programming using the Watchdog Timer

This Arduino sketch uses the watchdog timer on the ATtiny85 to interrupt every second to pulse the LED: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 #include <avr/io.h> #include <avr/wdt.h> #include <avr/sleep.h> #include <avr/interrupt.h> bool led = true ; void setup () { // Misc setup pinMode( 1 , OUTPUT); set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Setup watchdog timer to interrupt every second MCUSR &= ~ _BV(WDRF); WDTCR |= (_BV(WDCE) | _BV(WDE)); WDTCR = _BV(WDP1) | _BV(WDP2); WDTCR |= _BV(WDIE); sei(); } ISR(WDT_vect) { sleep_disable(); digitalWrite( 1 , led ? HIGH : LOW); led = ! led; // Execution continues in loop() } void loop() { sleep_enable(); sleep_cpu(); // MCU goes to sleep here; wake up by watchdog timer interrupt } The advantage of this approach is I can use the SLEEP_MODE_PWR_DOWN mode to put the MCU to sleep to save the maximum am

Test programming the ATtiny85

Just got my ATtiny85 chip today from the postman and playing with it now. There are quite a number of ways to program the ATtiny85, from the very cheap ( USBasp , Tiny AVR Programmer , USBtinyISP ) to the more expensive ( AVRISP mkII ). The Tiny AVR Programmer is probably the most convenient of the lot because it targets the ATtiny family specifically, so no cables are required. Just plug the chip into the provided socket. Since I already have a spare Arduino Uno lying around, I am going the no-cost way, using the Uno to program the ATtiny85. You basically need to hook up the Uno to the ATtiny85 on a breadboard via 6 jumper wires. It's actually easier than it sounds, and took all of a couple of minutes to do. Configuring the Uno to become an ISP The next step is crucial. You need to upload a sketch to the Uno so that it has the necessary code to become an ISP. That's how you can then program the ATtiny85 through the Uno. The first step is to load the ArduinoISP sket

ESPCLOCK V2.0 - Design

I previously started a project to hack an analog clock to sync with NTP . I call the project ESPCLOCK , because it uses the ESP8266 chip (or more specifically, the ESP-12E development board for the ESP8266) to integrate with the analog clock. From a usability viewpoint, I like the fact that there is no need to mess with timezones during setup. Basically when setting up the WiFi, the setup page grabs the timezone from your browser automatically. So setup is as simple as entering the WiFi credentials, and the clock will start keeping accurate time and handle daylight saving automagically. However, in its current state, there are two issues with the clock: 1. The battery life is awful. Connected to a 2400mAh USB battery pack, it can only last for about 27 hours. A typical analog wall clock will run for at least a year on a single AA battery. 2. To deal with possible power loss, it writes the current clock time to EEPROM every second. Since the EEPROM has a limited number of writ

High Intensity Interval Training

To maintain my body weight, I have been using the Fast Diet (once a week), which is cheap, easy to perform and does not require any special equipment or supplement. So far it has been working great for me. Recently, while watching the latest series of Trust Me, I am a Doctor , I come across something called High Intensity Interval Training , or HIIT: Basically, 15 minutes of high intensity training daily is good enough to maintain body fitness and can substitute for much longer moderate intensity exercise. Like the Fast Diet, I am attracted to this method of training because we are all time-poor these days, and having to devote 30 minutes or more each day for walking or other forms of exercise is next to impossible. In addition, no special equipment is required and it can be done anywhere with a bit of room. I have started doing this HIIT routine daily: Let's see whether I can maintain the regime like I do with the Fast Diet.

Refreshing Android MediaStore

The Android MediaStore maintains the metadata of audio, video and image files in the underlying filesystem for convenient consumption by relevant Android apps (eg. music player). The problem is when manipulating the SD card content with an Android file manager, sometimes the metadata cache becomes out of sync with the actual filesystem. So for example if you rename or delete a folder using a file manager, then connect the device via a USB cable to your PC to be accessed via MTP, the old folder may appear in Windows Explorer. Clicking "Refresh" does not work to update the content. The only way to refresh the cache is to reboot the device. Another method I found recently is to run an app that forces MediaStore to refresh its cache. There are many apps available for this purpose if you search for "rescan sd" in the app store. A lot of them won't work with Android 6.x (Mashmallow) and will crash when you try. One ad-free app that works  under Mashmallow is Resca

How to disable Firefox "Open in new window" context menu item

I can't remember how many times I have accidentally clicked on "Open in New Window" when I meant to select "Open in new tab" when using Firefox. Finally irritated me enough to find a solution. Locate C:\Documents and Settings\<username>\ Application Data\Mozilla\Firefox\Profiles . There should be two files: userChrome-example.css and userContent-example.css . Copy userChrome-example.css to a new file called userchrome.css and open it in a text editor. Add the following lines to the end of the file: /* Never show “Open in New Window” when right clicking */ #context-openlink {display: none !important;} I also added this block to remove "Open in New Private Window": /* Never show "Open in New Private Window" when right clicking */ #context-openlinkprivate { display: none !important; } Now my Firefox context menu shows only "Open Link in New Tab": Great!