Skip navigation
1 2 Previous Next

Enchanted Objects

19 Posts authored by: crjeder


Posted by crjeder Jun 24, 2015

Time is up! And I am not done yet. So I have to pack my stuff and present what I have achieved in the past 16 weeks.


Smart Key Hooks


What are smart key hooks? Or what are key hooks anyway?

Basically they are a place to hang your keys like this:


But for me it is a little more. By looking at it I know who's at home and who not and it is used to exchange important messages between family members:


(The mess is just utensils you want to reach from the doorstep.)

As is it works perfectly, is accepted by the users, has a intuitive user interface and is highly robust to operating errors by the user. Why does it need to be enchanted then? For integration into a SmartHome system and to make it's functions available online. For the challenge I'v decided to concentrate on on the later.


Planed Features

In Smart Key Hooks - Prelude I proposed the following enchantments:

  1. No user interaction necessary besides hanging the keys
  2. RGB-LEDs to display status of the absent persons (i. E. "will come back soon", "away until next day", "at work" ...)
  3. RESTful / IFTTT / Tasker (android) interface

The first feature is needed for user acceptance where the others really add functionality. 3) Provides local, physical functionality to the network and 2) adds information from the "Cloud" back to the physical interface. These are very high-level descriptions of the enchantments which, of course had to be concretised during the challenge.


Optional Features

Since I had no clue how long It could me take to implement the basic features or if I can implement them at all I specified a part of the functionality I would like to have as optional, hoping that everything runs smooth and I will be able to implement them as well.

  1. leaving speech messages which get played when the person respective the key returns
  2. Detection of a specific key ring independent of the hook it was hanged on
  3. Placing "ToDo" lists (on paper) on the board and sending "accepted" messages to listeners when it was removed

Item 1) is a huge enchantment which does not only add a lot of hardware (microphone, speaker, button, memory,...) but also the infrastructure for handling audio and adding a new interface, etc. In 3) I would integrate the second function which the physical hooks serve into the smart version. Detecting the changes on the messages and link push notifications to them. Item 2) was optional because I did not know if there is a feasible solution for identifying the individual key rings. The presence of any key ring could always be detected by a simple switch leaving it to the user to select the correct hook.




While testing various methods to detect and identify key rings which are placed on a hook (Identifying Keys) I found one solution which satisfies the optional feature 2).


By using 1-Wire EEPROM or ID devices inside a key tag I am able to identify individual key tags and thus key rings regardless on which hook they were placed as. In theory (but I haven't tested) this should work even when more than one key tag hangs on each hook since 1-Wire is a bus system. This is necessary for the clean and unchanged user interface of the Smart Key Hooks.

For the status LEDs I identified two options: use the provided Infineon RGB Shield and time division multiplex the output to multiple LEDs (preferred) or to use WS2812B LEDs on the SAMA5D4. In Using the RGB LED Lighting Shield on SAMA5D4 Xplained I found out that Linux does not support 10-bit I2C addresses and therefore abandoned this option as to time intensive.


Then I turned my attention to the second option which turned out to be a learning experience and not less time consuming. Since there was no library available which allowed interfacing with the WS2812 form Linux or the SAMA5D4 I had to find a solution: using PWM hardware to bit bang the required signal (Generating a Mysterious Signal, Use WS2812B on the SAMA5D4 Xplained and More Datasheet Studying). The code compiles but segfaults when I run it on the board. Unfortunately there is no time left to debug it.

The tasker interface was presented in Smart Key Hooks Client. By replacing the client libraries it should be relatively easy to interface to any HomeAutomation system. Combined with home automation Smart Key Hooks would unfold their full power. Possible application would be to check if doors (e. g. the shed door) are locked when the key is returned or if all windows are closed when the last person leaves. That was my idea when I proposed Smart Key Hooks as my entry in the design completion.

To Help the jury to rate this project I will summarize the all achievements:

Proposed Features:



No user interaction necessary besides hanging the keys

RGB-LEDs to display status

RESTful / IFTTT / Tasker (android) interface

Optional Features:


Leaving speech messages which get played when the person respective the key returns

Detection of a specific key ring independent of the hook it was hanged on

Detecting "ToDo" lists (on paper) on the board



WS2812B using PWM hardware
explanation how to use advanced PWM features on SAMA5D4
101 on logic analyser and debugging hardware
sending encrypted push notifications with pushbullet (or any other push service)
explained basics of 1-wire communication
experiments with "das U-Boot" on SAMA5D4
changing the Infineon RGB Shields firmware to accept 7-bit I2C addresses
identified signal lines which I could used as GPIO




In Enchanted Objects Design Challenge - Detailed Information element14 asked to give an assessment of the enchanted object which I will give in the following paragraph.



It is hard to imagine that normal use could destroy the Smart Key Hooks. Wear-out is not an issue here since no moving parts implement any of the enchantments. The most vulnerable part are the key tags. The prototypes easily can break or lose contact. But they can be easily made more resilient by a steel case and embedding the PCB in resin. A production key tag could look like this:


Since contacts of the 1-Wire bus are exposed (hook and back plane) they are exposed to electrostatic discharge (ESD). The devices I used are all protected to 8 kV (IEC 1000-4-2 Level 4) which is enough under normal circumstances. If you have a nylon carpet then you should think about extra protection (for up to 27 kV).

Therefore I can not see any parts which should need to be replaced due to failure for a very long time.


Cost for the whole solution is quite moderate:

PartApproximate Cost in € (per key tag)
Silicon ID (for key tag)1,00
PCB, Passive Components, Resin0,50
Key Tag Case1,00


That's 2,50 € per key ring where 5 to 10 should be enough for a normal household. Cost for the key rings are between 12,50 and 25 €

The real power of the SAMA5D4 Xpalined is not used therefore the cost for the central component can be significantly reduced by using e. g. the Raspberry PI model B which at the moment sells at around 30 €. Further reduction and WIFI connection (which most people prefer over wired LAN) can be archived by using a ESP8266 module which sell at ebay for around 3 €


PartApproximate Cost in €

MCU / Computer / Base Board

(Raspberry PI B)

WS2812B or similar LEDs 10 pcs.5,00
Passive Components1,00

The system cost is 48,50 to 61 €. Using a ESP8266 it comes down to 21,50 to 34,00 € which is really not bad for a smart home component.


The usage is almost exactly as a with the un-enchanted version. Simply hang the key ring on a hook. Only difference is that you have to hang the hole in key tag (like in the photo above). Tasker is not really easy to use but once configured it does its job perfectly. Over all Smart Key Hooks are an easy to use enchanted object.



The presence of key tags is tracked with a selectable time resolution - the interval in which the 1-Wire bus is probed for new nodes can be configured. Smart Key Hooks track the presence of keys, not people. While the a person and his / her key ring normally would correlate this is the window of opportunity for imposture. Like in the very good video Andy Clark (Workshopshed) posted as a comment to one of my blog posts. The while solution is absolutely accurate in detecting the presence of key tags it can be arbitrary wrong in detecting the presence of persons.



Network security basics as hardening (uninstalling unwanted services, secure configuration for the rest, changing default passwords, etc) and placing a firewall in front of the networked Smart Key Hooks is common practice so that I did not blog about it. A very powerful security measure is reducing the attack surface. This is archived by the fact that the server does not offer anything to the Internet but instead subscribes to a Pushbullet channel. Therefore the firewall allows only connections to (and answers from) the Pushbullet server(s). A hacker would have to attack Pushbullet or inject packages into the communication in order to do any harm to the Smart Key Hooks server. Packet injection is made almost impossible by using https.

An other facet of security is privacy. I do not want Pushbullet or anybody who could listen to the data transfers to learn anything about me and my families presence in the house. To archive this the messages sent are AES encrypted. For a small number of clients a pre shared key is a feasible and easy to implement option. The secure channel to transfer the key for the first time is simply to enter it on the mobile device. This is inconvenient but has to be done only once for every device. Further key changes can be sent as a message to the clients (which, of course, is encrypted by the old key). This is not perfect forward secrecy (see which means that when one key is compromised all future keys are also known to the enemy, but is IMHO good enough. If you suspect that a key is compromised you always can manually set a new key on every client an be safe again. This is feasible only if you have a small amount of clients to which you have a secure channel (i. e. physical access).

Security is covered in more detail in Smart Key Hooks – The Design.

Use of the Project's Results


As is I would use Smart Key Hooks (after ironing out the last problems) for the following:

  • Check if children meet their "curfew"
  • Send reminders based on "leafing" or "returning" conditions (e. g. "don't forget the milk)
  • Send push messages to all persons at home (like "Can anyone please check if I've turned of the electric iron")


In conjunction with smart home / home automation I'd have a lot of use cases:

  • Alerting family members when the leave that not all windows / doors are closed
  • Remind them to take a umbrella if it is going to rain within the next hours
  • Check if shed / garage is locked when they enter the house
  • Turn off outdoor lightning when they enter the house
  • Turn on / off security systems based on presence
  • Automatically operate blinds when nobody is at home
  • ...

Smart Key Hooks will be the first smart home piece in my home which definitely will get smarter over the next years.


The main project results for me are however the knowledge I gained and the nice people I've met. That alone was worth the effort and is the most valuable take away.



Finally allow me to thank to element14 and the sponsors for hosting the competition. It has been a pleasure to take part. And thanks to all those who helped me or where just fun to talk to although some of them also compete in the same challenge (in no particular order):

Andy Clark (Workshopshed), clem57, shabaz, mcb1, jancumps, DAB, balearicdynamics

I hope to see you all again

Linux support for 10-bit Slave Addressing

The I2C protocol knows about two kinds of device addresses: normal 7 bit addresses, and an extended set of 10 bit addresses. The sets of addresses
do not intersect: the 7 bit address 0x10 is not the same as the 10 bitaddress 0x10 (though a single device could respond to both of them).
I2C messages to and from 10-bit address devices have a different format.See the I2C specification for the details.
The current 10 bit address support is minimal. It should work, however you can expect some problems along the way:

  • Not all bus drivers support 10-bit addresses. Some don't because the  hardware doesn't support them (SMBus doesn't require 10-bit address  support for example), some don't because nobody bothered adding the code (or it's there but not working properly.) Software implementation  (i2c-algo-bit) is known to work.
  • Some optional features do not support 10-bit addresses. This is the  case of automatic detection and instantiation of devices by their drivers, for example.
  • Many user-space packages (for example i2c-tools) lack support for  10-bit addresses.


Note that 10-bit address devices are still pretty rare, so the limitationslisted above could stay for a long time, maybe even forever if nobody
needs them to be fixed.

(linux kernel Documentation/i2c/ten-bit-addresses)


That's bad news for me. But there might be a solution.


Firmware Modification

Since Infineon provides the source of the firmware of the RGB Shield I can try to change it to use 7-bit addresses.

My first attemt would be to simply modify the address to something 7-bit compatible. Steps to do are:

  1. download Dave
  2. download the firmware source code
  3. import source code in Dave as a project
  4. make changes
  5. compile
  6. program into flash

The steps 2, 3, 5 and 6 are covered in a tutorial by infineon and step 4 was suprisingly easy:

In the App view select the I2C003 APP:


Then right-click on it and select UIEditor. In UIEditor make the necessary changes:


Then compile and download to the board.

Enable I2C


The I2C-1 to which the RGB Shield is connected to is not enabled by default. This is done by modifying the device tree file (dts), compile it into a binary (dtb) and save that file to the flash

Device Tree

current dts:

I2C-1 is missing

i2c1: i2c@f8018000 {
  status = "okay";

and in the included "sama5d4.dtsi"

i2c1: i2c@f8018000 {
  compatible = "atmel,at91sam9x5-i2c";
  reg = <0xf8018000 0x4000>;
  interrupts = <32 IRQ_TYPE_LEVEL_HIGH 6>;
  dmas = <&dma1
  | AT91_XDMAC_DT_PERID(2))>,
  | AT91_XDMAC_DT_PERID(3))>;
  dma-names = "tx", "rx";
  pinctrl-names = "default";
  pinctrl-0 = <&pinctrl_i2c0>;
  #address-cells = <1>;
  #size-cells = <0>;
  clocks = <&twi0_clk>;
  status = "disabled";

i2c1 {
  pinctrl_i2c0: i2c1-0 {
  atmel,pins =

Compile device tree

make ARCH=arm dtbs

Should make all .dtb files

make ARCH=arm at91-sama5d4_xplained.dtb

would be enough.


Replacing dtb

Replace the current dtb with new one using SAM-BA as described at Linux4SAM

  1. Modify the Address to 0x180000
  2. Choose Send File Name open file dialog and select the dtb binary file and to program the binary to the NandFlash.
  3. Click Send File button to program the binary to the NandFlash in address 0x180000.


Now the Shield can be used on the Xplained board


Thoughts on Privacy

Posted by crjeder Jun 12, 2015

An interesting research paper about security vs. privacy. It is about securing the home through "smart" internet connected locks and how it could allow parents to spy on their teenage kids. When the kids circumvent the system in order to regain privacy security is even lower than with a "old-school" solution.

It is relevant to this project because very similar audit logs are produced by the smart key hooks. The information smart key hooks collect is "text-only" which is better accepted by the studies participants than a photo log. The papers authors suggest to reduce the "visibility of the logs":

One way to reduce the visibility of logs is to make the log accessible only on a website (“pull” access), rather than through automatic notification (“push” access)


Another approach to making information less visible without necessarily reducing utility is to present less granular logs. For instance, a teenager who pushes an 11:00 PM curfew would prefer a log that says the teen arived [sic] home “around 11 PM,” as opposed to at “11:13:42 PM.”

That's something worth to consider.


More Datasheet Studying

Posted by crjeder Jun 11, 2015

Some of you might have recognized that I omitted one significant detail in the C code in my last post "Use WS2812B on the SAMA5D4 Xplained":

How is the correct PWM clock frequency of 2.4 MHz configured?


Clocks, Clocks and more Clocks

The peripherals of the SAMA5D44 (no, this is not a typo, that's the name of the SOC on the SAMA5D4 Xplainded board) all receive their own clock signal. Relevant for PWM is the peripheral clock as shown in the diagram from the datasheet (page 1448):


Most clocks in the SOC are controlled by the Power Management Controller. Contrary to the name this component does not (only) turn the power of integrated devices on and off, it mainly controls the distribution of clock signals. (By not providing a clock signal to a specific component it is turned off.) The programmer can individually request those peripheral clocks to be turned on or off and can select a division factor to be applied to the boards master clock MCK. The factor can be 1, 2, 4 or 8 and is applied to the master clock.

The frequency of the peripheral clock can be calculated by BOARD_MCK / divider. The divider can be read / set through the PMC_PCR register and BOARD_MCK is defined in board.h. This would be nice and easy to use but would work only in a bare metal environment where the clock can not be influenced by other processes. But since I do not intend to dump the Linux running on the board I have to consider these values as variables. Back to the datasheet. It turns out that the relevant values for master clock are the PMC Master Clock Register:

  • CSS: Master/Processor Clock Source Selection
  • PRES: Master/Processor Clock Prescaler
  • MDIV: Master Clock Division

Those values determine the true value of MCK (master clock).

MDIV is an other divisor for the master clock. It can be 1, 2, 3 or 4

The prescaler supports the division by a power of 2 of the selected clock between 1 and 64. The PRES and MDIV fields in PMC_MCKR programm the prescaler.

CSS can have several values to select one of the following clock sources:

  • Slow Clock
  • Main Clock
  • UPLL Clock

Now we know which clock source is selected an how it's frequency is divided to yield the peripheral clock. Next step is to find the frequency of the source. All source clocks are provided by the Clock Generator.

Slow clock can be selected to be either the 32 kHz on chip RC oscillator or the external 32768 Hz quartz. Selection is made by the OSCSEL bit in the Slow Clock Controller Configuration Register.

Main clock similarly can be configured to use internal or external 12 MHz sources, therefore is always 12 MHz.

UPLL generates frequencies which are higher than the base frequency (main cock) with a PLL. It is programmed through MULA field of the PMC Clock Generator PLLA Register. The MULA field is the PLLA multiplier factor. This parameter can be programmed between 0 and 127. If MULA is set to 0, PLLA is turned off, otherwise the PLLA output frequency is PLLA input frequency multiplied by (MULA + 1). The output is optionally dived by 2 (selected by PLLADIV2) the to generate PLLACK output.

UPLL Clock is fixed to 480 (40 x 12) MHz for USB High Speed.

The result is divided by the MCK_DIV to yield the frequency of the periphal clock wihch is the input into the PWM clock generation.

In C the above looks like that:

int get_periphal_clock_frequency(uint32_t ID)
    int frequency, mck_div, mula;

    switch(PMC->PMC_MCKR & PMC_MCKR_CSS_Msk)
        case 0:                                 // Slow Clock is selected
            if(SCKC->SCKC_CR & SCKC_CR_OSCSEL)  // XTAL selected
                frequency = 32768;
            else                                // internal RC selected
                frequency = 32000;
        case 1:                                 // Main Clock is selected
            frequency = 12000000;
        case 2:                                 // PLLACK is selected
            mula = (PMC->CKGR_PLLAR & CKGR_PLLAR_MULA_Msk) >> CKGR_PLLAR_MULA_Pos;
            frequency = 12000000 * (mula +1);
        case 3:
            frequency = 480000000;

    PMC->PMC_PCR = PMC_PCR_PID(ID);     // config PMC register read mode for PWM clock
    mck_div = (PMC->PMC_PCR & 0x00ff00u) >> 8;  // read MCK divider -> PWM clock
    frequency = frequency / mck_div;


Generating the desired frequencies

Back to the original problem, calculate the divisors for the PWM clock:

Now that we know the input to the above diagram we can go ahead and do some basic math. To calculate the parameters PREA and DIVA in order to get the desired frequency we have to calculate and factorize the required divider.

divider = peripheral_clock / desired_frequency

split divider in the form  2^prea×diva


divider = 260

factors of 260: 2^2×5×13

=> prea = 2 and  diva = 5×13 = 65

How is factorization done? The answer is astonishingly simple: do a trial division! Since we only need to know the factor which is a power of two this is further simplified to this:

int calculate_PWM_dividers(int frequency, int *div, int *pre)
    uint32_t mck_div, f;
    int n;

    frequency = abs(frequency);             // no negative frequency
    f = get_periphal_clock_frequency(ID_PWM);
    *div = f / frequency;                    // required divisor

    // split div into pre and div
    // facorization of divider
    // pre -> power of 2
    // div = all other facors
    for(n=1; n <= 10; n++)
        if(*div % ((int) pow(2, n)) != 0) // if not a multiple of 2^n
            *pre = n - 1;         // then it was a multiple of 2^n-1
    *div = *div / ((int) pow(2, *pre));     // new divisor is the rest

Wrap this code nicely in some error handling code and that's it.

More Details on the WS2812B


The mysterious signal from my previous post was for a WS2812B LED. It was shown in Fairy Dust has arrived!. It is a RGB LED with integrated controller. The LEDs can be easily chained together:



If you are really crazy you can build something like this with those:



With an estimated power draw of 3 KW and 10.000 WS2812 LEDs this is really insane.


But back to the lab:

Besides of the power supply the LEDs use only a single pin for data transfer. The data is transmitted bit-wise by the "mysterious signall" with 8 bit per RGB but in GRB order (for whatever reason). After the last LED a reset signal is sent to start all over again. This is shown in the graph from the datasheet:



mcb1 pointed me to a link which gives valuable insight into the timing constraints of the protocol. Bottom line: The timing does not matter much as long as you can make sure that around the middle of the period the DIN line has the correct signal applied. No fancy assembly code needed and no high clock frequencies.


PWM Implementation of the WS2812B Protocol


The Basic flow is straight forward:

WS2812B Driver.png


PWM on the SAMA5D4 Xplained


There are several options to programm the board. Those I evaluated are (form highest abstraction to lowest):


  • Linux driver and API
  • Atmel Software Framework (ASF)
  • Low level GPL API by Atmel


The Linux driver does not support any kind of signaling the end of the period. More capable and less abstract is ASF but AFAIK SAMA5 series is not (yet) supported. So back to the ground level and (allmost) manually programm the registers using the GPL API. The following part of the C-code is heavily commented with information from (mainly) the datasheet. It is not yet ready and definitely not tested. But as it has taken me so long to find all this information it is time to publish it anyway:


* PWM Initialization
* ------------------
* Before using the PWM macrocell, the programmer must first enable the
* peripheral clock in the Power Management Controller (PMC).
    /* Disable to configure the first PWM channel */

* Before enabling the channels, they must be configured by the software
* application as described below: (p 1466)
* - Unlock User Interface by writing the WPCMD field in the PWM_WPCR.
* - Configuration of the clock generator (DIVA, PREA, DIVB, PREB in the
*   PWM_CLK register if required).
    mode = PWM_CLK_PREA() | (PWM_CLK_DIVA()); // require 2.4 MHz
    PWMC_ConfigureClocks(PWM, mode);
* - Selection of the clock for each channel (CPRE field in PWM_CMRx)
    mode = 0; // Begin configuring the CPRE register
* - Configuration of the waveform alignment for each channel
*   (CALG field in PWM_CMRx)
    mode |= !PWM_CMR_CALG; // left alligned
* - Selection of the counter event selection (if CALG = 1) for each
*   channel (CES field in PWM_CMRx)
    mode |= !PWM_CMR_CES; // Don't care since CALG = 0
* - Configuration of the output waveform polarity for each channel
*   (CPOL bit in PWM_CMRx)
    mode |= PWM_CMR_CPOL;
    PWM.PWM_CH_NUM[0].PWM_CMR = mode; // Write CMR register
* - Configuration of the period for each channel (CPRD in the
*   PWM_CPRDx register). Writing in PWM_CPRDx register is possible
*   while the channel is disabled. After validation of the channel, the
*   user must use PWM_CPRDUPDx register to update PWM_CPRDx as
*   explained below.
*   Source Clock Selection Criteria (p 1467):
* -- The event number written in the Period Register gives the PWM
*    accuracy. The Duty-Cycle quantum cannot be lower than 1/CPRDx
*    value. The higher the value of PWM_CPRDx, the greater the
*    PWM accuracy.
    PWM.PWM_CH_NUM[0].PWM_CPRD |= PWM_CPRD_CPRD(3); // Period length
* - Configuration of the duty-cycle for each channel (CDTY in the
*   PWM_CDTYx register). Writing in PWM_CDTYx register is possible
*   while the channel is disabled. After validation of the channel, the
*   user must use PWM_CDTYUPDx register to update PWM_CDTYx as
*   explained below.
* - Configuration of the dead-time generator for each channel (DTH and
*   DTL in PWM_DTx) if enabled (DTE bit in the PWM_CMRx). Writing in
*   the PWM_DTx register is possible while the channel is disabled.
*   After validation of the channel, the user must use PWM_DTUPDx
*   register to update PWM_DTx
* - Selection of the synchronous channels (SYNCx in the PWM_SCM
*   register)
* - Selection of the moment when the WRDY flag and the corresponding
*   DMA transfer request are set (PTRM and PTRCS in the PWM_SCM
*   register)
*      PTRM = 0 => DMA transfer request and WRDY are set to ‘1’ as soon as
*   the update period is elapsed
* - Configuration of the update mode (UPDM in PWM_SCM register)
* - Configuration of the update period (UPR in PWM_SCUP register)
*   if needed
    PWM.PWM_SCUP = PWM_SCUP_UPR(0); // UPR = 0 -> update every period
* - Configuration of the comparisons (PWM_CMPVx and PWM_CMPMx)
    //PWM.PWM_CH_NUM[0] =
* - Configuration of the event lines (PWM_ELMRx)
* - Configuration of the fault inputs polarity (FPOL in PWM_FMR)
    // Unused
* - Configuration of the fault protection (FMOD and FFIL in PWM_FMR,
*   PWM_FPV and PWM_FPE1)
    // Unused
* - Enable of the Interrupts (writing CHIDx and FCHIDx in PWM_IER1, and
    //PWMC_EnableChannelIt(*PWM, 0); //PWM_IER1 (same?)
* - Enable of the PWM channels (writing CHIDx in the PWM_ENA register)


This is only the setup part, I have still to find out how to calculate the clock frequency / how to programm prescaler and divider to produce a 2.4 MHz PWM signal.

For the beginning I will poll the WRDY signal to find the end of the period an update the CDTY (duty) register manually. For better (multi-tasking) performance I want to update CDTY in the PWM_IrqHandler (interupt handler).

Let us assume that I want to create a signal like this:


strange signal





Duration in

μs ± 150 ns

Treset> 50


The usual way to generate arbitrary signals is called "Bit banging". It requires software to set the output in the "HIGH" and "LOW" state in the exact timing given by the protocol. The timing requirements for this signal look pretty strict that I do not believe that this would be possible or at least not very reliable. So I am looking for some hardware support.

After a lot of head ache and reading datasheets the idea of using the PWM came into my mind.

Bit Banging with PWM


Let's look at the signal again:

  • it starts always with "HIGH" and ends with "LOW" (except for reset which is always "LOW")
  • length of signal is 1.25 μs (reset again an exception)
  • 0.05 μs resolution (0.05 is the greatest common divisor of 1.25, 0.4, 0.85 and 0.45)


Exact Solution

The signal can be generated with PWM of 1/0.05 μs = 20 MHz frequency. Therefore the "alphabet" above translates to:


SymbolDuty %


The PWM frequency of 20 MHz is quite high, can the signal be done approximated with lower frequency?


Reasonable Approximation

The odd thing about the spec for this signal is that it is not symmetric, i. E. the high time for "0" is not equal to the low time for "1" as I had expected. Since the rising edge of the signal is every 1.25 μs this allows the receiver to synchronize. The sampling presumably takes place at exactly the half of the time which explains the asymmetry: It gives a safety margin for the timing or rather does not require steep edges.

The tolerance for the falling edge is quite high. I did not recognize it at first sight, but when I converted the whole timing into nano seconds (ns) It's pretty clear:


Signal Name

Time of Falling Edge

Nominal [ns]

Time of Falling Edge

Minimal [ns]

Time of Falling Edge

Maximal [ns]



This allows a much more reasonable approach:

Divide the 125 ns in three sections ad vary the duty cycle between 1/3 and 2/3 or in decimal:


SymbolDuty %


The frequency in this case is only 2.4 MHz. That's much better!




The reset symbol is an exception - it does not fit in the above timing. It can be generated by 40 periods with a duty cycle of 0%.

Since we are able to generate the signal there is only one question left: What is this for?


Usage of the Signal


Did you recognize / guess the signal? What do you think it is for?


(solution in the next blog post)


Planing the Final Spurt

Posted by crjeder May 27, 2015

Inspired by jancumps post 1958 Turntable from the Black Forest - 21: Right-Sizing my Plans I decided to plan the last 5 weeks of the challenge and look back on what I've achieved.


Looking Back


The features I've promised are:

  1. No user interaction necessary besides hanging the keys
  2. Make key status available on-line
  3. RGB-LEDs to display status of the absent persons
  4. RESTful / IFTTT  / Tasker (android) interface

Additional, optional features I have proposed:

  1. Record speech messages which get played when the person / respectively the key returns
  2. Detect a specific key ring independent of the hook it was hanged on
  3. Placing "ToDo" lists (on paper) on the board and sending "accepted" messages to listeners


I had no plan how to reach the the goals I've set for the challenge until now. Not that I did not know the value of a good project plan, but I am not as experienced as the other contenders therefore I could not estimate the time I would need. Even the proposal was just a wild guess of what could be possible within 15 weeks.

Currently I am able to detect key rings independently of the hook they where placed on and send out the status to a prototype client which is integrated into tasker. Therefore I've achieved 1, 2,4 and b). This is not to bad. I am currently working on 3 and I am evaluating 2 options:

  • using the Infineon RGB Shield (Product LinkProduct Link) and multiplexing the output to 5 RGB LEDs
  • using WS2812B LEDs

In both cases I have the challenge of receiving an interrupt at the end of a PWM period. I've read the Data sheets of both the Infineon and the AMD processor. In both cases they mention that it should work but I can not find out how. I've already spent the combined spare time of 2 weeks on this problem. The documentation for the SAMA5D4 simply is not made for the hobbyist so I might overlook something obvious for the expert.


Looking Forward


Now it's time to do a top-down project plan. There are 5 weeks left and one important goal to reach along with the necessary project documentation. I guess I need 2 weeks to do the cleanup and do the final presentation for the challenge. That leaves me with 3 weeks to solve the Problem, implement the server on the SAMA5D4 (Product LinkProduct Link). For the later 1 estimate 1 week since it is already partially solved. This leaves me with 2 weeks of experimenting and debugging the code for driving 5 to 8 LEDs. Sounds doable but hopefully I'll find the missing puzzle peace soon.


Next Road Block

Posted by crjeder May 13, 2015

I've identified an other road block:

The RGB LED Lighting Shield uses 10-bit I2C addresses! I found a good explanation here. Should not be a big problem but standard tools as i2cdetect only work with 7-bit addresses. Let's how it works.

I am one of those who took the challenge to use the SAMA5D4 from the kit. My take on it is to boot using nfs mounted root file system. This would have the advantage that I would have as much space in the root file system as I need and that I could easily do changes to the rootfs without flashing the board again and again. This should dramatically speed up the development process.

Obtaining the rootfs Image


I'd like to use one of the large standard distributions so I look for a debian port to the arm architecture and fortunately it exists. But from there I can only download iso install images. Not exactly what I want. But to my rescue provides a rootfs image without kernel (scroll to the bottom of the page). That's important, because in this way I can use the kernel provided by atmel which includes the correct drivers.

NFS Server


I have a synology NAS which provides network storage over several protocols which include nfs. So I only have to unpack the rootfs to /volume1/rootfs/SAMA5D4 and tell the server about it. For the NAS a gui is provided.

If you want to use a generic linux server just add a line to /etc/exports:

/volume1/rootfs/SAMA5D4 all(rw,sync,root_squash,no_subtree_check)

After this restart the nfs server (on synology this happens automatically):

exportfs -a

service nfs-kernel-server restart

Now the rootfs is provided via nfs.


Das U-Boot


(German for "the submarine")

Das U-Boot, the Universal Boot Loader is the boot loader used by the system image with which the SAMA5D4 Xplained board ships. To change anything in the boot process I have to change the configuration of U-Boot. This is done on it's own command line which is reached by interrupting the boot process:


Hit any key to stop autoboot: 0


Now it's time to look at the documentation. To mount the rootfs through nfs the kernel parameters have to point to the nfs server.

The relevant kernel parameters are taken from

root=/dev/nfs nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>:<dns0-ip>:<dns1-ip>

To set this parameters use:

=> printenv bootargs

bootargs=console=ttyS0 <......>


=> setenv bootargs 'root=/dev/nfs nfsroot= console=ttyS0 <......> ip=dhcp'

Printing the content of the bootargs variable is necessary to append the old value to the new one with cut and paste.

Changes are made permanent by 'saveenv' but this should be done after testing.

Now boot the board with the 'bootd' command.

creating NFS state directory: done

starting statd: done

NFS daemon support not enabled in kernel


The kernel is compiled without nfs support. In order for this to work I would need to compile a new kernel. That's bad since time is allready short. I have to find an other solution. Thanks to peteroakes, clem57 and jancumps there is at least a way to use the board. I'll try this route next.


Heat up the Soldering-Iron

Posted by crjeder May 5, 2015

Today I've soldered the first prototype of the key fob:


Please forgive the very raw prototype. As 1-wire device I've used the DS2401 which provides the ID only (as opposed to my earlier test where I used an EEPROM), because it is the cheapest 1-wire device I could find. Unfortunately I was not able to get them in the SOT-223-3 package which is the smallest package I might be able to solder. Instead I went for the TO-92-3 package which is through hole and easy to solder.

On the upper side of the hanging hole you can see the copper wire I used to make sure that the PCB and the hook are in contact. I did the same for the hole for the ring, but only on the lower half. The ground wire of the DS2401 is connected to the ring hole and the 1-wire data pin (pointing up in the photo above) is connected to the hanging hole.

And that's how the finished prototype looks:




Before integrating LEDs I have to revise the communication protocol since the necessary information was not present before. Furthermore some properties are missing. The protocol should be:

  • Future proof
  • Secure
  • Safe against transmission errors / modified communication

Following information was not present in the previous protocol:

  • Key status changes
  • LED status

LED status will be changeable by the client.


Message Protocol


This is the specification of the version 1 of the communication protocol. The previous (version 0) is obsolete an won't be used anymore.

For the encryption mode used (CBC), an initialization vector (IV) is needed. To successfully decrypt the IV has to be known by the clients. It is sent before the message:

<random IV><encrypted message>

Where the message is of the format shown in the table below.


0Magic Number
6Key Status Bits
7Key Status Changed Bits
0RedGreenBlueBrightness LED 0
1RedGreenBlueBrightness LED 1
7RedGreenBlueBrightness LED 7

The message consists of two 128 bit blocks where the unused bytes in the first block are filled with random numbers. The block length of 128 bits resembles the block length of AES which works is independent of the key length. Therefore this choice makes sense but is not a requirement since AES does automatic padding. The second Block contains the color and brightness values for the (max) 8 LEDs. Each is represented as a 4 bit for each component (RGB) and brightens value. This should be enough accuracy since the LEDs are used for signaling and the colors should be distinguishable. More values will result in many indistinguishable colors.

The time field contains the lowest 16 bit of the JavaScritpt getTime() which is defined as the number of milliseconds between midnight of January 1, 1970.

Messages can be sent in both directions client -> server and server -> client. The server ignores everything but the RGBL data in the second block. This is used to set the color of the LEDs.


Since push message is sent to every registered cloud service client the sender may also receive the message. The client or server can detect this by comparing the whole received message against the most recent sent and then silently discard the duplicate message.

Status Update Message

Status updates are sent by the server on status changes. To disguise the time of actual changes to an external observer status updates are sent in random periods. The extraneous updates can be identified by a Key Status Changed field containing only zeros. The client is expected to silently discard this message.

On server start it does not have any previous status thus it will send an status update message with set all bits of the Key Status Changed field to one. The client may report this event as server restart and must update the status to the values sent by the server.

If the client restarts it sends a message with all color values set to 0 and all brightness values to the maximum to signal the status update request. The server will answer this with a status update as described below.

Color Change Message

Color change messages are status update messages sent by the client. The server will ignore all values but the color values. Color values where the R, G and B components are all zeros are ignored. After changing the color values according to the message the server sends a status update.

When the client restarts it sends a color change message with the color values set to 0 and the brightness to the maximum. This message does not result in any colors to be changed but the status update is sent.


Forward Compatibility

To make to protocol future proof I have to add at least forward compatibility.

From Wikipedia:

Forward compatibility is the ability of a design to gracefully accept input intended for later versions of itself. The concept can be applied to entire systems, electrical interfaces, telecommunicationsignals, data communication protocols, file formats, and computer programming languages. A standard supports forward compatibility if older product versions can receive, read, view, play or execute the new standard gracefully, perhaps without supporting all new features.


To achieve this I include a 4 bit protocol version information and a 4 bit message length. The message length will be in 128 bit blocks - 1 which allows a maximum size of 256 blocks or 4 k bytes. Future client versions which expect more data should add that on the end, the current client will read (length) blocks but ignores everything after the second one. Alternatively future protocol versions can use the random padding for information since the version 1 client will ignore the content.

Otherwise the communication does not depend on a specific transport protocol, as it is implemented now it can support any messaging app with interface to tasker with minimal changes.




The easiest mode of operation for a block cipher is electronic code book (ECB). But please erase that from your mind, your scratch book and everywhere else since it is not secure. For example see the following image encrypted using ECB:


(Image by Larry Ewing, and The GIMP  )

The original Image could easily be guessed, right?

The easiest secure mode is cipher block chaining (CBC). But as always carefully select the parameters involved according to your application. Using the same key and IV on repeating messages with CBC has the same effect as above. The blocks are encrypted to the same cipher text and therefore produce a repeating pattern. Therefore a random IV has to be used. This can be sent in the clear since it is not part of the key. The time and random padding in the middle of the first block serves as additional variation in the message.


Error Detection


To detect transmission errors or packet manipulation I simply check if the magic number at the beginning of the 1st packet is correct. Since one bit error in the encrypted packet will be distributed over the whole clear text this should be enough to serve as a indication of change. The magic number is the binary representation of the ASCII letters "CR". If a packet with a different magic number is received the packet is silently discarded.

I recognized that I tend to post only positive results but at the same time I learn a lot from the mistakes of others I decided to devote this blog to my time wasting effort of interfacing 1-Wire components from node.js. Several evenings I read blog post, documentation and code just to find out what I am doing wrong - with no result. It still did not work. Owfs was not able to detect the devices nor could the linux kernel show me the information in the /sys/bus/w1/ directory. I was a bit frustrating. I was about to order new components because I thought my first experience in SMD soldering went wrong. Today I went home a little early and spent the afternoon in my lab - despite the good weather. I used a logic sniffer to see what's going on. And this journey will be recorded in this blog post.



To eliminate as many unknowns from the equation I decided to test using my BeagleBone Black which I am more used to than the SAMA5D4.


On the BBB the P9-19 and 20 are the I2C-1 which I am going to use. The DS2482-100's SDA and SCL are 3.3 V capable so they can be connected directly. The Linux configuration does not have to be changed since the I2C-1 is enabled by default. Connect the DS24B33 EEPROM and I am done! Right? First test it with i2cdetect:

i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

The i2c to 1-wire bridge should show up at address 0x18.

NO! It isn't that easy. Reading more documentation I got a few things to try: pull-up resistors for SDA and SCL, kernel modules to load and much more. And nothing helped. So I disconnected everything and connected it again but out of frustration I did not disconnect the BBB contrary to a omnipresent warning that you never should connect anything to the pin headers while the board is running. And this time i2cdetect showed:

i2cdetect -y -r 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Vola! At least the DS2482 was detected.

If the drivers were loaded correctly /sys/bus/w1/ would show something:

root@beaglebone:~# ls /sys/bus/w1/devices/


Maybe the drivers are not loaded? Let's check:

root@beaglebone:~# lsmod
Module                  Size  Used by
g_multi                50407  2
libcomposite           15028  1 g_multi
mt7601Usta            641118  0

To install them manually I tried:

root@beaglebone:~# modprobe ds1wm
root@beaglebone:~# modprobe ds2482
root@beaglebone:~# modprobe omap_hdq
root@beaglebone:~# modprobe w1_ds2433

Nothing changed. More frustration. Ok. Don't give up! What else can I try? Other software? Other hardware? Analyse what's going on on the bus?

I decided to do the later.


Logic Analyser


Fortunately I've bought a simple USB 8-channel logic analyzer a while ago. Never used it seriously, though. Looks like is time again to learn something new. I have taped the SDA and SDL pins to see if the DS2482 works correctly. I already could verify that it is listening on address 0x18.


The first action on the bus is not a surprise - we see a write to address 0x18 (the address of the bus master) and then the byte 0xF0 which is the command "Device Reset". Good.


I had not expected to see the read from address 0x18, but reading the data sheet I found the recommendation to read the status register to verify if the reset was performed. After reset the read pointer points to the status register, therefore a simple read will result in the value of the status register. Here it is 0x18 or in binary 0b00011000. The status register bits are DIR-TSB-SBR-RST-LL-SD-PPD-1WB where:

Bit NameDescripiton
DIRBranch Direction Taken
TSBTriplet Second Bit
SBRSingle Bit Result
RSTDevice Reset: Reset has been performed.
LLLogic Level: Reads the logic state of the 1-Wire bus without initialising a communication. Updated on every read
SDShort Detected: Updated on every 1-Wire command.
PPDPresence Pulse Detect: Set when a presence detect pulse is seen by the bus master. Updated on every reset.
1WB1-Wire Busy: reports if the bus is currently in use.

The three most significant bits are for data transfer on the 1-wire bus, the others are real status bits. In this case the RST and LL are set which means the reset was performed and the 1-Wire bus is in "high" state.


Then the next command is written to the I2C bus: 0xE1 (Set Read Pointer) 0xF0 (Status Register). So the next command has to be a read. It resulted in 0x18, the same as above.


This time 0xB4 is written to the DS2482. This is the command for 1-Wire reset.


The status register is read again, but this time the result is 0x19 so the least significant bit has changed to "high" which means the 1-Wire bus is busy. The host has to wait until the command has finished. The next read returned 0x18, again. The reset was completed but no presence pulse detected. That's why I could not access any 1-Wire devices. But why? I checked the whole circuit and found two really stupid mistakes: on the 1 wire eeprom (DS24B33) the ground pin was connected to the 3V3 pin and the pull-up resistor's bands had the colours red-red-brown which is 220 Ω. The data sheet says Rpullup should be between 0.3 and 2.2 kΩ. I looked for a red-red-red labelled resistor and installed it instead. This time I got this result:


Finally there is the Presence Detect Pulse!  The rest of the communication read the 1-Wire ID form the DS24B33. Now the key identification works.




I used a quite advanced tool to find a set of very stupid mistakes which a more experienced person would have detected on the first sight or would not have made at all.

But on the Pro side I learned how to use a quite handy tool and a lot about I2C and 1-Wire bus. Since the competition is about learning this goal was meat. For the other goals I really have to catch up now.


Smart Key Hooks Client

Posted by crjeder Apr 20, 2015

I started my "career" in electronics not long ago when the first Raspberry PI became available. But looking on the specs I decided that the BeagleBone Black suits my needs better and bought one. What I liked most about it after playing with it for a while was the c9 IDE and node.js. Therefore I decided to do the programming for this challenge in node.js, too.

The Cloud

As the cloud service I have chosen Pushbullet because it has:

  1. an easy, restfull API
  2. clients for all OSes
  3. integration in Tasker

Downside is: It does not offer end to end encryption. Therefore I had to Implement it. Since I do not have a lot of clients pre-shared key works well and is used in the implementation. The Pushbullet API is abstracted in a node.js module for even more convenience.

Provisional Client

The client consists of two parts, Tasker and a javascript code. Tasker is "Total Automation for Android" (Tasker website) a tool I use to automate many task on my Android devices. It is much like IFTTT but on the device not in the cloud. For security and privacy reasons "on device" is the preferred solution. What can Tasker do? Again citing from the website:

Tasker is an application for Android which performs tasks (sets of actions) based on contexts(application, time, date, location, event, gesture) in user-defined profiles or in clickable or timer home screen widgets.

With the Pushbullet integration every message received by the Pushbullet client a Tasker event is triggered. This can be used to start a task like launch a specific app or play a ring tone. Unfortunately the message content can not be accessed from the event. This would be necessary to start different tasks on different status changes of keys. To the rescue one of the available tasks is "code" which can run javascript programs. Let us step through the relevant portions of the javascript (nodejs):

var aes = require('crypto-js/aes');
var PushBullet = require('pushbullet');
var pusher = new PushBullet('xxxx'); //replace this with your token

this code snippet imports aes encryption from crypto-js and the nodejs libraray for Pushbullet. The last line instances and initializes the Pushbullet API. The returned object ('pusher') can be used to talk to the cloud. To initialize you need an application token which you can find in your account settings. This is a very weak authentication Pushbullet supports OAuth, too but I haven't tried it yet.

var options = {limit: 100};


For the Pushbullet API we must set a limit to the maximal returned pushes to prevent memory overruns etc.

Then call the search for the last message using the history function:


pusher.history(options, function(error, response)
    if(error) throw error;
    if(response.pushes.length <= 0) throw 'Error: no pushes';

    var i = 0;
        if (response.pushes[i].active && (response.pushes[i].sender_name == 'IoT-test' || response.pushes[i].receiver_email == '@ljkawsfowe') && response.pushes[i].type == 'note')
            //var message = 'U2FsdGVkX1+Zls89vOpjlkXCcUQhDQrBEzZoH+3iuhU=';
            var message = response.pushes[i].body;
            if (message)
                var decrypted = aes.decrypt(message, "geheim");
                var mask = 1;
                // works for Max_KEYS < 16
                for (var i = 0; i < MAX_KEYS; i++)
                   setGlobal("Key" + i, ((decrypted.words[0] & mask) != 0)?"true":"false");
                   mask = mask << 1;

    } while (i < options.limit);

    // ToDo: Error: no push found


Line 3 & 4 are for error handling. Then setup the loop for searching the response for through the past messages for one from the controller. I have set up a 'channel' for this purpose. In pushbullet channels are private by default. That's good! Depending on the interface used to send the push the sender_name or receiver_email are set. I was not able to figure out if this is a bug or if there are other differences I am not able to see. In response.pushes[i].body there should be a base 64 encoded AES encrypted message of one block. In line 15 the 'decrypted' object contains the block in 16 bit integers. The for loop in lines 18 - 22 converts the one bit status into individual Boolean variables. In line 20 a tasker API function is used to set android environment variables. The (decrypted.words[0] & mask) != 0)?"true":"false" makes use of the 'conditional operator' which is defined as:


variablename = (condition) ? value1:value2 
variablename = value1 // if condition = true
variablename = value2 // if condition = false

Therefore the statement in the client code could have been written as:

bitvalue = decrypted.words[0] & mask;
if (bitvalue > 0)
     bit_bool = 'true';
     bit_bool = 'false';

Which is more readable, by far, but obiously less compact.

So if the decrypted message starting whith 00000101b the code inside the for loop (line 18 - 22) sets the following global variables:

Key1 = 'true';
Key2 = 'false';
Key3 = 'true';
Key4 = 'false';
Key5 = 'false';
Key6 = 'false';
Key7 = 'false';
Key8 = 'false';

This values can then be used by other Tasker actions.

Line 24 deletes the message as it is processed now.

The provisional Client lacks some functions I've proposed and testing. But I'd like to share it because the development takes me to long to and I do also value your comments which have been always very useful in the past.


Identifying Keys

Posted by crjeder Apr 7, 2015

Crucial to my design is the ability to detect and identify keys. The potential solutions are divided into following categories: wireless, wired and explicit. The later means the user explicitly states „this is key #11“ through some interface. This is the least desired one and will be the fall-back if everything else fails. Therefore let's concentrate on the other two.


Because of the popularity of RFID tags wireless identification was the technology I thought about first when looking for a solution to this problem. But there are many more which fall into two categories: active and passive wireless.

Passive Wireless

Passive Wireless is the “classic” RFID tag we see as labels on high priced goods every day. The RF chip is powered “over the air” by the reader which limits distance, data rate and processing power of such solutions. But for identification, data rate and processing power requirements are very low, thus cheap solutions will perform well in this scenario.

I did not know that there are different frequencies with different characteristics in RFID technology. The following table lists properties relevant in this project.



Typical max sensing

Distance in m

Multiple Tags?

Problematic to Operate near Metal

125 kHz

Low Distance, slow, expensive tags




13,5 MHz

ISM Band used for Smart Cards and Memory cards also NFC

+ cheap tags




~800 – ~900 MHz





2.4 GHz

ISM Band is also used for Bluetooth, BLE, ZigBee, WiFi, etc.





NFC and contact less Smart Cards use the same frequencies. 13.5 MHz readers and tags are easily available and cheap. UHF readers are very expensive so despite their good properties they will be excluded. 2.4 GHz passive tokens seem to exist only in theory. Therefore the choice boils down to two alternatives 125 kHz and 13.5 MHz which will be tested for their ability to communicate when the tag hangs between the keys. The metal may shield the tag and reliable reading might not be possible.

I have ordered one 125 kHz reader and key fobs and a NFC / RFID Arduino shield to try the most promising solutions.



(Foto by Adafruit Industries)

Active Wireless

Active tokens are very similar to passive ones, only with a battery. This is of course very simplified, but is enough to get an idea. By actively powering the RF device many of the limitations of passive devices can be overcome. Plus RF technologies which are to power consuming for passive tags like WiFi and Bluetooth can be used. I was not able to find any passive token in the 2.4 GHz ISM band but there exist active ones. Because of size and weight constraints BLE tokens are most viable.


Wired solutions are often simpler and cheaper than wireless ones, but are less practical or convenient. My first idea to detect keys hanging on a hook was using switch which gets pressed or released by the weight of the keys. The detection part is really simple, more difficult is the identification. This has to be outsourced to the user: The hooks and key rings are marked with a colour and users have to hang their key on the respective hook. That violates my idea of how the user interface should be but would be a solution if everything else fails. (see explicit identification)

Since there is only one conductor between a key fob and the board 1-Wire devices came into my mind. Usually a circuit for 1-Wire looks like this:



But 1-Wire bus is a marketing lie: they do not count the ground wire!



The question now is where do we get the ground from?


I have two ideas which I have to test. First use the human body as ground. The mass should be big enough for the small charge which has to be transported (ca. 7 nano coulomb). The resistance of the skin can be several kilo Ohms which may be too much. Since I am not an electronics expert and everybody I’ve so far asked could not answer this question I have to try it. Parts are ordered, stay tuned for updates.



While testing it turned out that the human skin is a very bad conductor which makes this version impossible at least with 3,3 V.

Since this does not work I would insulate the hook form the board and use the board as ground. Not as elegant but should work.





And indeed the keys are good enough conductors and when they are large enough they touch the board. So I have a solution!


Happy Easter!

Posted by crjeder Apr 5, 2015


I wish everybody a Happy Easter. Thanks Element14 for this cool competition and to all patient readers and to the helpfully and skilled participants.

Unfortunately there was not much progress on the competition from my side. But as an status update: I am looking for a solution to identify keys.

Here a sneak preview:



And to distract you from the challenge: Go outside it's spring! (ok, northern hemisphere only ;-)