Development in general requires time and money. Development of opensource projects is not an exception. To keep this online resource alive we heavily rely on your donations. If you feel like supporting us please make a donation.
Today we are publishing photos of fully assembled and tested MVFD 16S8D Panel, Rev 2.0. The board on the pictures is fully populated with components which means that apart from displaying alphanumeric information it can measure ambient light intensity, emit simple ‘beep’, receive signals from an IR remote control and shine with an RGB LED. As it is seen, the majority of components are located on the back side of the board so the top side looks really simplistic. It is worth mentioning that due to the use of through hole components and the fact that components are loaded on both sides the VFD glass should be soldered last during assembling process otherwise it would block access to some through hole pins.
MVFD 16S8D Panel PCBA Front Rev. 2.0
MVFD 16S8D Panel PCBA Back Rev. 2.0
The VFD Panel perfectly mates with either Luminardo board or MVFD Serial Backpack. However, it is also possible to drive it using basic Arduino such as Arduino Duemilanove which has not so many GPIO pin and equipped with only 32K of program memory. If needed, the number of wires can be reduced by eliminating features which are not used – for example, RGB LED, ambient light sensor, IR receiver or speaker.
MVFD Panel and Arduino Duemilanove pin mapping
VFD Panel JP1 pin
Arduino pin num/pin type
Driving VFD Panel is extremely simple as all heavy lifting is done by MVFD library. All that a developer needs to do is to physically wire the panel to Arduino board (of course), define VFD pins (an example is provided below) and initialise display. From that point controlling the panel becomes as easy as writing to a serial port.
The library contains a fair amount of embedded tests and demo effects so the first sketch showing the panel’s capabilities would be also simple (see below). The sketch makes use of a buzzer (you should hear a short ‘beep’ upon Arduino’s start), of an ambient light sensor (there is a demonstration of ‘day’ and ‘night’ modes), of the RGB LED (it pulsates during normal operation and flashes upon bootup and when an IR command is received and encoding standard is recognised). During the test the display demonstrates alphanumeric information, brightness control, flashing (blinking) effect and effect of scrolling line.
The picture of the working setup is provided below:
Arduino and MVFD 16S8D Panel in Action
The full test video showing the sketch and the panel in action is given below. In minimalistic configuration (only VFD glass is functional) only 6 wires would be needed (+5VDC, GND, DI, CLOCK, CHIP_SELECT, SHUTDOWN) so some Arduino’s GPIO pins could be freed up.
Before STL models can be sent to a 3D printer they need to be converted into format recognized by a specific make and model of a printer. This job is usually done by software distributed with a printer. Besides, additional manipulations need to be done: the model must be properly positioned at the very centre of printer’s platform, a raft and supports for some elements of the model must be generated (most of the times they can be autogenerated by the printer’s software), material type, preferable extruder (in case of more than one available), quality and additional 3D printing parameters must be set.
In our case we used FlashForge Creator Pro which has its own tricks to achieve best possible quality. First of all, we came up to understanding that our model should be positioned on its side, sitting on its rear end which contacts with the rear acrylic panel. That way all imperfections caused by the supports will be on the rear side. The model should be oriented as if rotated 90 degrees (as shown on the picture below). That way the left nozzle won’t occasionally interfere with the deposited plastic threads as in happened few times during one of our earlier experiment. It is strongly recommended not to use the second extruder for raft and supports as two plastics simply penetrate into each other during the process and sometimes it just looks ugly.
Luminardo Bottom Shell Ready for 3D Print
Both top and bottom shells just off the printer are shown below. Although these two are made of ABS we strongly recommend to use PLA as it shrinks less so there will be less unpleasant surprises after the print. Supporting structures and rafts are not removed yet. The bottom shell already has M3 standoffs screwed in.
Luminardo Green Case After 3D Printing
The fully assembled device is given below.
Luminardo Green Case Rear View
Luminardo’s front view can be seen on the picture below. The device is flashed with an Alarm Clock sketch.
The idea of making enclosure fully out of acrylic panels was abandoned due to ‘squarish’ look of the final product. We really wanted to create something a little bit more stylish and this is why the most obvious choice was 3D printing. That way it was possible to make rounded corners and streamline shape. However, with 3D printing it is almost impossible to get a transparent or at least translucent surface which was required at least for the front panel. So in the end a decision was made to have a mix of acrylic flat panels and 3D printed elements of enclosure. By doing this we could reduce the volume of 3D printed parts which are more expensive to make than acrylic laser cutting. We could also make front and rear panels transparent allowing clearly see not only VFD display but the electronics as well. And still it was feasible to give the case a modern look, thanks to the 3D printing technology which gives designer’s fantasy literally unlimited freedom. The sketch below demonstrates main features of the future case: flat rear and front acrylic panels held together by top and bottom curved halves, the top half has a cowl around the motion sensor.
The final design is done in Sketchup with free licence without need to manipulate with solid objects but it made designing effort a bit challenging and more time consuming. Both front and rear panels are made of a clear 2mm thick acrylic blank, in Ponoko the most appropriate blank was P1 (181 x 181 mm), however, it was still too big for us so we managed to fit panels for three Luminardo cases. The font panel has holes for a buzzer and RGB LED. The rear panel has cutouts for ISP, two serial and one I2C headers, a USB Type A Female and a USB mini connectors, a cutout for a temperature sensor and for a 1-Wire header.
Front and Rear Panels prepared for laser cutting in Ponoko
The top and bottom shells are 3D printed. Both of them have internal supports for the acrylic panels and the board assembly. The shells are held together by two M3 standoffs and two M3 screws. The top shell has a niche for the motion sensor and a hole for accessing RESET button. The model of the top shell is given below.
The bottom shell has two feet beneath and two holes for M3 screws. The model of the bottom shell is given below.
When 3D design is done the next step would be to export it to STL format before sending to a 3D printer. If the model was not designed as a solid object (this is actually our case) then be prepared that first STL model most probably contains some errors. To analyse and pinpoint such problems there are countless number of software tools. We used Meshmixer and Netfabb. Netfabb turned out to be more advanced, it could still detect some issues when Meshmixer didn’t complain about anything anymore but we still couldn’t pass through Ponoko’s validator. The problem was with one face being ‘degenerated’ and despite all our effort we could not find any issue. So eventually we simply allowed Netfabb to autorepair it and when it was done we were able to upload our model to Ponoko. Two pictures below show a model at fault and its degenerated face detected by Netfabb.
Luminardo Top Shell in Netfabb
Luminardo Top Shell – Degenerated Face
The final assembly is given below.
After several experiments we came to a decision that it is much better to 3D print both shells using PLA material. It has significantly less shrinkage comparing to ABS, it is still strong enough and can be safely used indoors without risk of degrading (in spite of opinions widespread in the Internet).
This is a second spin of Luminardo boards with the focus on elimination minor mistakes found in the revision 1.0. A motion sensor is fully integrated with the PCB this is why the board has an inflow on top of its outline. Also an obsolete inductor is replaced with the one of a similar footprint and bill of materials has been optimised in terms of component cost. But let’s take a step back and answer the question: what Luminardo is, why it was designed and what it can be used for? In short, Luminardo is an Arduino compatible ATMega128 powered board with MVFD panel 16S8D interface, USB Host, battery backed up RTC, motion and temperature sensors. A front panel adds a buzzer, a light sensor, an RGB LED and an IR receiver. It has compact sizes, also it is expandable and stackable like Arduino. But unlike Arduino it grows in length, not in height when extra boards are stacked inbetween the front panel and the main board. The slim form factor makes it look nice and unusual and (hopefully) modern. The first immediate idea would be to use it as typical Nixie clock out of nostalgic reasons only. But it can do more than just that. With replaceable front panels, with its expandability and with USB host functionality the application areas widens significantly. It can be a part of a home automation network, or used to control a toy city. Yet it is simple enough to be built by a DIY enthusiast.
The circuit diagram is given below. Not too many changes if compare with the revision 1.0:
The PCB layout component layout is given below. Hardly noticeable changes if not to take into account an integrated motion sensor and a reset switch.
Luminardo Component Layout Rev. 2.1
The PCB layout is given below. As usual, it utilises 2 layers to take advantage of good PCB manufacturer deals like Itead Studio. The design is also tailored to a specific Itead prototyping offer which is 100x50mm and comes at $25 for 10 color boards without shipment (or even $14.90 for green boards!)
Luminardo PCB Layout Ver.2.1
The 3D model of the whole assembly is available at 3D Warehouse so it becomes really easy to design extension boards or enclosures.
The top view of the 3D model is given below. In essence, no changes on this side.
Luminardo V 2.1 PCBA 3D Model Top View
The bottom view of the 3D model is given below. Distinctly visible the motion sensor, the reset switch, the electrolytic capacitors and the raised 14-pin VFD header which is a custom made of two stackable Arduino headers.
Luminardo V 2.1 PCBA 3D Model Bottom View
The video below shows how Luminardo and MVFD panel integrate together:
This is a deep redesign of MVFD 16S8D Panel Rev.1.0 project which fixes minor and major issues and finally solves the fundamental problem of some parts becoming obsolete. Let’s reiterate the reasons which were the main driving forces of the project to come into existence:
– Single power source (+5V) which makes it possible to drive the panel from a USB port or batteries, high and filament voltages are generated internally;
– No need in transformer which is usually a non-off-the-shelf part resulting in cheaper, lightweight and compact solution;
– Pulse filament drive is used, an equivalent of AC (as opposed to DC) eliminating brightness gradient across the length of the VFD glass;
– Popular, inexpensive and widely available chips are used to generate filament and high voltages, very low risk of them becoming obsolete;
– Feedback in high voltage generator circuitry helps to achieve constant brightness regardless of number segments and digits lit up;
– Adjustable high voltage to get highest brightness without reducing VFD lifetime;
– Adjustable DC offset for filament voltage to maximise VFD brightness and cut off ghosting effect;
– An inexpensive and popular VFD driver is used which is produced by several silicone manufactures under different names but in the same package with pin-to-pin compatibility also reducing the risk of the part becoming obsolete;
– Low power mode;
– An infra red (IR) receiver;
– A buzzer;
– An RGB LED;
– A photocell (light sensor);
– A dedicated VFD driver is controlled by SPI-like two wire iterface taking care of display refresh and offloading main CPU (even Arduino Uno can cope with the job);
– Most parts are through hole making it very easy to assemble even by DIY enthusiasts with average soldering skills;
The top and bottom component layout is given below. No dramatic changes in comparison with Rev.1.0, same PCB dimensions, same mounting hole locations, same locations for parts on the top side to maintain compatibility with the previous design. On the bottom side the bulky parts representing the PSU are grouped together allowing to free up space for mating with MVFD Serial Backpack.
MVFD 16S8D Panel Component Layout_Rev
The PCB layout is given below. It utilises 2 layers to take advantage of good PCB manufacturer deals like Itead Studio. The design is also tailored to a specific Itead prototyping offer which is 100x50mm and comes at $25 for 10 color boards without shipment (or even $14.90 for green boards!)
MVFD 16S8D Panel PCB Layout Ver.2.0
The 3D model of the whole assembly is available at 3D Warehouse so it becomes really easy to design additional peripheral to mate with the panel, to get a good understanding how the panel looks like or even make use of the 3D models of the parts for some other projects.
Once again, no facelifting on the top side, it looks pretty much the same way as Rev.1.0 looked:
MVFD Panel 16S8D V2 PCBA 3DModel Top View
The bottom side looks significantly different now mostly due to totally new design of PSU. Note, that in order to minimise dimensions, the inductor is placed horizontally but nothing prevents it from mounting vertically, it is just a matter of personal taste and size restrictions.
MVFD Panel 16S8D V2 PCBA 3D Model Bottom View
The video below shows how the panel integrates with previously designed MVFD Serial Backpack:
The problem of automated LED color detection seems relatively easy to solve. However, the devil is in details and when it comes to practice, there is always something which goes not as expected and our practical implementation was not an exception as we encountered multiple challenges. Nevertheless, there are some ways to overcome those challenges. The task was simple to formulate: implement a reliably functioning way of automated LED color recognition for PCBAs coming off a production line. Each PCBA had a three RGB LEDs and there was a requirement to check every basic color and make sure that those colors could be controlled individually, i.e., there was no shorts. Our first approach was to take a generic Web camera and by switching LED colors sequentially take three shapshots for red, green and blue colors, then apply a blob recognizing algorithm to count points of light and detect color for each point. As a result of first experiment, a few issues arised. First of all, bright LEDs very saturating the picture and always looked like a glowing white halo with either red, blue or green rim around it making it impossible to do blob and color detection. Secondly, the background acted like noise so it had to be at least reduced if not cancelled. And thirdly, the same setup keept giving very different pictures which depended on ambient lighting conditions. A typical picture taken with a generil web camera is given below:
LED Snapshot In Focus
We began experimenting with different Web cameras and soon established that much better results are subject to deliberate camera defocus. The most dramatic effect is given on the picture below, it is seen when a camera is defocused the LEDs are turning into nice round blobs evenly painted with monotonous color. Then is becomes possible to do blob recognition and count and detect color of each blob. The only problem is a distance between camera and LEDs under test – in oder for a camera to be able to defocus more, the longer focal length that camera must have and the greater distance between LEDs and camera must be to fit all theree LEDs in narrow camera’s angle of view. The best results with point of light defocusing we got with an USB microscope but it required at least 300 mm between LEDs and the camera which was simply impractical.
LED Snapshot With Camera Defocused
Continuing our search for an optimal camera we finally found LI-OV5640-USB-72 – a 5M USB camera with manual focus. The only modification that we needed to do was removal of two white illuminating LEDs:
LI-OV5640-USB-72 USB Camera
The camera didn’t have to be placed far away from the PCBA under test and at the same time it gave satisfactory results in terms of even color distribution accross the blobs while having blob borders sharp enough for reliable work of blob detection algorithm. In addition to ability to adjust brightness and saturation the camera also allowed for gain control and by finding optimal values for those three parameters and by adding a couple of layers of gray film in front of the camera lenses it also became possible to cancel the background altogether signigicanly simplyfing further image processing process. With the final tuning the camera generates pictures with the following quality which is really easy to postprocess:
LED Snapshot Camera’s Final Tuning – green and red colors
After numerous reports of failures to flash HM-10 Bluetooth modules with the Arduino CC-Debugger we were lucky enough to get the module for experimentation and troubleshooting.
HM-10 BLE Module
To our surprise the tool indeed was refusing to communicate with the HM-10. Even 'Info' button kept reporting 0 Kb of flash memory which was clearly wrong. It has been quickly established that the actual pitfall was in communication protocol between the Arduino and PC application, only one byte was dedicated for that which obviously couldn’t hold the value ‘256’. Fixing this fixed the values retrived by the 'Info' button but 'Read' operation kept failing. It turned out the be the similar problem again – as the transmission was packetized into 1 Kb blocks there was only one byte dedicated to a block number and given that the chip has 256 Kb it was destined to fail. The third and final issue was with uploading binary files which were smaller than the total size of a chip and which size was not the exact integer number in kilobytes. In other words, an image of 8192 bytes in size would be flashed correctly while, say, 89751 bytes would not. This has to do with different buffer sizes for the protocol exchange and internal buffer on Arduino which is used for DMA transfers when the actual flashing is performed. So, as a result, the last block of data was incomplete which didn’t trigger DMA operation and remaining portion of the image was simply not flashed. This is why attempts to flash v1_1.bin by bjoerke rendered the module non-functional. This has also been fixed. And finally, the physical interface between CC24XX chip and the debugger has been simplified to just three wires as shown on the picture below:
The HM-10 module wired to Arduino board and ready for flashing is shown on the picture below. Please note that there are only three signal wires now for communication plus VCC and GND, five in total:
Arduino with HM-10 Module
The following screenshot below shows CCLibFrontend app successfully detected HM-10 module. Note, that the chip ID represents CC2541 with 256Kb of flash memory. No license, BT address or HW revision are retrieved – they are properties of BLE122, BLE113 modules and not applicable to HM-10. IEEE address value in case of HM-10 is the actual Bluetooth address.
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.
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
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
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
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
The full blown ‘ready-to-flash’ setup is provided on the picture below:
Seeeduino As a CC-Debugger Setup
The comparison tables below highlight cost factors for all three solutions mentioned in this post:
*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.
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
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:
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.
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
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
… and 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:
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)
# enable bondable mode for systems which want to use it
# 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
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
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
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
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
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
# 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)
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:
if handle = 1 then
# Pull low P1.0 pin (switch LED on for 200 msec)
call hardware_io_port_write(1, $1, 0)
if handle = 2 then
# re-enable interrupts from the buttons again
call hardware_io_port_config_irq(0, $1f, 1)
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 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
The fully assembled first prototype looks like this: