Flashing BLE112 with Arduino-Based CC-Debugger

As it is always the case, many products from Texas Instruments require a CC-Debugger to flash program memory. Bluegiga’s BLE112 module is not an exception. But when one compares BLE112 and CC-Debugger prices things don’t look bright anymore – there is a little sense (if any) to pay $50 US dollars for a CC-Debugger to program an $11 dollar module. Things become even more ridiculous when a hobbyst is simply willing to flash his/her module only once using the code that is already compiled and debugged by someone else. Would it be possible to find a replacement for a CC-Debugger? Yes, but as always, something is to be sacrificed.

There is a great project at Github called CCLib that uses an Arduino which acts almost like a CC-Debugger. Indeed, nowdays Arduinos are very popular piece of hardware and if you are that kind of person who needs to flash a BLE module, chances that you already have Arduino board in stock are pretty high. But even if it is not the case, buying a basic Arduino board still will be much cheaper than CC-Debugger, besides, immediately after flashing Arduino could be used for another project. The solution works just fine, the only downside of this is an enormously long flashing time, this is because Arduino script works literally as a proxy for business logic implemented in Python scripts on a PC side. The datapackets traveling between PC and Arduino are short resulting in tremendous round trips when it comes to uploading or downloading BLE112 memory snapshots. So, to flash 128Kb it takes 1.5 hours! For some people it could be acceptable but we decided to redesign the whole concept of CCLib focusing on highest possible performance.

First, the logic implemented in Python scripts has to be translated to C/C++ and relocated to Arduino side so the data packets would essentially contain packetised binary files including just a little bit of overhead – packet type, packet length, block number, checksum etc. Second, the size of a single packet would need to be as big as Arduino’s buffers are capable to accommodate, this would be achieved by making Arduino’s app to send the size of its RX buffer before actual data exchange takes place. So, the more advanced Arduino board is used, the bigger its RX buffer and the more effective data exchange would be. Third, standard Arduino’s library is extremely slow when it comes to digital in/out which is very critical for this particular application so faster equivalents of those functions would be used.

The PC application would need to have GUI interface, no nasty command lines with pathetic attempts to display a progress bar. CSharp is probably the most popular language now so the app would be designed for Visual Studio 2013 Community Edition which any hobbist can download for free and use without limitations. Of course, everything is going to be opensource, as usual.

The final result of development effort is given below. Additional total 2k lines of source code has been added to the CCLib project effectively replacing Python scripts. On a PC side an app called ‘Arduino CC-Debugger’ has three configuration parameters in CCLibFrontend.exe.config file which are SerialPort, Baudrate and LogPath. All of them must be set to appropriate values once as they pretty much remain unchanged on a given PC. SerialPort is set to a USB-to-Serial port name which appears in Device Manager list upone plugging in Arduino board to the PC. Baudrate is set to 115200 which matches the port speed on Arduino side. LogPath is set to a directory that would contain log file generated by the Arduino CC-Debugger.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>
        <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="CCLibFrontend.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <userSettings>
        <CCLibFrontend.Properties.Settings>
            <setting name="SerialPort" serializeAs="String">
                <value>COM3</value>
            </setting>
            <setting name="Baudrate" serializeAs="String">
                <value>115200</value>
            </setting>
            <setting name="LogPath" serializeAs="String">
                <value>C:\CCLib-Frontend\</value>
            </setting>
        </CCLibFrontend.Properties.Settings>
    </userSettings>
</configuration>

GIU interface is intuitive and self-explanatory, there are only 3 buttons initiating either reading/writing or chip info retrieval sequence. There are fields for displaying the following information: chip ID, flash size, SRAM size, USB support flag, IEEE address, BT address, hardware version and license. Out of all these fields BT address, hardware version and license are kept at a special location in regular program memory so they could be wiped out or replaced, either accidentally or deliberately. That is why it is highly recommended to do a read operation on your module and keep the file as a backup before doing any writing. Also, for the sake of capturing screenshots and doing video presentations there is a ‘Hide values’ tick which, when enabled, shows only first two digits of your BT address and license preventing them from being stolen and at the same time allowing screenshot/video sharing. And finally, the screen form contains a progress bar which keeps an end user updated during lengthy operations. The total operation time is shown in seconds at the right bottom corner.

Arduino CC-Debugger Screenshoot

Arduino CC-Debugger Screenshoot

The Arduino CC-Debugger app accepts either binary (*.bin) or Intel HEX (*.hex) files. HEX files are parsed by another great third-party project, so-called LibGIS for .Net which is made part of the application. If a file is provided in HEX format, it will be converted to binary and written as image.bin. Then before flashing sequence BLE storage, BT address, hardware version and license will be read from the chip and merged with the content of ‘image.bin’ resulting in creation of ‘image_merged.bin’. Memory snapshots are generated by ‘Read’ command and written in binary format as ‘read.bin’. Each subsequent read operation overrides old file if it exists, same applies to ‘image.bin’ and ‘image_merge.bin’.

Physical connection between Arduino and BLE module comprises of three signal lines (DD, DC and RST) and in total requires 5 wires as Arduino uses two GPIOs for DD signal (one pin is configured as input for incoming data, one pin is configured as output for outgoing data ) plus one wire for ground. Mapping these four signals to Arduino’s GPIOs is done in ArduinoCCDebugger.ino in ‘Pinout configuration’ section and can be redefined to something else if needed. The BLE module’s inputs are not 5V tolerant so there must be resistor dividers as shown on the picture below.

Arduino - BLE112 Level Converter

Arduino – BLE112 Level Converter

Alternatively, a 3.3V Arduino could be used eliminating necessity of resistors. For example, Seeeduino V.3.0 board has 3.3V/5V selector and therefore it doesn’t require resistors when set to 3.3V mode. Another big plus of Seeeduino is two LEDs connected in parallel to RX/TX lines which conveniently provides with visual indication of data traffic over serial interface so no need in external LED which is used in CCLib project.

Seeeduino Voltage Selector Is Set to 3.3V

Seeeduino Voltage Selector Is Set to 3.3V

A BLE module is connected to Arduino via flat cable and 2.5mm-to-1.27mm adapter as shown on the picture below. The adapter could be the one which comes with CC-Debugger, it is also possible to buy it from ebay or simply build.

Flat Cable With 2.5 to 1.27mm Pitch Adapter

Flat Cable With 2.5 to 1.27mm Pitch Adapter

The full blown ‘ready-to-flash’ setup is provided on the picture below:

Seeeduino As a CC-Debugger Setup

Seeeduino As a CC-Debugger Setup

The comparison tables below highlight cost factors for all three solutions mentioned in this post:

Variant I – flashing with original CC-Debugger
Item Flashing time Price, USD
CC-Debugger few seconds 49.00
Variant II – using Arduino + CCLib
Item Flashing time Price You save
CCLib project + Arduino Uno 1.5 hours(!) Starts from $3 USD at aliexpress
Total 3.00* 46.00
Variant III – using Arduino + Arduino CC-Debugger
Item Flashing time Price You save
Arduino CC-Debugger + Arduino Uno 80 secs(!) Starts from $3 USD at aliexpress
Total 3.00* 46.00 + a lot of time!

*Note, that you may end up spending 0 if you already have Arduino.

This project also opens the following possibilities:
1) run the code on faster Arduinos and therefore achieve performance close to the original CC-Debugger or even run it on such boards as Particle (formerly Spark) and flash BLE modules from Apple/Android devices via Cloud;
2) in systems where BLE module works as a slave under control of a host microprocessor it becomes very easy to upgrade/update BLE firmware using host controller through its Serial/WiFi/USB/whatever capabilities.

Downloads:

1. Arduino CC-Debugger sketch & library Rev1.0
2. Arduino CC-Debugger Frontend Rev1.0

The video summarising development effort is given below:

A Man and His Dream to Fly

This is the man whom I met in North Sydney last year. He turned out to be an entrepreneur, a test pilot, an owner of an advertising agency on Miller Str. and God knows who else. I designed for him a a pilot display for his turbofan power jet: http://magictale.com/category/pilot-display-4-turbine/ and at that time was rather skeptical listening his a bit crazy descriptions of the project while sitting in a small cafe in North Sydney.

Pilot Display Fully Assembled

Pilot Display Fully Assembled

The man was violating all the rules during the process: primitive design requirements which kept changing up to the stage of hardware prototyping, loosely coordinated team, all deadlines were ‘yesterday’ or at least ‘ASAP’. I was never a true member of his distributed team and worked in isolation so the total effectiveness of the whole design process should’ve been very poor yet, this is what happened one year later:

http://jetpackaviation.com/the-worlds-only-jetpack-soars-past-the-statue-of-liberty-new-york/

The man is on front pages of the US newspapers. His newly established company skyrocketed from non-existence to where it is now. Everybody immediately understood why this product is needed and how to use it, thanks to the ‘Iron man’ movie. This is the power of The Dream and importance the right technology at the right time.

Dmitry

The relevant video is given below:

The BlueButton – Assembling & Testing First Prototype

The PCBs eventually arrived, however, this time it was somewhat disappointing: instead of usual two weeks the manufacturing process along with the shipment took almost four weeks. The quality seems to be fine and no ‘gotchas’ have been found so far so hopefully soldering will go smoothly.

This is how the PCBs look like:

BlueButton PCBs Manufactured

BlueButton PCBs Manufactured

The amount of components in this project is really small, it takes about 30 min… 1 hour to solder all of them. The only thing that needs to be kept in mind is that BLE module should be loaded before the battery holder and the P3 (CC_Debugger) connector. This would simplify the assembling process. The fully assembled board is shown below (top side of the PCBa):

BlueButton PCBA Top Side

BlueButton PCBA Top Side

… and bottom side:

BlueButton PCBA Bottom Side

BlueButton PCBA Bottom Side

Before the board can be programmed, we need to implement an application (also known as BGscript). As a base hid-over-gatt-keyboard application example is used as it in essence does everything that our BlueButton needs to do: it works as a HID keyboard over Bluetooth so no additional drivers on a host computer would needed. However, there some changes and enhancements that will be done to the original code. First change is in hardware.xml to pull port 0 pins up and port 1 – low. We also enable sleep mode “3” which is the most power preserving mode, however, it can’t be used in current application without additional changes which will be introduced later:

<?xml version="1.0" encoding="UTF-8" ?>
<hardware>
    <sleeposc enable="true" ppm="30" />
    <usb enable="false" />
    <txpower power="15" bias="5" />
    <script enable="true" />
    <slow_clock enable="true" />
    <!--pmux regulator_pin="7" /-->
    <port index="0" tristatemask="0" pull="up" />
    <port index="1" tristatemask="0" pull="down" />
    <sleep enable="true" max_mode="3" />
</hardware>

Second change is in the script. In system_boot we configure ports to enable the LED and interrupts from 5 buttons:

event system_boot(major, minor, patch, build, ll_version, protocol, hw)
    # configure P1.0 as output
    call hardware_io_port_config_direction(1, $1)

    # Pull low P1.0 pin. Parameters: I/O port to write to 0/1/2,
    #                               bitmask of pins to modify,
    #                               bitmask of pin values to set
    call hardware_io_port_write(1, $1, 0)

    # start advertising in connectable mode
    call gap_set_mode(gap_general_discoverable, gap_undirected_connectable)
	
    # remove all bonds (optional! normally this shouldn't be run on every boot)
    #call sm_delete_bonding($ff)
    
    # enable bondable mode for systems which want to use it
    call sm_set_bondable_mode(1)
    
    # enable interrupt on P0_0, P0_1, P0_2, P0_3, P0_4 rising edge ('A', 'B', 'C', 'D' and 'E' keys)
    # (parameters are port=0, bitmask=0b00001111, edge=rising)
    call hardware_io_port_config_irq(0, $1f, 1)

    # use default report mode for keyboard
    hid_attribute = hid_keyboard_in
end

Then when handling events from 5 buttons there are two additions: suppressing bouncing effect by disabling interrupts the any button for a specific time and activating LED to indicate button press:

# catch button press for P0_0, P0_1, P0_2, P0_3, P0_4 (active HIGH configuration, hardware.xml pulls it high)
event hardware_io_port_status(delta, port, irq, state)
    if port = 0 then
        # build HID report:
        # 0:0x02 = left shift (should be capital A or Z unless caps lock is on)
        # 1:0x00 = RESERVED
        # 2:0x?? = key down (will be set to either A or Z code below)
        # 3:0x00 = empty key slot
        # 4:0x00 = empty key slot
        # 5:0x00 = empty key slot
        # 6:0x00 = empty key slot
        # 7:0x00 = empty key slot
        report(0:8) = "\x02\x00\x00\x00\x00\x00\x00\x00"
        if (irq & $01) = $01 then
            # P0_0 is HIGH and the source of this interrupt, so use "A" code
            report(2:1) = $04   # "A" key code, 4
        end if
        if (irq & $02) = $02 then
            # P0_1 is HIGH and the source of this interrupt, so use "B" code
            report(2:1) = $05   # "B" key code, 5
        end if
        if (irq & $04) = $04 then
            # P0_2 is HIGH and the source of this interrupt, so use "C" code
            report(2:1) = $06   # "C" key code, 6
        end if
        if (irq & $08) = $08 then
            # P0_3 is HIGH and the source of this interrupt, so use "D" code
            report(2:1) = $07   # "D" key code, 7
        end if
        if (irq & $10) = $10 then
            # P0_4 is HIGH and the source of this interrupt, so use "E" code
            report(2:1) = $08   # "D" key code, 7
        end if
        
        # write HID report
        call attributes_write(hid_attribute, 0, 8, report(0:8))

        # build and write HID report for "release" action:
        # 0:0x00 = no modifiers (i.e. release previous left shift)
        # 1:0x00 = RESERVED
        # 2:0x00 = empty key slot (i.e. release previous 'A')
        # 3:0x00 = empty key slot
        # 4:0x00 = empty key slot
        # 5:0x00 = empty key slot
        # 6:0x00 = empty key slot
        # 7:0x00 = empty key slot
        report(0:8) = "\x00\x00\x00\x00\x00\x00\x00\x00"
        call attributes_write(hid_attribute, 0, 8, report(0:8))
        
        # Pull high P1.0 pin (switch LED on for 200 msec)
        call hardware_io_port_write(1, $1, 1)
    
        # Disable interrupts from the buttons
        call hardware_io_port_config_irq(0, $0, 1)
        
        #Set timer to generate single shot event in 100msec
        call hardware_set_soft_timer(3276, 1, 1)

        #Set timer to supress bouncing effect - no interrupts for next 500msec        
        call hardware_set_soft_timer(16380, 2, 1)
    end if
end

And finally, there is an extra function that handles events from two timers: when the LED is to be switched off and when interrupts from the buttons are to be enabled again:

event hardware_soft_timer(handle)
    if handle = 1 then
        # Pull low P1.0 pin (switch LED on for 200 msec)
        call hardware_io_port_write(1, $1, 0)
    end if

   if handle = 2 then
        # re-enable interrupts from the buttons again
        call hardware_io_port_config_irq(0, $1f, 1)
   end if
end

As a next step, the BLE112 module has to been programmed with the compiled script. In order to do this, a CC-Debugger is needed. It must be connected to the target board via convertor board 2.54 mm - 1.27 mm connector which comes with the debugger. The target board must be powered for the programming operation, in other words, a coin battery has to be installed. When CC-Debugger is plugged in to a PC via USB cable and when CC-Debugger and the target board are connected with a 10 pos. flat cable the LED on CC-Debugger should go green after pressing RESET button. The script is uploaded then to the target board by Bluegiga BLE upload tool.

BlueButton PCBA bing programmed by CC-Debugger

BlueButton PCBA being programmed by CC-Debugger

When programming is complete, CC-Debugger is unplugged and the board is then secured in a 3D printed enclosure by four self-tapping screws as shown on the picture below:

BlueButton Enclosure Exploded

BlueButton Enclosure Exploded

The fully assembled first prototype looks like this:

BlueButton Enclosure Assembled

BlueButton Enclosure Assembled

Downloads:

1. BlueButton Firwmare Rev1.0

The relevant video is given below:

The BlueButton – Envisaging Enclosure

Continuing the development cycle of the BlueButton today we are going to create an enclosure prototype which potentially could be 3D printed. The goal would be to fit PCBA into a plastic box comprising of three parts: a top shell, a bottom shell and a round button. All 3D bodies will be created by extrusion of profiles along two paths as shown on the picture below. The profiles are made no less than 2.5 mm which would correspond the thickness of plastic walls. The bottom shell is going to have four moulded standoffs to support PCBA, the top and bottom shells will be held together with friction. The round button would have a funnel-like hole at its centre letting the LED shine through.

BlueButton Enclosure Before Exctrusion

BlueButton Enclosure Before Exctrusion

The PCBA will be secured onto the bottom shell with self-tapping 3mm screws. The round button will rest on tactile switches’ actuators as shown on the picture below.

BlueButton Enclosure Assembled Front Section Cut

BlueButton Enclosure Assembled Front Section Cut

The exploded assembly is given below.

BlueButton Enclosure Disassembled ISO

BlueButton Enclosure Disassembled ISO

And the final result of a fully assembled BlueButton is shown below.

BlueButton Enclosure Assembled ISO

BlueButton Enclosure Assembled ISO

A 3D model of the enclosure with PCBA is provided below.

Downloads:

1. BlueButton Enclosure 3D Model Rev1.0

2. BlueButton Enclosure 3D Template Rev1.0

Our Website is Mobile Friendly Now

As a result of ongoing effort our website became mobile friendly or, using the trending words, ‘it has a responsive design’. The blog is still readable even on devices with very narrow canvas and should look reasonably well on Android phones and iPhones. In addition to that, now there is a QR Code of the current page one the right sidebar. You may navigate through the site on a desktop PC then scan the URL of the current page encoded by QR Code and continue browsing on your mobile device without even need to type a single character. We will keep working on even better user experience and meanwhile if you spotted any problem or have a suggestion please let us know.

‘Man it is Voodoo Magic!’

Silicon Chip August 2015

Silicon Chip August 2015

Silicon Chip Magazine - Editor's response

Silicon Chip Magazine – Editor’s response

Silicon Chip Magazine - Editor's response continuation

Silicon Chip Magazine – Editor’s response continuation

The BlueButton Project

Recently, after attending Ability-Maker-Meetup we were inspired by a group of friendly and openminded people with vision, passion, creativity and tremendous variety of skillsets. The people who share the same goal – to help those in need and with limited mobility by making openhardware things making hard lives of disabled people a bit easier and brighter. And by having design files free and open to anybody it would significantly reduce the final price of a product, increase its flexibility and make it possible to integrate with more platforms and other projects. It would also help to bring back to Earth people who totally lost sense of reality, people who sell primitive things for absolutely ridiculous prices like these. No wonder that we soon found ourselves being inadvertently involved into one of the projects.

On a surface the project sounded really simple – design a wireless button with tactile sensation for scanning software to communicate to a tablet PC for just under $40. However, this quickly led to conflicting requirements. First of all, a wireless interface needs battery and the last thing you want is to put a wireless button on charge every night. Especially if you are not as mobile as an average person. Which means that we need an ultralow power consumption and it really leaves us with two options: low energy Bluetooth (aka Bluetooth 4, aka BLE) and Zigbee. Most mobile devices don’t have Zigbee radios and it is rather exotic piece of hardware. Yes, there are Zigbee dongles in micro SD card form factor so potentially it is possible to make, for instance, a mobile device Zigbee enabled at the cost of not having external flash memory. Also, this solution would require specific drivers to support Zigbee connectivity. On the other hand, most mobile platforms have inbuilt Bluetooth radios. Not all of them are compatible with BLE standard, however, and it is BLE only that can give us truly low power consumption allowing to give enough juice to a button for months if not a year or two and even a coin battery would have enough capacity for this.

Another thing to consider is development effort on a mobile platform side, to be more specific, absence of such. Otherwise the development time for one driver would be multiplied by the number of mobile platforms that ought to be supported. In the world of USB the most obvious choice would be HID. There are also implementations of HID over Bluetooth and if we choose this one there won’t be need for any custom made driver at all. It is worth mentioning, however, that not all mobile platforms with BLE stack have HID support – this problem could be solved by using another (even user-specific) Bluetooth 4 profile and implementing custom driver on a mobile platform. But how to deal with mobile platforms that don’t support Bluetooth 4? Currently there are solutions on the market which are both Bluetooth 2 and Bluetooth 4 compatible but such a compatibility comes at a price: they are more expensive and more power hungry as in essence they have to accommodate two radios so by using them we would shoot ourselves in a foot again with need to recharge/replace batteries every so often. So our choice would be to have a pure Bluetooth 4 button only and design and distribute separately a ‘Bluetooth-4-to-whatever’ translator that is powered by a wall adapter. This translator, however, would be out of scope of this article.

We also need to keep in mind that instead of using specialised chips we actually need an FCC certified module with fixed antenna. That way we can safely avoid intricacies of RF designing (which is more like black magic than actual designing) and possible customers’ accusations like ‘your device can cause harm to a live tissue by its electromagnetic radiation’.

Summarising the requirements and ‘nice to have’ features, there is the list of criteria for a potential BLE module that we will be going to look for:

  • An FCC certified Bluetooth 4 (BLE) module with fixed antenna;
  • Support of HID BT profile;
  • Handsolderable pins (no QFN, BGA like footprints, it is a DIY project after all) yet compact form factor;
  • Reasonable price (less than $20);
  • Minimum power consumption, capable of entering deep sleep modes and waking up by external interrupts;
  • Voltage supply in the vicinity of 2…3V to be powered directly off a 3V coin battery and therefore avoiding using of extra DC-DC converter;
  • Configurable/programmable which would allow not to use external microprocessor and bring down the cost and power usage even more;
  • No need in external debugger to reconfigure/reprogram the module;
  • Opensource or free development environment (yes, dear Texas Instruments, we know your shallow jokes);
  • The module must be futureproof, or in other words be designed by a company specialising in wireless modules with proper technical support, definitive end of life/end of support terms and so on. Not like the toys from Adafruit;

As a result of our search the best candidate matching our requirement would be BLE112-A-V1 module for the retail price of $15.66 from Digikey as it is shown on the picture below:

BLE112-A-V1 Module

BLE112-A-V1 Module

At a first glance the module looks amazing: a 8051 processor as a core which makes it possible to write conventional C code and upload it to the module, three (!) ways of firmware upload – either over USB interface, OTA (over the air) or by means of CC-Debugger (oh no, the chip is made by Texas Instruments, a notorious cheater with CC2430 Zigbee chip, overpriced development environment for it, buggy and unstable Zigbee stack without access to source code and cowardly abandoned support). However, after a closer look it is seen that there is no way to write in C when not using an external host processor and the code has to be written is a BASIC-like compilable script invented by Bluegiga. As for the firmware uploads, once USB is enabled it uses so much power that it defeats the whole purpose of low energy Bluetooth and OTA works only if certain conditions are met so it really leaves us with the only way – CC-debugger (which would cost us some additional money). Apart from these inconveniences everything else looks quite reasonable so we are going to use the module as a cornerstone for our project.

The fist revision of circuit diagram is given below. The module and capacitors C1...C4 are part of the reference design provided by the BLE112 datasheet. The power source is a CR2032 coin battery with J2 jumper allowing to measure current consumption during development cycle. Instead of just one button there are four tactile switches SW1...SW4 which can be programmed to the same logical button. There is also an option to connect an external, more durable button if needed using P2 EXT_BTN connector. Resistors R2...R6 provide weak pull-up when a module is in deep sleep mode and thus making sure that the microprocessor’s inputs are in definitive states. If no external button is used, R6 must not be loaded. Connector P1 SER_DBG is used for serial debug output during development. An LED LED1 can be used as an optional visual indication of a button press and it is connected to a GPIO capable of sourcing up to 20 mA. However, given that we have very tight power budget, we are using a 2mA LED with high resistance in series. J1 provides a way to disconnect LED altogether is longer battery life is needed. Or alternatively, both LED1 and R1 can be unloaded. P3 CC_Debugger allows to connect CC-Debugger and upload a custom designed application.

Blueutton Circuit Diagram Rev.1.0

Blueutton Circuit Diagram Rev.1.0

A PCB layout is done on 2 layer 50x50mm blanks to take advantage of budget PCB manufacturing service by ITeadStudio. On the top side the buttons are the most extending mechanical parts to accommodate a big round plastic lid on top covering all four buttons. The bulky components are residing on the bottom side. Both top and bottom sides are filled with copper polygons connected to ground with cut-off window near module’s antenna area as per datasheet layout guidance. The two ground plains are stitched with vias across the cut-off’s perimeter to minimise noise and electromagnetic emission as much as possible. Our initial intention was to squeeze everything into Keyfob case but after thorough consideration the idea was rejected because of the really small rubber button which would be difficult to press so the decision was to make a 3D printed case specifically designed for our PCB.

BlueButton Component Layout Rev 1.0

BlueButton Component Layout Rev 1.0

A 3D model of the PCB is provided below.

BlueButton PCBA 3DModel Top View

BlueButton PCBA 3DModel Top View

BlueButton PCBA 3D Model Top Iso View

BlueButton PCBA 3D Model Top Iso View

BlueButton PCBA 3D Model Bottom Iso View

BlueButton PCBA 3D Model Bottom Iso View

Upon arrival of the manufactured PCBs we will be assembling the first prototype and testing our custom made scripts. Also we will be designing a simple enclosure model which then most probably will be 3D printed. All this will be posted in the next article.

Downloads:

1. BlueButton Gerber files Rev1.0

2. BlueButton Eagle files Rev1.0

3. BlueButton PCBA SketchUp 3D Model Rev1.0

4. BlueButton Component 3D Models

5. BlueButton BOM (Bill Of Materials)

Revisiting VFD PSU – Part III

It is time to test our revisited VFD PSU in real life. We are going to build a quick prototype using a PCB from MVFD 16S7D Panel with minimum components loaded. All we need to solder is a VFD controller IC2 (instead of HT16515 we are going to use PT6315 as they are pin-to-pin compatible), a 82k resistor R14 to keep controller’s oscillator running, a decoupling 100n capacitor C11 and CTRL connector along with VFD glass VFD1. The PCB is then connected with the PSU to provide filament (~2.5ADC), high voltage (-24VDC) and logic voltage supply (+5VDC) as shown on the picture below.

VFD_PSU_EXP01 VFD Driver Soldered

VFD_PSU_EXP01 VFD Driver Soldered

To drive the VFD controller our specifically designed Arduino compatible VFD Serial Backpack is used. The backpack is programmed with a slightly modified Magictale VFD Demo lib published in VFD driver demo article. The backpack is simply attached to the VFD panel, it gets power from it and at the same time communicates with PT6315.

VFD_PSU_EXP01 Backpack Attached

VFD_PSU_EXP01 Backpack Attached

The prototype works smoothly, in our experiment it jumpstarted immediately without any troubleshooting. The brightness of the VFD is much better than the original MVFD 16S7D panel. Also there is no brightness gradient, thanks to the pulse filament drive.

VFD_PSU_EXP01 With Serial Backpack

VFD_PSU_EXP01 With Serial Backpack

However, nothing can be perfect. This solution exhibits a ghosting effect when some segments are faintly glowing while they actually must be completely dark as it is shown on the picture below. The reason for this is absence of cut-off voltage which we hopefully can solve by adjusting some components of the PSU but this will be our next exercise.

VFD_PSU_EXP01 Ghost Effect

VFD_PSU_EXP01 Ghost Effect

Despite of a couple of annoying issues such as ghosting effect and a bit excessive current consumption of the whole prototype (250mA) we managed to prove that the new PSU is generally functional and has some improvements over the old design. And most importantly, it is very cheap and doesn’t have fancy chips which could potentially become obsolete in nearest future without any hope to be replaced with something similar.

Revisiting VFD PSU – Part II

We are continuing our experiments with an alternative VFD power supply which we started some time ago. The high voltage part remains pretty much unchanged for now – it is an inverting regulator based on inexpensive chip MC34063. Excessive current consumption (60-70mA) in idling mode is still an issue but we are not going to address it today and the circuit diagram of HV part is in essence what we had during the previous experiment:

MC3463 Inverting Regulator

MC3463 Inverting Regulator

The second part, a filament driver, is based on a… LM4871 audio amplifier. We have been inspired by the idea described in great detail in The VFD Stuff article but what we didn’t like in the original design was a requirement for 12VDC (and we wanted a solution capable of working off 5VDC). Also, LM1877 is an old chip, so old that it doesn’t have a shutdown pin. Learnt on our previous mistakes we didn’t want to use something which could become obsolete at any point in time. Having a few things in question and before rushing and finalising our PSU design we also wanted to build a prototype to make sure that it would going to fly. So the following simplified circuit diagram was used to test its pros and cons:

LM4871 Square Wave Generator

LM4871 Square Wave Generator

A SOIC-to-DIP 8 pin adapter, bunch of wires and jelly beans have been used for a proof of concept, no PCB. To our surprise, the circuit was not demonstrating stable results, the generated square wave had some parasitic spikes the amount and magnitude of which varied greatly over time and we couldn’t understand the reason.

VFD_PSU_EXP01 Test Without PCB

VFD_PSU_EXP01 Test Without PCB

The two pictures below shows two spikes at the beginning of a square pulse and this not a bad case as we witnessed much, much worse. Eventually, after numerous on/off switch cycles and attempts to comprehend the nature of the noise we ended up with entangled wires killing the amplifier in the end as a result.

Square Wave Parasitic Spikes without PCB

Square Wave Parasitic Spikes without PCB

Square Wave Parasitic Spikes without PCB

Square Wave Parasitic Spikes without PCB

After the failure we decided not to repeat same mistakes and build a prototype on a proper PCB thanks to ITead Studio, it is very cheap now. The two parts (HV and filament driver) have been merged into a single circuit diagram as shown below. We deliberately made some room for more things to try and adjust: voltage dumping resistors R7, R8 (which needs to be later replaced with something more elegant), transistor Q1 to play with current consumption in idling mode for HV part and the trick of offsetting filament AC voltage down to -20…-24V (R8, R10, C7, C8).

VFD_PSU_EXP01 Circuit Diagram

VFD_PSU_EXP01 Circuit Diagram

The board was easily routed and fitted on a standard blank of 50x50mm, some real estate has been even reserved for prototyping area. All components reside on a top layer as shown below:

VFD_PSU_EXP01 Compoment Layout

VFD_PSU_EXP01 Compoment Layout

Then a 3D model of PCBA was designed to make sure that there was no interferences between components and nothing was overlooked:

VFD_PSU_EXP01 PCBA 3DModel Top View

VFD_PSU_EXP01 PCBA 3DModel Top View

VFD_PSU_EXP01 PCBA 3DModel Top ISO View

VFD_PSU_EXP01 PCBA 3DModel Top ISO View

VFD_PSU_EXP01 PCBA 3DModel Bottom ISO View

VFD_PSU_EXP01 PCBA 3DModel Bottom ISO View

The manufactured PCBs arrived exactly in two weeks, no surprises here:

VFD_PSU_EXP01 PCBs Manufactured

VFD_PSU_EXP01 PCBs Manufactured

First PCBA has been loaded with components, as per original schematics Q1 and R11 are not loaded instead Q1 Base and Emitter are connected with a wire, R10 is not loaded and R10 is replaced with a wire.

VFD_PSU_EXP01 PCBA Assembled

VFD_PSU_EXP01 PCBA Assembled

Generated square wave is much more cleaner now, all parasitic spikes disappeared:

Square Wave No Parasitic Spike On PCB

Square Wave No Parasitic Spike On PCB

Square Wave No Parasitic Spike On PCB

Square Wave No Parasitic Spike On PCB

And the most important step is actual connection of a VFD. As we don’t have any controller at the moment we can simply apply filament voltage and pull one grid and one segment to ground (not to -24V, it is actually filament voltage which oscillates about -24V). The picture below shows that our prototype works even though is consumes a bit excessive current – 230 mA. Our goal would be to bring it down to 150 mA in the next exercise.

VFD_PSU_EXP01 In Action

VFD_PSU_EXP01 In Action

Downloads:

1. VFD_PSU_EXP01 Gerber files Rev1.0

2. VFD_PSU_EXP01 Eagle files Rev1.0

3. VFD_PSU_EXP01 PCBA SketchUp 3D Model Rev1.0

4. VFD_PSU_EXP01 Component 3D Models

5. VFD_PSU_EXP01 BOM (Bill Of Materials)

Electronic OBDII Gauge on Luminardo

Let’s make something more complex using Luminardo, a Bluetooth dongle, a OBDII translator ELM327 and a 128×64 pixels graphical monochrome OLED display SSD1306. The plan would be to utilise USB host functionality to communicate to ELM327 via SPP interface and represent such parameters as engine RPM, vehicle speed, battery voltage, remaining fuel on a display. In a way it will be like the well known OBDuino, however, we are going to take full advantage of a graphical display and in our case we are going to have a wireless communication interface. For simplicity sake we won’t implement trip computer to calculate distance traveled, fuel consumption per 100 km or tank distance, instead, we will be focusing on user interface and modular firmware architecture which would allow to integrate additional functionality later and with minimum development effort.

The information displayed on a display in mostly numeric, some of them more significant, some of them less, so most probably we will need to have several font sizes (or fonts). We strongly believe that it this application numeric data would be looked more professional if seven segment font is used. And if so, we would need to add more seven segment fonts as we have only 32×50 sevenSegNumBigFont. To add more options we will introduce 25×40 sevenSegNumMediumFont and 10×16 sevenSegNumSmallFont fonts and define them in glcdfont.h.

Next step is to prepare icons, the plan would be to display a number next to icon so that it would be intuitively clear and obvious what kind of information a number represents. For example, a battery icon for voltage readings, a fuel dispenser icon for tank level, a thermometer icon for temperature readings, well, you’ve got the idea. The will be two icons of the same type – one which fills the whole display for warnings in case of critical levels and one is of a regular size, 18 pixels maximum in height to roughly match with the small seven segment font. We would need the following icons: a car battery, a bluetooth, a fuel dispenser, a thermometer, a ‘car doors open’, a clock. The last two are ‘just in case’. All these icons will be defined in Icons.h.

Let’s also specify the most important architectural considerations. First of all, we will be heavily relying on Bluetooth communication between our Luminardo board and ELM327 OBDII adapter. Therefore, we will have to indicate explicitly connection status and upon boot up don’t progress to any screen with numbers until the connection is successfully established. It would be also necessary to distinguish two different states of connection: successful pairing/connection with ELM327 and successful recognition of the OBDII protocol with ability to communicate to a vehicle. That way to will definitely detect situations when Luminardo can communicate to ELM327 but ELM327 can’t communicate to a vehicle. It would be also highly desirable to display additional information about ELM327 upon connection – for example, its firmware revision number.

Next, we won’t be using delays in our code as it is very wasteful style of programming, especially for embedded devices with their limited computational power and battery power sources. Given that we have only single thread process (which is a limitation of most 8-bit microprocessor systems including Arduino) required delays between subsequent operations will be achieved by introduction states and counters, holding number of milliseconds passed since the previous operation. That way in the main loop we will be checking each counter whether it is time to progress to the next state, execute next operation and update counter with a new value or simply move on to check next counter. The code execution flow in this case will be non-blocking as this is exactly what we want.

Some parameter values will be refreshed less frequent than others. For example, engine RPM and vehicle speed will be requested from the vehicle every time when display is refreshed whereas tank level, battery voltage and temperature values change much slower and therefore they need to be retrieved and updated on the screen less frequent. Given, that from our previous experiments with display we discovered that full frame refresh takes longer than the actual transfer of block of data from microcontroller to OLED, we will be updating only those areas on the screen which are changing. In other words, if we retrieved just new values for PRM and speed we will be updating only appropriate numbers on the screen and nothing else.

With modularity and simplicity in mind, the sketch will be subdivided into several logical parts: the main part Luminardo_OBDII_BT_128x64_i2c.ino with top level logic, settings, definitions and global variables in Luminardo_OBDII_BT_128x64_i2c.h, string constants in Messages.h, auxiliary/utility functions in Utils.h and graphics in Icons.h.

There are two things to be configured before your Luminardo board will be able to find and connect to your ELM327. It is ELM327 Bluetooth address and pin code. Note, that Bluetooth address is specified in reversed order as shown in the code below:

//40:22:11:00:69:58 ELM327 OBDII
uint8_t remote_addr[6] = {0x58, 0x69, 0x00, 0x11, 0x22, 0x40};
SPPi SerialBT(&Btd, "Luminardo", "1234", true, (uint8_t*)&remote_addr);

It is also possible to adjust warning thresholds, these are: battery low voltage level (in volts multiplied by 10) and tank level (percentage remain) as shown in the code below:

#define BATTERY_VOLTAGE_WARN_THRESHOLD 110 //Multiplied by 10
#define TANK_LEVEL_WARN_THRESHOLD 30 //Percentage remain

Luminardo was specifically designed with slim form factor in mind and more small but useful features if compare with Arduino boards. However, given that Luminardo is an Arduino clone, it is possible to build the same functionality using an Arduino board. The final result will be rather bulky but nevertheless, it is still very much possible.

The final source code is freely available below.

Downloads:

1. Luminardo_OBDII_BT_SSD1306_2015_04_29.zip Luminardo OBDII sketch with customised SSD1306 OLED library;

2. USB_Host_Shield_2_SPP_Client_Support_2015_05_05.zip Customised USB Host 2.0 library with SPP client support;

3. Github repository with Luminardo core for Arduino environment;