Asus RT-N12 wireless bridge

As our Panasonic TV works best with wired connection for Internet access, I needed a wireless bridge (or a wireless end point) with RJ-45 ethernet cabling. The set-up looks like this:


The good quality 300n routers have become rather cheap ( got a new Asus RT-N12 D1 for 20 Euro ). With the appropriate Tomato firmware, it can work as a simple wireless bridge. The D1 version of Asus RT-N12 is the most recent hardware version with 8 MB space for the firmware. The first version of Asus RT-N12 without suffix (e.g. no B1, C1 or D1) has 4 MB space for the firmware, but also works out OK with a minimum version of the Tomato firmware.RT-N12-1st


  1. Connect an UTP cable from one of the LAN port to a PC LAN connector.
  2. Keep the Restore button for 20 seconds while adding DC power to the router.
  3. After another 20 seconds, start a browser and goto (or the router IP you might have set up earlier)
  4. The Broadcom CFE miniWeb server page shows up:


For the old version of Asus RT-N12 , you will need this firmware: Tomato-mini For the Asus RT-N12-D1, use this Tomato firmware: Tomato-max

5. Choose the firmware file and click upload, and the firmware flashing goes on. The received file size shown is for “Tomato-max”.!


6. Goto and enter login: admin and password: admin


7. Goto the menu Tomato Adminstration -> configuration and select the option: “Erase all data NVRAM memory..” and click OK.:


8. Now we need to configure the Tomato to work as a wireless bridge in the Basic -> Network menu. In this case, an Android smart phone with hot-spot enabled works as the host router. The host router gateway IP and DNS are Choose an IP for the bridge in case you want go into the Tomato admin page later on, here is choosen. Wireless mode is “Wireless ethernet bridge” . The SSID and password is exactly what you use on the host router. Press save for the new configuration to be activated.



This is it, to bridge your host router by wireless, connect the UTP wired device(s) to one of the four LAN ports on the rear side of the router.

Wireless IOT ESP8266-01

For a wireless timelap camera shutter project, I got hold of a few cheap (~2 Euro) ESP8266-01 Internet Of Things (IOT) modules. They are small (25x12mm) wifi 2.4 GHz ready devices with an integrated TCP/IP stack, a filesystem and an script interpreter for the Lua programming language:


To flash new firmware and to upload Lua scripts, you will need:

  1. A serial converter module from USB to 3.3 V serial.
  2. A 3.3 V @ 300 mA power supply.
  3. Buttons to reset and to enable flash mode.
  4. Firmware building via the cloud service.
  5. ESP8266 firmware flasher program
  6. Lua script uploading program

At Ebay or Aliexpress, the serial converter module from USB to 3.3 V serial can be obtained at around 1 €. The signal level can be selected ( 3.3 V or 5V ) for this version with the CH340G converter chip:

CH340 Serial Converter Module

I designed a ESP8266-01 programmer with a LED at GPIO2:


Next step is to obtain the necessary firmware for the actual project. Quite a number of modules are available to build a specific ESP8266 firmware. This is made possible with a “Cloud Build Service” at:  :


Clicking on “cloud build service” provides the option to choose the modules you want for the build.:


I wanted a http socket on top of the built-in tcp/ip stack, so the HTTP module is selected. Further down the web page your email address is needed for the automated build service to inform when the actual build process is finished and the build is ready to download. The build I got from the above module selection is available here: nodemcu-8-modules

The Windows version of the ESP8266 firmware flasher program is available from ESP8266 firmware flasher . Connect power and the serial converter module to the ESP8266. Serial converter TXD goes to RX of the ESP8266 and serial converter RXD goes to TX of the ESP8266. Keep the Flash button pressed and press Reset button once. Release the Flash button. Select the binary build file in the Config tab and start the firmware flashing process:


To upload Lua scripts to the ESP8266 module, I prefer the Esplorer program available from  :


The Lua script is loaded into the left panel, and can be transferred for testing via the selected COM-port. The right panel shows the result of the script.

At you will Lua script examples for the ESP8266.

My version of the http serverside script to toggle the LED at GPIO2 is available here:  server_LED-blink_template

The first line: wifi.setmode(wifi.STATION)  defines the wifi mode to STATION

The second line: wifi.sta.config(“your-ap-ssid”, “your-ap-password”)  defines the ssid and password of the wifi access point you are going to use. No fixed IP is defined, that is, the access point must provide the IP via DHCP.


Switching between DVB-C and DVB-T signals

Nowadays, newer TVs has one common antenna input for DVB-C and DVB-T signals, which is the case for our Panasonic TX-55AS750 TV as well.

The TV is able to scan all channels into separate channel lists for the DVB-C and DVB-T signals.

Combining the signals with a simple T-connector wont work, as many of the TV channels overlap.


One option is to buy an extra DVB-tuner and connect it to the HDMI input!.. and an extra remote for the DVB-T channel selection.   BUT on the Panasonic TV remotes, I have used for testing, you will find a “TV” button to toggle between the DVB-C and DVB-T channel lists.


The challenge is to make a piece of electronics that can grap and detect the infrared signal of the “TV” button in order to control an antenna switch connected to the common antenna input of the TV.

The installation set-up came up to look like this (click the image to enlarge):


I ended up using 4 remote control buttons for the infrared receiver:

  1. “TV” button to toggle an antenna relay with signal inputs for DVB-C and DVB-T.
  2. When the “Exit” button follows the “TV” button the antenna relay is toggled, just in case the TV and the relay are out of sync.
  3. When the “eHelp” button is followed by the “Exit” button, the output for the antenna LED light is toggled.
  4. When the “lastView” follows the “TV” button the antenna relay output is toggled. Successive “lastView” will  toggle the antenna relay output as well.

The antenna switch I use is the Spaun SAR 12F, requiring a voltage supply of 10..20 V DC @ max. 35 mA provided by an external power inserter, and a 5..18 V DC @ max. 1.5 mA for the relay control signal. The datasheet is here: SAR12F


The electronics I made for the IR receiver and antenna relay controller :


A Sharp GP1UX511QS 38 KHz infrared receiver is used for receiving the signals from the Panasonic remote, but any 38 KHz infrared receiver should do the job.

At the LED connector, 2 high brights LEDs can be added to indicate the DVB-T signal is switched to the TV and  to indicate the antenna LED is turned on.


On request, I can provide a zipped version of the Eagle design files.


The 12 V power inserter is a stripped down and modified version of the Triax FP501 power inserter.. The 230 V AC supply and the internal 78L05 voltage regulator are removed. A 12 V DC connector provides power to the inserter via the black plug shown in the picture above.


I have described the Attiny25 set-up and software in the second part of a blog here: panasonic-tv-ir-decoder





Panasonic TV IR decoder

Two versions of the IR decoder are implemented and described here:

1. A dedicated IR decoder for the antenna switching circuit project.

2. The stand alone IR decoder with a display to read the IR codes.

1. Panasonic TV infrared decoder for the antenna switching.

For the antenna switching circuit , I needed a piece of electronics to decode specific IR codes from Panasonic TV remotes:


To measure the output of the remotes, an infrared receiver is needed. I used a Sharp GP1UX511QS 38 KHz infrared receiver, but any 38 KHz infrared receiver should do the job.

With an oscilloscope I got the following screens for the remote buttons: “TV”, “EXIT”, “eHelp” and “lastView” :





The transmitted bit pattern has a syncronization part, a 16 bit address and a 32 bit of data to identify the button being pressed. For each button two identical bit patterns are transmitted, and 3 times for the red “Power” button.

The syncronization part is the long “LOW” followed by “HIGH”:   sync

The following 48 bits ( 16 bit address + 32 bit data ) is encoded like this:

0 : A short “LOW” followed by a short “HIGH”

1 : A short “LOW” followed by a long “HIGH”

By looking through the bit patterns for the “TV”, “EXIT” and “eHelp” buttons, I got the following data values in hexadecimal:

“TV” button:       Address : 4004  data: 01400C4D

“EXIT” button:   Address : 4004  data: 0100CBCA

“eHelp” button: Address : 4004  data: 01003534

“Last view” button: Address : 4004  data: 0100ECED

I decided to use an 8 pin Attiny25 microcontroller to do the decoding of the specific bit patterns. The schematic is clipped from the antenna switch project.


The free Atmel Studio 7 from  was used for compiling the C code. An AVR-ISP MKII programmer was used to flash the Attiny25.

The Attiny25 uses the internal clock generator at 1 MHz with the DIV8 fuse enabled.

The program to decode the bit patterns uses port interrupt at PB2 on negative going edges (INT0). Timer 0 is set to be free running with a divide by 64 prescaler, providing timer intervals of 64 usec.:

TCCR0A = 0;
TCCR0B = 3<<CS00;           // Prescaler /64 , 64 usec. timer
MCUCR |= (1<<ISC01);        // Interrupt on falling edge
GIMSK |= _BV(INT0);            // Enable external interrupt INT0
sei(); // enable global interrupts

Three global 16 bit variables hold address, dataHigh and DataLow.

volatile unsigned int RecdAddress;
volatile unsigned long RecdDataH;
volatile unsigned long RecdDataL;

The newFrame has a value of 1 when new address and data are available.

volatile uint8_t newFrame;

The INTO interrupt routine simply measures the elapsed time ( provided by Timer 0 ) from last INT0 interrupt.  In case of timer overflow, the interrupt starts looking for the next syncronization pattern. When a new frame with address and data is received,  the newFrame variable is set to 1.

ISR(INT0_vect) {
int BitTime = TCNT0;
int Overflow = TIFR & 1<<TOV0;
if (NextBit == 48)    // looking for the Panasonic header period
{                        // in between 4700 and 5700 usec.
if ((BitTime >= 73) && (BitTime <= 89) && (Overflow == 0))
RecdAddress = 0;
RecdDataH = 0;
RecdDataL = 0;
NextBit = 0;
}    // got header, now ready to receive 48 bit data
if ((BitTime > 30) || (Overflow != 0))
NextBit = 48; // max bit period exceeded, restart
if (BitTime > 15)    // if bit time > “0”-time, e.g. add “1” into the bit position
if (NextBit <= 15) RecdAddress = RecdAddress | ((unsigned int) 1<<(15-NextBit));
if ((NextBit <= 31) && (NextBit > 15)) RecdDataH = RecdDataH | ((unsigned int) 1<<(15-(NextBit-16)));
else RecdDataL = RecdDataL | ((unsigned int) 1<<(15-(NextBit-32)));
if (NextBit == 48) newFrame = 1; // signal to main() to retrieve data
TCNT0 = 0;            // Clear counter
TIFR |= 1<<TOV0;        // Clear overflow
GIFR |= 1<<INTF0;        // Clear INT0 flag

The complete Attiny25 program is found here: main1.c

2. Stand alone Panasonic TV infrared decoder with LCD display

As a spin off from the Attiny25 based IR decoder, I wanted a display to show the Panasonic IR code values instead of reading and translate the code timing from an oscilloscope. The LCD display shows Panasonic TV IR codes for the address (16 bit) and data (2 * 16 bit). The hardware is the Arduino Nano v.3 and a 16*2 character LCD display with the PCF8574 port expander to provide an I2C (TWI) interface. These parts are less than 2 Euro each from


The Sharp GP1UX511QS 38 KHz infrared receiver is connected to the Atmega328P interrupt input, INT0 (PORTD2).:


The Atmel Studio software for this solution includes I2C and LCD libraries.

The free Atmel Studio 7 from  was used for compiling the C code. An AVR-ISP MKII programmer was used to flash the ATmega328P. The ATmega328P clock generator uses the external 16 MHz x-tal on the Arduino Nano board.

The program to decode the bit patterns uses port interrupt at PD2 on negative going edges (INT0). Timer 0 is set to be free running with a divide by 1024 prescaler, providing timer intervals of 64 usec.

The complete source code is available here: PanaIR_I2C_LCD


Diesel motorcycle speedometer

For the diesel motorcycle project, I wanted a 120 kmh speedometer. I found a KUS 120 kmh speedometer that needs a square wave signal with a frequency proportional to the displayed speed value.


The speedometer needs a 500 Hz signal at 30 kmh and at 60 kmh a 1000 Hz signal is needed and so on. I placed a Hall-effect sensor along with a small magnet at the motorcycle front wheel to measure wheel rotation speed. The challange is to add a piece of electronics to convert the front wheel speed signal to the signal required by the speedometer. For this purpose a microcontroller is needed to do the calculations for the signal conversion. I used the Attiny85 with an external 8 MHz crystal to do the job and ended up with this circuit:


The Hall-effect sensor is supplied with 5 V DC at the SV1 connector, and Hall-effect signal is at SV1 connector pin 2. I used the Atmel Studio software development program to compile the AVR GCC C code and to flash the Attiny85 microcontroller. The flash device is the AVR-ISP MKII.

The speedometer conversion/interface PCB looks like this:


I did a conversion table to cope with the lack of a 16 bit counter in the Attiny85, it helps to understand the C code 😉  In the table, Rulleomkreds ~ Wheel Circumference.


The C code is listed here:

/* Speedometer pulse converter program using an ATTINY25. Converts a pulse per
wheelrotation to a KUS speedometer signal that provides 1000 Hz at 60 km/h.
3 Attiny25 interrupts are in use:
INT0 ISR starts measuring the next wheel rotation period
Timer0 ISR counts the wheel period using 0.25 msec increments
Timer1 ISR toggles the output pin at the required speedometer freq.
Conversion table and calculations are provided in an spread sheet !
Erik Henneberg – 2013.11.23
2014.04.27 – Increased wheel sensorpulses by 4 % ( 1 + 26 / 25 )
to achieve higher Timer1 counter/prescale values to lower the
output signal frequency to the speedometer by 4 %
2014.04.30 – adjusted wheel circumference to 2040 mm
#include <avr/io.h>
#include <avr/interrupt.h>
#define WheelCircumference 2040 // wheel circumference in mm
#define MaxSpeed 120 // max. speed is 120 kmh
#define MinSpeed 4 // min. speed is 5 kmh

// define wheel period limits in 0.25 msec resolution, 4 KHz ticks
#define MinPeriod 244 // WheelCircumference *36 / 10 / MaxSpeed / 0,25 msec
#define MaxPeriod 7344 // WheelCircumference *36 / 10 / MinSpeed / 0,25 msec

#define TACHO PORTB0 // tacho signal output attiny pin 5
#define INT0_PIN PORTB2 // wheel signal attiny pin 7

static unsigned int WheelTimer;    // 4 KHz tick counter

int main(void)
WheelTimer = 0;
DDRB |= _BV(TACHO); // set the TACHO pin as an output
DDRB &= _BV(INT0_PIN); // set the INT0_PIN pin as an input
PORTB |= _BV(INT0_PIN); // pull up resistor on INT0_PIN input
GIMSK |= _BV(INT0); // Enable external interrupt INT0
MCUCR |= (1<<ISC01) | (1<<ISC00); // INT0 on rising edge

// timer0 controls the 4 khz interrupt to measure the wheel sensor period
GTCCR |= _BV(TSM) | _BV(PSR0); // stop and clear
TCCR0A |= _BV(WGM01); // enable ctc
TCCR0B |= _BV(CS01); // clk/8
TIMSK |= _BV(OCIE0A); // enable output compare a interrupt
TCNT0 = 0;
OCR0A = 31; // 4 khz timer0 interrupt
TCCR1 = 0; // Stop Timer1, no output signal
sei(); // enable global interrupts

while(1) { }

ISR(INT0_vect) {            // handles the external INT0 ( wheel sensor ) interrupt
unsigned int temp;
if ((WheelTimer < MaxPeriod) && (WheelTimer > MinPeriod))
TCCR1 = 0; // Stop Timer1
TCCR1 |= _BV(CTC1);            // clear timer1 when it matches the value in OCR1C
TIMSK |= _BV(OCIE1A);        // enable interrupt when OCR1A matches the timer value
if (WheelTimer < 985) {        // 985 = 1024 / 1.04
temp = WheelTimer * 26; //.. to keep calculation within 1024
temp = temp / 25;        // adds 4 % to wheel pulse timer count
temp = temp/4;            // OCR = ( WheelPeriodTemp * 1.04 ) / 4
OCR1A = temp;            // set the match value for interrupt
OCR1C = temp;            // and the same match value to clear the timer
TCCR1 |= _BV(CS10) | _BV(CS11); // set prescaler to divide by 4 and restart timer 1
else {             // (WheelTimer < MaxPeriod and WheelTimer > 985)
temp = WheelTimer / 4;    // divide by 4 ..
temp = temp * 26;        // .. to keep calculation within an unsigned int
temp = temp / 25;        // adds 4 % to wheel pulse timer count
temp = temp/8;            // OCR = ( (WheelPeriodTemp/4)*104% ) / 8
OCR1A = temp;            // set the match value for interrupt
OCR1C = temp;            // and the same match value to clear the timer
TCCR1 |= _BV(CS11) | _BV(CS12); // set prescaler to divide by 32 and restart timer 1
WheelTimer = 0; // reset WheelTimer

// 4 kHz timer0 interrupt running continously. Provides ticks to measure wheel rotation time.
if (WheelTimer >= MaxPeriod) { // if Wheelrotation low or zero
TCCR1 = 0; // Stop Timer1
WheelTimer = MaxPeriod;
} else WheelTimer++;

// Outputs the signal to the speedometer. Toggles output pin.
ISR(TIMER1_COMPA_vect) { // handles the Timer1 Compare Match A interrupt
PORTB ^= _BV(TACHO); // just toggle the TACHO output signal


Diesel motorcycle rev. counter

For the diesel motorcycle project, I wanted a 4000 rpm rev. counter. I found a KUS rev. counter that has a signal scaling button on the rear side:


The diesel engine is a Ruggerini MD151 that has a flying wheel with a 2 phase generator output. A piece of electronic did the job to interface the generator output to the input of the revolution counter:


The PCB layout looks like this:


A small road trip shows the diesel rev. counter in action:


Electronic bar end turn signal

For the diesel motorcycle project I wanted to save space for the central wiring cluster in the main beam lamp housing. Thus, the turn signal relay was replaced two electronic relays with integrated SMD LEDs. They go into the bar ends using a Hella bar end signals.


The original bulb with holder is replaced by a printed circuit board, that holds the electronic turn signal relay along with the white SMD LEDS:


When 12 V DC is applied from the turn switch, the LEDs start blinking. The double sided PCB with 4 white LEDs on each side, looks like this to go into the Hella turn signal housing: