I’m happy to announce the release of a new version of firmware.
How to Update Your Firmware
With the latest version of the app, the process should be automatic next time you try to connect to your Mooshimeter with the most recent update of the app [Note: At the time of publication (March 11 2015) the iOS app shown is still waiting for Apple review]. The process should take about a minute.
Bug report: After the process completes, swipe the scan screen again to update the firmware version numbers stored in the app. Otherwise the app will try to initiate a new firmware download. (Thanks Sean)
There are some bugs in the Android BLE stack that make the firmware update process different. To update firmware on Android, do the following from the most recent version of the app:
- Scan for your meter
- Push the reset button on your meter
- While the LED is blinking slowly (5 second window) connect to the meter from the app.
- If you miss the 5 second window and are taken to the meter view page, don’t worry. Just disconnect from the meter and try again.
- If you connected in the 5 second window you will be taken to the firmware upload page. Press the “Upload firmware” button and wait. Unfortunately on Android the firmware upload process takes about 8 minutes.
Why is a manual reset necessary for Android?
In the Mooshimeter there are actually 2 separate firmware images – the Bootloader and the Application. The Bootloader’s sole purpose is to update the Application. When the Mooshimeter is rebooted, the Bootloader turns on for 5 seconds and waits for someone to connect to it to update the application. This is when the LED is flashing slowly. If nobody connects to it in that time, it checks the Application firmware for validity and then boots it. Both the Bootloader and Application firmware advertise their BLE connectivity using the same hardware MAC address. There’s a bug in the Android BLE stack – it makes an erroneous assumption that a BLE device will always offer the same services, so Android only asks for those services the first time it connects to a device. On subsequent connections, it reads the available services from a cache. This is a major problem for the Bootloader, because it offers completely different services from the Application! Thanks to Miguel on StackOverflow there’s a hack to force Android to empty the services cache. But it really is a hack and it does some screwy things to the Android BLE stack when you quickly disconnect and reconnect.
On top of this bug, disconnect events seem to take a very long time to reach the Android app code, so when the Android App tells the Application firmware to reboot in to OAD, the Android BLE stack freezes for a few seconds until it registers the disconnection, usually missing the 5 second window. So right now the most reliable way is to have the human handle the timing. Not elegant but it works.
Why is firmware upload so much slower on Android?
In short, another Android BLE bugs. BLE connections work by having the two devices swap packets at a fixed interval (dictated by the smartphone – typically 30ms). The amount of data you can shove in to one transaction limits the data rate. On iOS you can easily shove 4 frames worth of firmware data in to one transaction (64 bytes), and get all 4 frames confirmed in the next BLE transaction. On Android this has been very flaky, and the only way I’ve found so far to get firmware transmission to be reliable is to send the firmware one frame at a time and acknowledge every frame. This means instead of 4 frames and 4 confirmations per transaction, it’s doing a frame in one transaction, a confirmation in the next, etc., cutting the data rate by a factor of 8. I may be able to get around this, but the inconsistent implementation of the BLE stack across different Android devices makes me hesitant.
Power Consumption Bug Fix
In hammering out the logging feature I found a nasty bug that was causing excess current draw in standby mode. The bug raises the quiescent current draw from <10uA to about 300uA. This bug lowers the expected battery life of the meter to less than a year. So performing a firmware update is highly recommended! Technical explanation: The bug was one of the oldest in the book. There is an IO line with a 10K pulldown resistor on the MCU that was being driven high and not reset when the MCU goes to sleep.
The new firmware adds SD card logging. After uploading the new firmware to the device, logging works as follows:
- Open the back cover and insert an SD card until it clicks in to place.
- Any SD card under 32GB formatted with the FAT filesystem should work. The FAT filesystem is the default most cards ship with, so if you don’t know what a filesystem is, you’re probably fine.
- Close the back cover.
- Physically connect the meter to the hardware you want to log data from.
- From the app, set up the meter to be measuring the values and range you want.
- The meter will not auto-range when logging, so be sure to set the range so it encompasses the entire expected value of the thing you’re measuring.
- (Optional) Change the logging interval.
- The meter will take a reading, write it to the SD card, and sleep for one interval time before waking again. The default interval time is 1 second. On the configuration page you can set the log interval to be longer or shorter. A longer interval means longer battery life, but less data in the log.
- Press the “Logging” button on the meter view page. It should turn green.
- Disconnect from the meter.
- You can do this by pressing the back button in the top left of the mobile app to return to the Scan page. If the SD card is correctly initialized, the meter will blink every time it takes a sample. So if you set the sampling interval at 1 second, the meter should blink once per second.
The above will be ported in to the support resources soon. To retrieve the log:
- Disconnect the meter from what you’re measuring.
- Open the back cover.
- Remove the SD card and connect it to your computer.
- Run the conversion script CONV.PY
- The l0gs are stored in a binary format native to the meter. For convenience, the meter will write a conversion script in Python to the SD card that will convert the data to a CSV (comma separated value) format.
- Python is an extremely popular scripting language which is probably already installed on your computer. If you don’t have python installed it is available here.
- Open and process the CSV files in your favorite spreadsheet application.
I’ve alluded in the forums to “timing issues” that were bugging this feature up and slowing development. I’ll try to elaborate on what made this feature difficult to implement. At the heart of the Mooshimeter is a CC2540 from TI. It’s a marvelous little MCU and BLE radio in one. However it has some limitations that aren’t immediately apparent until you are developing with it. The biggest of these limitations from a firmware development perspective is that the codebase provided by TI does not react well when any single process uses the processor for more than roughly 100ms continuously. Even though the radio interrupts are the highest priority and should be able to grab the processor from a lower priority task, the radio interrupts drive a framework that relies on the OSAL (operating system abstraction layer, a task-scheduling system provided by TI) not running any long tasks. If an OSAL task running too long only caused the BLE to disconnect that would be one issue, but it causes the BLE stack to fail entirely such that the device is no longer connectable until a reboot. It’s hard to tell exactly what’s going on because the radio stack itself is closed-source, and provided only as a binary that must be statically linked in.
A quick aside: I think TI has recognized this limitation is a major drag on developers. Their successor to the CC2540, the CC2640, is radically different and has a totally separate core running the timing-critical aspects of the protocol stack, leaving much more of the main processor free for application code. Also the processor is a major upgrade – it’s a 32-bit ARM3 instead of a puny 8-bit 8051. Math becomes so much easier… doing RMS calculations on buffers of 24-bit data with an 8-bit processor is painfully slow. The CC2640 datasheets were only released a few weeks ago, and I can tell you I’m excited to try it out. It’s a very strong candidate for the core of Mooshimeter 2.0. Nordic Semi also has some handsome chipsets with advantages over the CC2540. But one thing at a time…
Talking to an SD card involves a lot of waiting around. SD cards are slow to initialize and to write, with larger cards generally being slower. After powering up an SD card, the host must command it to leave the idle state, which can take hundreds of milliseconds. After every read and write operation to the card, the host must wait until the SD card is ready again before sending the next operation. Since the SD card has no IRQ, this means polling the card.
The SD card interface on the Mooshimeter is based on elm-chan’s FatFs module, which is a wonderful free library but not designed to run asynchronously. Since the long polling delays cause the BLE stack to crash unrecoverably, chunks of the library had to be redesigned to run asynchronously. It still needs more work before it can talk to an SD card while maintaining a BLE connection, but it can run without delaying so long it borks the stack.
First: The top priority for the next few days will be improving documentation and website resources, both for support and for development.
Second: The apps are improving but there are still a few missing features that would increase utility. Actual numerical power factor display is still missing. Logging in the app itself (instead of to SD card) has been requested and would be very useful – basically just something to save your entire multimeter session to a log file on the phone itself.
Third: Obviously having to remove the SD card to retrieve the logs is a hindrance and cuts down on some useful embedded applications. The next firmware goal is to get the logs streaming out over the wireless connection. This is difficult because it involves having the SD card and the BLE connection active simultaneously, which is quite difficult because of the timing issues above. It’s achievable but it involves rewriting more of the filesystem and disk access code to be asynchronous.
Finally: Word has been spreading about the meter and there is a decent stream of orders coming in. That’s very encouraging because there’s been no marketing, it’s all word of mouth. So calibrating, packing, and shipping is still happening in the background.
I’m a little behind in the forums, I’ll make a pass through shortly. Sorry, it’s been a tight debugging loop trying to get around the logging issues. Thanks for reading!