2016. március 30., szerda

AutomaTales - Rolling code receiver

[2016.04.16]: When I wrote this article didn't realized, that I used the old location of the cape manager slots file. Corrected.

When you sit in your car and try to enter to your garage, I know it is not fancy, but the most convenient device is the tiny remote you can hang on your keyring (something integrated into your car would be better and fancier, I may add something like this later on).

To be able to remote control the OpenHAB and the garage door/lights through it, I bought this rolling code receiver on the aliexpress:

http://www.aliexpress.com/item/RF-Rolling-Code-Decoding-Receiver-Module-2-Transmitters-DC-5V-4CH-TTL-Output-Learning-Momentary-Toggle/32295201884.html



My plan is to use it for switching the lights in the garage, control the garage doors and a few more (as it has two more buttons - exactly two) tasks.

First I put this onto a breadboard, powered up, and tried out if it works.

It was working for the first try, finding out the different channels for the buttons was easy like a child's play.

The only problem with the device, that it has 5V logic outputs and I want to connect to my BeagleBone Greens GPIO what isn't 5V safe.

I decided to use the simplest level shifter on earth possible. A resistor divider. A 39K and a 68K resistor does its job like champ, if you measure it with a multimeter.

The next part is to setup the GPIO on the BeagleBone. The OpenHAB uses the Linux GPIO Sysfs interface, what is supereasy to use (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).

First I tried to read the data from the command line. Connected one channel to the GPIO_60 (P9 pin 12) of the BBG.

On the console the following commands are needed:

echo '60' > /sys/class/gpio/export
echo 'in' > /sys/class/gpio/gpio60/direction

After this you can read the pin value by the following command:

cat /sys/class/gpio/gpio60/value

The commands went well, but doesn't matter if I push the button on the remote or not, always get back a 1.

Measured the input with a multimeter. It gives 1.6V even the pin of the receiver is on 0V. This means, that the BBG input pin is pulled up.
From this point I've two choice:

1. Switch of the pull up somehow
2. Use some active circuit as level shifter instead of the resistors.

I went for the first one.
Looked around and it clearly turned out, that changing the pull-up is not part of the linux GPIO framework. Read many things and found that BBG uses Cape Manager Overlays for this task. It was sometimes there, sometimes not, but on the 4.1.x kernel what I'm using is already part of the mainline kernel.

Here are some articles about it:

https://github.com/jadonk/validation-scripts/blob/master/test-capemgr/README.md
http://www.thing-printer.com/cape-manager-is-back-baby/
http://www.valvers.com/embedded-linux/beaglebone-black/step04-gpio/

The overlay repository (you can learn from it, but not necessary for the task here):
https://github.com/RobertCNelson/bb.org-overlays

The most useful of my findings was this online tool:

http://kilobaser.com/blog/2014-07-28-beaglebone-black-devicetreeoverlay-generator

It is able to create the overlay you need.

So for switching off the pull-up on Gpio 60 above you have to do the following things:

1. Save this file into the /lib/firmware under the name bspm_p9_12_2f-00A0.dts

/*
 * This is a template-generated file from BoneScript
 */

/dts-v1/;
/plugin/;

/{
    compatible = "ti,beaglebone", "ti,beaglebone-black";
    part_number = "BS_PINMODE_P9_12_0x2f";

    exclusive-use =
        "P9.12",
        "gpio1_28";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            bs_pinmode_P9_12_0x2f: pinmux_bs_pinmode_P9_12_0x2f {
                pinctrl-single,pins = <0x078 0x2f>;
            };
        };
    };

    fragment@1 {
        target = <&ocp>;
        __overlay__ {
            bs_pinmode_P9_12_0x2f_pinmux {
                compatible = "bone-pinmux-helper";
                status = "okay";
                pinctrl-names = "default";
                pinctrl-0 = <&bs_pinmode_P9_12_0x2f>;
            };
        };
    };
};

2. Compile it:
dtc -O dtb -o /lib/firmware/bspm_P9_12_2f-00A0.dtbo -b 0 -@ /lib/firmware/bspm_P9_12_2f-00A0.dts

3. Load it:
echo bspm_P9_12_2f > /sys/devices/bone_capemgr.?/slots


echo bspm_P9_12_2f > /sys/devices/platform/bone_capemgr/slots

After this, the pull-up switched off. And I was able to read status of the remote.

Ok. Now it works for one channel, but what about four? I can generate four overlays, but how to combine them. I found very little information on it, until I found Adafruit's documentation:

https://learn.adafruit.com/introduction-to-the-beaglebone-black-device-tree/device-tree-overlays

Based on this, I was able to successfully combine the four generated overlays. Finally I used the P8 pins from 7 to 10.

The overlay (suf_keeloq-00A0.dts):

/*
 * SUF - 4-Channel Keyloq receiver cape
 */

/dts-v1/;
/plugin/;

/{
    compatible = "ti,beaglebone", "ti,beaglebone-black";
    part_number = "SUF-KEELOQ";

    exclusive-use =
        "P8.7",
        "P8.8",
        "P8.9",
        "P8.10",
        "mmc1_sdcd",
        "gpio2_3",
        "gpio2_5",
        "gpio2_4";

    fragment@0 {
        target = <&am33xx_pinmux>;
        __overlay__ {
            suf_keeloq_pins: pinmux_suf_keeloq_pins {
                pinctrl-single,pins = <
0x090 0x2f
0x094 0x2f
0x09c 0x2f
0x098 0x2f
>;
            };
        };
    };
    fragment@1 {
        target = <&ocp>;
        __overlay__ {
            suf_keeloq_pinmux {
                compatible = "bone-pinmux-helper";
                status = "okay";
                pinctrl-names = "default";
                pinctrl-0 = <&suf_keeloq_pins>;
            };
        };
    };
};

Compile and load:
dtc -O dtb -o /lib/firmware/suf_keeloq-00A0.dtbo -b 0 -@ /lib/firmware/suf_keeloq-00A0.dts 
echo suf_keeloq > /sys/devices/bone_capemgr.?/slots
echo suf_keeloq > /sys/devices/platform/bone_capemgr/slots

Now it works, but somehow it need to be loaded at boot.
To achieve this, you should add into the /boot/uEnv.txt:

cape_enable=bone_capemgr.enable_partno=suf_keeloq

NEXT: Integrating into the OpenHAB

Nincsenek megjegyzések:

Megjegyzés küldése