• Home
  • About
  • Portfolios
  • Blog
Potable FM Radio

Portable FM Radio with indoor temperature and humidity monitoring

Motivation

I wanted to experiment with battery-powered devices and simple user interfaces in embedded systems. I needed a project to practice with, so I decided to build this portable stereo FM radio with indoor temperature and humidity monitoring.

 

Features

  • Stereo FM audio output
  • Humidity and temperature monitoring
  • 18 hours of continuous playback
  • detecting and processing both Radio Data Service (RDS) and Radio Broadcast Data Service (RBDS) information
  • 20 radio station logos can be stored in EEPROM
  • Colorful ambient light with different modes

Engineering Challenges

Power consumption 

To extend the battery life, the software and hardware had to be optimized to get the most from the single-cell battery powering the device. First, the frequency of the MCU was reduced to 8Mhz and the power to 3.3V. The second optimization on the hardware was to replace the linear regulator with a switching regulator.

The software was designed to reduce power consumption by powering down the ADC and brownout detector and sending the MCU to sleep. The device will wake up periodically every 5 seconds to update the LCD. The device can also be woken by an external interruption (i.e. the user turning the knob).

Wake vs Sleep current consumption

 

Software

The control software is written in C++, the cross-compile and link to the Arduino core lib is made using cmake/avr-gcc. Due to memory size limitation, the Arduino IDE wasn’t suitable for the purpose of this project.

The main loop

The main loop maintains a pointer to the current running service. At each iteration, we read the user inputs and handle them to the current service before calling its update function. The main loop is also responsible for switching between available services. If no user input is received within a “timeout delay” the current service is set to idle.

Services

  • Idle: in this state, the system cycles through different screens (Station info, Temperature, Humidity, Humidity index)
  • Menu: is used to display system properties and edit them
  • Radio
  • Power management

The virtual class ServiceBase is inherited by the Idle, Radio and Menu services. Each inheriting class must implement the three pure virtual functions:

  • start() : service initialization and setup
  • update() : update the current screen
  • userInput(_userInput input) : for reading user inputs

The power management service is run at the end of each iteration and is responsible, as its name suggests, for all power management related functions.

  • Measures and updates the current voltage level and power consumption.
  • Puts the device to power-saving mode, by putting the MCU and FM tuner to sleep.

User inputs

The rotary encoder with the integrated momentary switch can be used to trigger different actions on the device based on the current context.
When the device is in Idle state, and the knob is turned to the left or right, the volume goes up and down. If the user keeps the button pressed while turning the knob the current frequency is increased or decreased. This can be used for fine-tuning. If the button is pressed, the current state goes to radio.
In radio state, the left and right knob turns are interpreted as Next/Previous channel.
A long button press sets the system to the Menu state. In this state, the user can navigate between different menus using the knob. The user can enter a menu with a button click. The LCD will display the available options of the sub-menu.

Hardware

The electronics used for this project are very simple. The main board is a custom-designed PCB with an Atmega328p microcontroller. The circuit includes a LiPo battery charger based on the MCP73831T.

The board includes connectors and slots for :

  • The FM tuner, a breakout for the Silicon Laboratories Si4703 FM tuner chip from Sparkfun
  • The rotary encoder
  • Humidity&Temperature sensor
  • LDR (Light Dependent Resistor)
  • Audio amplifier
  • LCD screen

 

 

 

Two 3″ PVC pipes are used as a base for the structure, to which are attached the front, top and bottom panels. The speakers are mounted on the pipes to improve sound quality.
The back panel is made out of plywood. It houses the power input, antenna, humidity sensor and power switch.
The top and bottom plates are made out of a single-sided PCB, on which I etched some fancy Arabic calligraphy and motifs on the copper side. The top plate is used to house the neopixel RGB ring and the rotary encoder. The LDR is mounted on the right tube to avoid noise due to light emitted from the neopixel LED.

motherboard and LCD tray
Back panel
© 2019