Air602 Weather Indicator

Air602 is a 2.4GHz Wi-Fi module based on Winner Micro W600 system-on-chip. Being a new release, it has limited software support. It took me more than a day to make it blink.

Naturally, the next step is to connect a sensor. I decide to reproduce the ESP8266 weather indicator but with Air602 instead.

Air602 Board Pinout

The Air602 development board, labelled EVB_W602_A11, has six pins:

Air602 pin W600 pin
RX1 PB11
TX1 PB12

Air602 Hands On and Blink with C SDK

I hear there's a new WiFi microcontroller that is cheaper than ESP8266's "unbeatable" low price tag. It is the Air602, a 2.4GHz Wi-Fi module based on Winner Micro W600 system-on-chip.

Buying an Air602

Currently, Seeed Studio is the only seller for this module. It comes as a bare module for $1.90, or a development board for $2.90. The bare module lacks an antenna and requires surface mount soldering that I'm not comfortable with, so I purchased the development board version that comes with antenna, power regulator, and USB-UART chip.

photo of Air602 development board

My order was shipped from Hong Kong, and it took about two months for the order to arrive United States.

Is Junxiao in the Room? Presence Detection with nRF52 Bluefruit

I recently obtained some Adafruit Feather nRF52 Bluefruit LE (paid link) boards. The main chip on this board is the nRF52832 from Nordic, which offers Bluetooth Low Energy (BLE) communication, but does not have WiFi. Adafruit made a nice Arduino core for nRF52, so that it can be programmed easily with the familiar Arduino environment.

Incidentally, this isn't the first BLE device I have. Many small battery-powered devices, including the Fitbit Alta HR tracker (paid link) I wear daily, uses BLE for communication. This means, I could use the nRF52 board to answer one question: is Junxiao in the room?

#include <bluefruit.h>

// UUID of Fitbit Alta HR: ADABFB00-6E7D-4601-BDA2-BFFAA68956BA
const uint8_t FITBIT_UUID[] = {
  0xBA, 0x56, 0x89, 0xA6, 0xFA, 0xBF, 0xA2, 0xBD,
  0x01, 0x46, 0x7D, 0x6E, 0x00, 0xFB, 0xAB, 0xAD,

unsigned long lastReport = -1;

void setup()

  Bluefruit.begin(0, 0);


void scan_callback(ble_gap_evt_adv_report_t* report)
  unsigned long now = millis();

  Serial.printf("%09d ", now);
  Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
  Serial.printf(" %d\n", report->rssi);

  lastReport = now;

void loop()
  digitalWrite(LED_BUILTIN, millis() < lastReport + 5000);

This sketch initializes a BLE scanner. filterUuid asks the scanner to invoke scan_callback function whenever it receives an advertisement from a Fitbit Alta HR, identified by the service UUID ADABFB00-6E7D-4601-BDA2-BFFAA68956BA (readable by Bluefruit app for iPad). useActiveScan(false) configures the scanner to passively listen for periodical advertisement packets without transmitting "scan request" packets, to conserve battery on my wristband. When a "report" (scan_callback invocation) is received, the red LED is lit for five seconds.

In practive, it works OK. When I'm within 10 meters from the Bluefruit board, the LED lights up frequently, but it's not consecutive because the Fitbit does not advertise itself very often. If I put my Fitbit into the microwave (paid link) acting as a Faraday cage, the onboard LED no longer lights up. Oops, I got to run before my Fitbit gets fried in the microwave!

Loud Pumpkin with Circuit Playground

It's October. Pumpkins are filling the grocery stores. This means one thing: Halloween is coming!

I'm told that I'm supposed to wear a costume on Halloween. However, I'm too broke to buy an outfit for just one day, so I'm going to wear a colorful circuit board instead. This year, I'm going to become a pumpkin. Well, sorta.

The board is an Adafruit Circuit Playground Express. It packs 10 NeoPixel LEDs that can display any color, four sensors, and a few buttons. My code uses the microphone sensor to measure how loud is the environment. Based on measured sound pressure, it then lights up a number of NeoPixels to #ff7619 the "pumpkin color".

#include <Adafruit_CircuitPlayground.h>

void setup() {

void loop() {
  float sp = CircuitPlayground.mic.soundPressureLevel(100);
  int peak = map(sp, 56, 90, 0, 9);

  for (int i = 0; i <= peak; ++i) {
    CircuitPlayground.strip.setPixelColor(i, 0xff7619);

ESP8266 Call Button

It's NDN Community Meeting again and this time I'm officially presenting HomeCam at the demo session. I'm the sole presenter of this project. Normally, I have to stay at my table to show my project to the audience. However, I don't want to miss the chance of seeing what others have been doing. To solve this dilemma, I come up with an idea: a call button.

I put a big button on my table. It is labelled as: if I'm not here, press the button to send an Interest. Then, I wear a battery powered light ring on my body. Whenever someone presses the button, it lights up for 15 seconds.

me wearing a light ring at NDNcomm demo session

How It Works

Both the button and the light ring are based on ESP8266. The light ring unit acts as WiFi access point and NDN producer. The button unit acts as WiFi station and NDN consumer. When the button is pressed, the consumer transmits a signed Interest, and the producer turns on the light for 15 seconds after verifying the signature. Since the light ring unit is battery-powered, it enters deep sleep mode if there's no connected WiFi client.


1998年,我参加小学生作文竞赛时写下了一篇《二十一世纪电视畅想》。 20年过去了,让我们来看看,这些畅想变成现实了吗?

小朋友们,你们想过没有二十一世纪的电视是怎样的呢? 我学习之余,常在潜心研究、精心设计着它们呢。我告诉大家,到那时的电视机呀,小的只有手表这么小,大的足有三层楼高。

在二十一世纪,“手表这么小”的电视机称为“智能手表”。 它们不能直接接收电视信号,而是接入移动通讯网络,通过因特网可以观看电视。

“三层楼高”的电视机在广告业已经普及。 纽约时报广场就有多幅大型电视屏幕,每天24小时播放广告:


Get Online in McDonald's with ESP8266

McDonald's used to be the largest chain of free restrooms in the world. Nowadays, they are the largest chain of free WiFi across the United States. Every McDonald's I've been to offers AT&T WiFi services. I can walk in, connect to "attwifi" on my phone, accept the license agreement, and I'm online.

attwifi captive portal in McDonald's

The license agreement page is called a captive portal, a web page displayed to newly connected users before they are granted broader access to network resource. While it's trivial to click through the captive portal on a smartphone, if you are wearing an ESP8266 as a connected jewelry, it would not connect successfully. When I encountered a captive portal in my apartment WiFi, I made an Arduino sketch to send the packets I found through Fiddler, but McDonald's WiFi is different:

  • Each McDonald's store hosts their captive portal on a different domain.
  • The form submission step needs several parameters from the HTML, but does not use cookies.

attwifi captive portal form HTML

How to Print uint64_t in Arduino

The Arduino programming language looks like C++, but it is weird in its own way: there's no C++ standard library. In C++, you can print a variable to the debug console with std::cerr << x;. In Arduino, you have to write a function call: Serial.print(x);. I love that the Streaming library brings back the familiar syntax Serial << x; through some template and macro magic. But when it comes to a uint64_t variable, nothing works!

error: call of overloaded 'print(uint64_t&)' is ambiguous

note: candidates are:
note: size_t Print::print(const __FlashStringHelper*) <near match>
note:   no known conversion for argument 1 from 'uint64_t {aka long long unsigned int}' to 'const __FlashStringHelper*'
note: size_t Print::print(const String&) <near match>
note:   no known conversion for argument 1 from 'uint64_t {aka long long unsigned int}' to 'const String&'

The cause of this error is: Arduino does not know how to print a uint64_t!

How Arduino Prints Stuff

Arduino contains a subset of C++ standard library, plus some additional headers known as the "Arduino Core". Each microcontroller has its own Arduino Core: AVR, SAMD, ESP8266, ESP32. They follow roughly the same API, one of which is the Print class that knows how to print stuff.

Simple Temperature and Humidity Indicator with ESP8266 and HTU21D Sensor

I decide to mix up a few existing toys to make a simple temperature and humidity indicator. ESP8266 reads temperature and humidity from an HTU21D sensor, and displays the numbers on a 4-digit 7-segment LED display. Since a 4-digit display isn't wide enough for both temperature and humidity, the display cycles between temperature, humidity, and a blank state.

temperature and humidity on LED display


Bill of materials

Listen to Podcasts

Apartment life involves a lot of chores: cooking, cleaning, folding laundry, etc. Many American housewives watch TV while doing chores, but I do not have a TV. The next closest thing is the radio, but I find it boring to listen to the same news over and over. In Dec 2016, as I scroll through my iPad Mini (paid link), I discovered the best activity to accompany chores: podcasts!

A podcast is a series of periodically published digital audio files that a user can download and listen to. iPad Mini comes with a Podcasts app that allows me to search for, subscribe to, download, and listen to podcasts.

My initial subscriptions include:

  • Radiolab, in-depth news stories. It's similar to a magazine, but in an audio format.

    My favorite episode is The Ceremony, a report about how Zcash generated their cryptocurrency parameters.

  • Stranglers, true crime stories about the Boston stranglers. They kept my eyes wide open at nights.

Listening to podcasts improves the quality of my housekeeping, because I do not rush through the chore so that I can switch to more "enjoyable" activities sooner. Instead, I can take my time cleaning the bedroom, while enjoying great audio content. I do have to keep it quiet, so that I can hear what's coming out of the small speaker on the iPad Mini.