Brubel,
Thaks for the help. I have mostly guessed the ansewers you gave.
I guess I can summarize my issue as follows: How can I clear the UART buffer? I have used the 'evaluate' example to send 'bme280.temperature' to it and after read, it executes an 'eval()' and writes the result back to the RPi.
Occasionally, I get an empty string back. I bypass this with an if len() >0 and else just return. What this inevitably does is eventually actually fill the uart buffer with the requested data.
Now either I can increase the time.sleep(20) to longer and hope before then it gets read correctly. I send a uart.write(str(result)) and then uart_service.write(b'\n') so there is an end of line being sent. Now, I read somewhere that the python 'readline()' command reads until an end of line is read. Is that not so? I would like to know what other python IO type arguments I can add. It appears to me that the UARTService from BLERadio doe snot support any other arguments except the 'payload'(?). I have tried to utilize some things like 'timeout=x)' to increase the read time. Wha tI also understand is that read() (and readline()?) are blocking, but that does not appear to be the case. When I use a print whatever comes across that is 'empty' There is a line return and no characters.
Anyway, two questions, is this just a simple wait longer? Or, is it something I need to handle as an error or something and try to either clear the buffer, or something you can suggest?
Here is code for the RPi:
Code: Select all
# pibleuart_ble280
# Connect to an "eval()" service over BLE UART.
# have nRF52840 evaluate temperature, humidity and pressure and return them to RPI bia BLE.
# Rpi will send data to aio via wifi
# Roger Ayotte March 5, 2021
# based on the eval example
# Connect to an "eval()" service over BLE UART.
import time
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
ble = BLERadio()
uart_connection = None
sensor_read_delay = 300
from Adafruit_IO import Client, Feed, Data, RequestError
import datetime
# Set to your Adafruit IO key.
# Remember, your key is a secret,
# so make sure not to publish it when you publish this code!
ADAFRUIT_IO_KEY = 'aio_Fzve6425emwZSbMDz9nTeAvjI1dj'
# Set to your Adafruit IO username.
# (go to https://accounts.adafruit.com to find your username).
ADAFRUIT_IO_USERNAME = 'Rcayot'
# Create an instance of the REST client.
aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY)
# Set up Adafruit IO Feeds.
temperature_feed = aio.feeds('temperature')
humidity_feed = aio.feeds('humidity')
pressure_feed = aio.feeds('pressure')
def get_and_send_temperature():
request_temperature = "bme280.temperature"
uart_service.write(request_temperature.encode("utf-8"))
# uart_service.write(b'\n')
time.sleep(20)
temperature = uart_service.readline().decode("utf-8")
data = str(temperature)
if len(data) > 0:
print(data, 'recieved')
data = (1.8)*float(data) + 32.0
data = round(data, 2)
time.sleep(1)
aio.send_data(temperature_feed.key, str(data))
else:
print('empty string recieved')
temperature = uart_service.readline().decode("utf-8")
return
print(data, 'sent')
def get_and_send_humidity():
request_humidity = "bme280.humidity"
uart_service.write(request_humidity.encode("utf-8"))
#uart_service.write(b'\n')
time.sleep(20)
humidity = uart_service.readline().decode("utf-8")
data = str(humidity)
if len(data) > 0:
print(data, 'recieved')
time.sleep(1)
aio.send_data(humidity_feed.key, str(data))
else:
print('empty string recieved')
return
print(data, 'sent')
def get_and_send_pressure():
request_pressure = "bme280.pressure"
uart_service.write(request_pressure.encode("utf-8"))
#uart_service.write(b'\n')
time.sleep(20)
pressure = uart_service.readline().decode("utf-8")
data = str(pressure)
if len(data) > 0:
print(data, 'recieved')
time.sleep(1)
aio.send_data(pressure_feed.key, str(data))
else:
print('empty string recieved')
return
print(data, 'sent')
while True:
if not uart_connection:
print("Trying to connect...")
for adv in ble.start_scan(ProvideServicesAdvertisement):
if UARTService in adv.services:
uart_connection = ble.connect(adv)
print("Connected")
break
ble.stop_scan()
if uart_connection and uart_connection.connected:
uart_service = uart_connection[UARTService]
while uart_connection.connected:
print('temperature requested')
get_and_send_temperature()
time.sleep(15)
print('humidity requested')
get_and_send_humidity()
time.sleep(15)
print('pressure requested')
get_and_send_pressure()
time.sleep(600)
here is the code for the nRF52840:
Code: Select all
# Provide an "eval()" service over BLE UART.
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.nordic import UARTService
import time
import board
import busio
import adafruit_bme280
ble = BLERadio()
uart = UARTService()
advertisement = ProvideServicesAdvertisement(uart)
# Create library object using our Bus I2C port
i2c = busio.I2C(board.SCL, board.SDA)
bme280 = adafruit_bme280.Adafruit_BME280_I2C(i2c)
while True:
ble.start_advertising(advertisement)
print("Waiting to connect")
while not ble.connected:
pass
print("Connected")
while ble.connected:
s = uart.readline()
if s:
try:
result = (eval(s))
print(result, 'received')
except Exception as e:
result = repr(e)
print(result, 'e')
uart.write(str(result))
uart_service.write(b'\n')
print(result, 'sent')