0

My (python) program (on Raspberry Pi zero W) turns on/off a GPIO pin (connected to a relay module) depending on the RSSI signal of my phone (connected via bluetooth) and the status of one more GPIO pin (a button). The relay should be turned ON If the button is ON and the if RSSI reads zero or above.
[for most of the time of the day, the phone will be connected and button will be OFF]

button connection

Here is a PART of the code (I have the complete code which works correctly)

    def get_connected_devices(check_dev = False):
        devs =  subprocess.check_output(["sudo", "hcitool", "con"]).split('ACL')
        if len(devs) is 1:
            return False
        else:
            del devs[0] #removes the first element
            device_list = []

            for dev in devs:
                device_list.append(dev[1:18])

            if check_dev:
                if check_dev in device_list:
                    return True
                else:
                    return False
            else:
                return device_list

    while get_connected_devices(phone.mac):
        if button.is_pressed and phone.read_rssi():
            while True:
                if phone.rssi >= 0:
                    relay.power_on()

                #conditions to turn off the relay
                elif phone.n_signal >= true_max_n_count or phone.rssi < phone.away_threshold:
                    relay.power_off()
                    sleep(rssi_interval)
                    break

                if not phone.read_rssi():
                    if not get_connected_devices(phone.mac):
                        print "phone disconnected"
                        relay.power_off()
                    break
                sleep(rssi_interval)
            continue
        sleep(button_check_interval)

This code keeps checking if the phone is connected (using my own function) and the status of the button (using gpioZero) every 1.7 seconds and if it is pressed it starts reading the RSSI

My questions:

a) Does reading the status of the button continuously uses more energy than reading the RSSI continuously. If so I can make it keep reading the RSSI and when it reads 0 dhn it can check the button status.
I am asking this because my previous version of the program does not check the button status and works only depending on the RSSI and the current version with the button seems to discharge my battery too quickly. Please tell me how to make it more power efficient.

b) any better way to check if the phone is connected?, so to pause the program while connected AND button is not pressed. maybe using threads?

1

I suspect the answer is to have events rather than a while loop.

Not sure on the logic on this project... Is it: when the button is pressed, check for the phone being connected (or nearby)?

This would mean you could use when_pressed https://gpiozero.readthedocs.io/en/stable/recipes.html?highlight=when_pressed#button

For reading the phone connection, you could use the BlueZ DBus API that is documented at:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/device-api.txt

The pydbus library is a good library to use for DBus clients.

I don't have the hardware to test this so there might be issues with the code below, but this is how I would structure it.

I have also chosen to ignore RSSI for the minute to make this example simpler.

from gpiozero import Button
from signal import pause
import pydbus

# Button pin number
btn_pin = 18

# Phone setup information
phone_addr = 'DE:82:35:E7:CE:BE'
bluez_service = 'org.bluez'
adapter_path = '/org/bluez/hci0'
device_path = f"{adapter_path}/dev_{phone_addr.replace(':', '_')}"
# Get adapter and device objects
bus = pydbus.SystemBus()
adapter = bus.get(bluez_service, adapter_path) 
device = bus.get(bluez_service, device_path)


def button_event():
    if device.Connected:
        print("phone connected")
        relay.power_on()
    else:
        print("phone disconnected")
        relay.power_off()
        
button = Button(btn_pin)

button.when_pressed = button_event

pause()
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.