Saturday 7 October 2017

Bluetooth IoT Solar Battery Voltmeter Redux

From the last post we showed that the 3.3V TTL Arduino HC-06 can be mounted to an RS-485 USB PIC18F14K50  and be made to work. Here we add the analog input feature from another earlier post and hopefully the HC-06 will play nice. That was indeed the case, after a little persuasion.

Arduino HC-06 with RS-485 USB PIC18F14K50
This removed the need to use a Raspberry Pi for our Solar Battery Voltmeter and save 160mA of current consumption.

Mounted on the solar battery. The power adapter is a USB phone charger for use in a car cigarette lighter socket
The php script on the webserver simply executes the bluetooth master code directly, and the bluetooth link proved workable despite the webserver being inside the study with the doors and windows closed at least 10m away.

Despite the apparently simple task of integrating two features, caution is recommended. I modified a new RS-485 USB dongle for bluetooth and re-tested every time something new is added. The original working set is kept in case I needed a good set to test my software. Otherwise hardware and software errors tend to feed each other and you end up with an indigestible tangle.

First the new build was tested using easyhooks exactly like the previous post. Take care not to change the software at this point.

Next the bluetooth cable was assembled and the whole lot was retested. The HC-06 defaults to 9600 baud but the USB PIC18F14K50 starts up at 19200 baud. It was trivial for the Raspberry Pi to set the latter to 9600 baud, but without the Pi the PIC18F14K50 had to be made to power up at 9600 baud.

The analog input mod was then added. Here was a new wrinkle - when the analog code transmitted over the bluetooth channel somehow the result bytes fed back into the bluetooth receiver and triggered yet more transmissions. The PIC18F14K50 program was modified to only start analog input (and transmitting) only on receipt of the command 'z' and not just any keystroke.

The software is much the same as the last bluetooth post:

root@aspireE1:/home/heong$hciconfig
hci0:   Type: BR/EDR  Bus: USB
        BD Address: A4:DB:30:55:9C:AA  ACL MTU: 1022:8  SCO MTU: 183:5
        DOWN
        RX bytes:574 acl:0 sco:0 events:30 errors:0
        TX bytes:368 acl:0 sco:0 commands:30 errors:0

If you get nothing at this stage, you do not have a bluetooth controller, but if you get output like that above you go on to:

root@aspireE1:/home/heong$hciconfig hci up

If you check again your controller should read 'UP':

root@aspireE1:/home/heong$hciconfig
hci0:   Type: BR/EDR  Bus: USB
        BD Address: A4:DB:30:55:9C:AA  ACL MTU: 1022:8  SCO MTU: 183:5
        UP RUNNING
        RX bytes:1148 acl:0 sco:0 events:60 errors:0
        TX bytes:736 acl:0 sco:0 commands:60 errors:0

root@aspireF15:/home/heong$bluetoothctl
[NEW] Controller 00:15:83:15:A3:03 BlueZ 5.40 [default]
[NEW] Controller C8:FF:28:27:7D:2C BlueZ 5.40
[bluetooth]# devices
[bluetooth]# paired-devices
[bluetooth]# power on
[CHG] Controller 00:15:83:15:A3:03 Class: 0x00010c
Changing power on succeeded
[CHG] Controller 00:15:83:15:A3:03 Powered: yes
[bluetooth]# scan on
Discovery started
[CHG] Controller 00:15:83:15:A3:03 Discovering: yes
[NEW] Device 98:D3:32:20:BB:7B 98-D3-32-20-BB-7B
[CHG] Device 98:D3:32:20:BB:7B LegacyPairing: no
[CHG] Device 98:D3:32:20:BB:7B RSSI: 127
[CHG] Device 98:D3:32:20:BB:7B Name: HC-06
[CHG] Device 98:D3:32:20:BB:7B Alias: HC-06
[CHG] Device 98:D3:32:20:BB:7B LegacyPairing: yes
[CHG] Device 98:D3:32:20:BB:7B RSSI is nil
[bluetooth]# agent
Missing on/off/capability argument
[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
[CHG] Device 98:D3:32:20:BB:7B Connected: yes

At which point we do:
root@aspireF15:/home/heong/mpg$rfcomm bind /dev/rfcomm0 98:D3:32:20:BB:7B 1

The python script (easily called by a webhost PHP script) is:
root@aspireF15:/home/heong/solar$cat analog_pic/bluetooth_solarbat.py
#!/usr/bin/python
import serial
from time import localtime, strftime, sleep

port=serial.Serial('/dev/rfcomm0', timeout=3)

if __name__ == "__main__":

  sleep(5)
  Vbat = ''
  port.write('z')
  Vbat= port.read(100)
  Battery_Voltage=int(format(ord(Vbat[0]), '02x'), 16)*256 + \
                  int(format(ord(Vbat[1]), '02x'), 16)
  if Vbat[2:5] != 'HCM':
    print 'HCM Checkbyte Fail', Vbat

# Calibrated_Battery_Voltage = Battery_Voltage * 13.75 / 689
  Calibrated_Battery_Voltage = (Battery_Voltage * 5.0) / 1024 # convert to floating point
  print 'Bluetooth power',
  print format(ord(Vbat[0]), '02x'),
  print format(ord(Vbat[1]), '02x')


  print Calibrated_Battery_Voltage,'Volts',strftime("%Y-%m-%d %H:%M:%S", localtime())

  Battery_Voltage=int(format(ord(Vbat[5]), '02x'), 16)*256 + \
                  int(format(ord(Vbat[6]), '02x'), 16)
  if Vbat[7:10] != 'LJP':
    print 'LJP Checkbyte Fail', Vbat

  for j in range(len(Vbat)):
    print format(ord(Vbat[j]), '02x'),
  print('\n')

# Calibrated_Battery_Voltage = Battery_Voltage * 12.56 / 640
  Calibrated_Battery_Voltage = Battery_Voltage * 13.75 / 689
  print 'Solar battery power',
  print format(ord(Vbat[5]), '02x'),
  print format(ord(Vbat[6]), '02x')
  print Calibrated_Battery_Voltage,'Volts',strftime("%Y-%m-%d %H:%M:%S", localtime())


Note the raw output is still printed at this stage to aid with calibration.
One of the analog inputs have been connected to the PIC18F14K50 input power (5V), as it might come in handy should I connect the setup directly to the solar panel output, bypassing the battery.

When executed the script should read:

root@aspireF15:/home/heong/solar$analog_pic/bluetooth_solarbat.py
Bluetooth power 03 f9
4.9658203125 Volts 2017-10-08 08:40:05
03 f9 48 43 4d 02 7f 4c 4a 50

Solar battery power 02 7f
12.7521770682 Volts 2017-10-08 08:40:05

There you have it, a solar battery voltmeter that only takes 30mA at 5V. A wireless IoT device makes a voltmeter lot safer to read, and gives us the confidence to later connect it to read much higher voltages- 100Vac, 240Vac, 340Vdc. Imagine dropping one of these babies into a 10KW inverter (used electric vehicles, escalator, elevator) to diagnose problems. Makes a change from poking at the charred remains trying to do the same.

I originally intended to post a link to the PHP script to read the battery voltage online, but for some reason bluetoothctrl would not run properly on my Beaglebone White webhost CPU nor my backup webhost, an older Acer laptop.

Which brings me to why I like using a full Linux installation as an embedded controller whenever I can. When prototyping, little niggles like this crop up all the time. With a full installation, this almost never become a show-stopper. This is because it is much easier to modify a full Linux installation than any system which has already been cut down, like busybox, uLinux or a dedicated embedded OS.

Happy trails. 

No comments:

Post a Comment