Funky v2 is a miniature open source/hardware Arduino Leonardo clone with RFM12B module, intended for low power, battery operated remote node with USB interface. Due to the miniature size, only few carefully selected pins are available as a side header, none the less that is more than sufficient to interface several sensors at a time.
Having gained experience with my Funky v1 project, I decided to create a new version. The project is a success, yet the areas I wanted to optimize are
- The Attiny84 MCU that was used in the Funky v1 has limited RAM and sketch memory
- The Attiny84 requires an ISP programmer for sketch uploading
- The Attiny84 required a modified Arduino core
- Many of the available Arduino libraries are not compatible with Attiny84
So the Funky v2 was created, see my posts here , here and here
- Board size is mere 22×22.8mm (0.87″x0.89″) in size (same as Funky v1)
- The MCU used in an Atmega32U4, the same MCU that Arduino Leonardo uses. This makes the Funky v2 a minuature Arduino Leonardo compatible board with RFM12b module
- The Funky v2 has the Caterina bootloader, so programming is done with Arduino IDE via micro USB
- Uses external 8Mhz crystal (can switch to internal RC clock in software as described here)
- Operates on 3.3V
Funky v2 is available for sale in limited quantities in the shop
Eagle design files and example sketches are available on my github repository.
Funky v2 revision 1 schematic/board layout:
Note the added MOSFET to control the RFM12B’s power state; This requires explicitly powering up RFM12B before initialization:
pinMode(A5,OUTPUT); // RFM12B power control pin digitalWrite(A5,HIGH); //Make sure the RFM12B is off delay(20); // Allow for RFM12B to start, you may use sleep to save power too ....RFM12B initalization code here.......
Setting up Arduino IDE for the board
As the Funky v2 operates at 8Mhz, we can use the instructions and drivers already available for the Arduino Fio v3:
1. Download the Arduino Add-on and drivers from here.
2. Installing this Arduino Addon is required for all platforms. This will add a Fio v3 option to your Boards menu within Arduino IDE.
To install this addon, unzip the Fiov3 folder into a ‘hardware’ folder withing your Arduino sketchbook. If you don’t know where your sketchbook is located, you can find it’s location by going to File > Preferences within Arduino.
3. Once unzipped, close any Arduino IDE windows and reopen. The following board should be listed in the Tools > Board menu now:
Fio v3 (Leonardo)
Important: Though the new bootloader is Leonardo-compatible, DO NOT select “Arduino Leonardo” from the Tools > Board menu before uploading code to the Fio v3. Because the Fio v3 runs at 8MHz, the sketch uploaded to the board must be configured for that same speed.
4. Installing drivers. Windows users will need to install drivers the first time you connect the Fio v3. Usually a New Hardware Wizard will pop up, you’ll need to direct it to the included “Drivers” folder. The driver is “SparkFun Fio v3.inf”.
The included driver will work for the new (Leonardo – VID/PID = 0x1B4F/0xF100 (bootloader) and 0xF101 (sketch)) versions of the Fio v3.
Your Windows may complain about installing unsigned driver, there are multiple resources on the Internet on how to allow that anyway. I used these for my Windows 8 installation.
Powering the board
Note: The micro-USB connector is soldered on the board — not through it. Be gentle when plugging and unplugging your USB cable.
The board can be powered from the micro USB plug and will regulate that input to 3.3V using the MCP1700 LDO regulator that is included by default on the board. The VUSB line is exposed as a pin on the side header, meaning that you can power the board from there too, just do not exceed the 6V limit that the Atmega32u4 VUSB has. The MCP1700 dropout voltage according to the datasheets is 178mV meaning the minimum supply voltage when powering via the VUSB should be 3.3V+0.178=3.478V. When directly powering the board from battery source (VCC), keep in mind that the MCP1700 will leak current if voltage >3.3V is applied to the output gate and nothing on the input. Powering from voltages lower than 3.3V will keep you out of trouble, this is the typical case when powering from single CR2032 battery or couple AA batteries. I have described this in more detail here.
The board carries an option for the 3.0V version of the (not 3.3V due to the above outlined issue) LTC3525ESC6 boost regulator and supporting elements to be included, this is useful option, when you wish to power the board from a 0.8 – 5.5V source and get regulated 3.0V.
The board can also be powered from a single CR2032 battery, unlike the Funky v1 the battery holder now can only be soldered at the side where the RFM12B module lays as the micro USB connector stands on the way on the reverse side. See example of this setup here.
Running on battery is one one of the advantages of the Funky project, however it needs taking special care to reduce power usage and therefore prolong battery life. Using this example sketch I managed to bring the power consumption down to 0.04mA.
If you want to be able to run in the 2.2-3.3V range, you have to bring down the BOD level a bit from the default 2.6V. In doing so, take precautions not to overclock, set the fuses to run on 1Mhz. You can speed up in the sketch to 4Mhz so you can talk over SPI to the RFM12B module. Here are the fuse settings I used:
External crystal 8Mhz, start-up 16K CK+65ms; Divide clock by 8 internally; [CKDIV8=0] (We will start at 1Mhz since BOD level is 2.2V) Boot Reset vector Enabled (default address=$0000); [BOOTRST=0] Boot flsh size=2048K words Serial program downloading (SPI) enabled; [SPIEN=0] BOD=2.2V or: low_fuses=0x7f high_fuses=0xd8 extended_fuses=0xcd
Funky v2 header pins
The side header of the Funky v2 started as intended Jeelabs’s JeePort, but that changed slightly as I advanced with the design. The reason for that is that JeePorts are Atmega328 specific and there is no information on which pins JCW will use in a future Atmega32u4 (if ever) based JeeNode. I still kept the overall idea of having a 5V-DIO-GND-3.3V-AIO-IRQ concept. Having said that, the Ports library will probably work with minor modifications.
- Pin 1 connects to VUSB and provides +5V if the USB cable is plugged in. It can also be used to power the board from a 3.5-6V source, given the USB cable is disconnected. Typical application of this pin would be to provide 5V for sensors attached to the header
- Pin 2 connects to Digital 13, a special pin with timer output to drive IR LEDs for example.
- Pin 3 connects to GND
- Pin 4 connects to VCC (3.3V if powered via the USB or the voltage that your battery is providing if powered by a battery)
- Pin 5 can be used both as Digital 8 or Analog 8 in Arduino IDE, it is a pin that supports pin-change interrupts: Needed for RX of SoftwareSerial (TX can be digital any pin)
- Pin 6 is Connects to Digital 2 pin, also can be used for IRQs
The on-board LED is connected to Digital 1
Detecting USB connection
This is useful when determining weather we are running on battery power or USB power and take measures to reduce power consumption if we are running on battery. See my full pose here.
void setup(){
USBCON = USBCON | B00010000;
pinMode(1,OUTPUT); // The on-board LED
delay(150); // Wait at least 150ms (necessary)
if (UDINT & B00000001){
// USB Disconnected code here
digitalWrite(1,HIGH);
}
else {
// USB is connected code here
digitalWrite(1,LOW);
}
}
void loop(){
}
Power saving techniques
When running on battery, we aim to cut power consumption down as much as possible. The following code will bring Funky v2 to about 0.03mA sleep current when running with BOD fuse disabled and at 4Mhz. Also see a complete example on GitHub.
ADCSRA =0;
power_adc_disable();
power_usart0_disable();
//power_spi_disable(); /do that a bit later, after we power RFM12b down
power_twi_disable();
power_timer0_disable();
power_timer1_disable();
power_timer3_disable();
PRR1 |= (uint8_t)(1 << 4); //PRTIM4
power_usart1_disable();
// Switch to RC Clock
UDINT &= ~(1 << SUSPI); // UDINT.SUSPI = 0; Usb_ack_suspend
USBCON |= ( 1 <<FRZCLK); // USBCON.FRZCLK = 1; Usb_freeze_clock
PLLCSR &= ~(1 << PLLE); // PLLCSR.PLLE = 0; Disable_pll
CLKSEL0 |= (1 << RCE); // CLKSEL0.RCE = 1; Enable_RC_clock()
while ( (CLKSTA & (1 << RCON)) == 0){} // while (CLKSTA.RCON != 1); while (!RC_clock_ready())
CLKSEL0 &= ~(1 << CLKS); // CLKSEL0.CLKS = 0; Select_RC_clock()
CLKSEL0 &= ~(1 << EXTE); // CLKSEL0.EXTE = 0; Disable_external_clock
// Datasheet says that to power off the USB interface we have to:
// Detach USB interface
// Disable USB interface
// Disable PLL
// Disable USB pad regulator
// Disable the USB interface
USBCON &= ~(1 << USBE);
// Disable the VBUS transition enable bit
USBCON &= ~(1 << VBUSTE);
// Disable the VUSB pad
USBCON &= ~(1 << OTGPADE);
// Freeze the USB clock
USBCON &= ~(1 << FRZCLK);
// Disable USB pad regulator
UHWCON &= ~(1 << UVREGE);
// Clear the IVBUS Transition Interrupt flag
USBINT &= ~(1 << VBUSTI);
// Physically detact USB (by disconnecting internal pull-ups on D+ and D-)
UDCON |= (1 << DETACH);
power_usb_disable(); // Keep it here, after the USB power down
rf12_initialize(storage.myNodeID,storage.freq,storage.network); // Initialize RFM12
// Adjust low battery voltage to 2.2V
rf12_control(0xC000);
rf12_sleep(0); // Put the RFM12 to sleep
power_spi_disable();
When disabling the USB connection or going in sleep mode, you will lose connectivity with the host system, therefore lost ability to upload new sketch using the usual method. The Caterina bootloader for the Funky v2 is a slightly modded version of the Arduino Fio v3, mainly for the different (and only) LED on the Funky v2. The bootloader also slightly differs from the ”stock” Caterina bootloader because it passes control to the sketch immediately on board power-up and will only go in bootloader mode for 8 seconds on external reset (or if no sketch is present). This is done so that no time is lost between board power-up and the sketch powering down the unused peripherals. This behavior may cause you trouble, if you disable the USB circuitry too soon. You can recover from the situation by connecting briefly a jumper wire between GND and the RESET pin on the Funky’s ISP header, at which point you generate an external reset and enter the bootloader for 8 seconds.
Examples for usage:
https://github.com/mharizanov/new_Funky/tree/master/examples
Bill of Materials
BAT2 BATTERY20PTH BATTCOM_20MM_PTH SparkFun 1 C2 100nF C-EUC0603K C0603K rcl 1 C3 1µ CAP0603-CAP 0603-CAP SparkFun 1 C4 10µ CAP0805 0805 SparkFun 1 C5 1uF C-EUC0603K C0603K rcl 1 C6 1u C-EUC0603K C0603K rcl 1 C7 100nF CAP0402-CAP 0402-CAP SparkFun 1 C8 22pF CAP0402-CAP 0402-CAP SparkFun 1 C9 22pF CAP0402-CAP 0402-CAP SparkFun 1 C10 1uF CAP0402-CAP 0402-CAP SparkFun 1 D1 Green LED0603 LED-0603 SparkFun 1 D2 DIODESOD-323F SOD-323F adafruit 1 IC2 LTC3525 LTC3525 SC70 JeeLabs 1 IC3 MCP1703CB MCP1703CB SOT23 linear 1 JP1 M01PTH M01PTH 1X01 SparkFun 1 JP2 M01PTH M01PTH 1X01 SparkFun 1 L1 10 µH INDUCTOR1210 1210 SparkFun 1 PORT1 JEEPORT-FEMALE JEEPORT-FEMALE 1X06_FEMALE_LOCK.010 JeeParts 1 Q1 P-MOSFET MOSFET-PCHANNEL SOT23 SparkFun 1 R1 22 RESISTOR0402-RES 0402-RES SparkFun 1 R2 100K R-EU_R0402 R0402 resistor 1 R3 10K RESISTOR0402-RES 0402-RES SparkFun 1 R4 22 RESISTOR0402-RES 0402-RES SparkFun 1 R6 330 RESISTOR0402-RES 0402-RES SparkFun 1 RFM12B RFM12B RFM12B RFM12B JeeParts 1 SJ1 SJ SJ jumper 1 U$2 AVR-ISP-6-EDGE AVR-ISP-6-EDGE 6PAD_ISP avr-7 1 U3 ATMEGA32U4 ATMEGA32U4QFN2 QFN-44-NOPAD SparkFun 1 X1 USB-MICROB USB-MICROB USB-MICROB SparkFun 1 Y1 8MHz CRYSTAL5X3 CRYSTAL-SMD-5X3 SparkFun 1
Licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.












Martin, this is pretty sweet! The only thing that concerns me is that you only provide 3 I/O pins with so much horsepower. How much do these boards end up costing you? It seems to me that it would be totally worthwhile to add another 8-pin strip on the other side. That would only add a couple of millimeters and allow you to add 6 more I/O (assuming VCC+GND pins). I.e. a perhaps 4mm extra space and you get 9 I/Os…
I intended this for interfacing with a single sensor, i.e. temperature, humidity, light level, PIR, pulse counter or sending IR/RF codes etc. It is just about the size of a button cell battery and can be powered by one, so having more pins would put more strain to the limited battery power anyway.
Anyway, I will probably create a bigger “cousin” to the Funky v2 with more pins available some day