Saturday 23 December 2017

IoT Bluetooth Relay Board for Autogate

Clockwise from top: Arduino dual relay, LM2956 boost-buck DC-DC converter, bluetooth USB PIC18F14K50 and HC-06 bluetooth module
The IoT Autogate is simply a combination of two systems, the remote-controlled Autogate and the Bluetooth Solar Battery Voltmeter. with the addition of a cheap (only RM10) Arduino dual-channel relay board.
Arduino 5V opto-isolated dual relay PCB
The PIC18F14K50 (it is really an incarnation of the Microchip Low Pincount Development Kit)  can drive the optoisolator input directly using two of its spare pins configured as digital output. Best of all the relay coil consumes little power: 80mA per active relay. When it is not active the power used is 10mA at 5V or 0.05W. This is very useful because in the event of a power cut and the autogate is running on battery, you want the gate to remain powered for as long as possible.

The relay board logic is reversed, that is a 'low' or 0V output by the PIC18F14K50 turns the relay on. I happened to have the pins RC4 and RC5 free so I used them. This is the same port as the voltmeter's analog input pins (RC6 & RC7).

I first tested it from the USB port of my laptop. This lets me start testing from a clean USB Microchip Low Pincount Development Kit software and helps prevent errors in my bluetooth code from affecting the relay board code. It is safer to use a USB hub, preferably one which has its own 5V power in case a wiring mistake damages your laptop.

First of, simply set TRISC correctly for both analog inout and digital output:
    #define mInitAllLEDs()      LATC &= 0xC0; TRISC &= 0xC0;
If you need to delve further into this code you first need to read the (rather thick) PIC18F14K50 datasheet.

We put a little veneer of C over the new analog output bits:
    #define digital_output_1    LATCbits.LATC4 // 2017-12-03
    #define digital_output_2    LATCbits.LATC5 // 2017-12-03

So, to turn both relays off (like on power up) we simply do:
    digital_output_1 = 1; //Make sure relays are off
    digital_output_2 = 1; //Make sure relays are off

I simply added a counter to the USB code and wrote the value of the counter to the PIC18F14K50 output port. The first time a voltmeter command is issued, only one relay comes on (01). The second command causes the first relay to go off and the second relay to come on (10). The third command causes both relays to go off (11). The forth command causes both relays to come on (00).

The actual test is simplicity itself (python rocks!) and took just a few minutes. The relays duly clicked in their assigned order:

$python
Python 2.7.11 (default, Mar  3 2016, 13:35:30)
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> port=serial.Serial('/dev/ttyACM0', 19200, timeout=1)
>>> port.write('z');port.read(20);
1
'\x00\x03HCM\x00\x00LJP\x00'
>>> port.write('z');port.read(20);
1
>>> port.write('z'); port.read(50);
1
'\x02/HCM\x01}LJP\x00'
>>> port.write('z'); port.read(50);
1
'\x03\xd1HCM\x03eLJP\x00'

Now with the new digital output function working it is time to test it with the bluetooth code. To do so I needed to power on from a non-USB 5V. Otherwise the PIC18F14K50 would detect the USB port and would not run the bluetooth code. This is easily done with a power bank.


 

As before, use hciconfig and bluetoothctl.

[bluetooth]# devices
[bluetooth]# paired-devices
[bluetooth]# power on
Changing power on succeeded
[bluetooth]# scan onm
Invalid argument onm
[bluetooth]# scan on
Discovery started
[CHG] Controller C8:FF:28:27:7D:2C Discovering: yes
[NEW] Device 98:D3:32:20:BB:7B HC-06
[bluetooth]#
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# pair 98:D3:32:20:BB:7B
Attempting to pair with 98:D3:32:20:BB:7B
[CHG] Device 98:D3:32:20:BB:7B Connected: yes
Request PIN code
[agent] Enter PIN code: 1234
[CHG] Device 98:D3:32:20:BB:7B UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device 98:D3:32:20:BB:7B Paired: yes
Pairing successful
[CHG] Device 98:D3:32:20:BB:7B Connected: no
[bluetooth]#

Then 

$rfcomm unbind /dev/rfcomm0 98:D3:32:20:BB:7B 1
$rfcomm bind /dev/rfcomm0 98:D3:32:20:BB:7B 1

Back to python (did I say python rocks?)

$python
Python 2.7.11 (default, Mar  3 2016, 13:35:30)
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import serial
>>> port=serial.Serial('/dev/rfcomm0', timeout=3)
>>> port.write('0');port.read(100)
1
'\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x0
3\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xf
bHCM\x009LJP\x03\xfbHCM\x009LJP'
>>> port.write('1');port.read(100)
1
'\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x0
3\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xf
bHCM\x009LJP\x03\xfbHCM\x009LJP'
>>> port.write('2');port.read(100)
1
'\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x0
3\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xf
bHCM\x009LJP\x03\xfbHCM\x009LJP'
>>> port.write('3');port.read(100)
1
'\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x0
3\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xf
bHCM\x009LJP\x03\xfbHCM\x009LJP'
>>> port.write('0');port.read(100)
1
'\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x0
3\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xfbHCM\x009LJP\x03\xf
bHCM\x009LJP\x03\xfbHCM\x009LJP'
>>>

Finally, I needed a 12V to 5V DC to DC power supply. The autogate runs off a 12V backup battery, and while I could wire to the autogate controller's 5V (it is also a Microchip) that would mean soldering two wires to every time I changed controllers. Again Arduino provided the answer: the LM2596 module that cost RM3.50 on sale.


Do power it up and set the output before you connect it to your PIC18F14K50, for the LM2596 is a step-up (boost) as well as step-down (buck) converter. The trimpot is multiturn, so it might take a bit of turning to get it down to 5V. Hook it up to the PIC18F14K50 and we are ready to mount it into the autogate

You can go faster and jump right to the bluetooth section, but I find while these methodical baby-steps may take a little longer, it sure beats two weeks of confusion while you sorted out the interacting bugs from hardware build, digital output code and bluetooth code. 

Perhaps you can spot the bug in my code, which I will address in the next post. 

Happy trails.

No comments:

Post a Comment