Experimentation with Circadian Rhythm Fasting

I have been doing the Fast Diet for a couple of years now. It works wonderfully, without having to buy any special equipment or supplement, which is fantastic. However, even after all this time, the diet days still need getting some use to. This is especially true when I am on "maintenance" mode, which means you fast once instead of twice a week. Because I am doing it less frequently, the diet day becomes harder because the body takes more time to adjust.

Some time back, I came across an article talking about Circadian Rhythm Fasting, popularized by Dr Jason Fung and many others. Here's a more recent article on the topic. The main idea is to restrict eating to a small window of the day, effectively fasting for the rest of the time. Like the Fast Diet, it does not require any special equipment or supplement, and is very flexible with the timing. For example, you can choose to start at 7am and end at 3pm, or start at 12pm and end at 6pm. However, the common guideline is to…

MIUI: Connecting to MJX Bugs B2W

I recently purchased the MJX Bugs B2W drone, and had a lot of difficulty connecting to the onboard 5GHz WIFI camera from the Bugs Go app. I finally figured out the solution, and it was totally unexpected, so I thought I'd share it here for anyone faced with the same issue.

I am using the Redmi Note 4 to connect, and that phone supported 5GHz WIFI, so I had no problem connecting to the drone hotspot. But when I launched the Bugs Go app, I keep getting the "Aircraft not connected" message. I tried a couple of stuff, including resetting the 5GHz channel used by the drone (by pressing on the "Camera" button on the remote controller for about 8 seconds, until you hear 3 beeps). Nothing worked.

Then I realized when I connect to the drone hotspot and run Bugs Go, I see this message:

It didn't occur to me initally to tap on the message, because I already knew the drone hotspot had no Internet acess. So out of desperation, I tapped on the message:

By selecting "…

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:

voidloop() { // Execute loop() every secondif (!timer1) return; else timer1 =false; // Measure supply voltage// Source: 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 conversionwhile (bit_is_set(ADCSRA, ADSC)); //…

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 ="[loc]&timestamp=[ts]"; constchar* 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 ="[loc]&timestamp=[t…

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:

ESP-12E ➜ ATtiny85

   D1       Pin 2
   D2       Pin 1

D1 and D2 are both connected 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#include <stdint.h>#include <Wire.h> byte tx =0; voiddebug(constchar*format, ...) { char buf[256]; va_list ap; va_start(ap, format); vsnprintf(buf, sizeof(buf), format, ap); va_end(ap); Serial.println(buf); } voidsetup() { Serial.begin(115200); Wire.begin(); } voidloop() { Wire.beginTransmission(0x26); Wire.write(++tx); Wire.endTransmission(); debug("tx = %d", tx); Wire.requestFrom(0x26, 1); if (Wire.available() >=1) { …

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#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); 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 0 after a compare match TIMSK = _BV(OCIE1A); // Interrupt on compare match with OCR1A// Start timer in CTC mode; prescaler = 4096; TCCR1 = _BV(CTC1) | _BV(CS13) | _BV(CS12) | _BV(CS11); sei(); } void loop() { if…

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; voidsetup() { // 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 amount of power when there is nothing to be done. T…