This page will get more content over time but for now it just holds some points of interest and some instructions on how to bootstrap the board with an off-the-shelf microcontroller (fuses set for 1MHz, internal oscillator).
The latest model of the 0118 wireless sensor board PCB has two connectors for programming the chip. The first is the 6-pin ICSP (In-Circuit Serial Programming) and the second is the FTDI-based programming connector.
Before we can use Arduino to program the ATMega328p we have to upload a program called a bootloader. Once this in place we can use the FTDI programmer.
So here we go:
Functionality and Component Selection
Call it Design Specification, call it wish list.. This is what I want to use these devices for at some stage:
- PIR sensor
- Temperature sensor
- Voltage Measurement
- Easy interfacing with LCD
- battery powered
- option to attach solar panel for re-charging
- range of at least 1km LOS
The first design took care of many of these points and I settled on incorporating the following components on one PCB:
- MCP1703 250mA 3.3V linear voltage regulator
- MCP79410-I/SN Realtime Clock
- MCP73831T-2ACI/OT LiPo Charge Controller
- RFM12B 433MHz 1mW Transceiver
Current BOM (PCB version 0.3):
R1 33k (PV charge resistor, 47k is good too, just less current) R2 10k mcu RESET pullup R3,R4 4k7 (pullup resistors for I2C) R5 1k (LED series resistor) R6 10k (pullup for RTC interrupt R7,R13 10k (voltage divider for external voltage sampling) R9 10k (fet gate current limiting resistor for reverse-voltage protection) R10 4k7 (DS18B20 parasitic power resistor) R11,R12 10k (fet gate bleed-off resistors) R14 10k (radio_on fet gate resistor) C1,C11,C4 1uF C2 4.7uF C3,C5,C6,C9,C10 0.1uF C7,C8 7pF (10pF ok too, Crystal loading caps) XT1 32.769kHz (RTC Crystal) T1,T3,T6 NDS352AP Fet to control power to the radio module, battery reverse-polarity protection and ext voltage sampling circuit T5 BSS138 N-Ch FET to control external voltage sampling circuit D1 1N4001 DO-214AC diode to drop voltage to radio module D2 LED (on D9, not D13) U1 ATMega328P-AU (32-pin TQFP, preloaded with 'breadboard' bootloader) U2 MCP73831T Li-Po 4.2V charge controller SOT23-5 U3 DS18B20 OneWire temperature sensor (-125 to 125degC) U4 RFM12B (1mW), RFM69CW (17mW) or RFM69HCW (100mW) Hope RF transceiver module U5 SMA (edge pcb) connector [RS-Online 526-5785] U6 MCP79410 Realtime Clock SOIC
With regards to the LiPo charge controller Status pin: tristatelogic-vs-opendrain
Uploading the bootloader in a brand new ATMega238p chip
(pretty much following this: https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard )
Step 1: add wires to facilitate the Arduino to be an ISP programmer
For the programming we will use an already functioning Arduino board as the programmer.
Hook up power plus 4 programming wires (D10, D11, D12 and D13) to the new chip.
NOTE: the RESET line is directly connected; no 100nF caps or 10k resistors anywhere.
Step 2: set up the Arduino IDE and the Breadboard files
We will use the Arduino IDE version 1.0.6 (the latest in the 1.0.x series) to do the programming.
Download from here: https://www.arduino.cc/en/Main/OldSoftwareReleases#1.0.x
While you're there, also grab the 'breadboard' files from here: https://www.arduino.cc/en/uploads/Tutorial/Breadboard1-0-x.zip or locally here: File:Breadboard1-0-x.zip
(for 1.6.x version: download from here: https://www.arduino.cc/en/uploads/Tutorial/breadboard-1-6-x.zip or grab locally here: File:Breadboard-1-6-x.zip )
Set up Arduino by simply unzipping it in a directory. There you'll find the 'arduino' binary. Just run it and see if all looks good. From the menu go File - Preferences and note the path used for the 'sketchbook location' (e.g. /home/<user>/sketchbook). Close the Arduino IDE when done.
Make sure there's a 'hardware' folder in the 'sketchbook' folder and unzip the Breadboard1-0.x.zip in there.
Now start the Arduino IDE again.
From the menu check 'Tools - Board' and in the list, probably at the bottom, you should have a board called 'ATMega328 on a breadboard (8 MHz internal clock)'.
So far so good.
Step 3: turn the working Arduino into a ICSP Programmer
The Arduino IDE caters for this and has the sketch already available in the menu.
Open the sketch at: 'File - Examples - ArduinoISP'
Now program this sketch as you normally would (to the already working Arduino)
(I assume you have already set the correct serial port)
Step 4: change the programming method
Now that the Arduino is ready to program a new chip we need to make a change in the IDE that we're not using the USB cable to program the already working Arduino (otherwise we'll be overwriting the ArduinoISP programming sketch), but instead use the Arduino as a programmer to program something else. The Arduino sketch will effectively act as a tunnel and forward the code over the 4 programming wires and load up the new chip.
From the menu, select: 'Tools - Programmer - Arduino as ISP'
Whatever we program now will be coming out over the 4 programming wires.
Step 5: select the target board we wish to program
We're almost ready to program, but before we do we must tell the IDE what type of chip is connected to the 4 programming wires. This information is stored in a 'boards' file. When we unzipped the 'Breadboard1-0.x.zip' file in the 'hardware' directory we presented the Arduino IDE with a new board configuration specifically for this purpose. The boards file we unzipped is only to be used for ATMega328 chips and it will use fuse settings that will make it use the internal oscillator and run at 8 MHz.
From the menu, select: 'Tools - Board - ATMega328 on a breadboard (8 MHz internal clock)'
Step 6: upload the bootloader
Everything is now in place to attempt the uploading of the bootloader code into the new chip using an existing, working Arduino, as the ISP Programmer.
Confirm that on the status bar the Arduino IDE shows the Breadboard name and the port we'll use. All good? Let's go..
From the menu, select: 'Tools - Burn Bootloader'
The lights on the working Arduino board will flash for about 30 seconds and then the IDE should show the message 'Done burning bootloader'.
You may now move the newly programmed ATMega328 into your own project and use the FTDI method of programming it.
The RESET line is one item I would like to address:
When you have uploaded the bootloader into the new chip and wish to program it using the FTDI method, you should add the following circuitry to the chip's RESET line in order to guarantee successful programming every time you use the Arduino IDE and the FTDI method.
100nF FTDI Vcc --+-----||-----+---- RESET | | +----/\/\/---+ 10k
- to program a new bootloader into an ATMega328 using another Arduino with the ArduinoISP sketch it is important that the RESET line is directly connected. Once the bootloader has been loaded into the new micro and the FTDI programming method is used (no longer connected with the original Arduino board) then a 100nF capacitor is required. Without this capacitor the FTDI programming fails.
Version 0.1, initial board (June 2016)
In this version:
- Apart from bugs below, most things work
- GND trace missing from PV to three header pins
- T1 (RADIO_ON FET) swapped Drain and Source
- A2 and A3 swapped (Silkscreen A2 = real A3, Silkscreen A3 = real A2)
- move top silkscreen text further away around the 3-pin connector (under I2C connector) and around the 6-pin (with A6 and A7 pins) connector.
- bigger fonts underneath power connectors (PV, LiPo)
- move SMA connector slightly inwards into pcb?
- re-use pin D9 to use it as an extra IO pin
- move things around to better fit an external connector (DB9/DB15?)
- bypass track pads for RESET capacitor for initial ISP programming
- add white area to write version numbers
- shorten RTC pads
- bigger SOT-23 pads?
- check signal trace from RFM to SMA for 50R impedance
- add a pushbutton?
- reposition holes slightly for better fit in enclosure
Version 0.2 (Oct 2016)
In this version:
- increased ground plane under radio module
- 50R impedance signal tracks for antenna
- shortened board a little for better fit with SMA connector
- repositioned holes for better fit in enclosure
- moved pin label silkscreens a bit further so they can be read better
- shortened pads for RTC module
- removed ICSP header
- added pushbutton
- added pin D9 through-hole
- added white area next to SMA connector to write version numbers
- added solder-jumper-pad for measuring power after MCP1703
- added GND track from PV to 3 header pins
- A2/A3 still persists?
- T1 (RADIO_ON FET) swapped Drain and Source
Version 0.3 (June 2017)
In this version:
- added extra white silkscreen pad for notes
- fixed controlling switched power to the radio
- disconnected Aref to Vcc so we can use the internal 1.1V voltage regulator
- swapped pinout for A2 and A3 (now correct: A1, A2, A3)
- ran some low-power code and was able to get the consumption from a 4.1V 100mAh LiPo down to around 3uA. This is with the MCP79410 Realtime Clock, I2C 10k pullup resistors + MCP73831T LiPo charge controller.
As it turns out, the MCP1703 LDO linear voltage regulator has some issues. Google transient response and PSRR for details, but what it basically comes down to is that when the 1703 needs to suddenly cater for a bigger current draw, it drops the voltage for a few us before it can recover from the sudden change. On the scope I saw that when I turned on the radio (drawing about 20mA) the voltage dipped from 3.3V to about 2.4V for about 8us. There may be other things happening as well, but the result was that the atmega328 went into reset every time the radio was switched on. Because I am aiming for low power consumption and want to switch of the radio when the mcu is in sleep mode, this issue needs to be rectified. For a while I started looking at LDOs that have a better transient response, but I found I was getting into more expensive parts and perhaps harder to get as well. Don't get me wrong, the 1703 is a great low-power device when the transient response is not an issue, but for me it was just not the right choice.
I then started looking at the possibility of removing the LDO altogether. I ran some checks and it turned out that the RTC, DS18B20 and the ATmega328 were more than capable of running off 4.2V (maximum voltage when a 1S LiPo is charged). The only part that could handle only up to 3.6V was the RFM radio module. After doing some tests I experimented with just putting in a single 1N4001 diode to drop the power by 0.7V. This is now my current solution to the problem. I checked whether I needed one or two diodes in series and came up with the following chart:
This shows that with 1 series diode the voltage is lowered enough to safely power the radio module even when the battery is fully charged. I did further tests by lowering the input voltage even further and I could theoretically have the battery voltage drop to 3.3V and the radio would still be able to function properly. Of course, you would not want to run a LiPo battery that low, but it's nice to know where the edge of operation conditions are.
Losing the LDO made several improvements for this project:
- less current drain on the battery as the LDO is not taking up any power anymore
- more space on the circuit board as the LDO and its surrounding caps are gone (although I do now have to add the diode, DO-214 footprint)
- made the design somewhat simpler and cheaper
- improves power stability as the LDO no longer causes a dip whenever a big(ish) load is connected
- longer battery life as the LDO needs to overcome the dropout voltage (according to the datasheet a 3.3V 1703 is out of spec when fed with less than 4V on the input and supplying the maximum 250mA output). Not that I want to, but I can run my LiPo now down to 3.3V and still get the radio to work.
- no longer a restriction of 250mA current draw
External connector pinout
Using a DSUB9 connector:
GPS 1W ExtV BZ free | | | | | | | | | | 1 o o o o o 5 6 o o o o 9 | | | | GND PV |---| | | Batt | pcb
MCP7383 LiPo Charge Controller - charge current and Rprog resistor values
500.0 mA 2 k 454.5 mA 2.2 k 416.7 mA 2.4 k 370.4 mA 2.7 k 333.3 mA 3 k 303.0 mA 3.3 k 277.8 mA 3.6 k 256.4 mA 3.9 k 232.6 mA 4.3 k 212.8 mA 4.7 k 196.1 mA 5.1 k 178.6 mA 5.6 k 161.3 mA 6.2 k 147.1 mA 6.8 k 133.3 mA 7.5 k 122.0 mA 8.2 k 109.9 mA 9.1 k 100.0 mA 10 k 90.9 mA 11 k 83.3 mA 12 k 76.9 mA 13 k 66.7 mA 15 k 62.5 mA 16 k 55.6 mA 18 k 50.0 mA 20 k 45.5 mA 22 k 41.7 mA 24 k 37.0 mA 27 k 33.3 mA 30 k 30.3 mA 33 k 27.8 mA 36 k 25.6 mA 39 k 23.3 mA 43 k 21.3 mA 47 k 19.6 mA 51 k 17.9 mA 56 k 16.1 mA 62 k 14.7 mA 68 k
Version 0.4 (July 2017)
In this version:
- removed the MCP1703 LDO linear voltage regulator. Everything is now powered straight off the battery
- 50 Ohm Z for antenna stripline and connector
- on-board P+N-Fet controlled voltage divider for external Voltage measurements + added an extra pad to conveniently connect an external voltage source for measuring.
- disconnected Vref from Vcc so that we can use the internal 1.1V reference for measuring battery voltage
- Added pads for an on-board Dallas DS18B20 'OneWire' temperature sensor
- Added an inline 1N4001 diode to the power tail to the radio module. This drops down the voltage enough to operate the module within specs.
- added a reverse-polarity protection P-Fet across the battery terminals
- moved the Crystal loading caps a bit further so that soldering doesn't overflow in the Crystal pads
- in V0.3 the Vcc line from the FTDI connector to the nearby Vcc track got deleted. It's now back again.