MikrofonSensor und TemperaturSenor die zwei Python programme funktionieren. mit den jeweiligen 2 json Datein. Beim TemperaturSensor wird im Terminal keine Wertre ausgegeben aber in der json Datei kann man die Temp und Hum sehen.

This commit is contained in:
Chiara 2025-05-28 14:53:44 +02:00
parent 4c654ec969
commit 1751076592
2614 changed files with 349009 additions and 0 deletions

View file

@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Generic Connection class for Binho Nova to keep track of connection"""
class Connection:
"""Connection class"""
__instance = None
@staticmethod
def getInstance():
"""Static access method."""
if Connection.__instance is None:
Connection()
return Connection.__instance
def __init__(self):
"""Virtually private constructor."""
if Connection.__instance is not None:
raise Exception( # pylint: disable=broad-exception-raised
"This class is a singleton!"
)
# pylint: disable=import-outside-toplevel
from binhoHostAdapter import binhoHostAdapter
from binhoHostAdapter import binhoUtilities
# pylint: enable=import-outside-toplevel
devices = binhoUtilities.listAvailableDevices()
if len(devices) > 0:
Connection.__instance = binhoHostAdapter.binhoHostAdapter(devices[0])
else:
raise RuntimeError("No Binho Nova found!")

View file

@ -0,0 +1,182 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""I2C Class for Binho Nova"""
from adafruit_blinka.microcontroller.nova import Connection
class I2C:
"""Custom I2C Class for Binho Nova"""
WHR_PAYLOAD_MAX_LENGTH = 1024
def __init__(self, *, frequency=400000):
self._nova = Connection.getInstance()
self._nova.setNumericalBase(10)
self._nova.setOperationMode(0, "I2C")
self._nova.setPullUpStateI2C(0, "EN")
self._nova.setClockI2C(0, frequency)
self._novaCMDVer = "0"
if hasattr(self._nova, "getCommandVer"):
response = self._nova.getCommandVer().split(" ")
if response[0] != "-NG":
self._novaCMDVer = response[1]
def __del__(self):
"""Close Nova on delete"""
self._nova.close()
def scan(self):
"""Perform an I2C Device Scan"""
scanResults = []
for i in range(8, 121):
result = self._nova.scanAddrI2C(0, i << 1)
resp = result.split(" ")
if resp[3] == "OK":
scanResults.append(i)
return scanResults
def writeto(self, address, buffer, *, start=0, end=None, stop=True):
"""Write data from the buffer to an address"""
end = end if end else len(buffer)
readBytes = 0
if int(self._novaCMDVer) >= 1:
chunks, rest = divmod(end - start, self.WHR_PAYLOAD_MAX_LENGTH)
for i in range(chunks):
chunk_start = start + i * self.WHR_PAYLOAD_MAX_LENGTH
chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
self._nova.writeToReadFromI2C(
0,
address << 1,
stop,
readBytes,
chunk_end - chunk_start,
buffer[chunk_start:chunk_end],
)
if rest:
self._nova.writeToReadFromI2C(
0, address << 1, stop, readBytes, rest, buffer[-1 * rest :]
)
else:
self._nova.startI2C(0, address << 1)
for i in range(start, end):
self._nova.writeByteI2C(0, buffer[i])
if stop:
self._nova.endI2C(0)
else:
self._nova.endI2C(0, True)
# pylint: disable=unused-argument
def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
"""Read data from an address and into the buffer"""
end = end if end else len(buffer)
result = self._nova.readBytesI2C(0, address << 1, len(buffer[start:end]))
if result != "-NG":
resp = result.split(" ")
for i in range(len(buffer[start:end])):
buffer[start + i] = int(resp[2 + i])
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
# pylint: disable=too-many-locals,too-many-branches
def writeto_then_readfrom(
self,
address,
buffer_out,
buffer_in,
*,
out_start=0,
out_end=None,
in_start=0,
in_end=None,
stop=False,
):
"""Write data from buffer_out to an address and then
read data from an address and into buffer_in
"""
out_end = out_end if out_end else len(buffer_out)
in_end = in_end if in_end else len(buffer_in)
if int(self._novaCMDVer) >= 1:
totalIn = in_end - in_start
totalOut = out_end - out_start
totalBytes = totalIn
if totalOut > totalIn:
totalBytes = totalOut
chunks, rest = divmod(totalBytes, self.WHR_PAYLOAD_MAX_LENGTH)
if rest > 0:
chunks += 1
for i in range(chunks):
# calculate the number of bytes to be written and read
numInBytes = self.WHR_PAYLOAD_MAX_LENGTH
if totalIn < self.WHR_PAYLOAD_MAX_LENGTH:
numInBytes = totalIn
numOutBytes = self.WHR_PAYLOAD_MAX_LENGTH
if totalOut < self.WHR_PAYLOAD_MAX_LENGTH:
numOutBytes = totalOut
# setup the buffer out chunk offset
buffer = "0"
if numOutBytes > 0:
chunk_start = out_start + i * self.WHR_PAYLOAD_MAX_LENGTH
chunk_end = chunk_start + numOutBytes
buffer = buffer_out[chunk_start:chunk_end]
result = self._nova.writeToReadFromI2C(
0, address << 1, stop, numInBytes, numOutBytes, buffer
)
totalIn -= numInBytes
totalOut -= numOutBytes
if result != "-NG":
if numInBytes:
resp = result.split(" ")
resp = resp[2]
for j in range(numInBytes):
buffer_in[
in_start + i * self.WHR_PAYLOAD_MAX_LENGTH + j
] = int(resp[j * 2] + resp[j * 2 + 1], 16)
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
else:
self._nova.startI2C(0, address << 1)
for i in range(out_start, out_end):
self._nova.writeByteI2C(0, buffer_out[i])
if stop:
self._nova.endI2C(0)
else:
self._nova.endI2C(0, True)
result = self._nova.readBytesI2C(
0, address << 1, len(buffer_in[in_start:in_end])
)
if result != "-NG":
resp = result.split(" ")
for i in range(len(buffer_in[in_start:in_end])):
buffer_in[in_start + i] = int(resp[2 + i])
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
# pylint: enable=unused-argument,too-many-locals,too-many-branches

View file

@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""Binho Nova pin names"""
class Pin:
"""A basic Pin class for use with Binho Nova."""
IN = "DIN"
OUT = "DOUT"
AIN = "AIN"
AOUT = "AOUT"
PWM = "PWM"
LOW = 0
HIGH = 1
_nova = None
def __init__(self, pin_id=None):
if not Pin._nova:
# pylint: disable=import-outside-toplevel
from adafruit_blinka.microcontroller.nova import Connection
# pylint: enable=import-outside-toplevel
Pin._nova = Connection.getInstance()
# check if pin is valid
if pin_id > 4:
raise ValueError("Invalid pin {}.".format(pin_id))
self.id = pin_id
def init(self, mode=IN, pull=None):
"""Initialize the Pin"""
if self.id is None:
raise RuntimeError("Can not init a None type pin.")
# Nova does't have configurable internal pulls for
if pull:
raise ValueError("Internal pull up/down not currently supported.")
Pin._nova.setIOpinMode(self.id, mode)
def value(self, val=None):
"""Set or return the Pin Value"""
if self.id is None:
raise RuntimeError("Can not access a None type pin.")
# read
if val is None:
return int(Pin._nova.getIOpinValue(self.id).split("VALUE ")[1])
# write
if val in (self.LOW, self.HIGH):
Pin._nova.setIOpinValue(self.id, val)
return None
raise RuntimeError("Invalid value for pin")
# create pin instances for each pin
IO0 = Pin(0)
IO1 = Pin(1)
IO2 = Pin(2)
IO3 = Pin(3)
IO4 = Pin(4)
SCL = IO2
SDA = IO0
SCK = SCLK = IO3
MOSI = IO4
MISO = IO2
SS0 = IO0
SS1 = IO1
PWM0 = IO0
# No PWM support on IO1
PWM2 = IO2
PWM3 = IO3
PWM4 = IO4
# orderd as (channel, pin), id
pwmOuts = (((1, 0), PWM0), ((1, 2), PWM2), ((1, 3), PWM3), ((1, 4), PWM4))
UART1_TX = IO4
UART1_RX = IO3
# ordered as uartId, txId, rxId
uartPorts = ((0, UART1_TX, UART1_RX),)

View file

@ -0,0 +1,241 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""PWMOut Class for Binho Nova"""
try:
from microcontroller.pin import pwmOuts
except ImportError:
raise RuntimeError("No PWM outputs defined for this board") from ImportError
from microcontroller.pin import Pin
# pylint: disable=unnecessary-pass
class PWMError(IOError):
"""Base class for PWM errors."""
pass
# pylint: enable=unnecessary-pass
class PWMOut:
"""Pulse Width Modulation Output Class"""
# Nova instance
_nova = None
MAX_CYCLE_LEVEL = 1024
def __init__(self, pin, *, frequency=750, duty_cycle=0, variable_frequency=False):
"""Instantiate a PWM object and open the sysfs PWM corresponding to the
specified channel and pin.
Args:
pin (Pin): CircuitPython Pin object to output to
duty_cycle (int) : The fraction of each pulse which is high. 16-bit
frequency (int) : target frequency in Hertz (32-bit)
variable_frequency (bool) : True if the frequency will change over time
Returns:
PWMOut: PWMOut object.
Raises:
PWMError: if an I/O or OS error occurs.
TypeError: if `channel` or `pin` types are invalid.
ValueError: if PWM channel does not exist.
"""
if PWMOut._nova is None:
# pylint: disable=import-outside-toplevel
from adafruit_blinka.microcontroller.nova import Connection
# pylint: enable=import-outside-toplevel
PWMOut._nova = Connection.getInstance()
PWMOut._nova.setOperationMode(0, "IO")
self._pwmpin = None
self._channel = None
self._enable = False
self._open(pin, duty_cycle, frequency, variable_frequency)
def __del__(self):
self.deinit()
PWMOut._nova.close()
def __enter__(self):
return self
def __exit__(self, t, value, traceback):
self.deinit()
def _open(self, pin, duty=0, freq=750, variable_frequency=False):
self._channel = None
for pwmpair in pwmOuts:
if pwmpair[1] == pin:
self._channel = pwmpair[0][0]
self._pwmpin = pwmpair[0][1]
self._pin = pin
if self._channel is None:
raise RuntimeError("No PWM channel found for this Pin")
if variable_frequency:
print("Variable Frequency is not supported, continuing without it...")
PWMOut._nova.setIOpinMode(self._pwmpin, Pin.PWM)
# set frequency
self.frequency = freq
# set period
self._period = self._get_period()
# set duty
self.duty_cycle = duty
self._set_enabled(True)
def deinit(self):
"""Deinit the Nova PWM."""
# pylint: disable=broad-except
try:
if self._channel is not None:
# self.duty_cycle = 0
self._set_enabled(False) # make to disable before unexport
except Exception as e:
# due to a race condition for which I have not yet been
# able to find the root cause, deinit() often fails
# but it does not effect future usage of the pwm pin
print(
"warning: failed to deinitialize pwm pin {0}:{1} due to: {2}\n".format(
self._channel, self._pwmpin, type(e).__name__
)
)
finally:
self._channel = None
self._pwmpin = None
# pylint: enable=broad-except
def _is_deinited(self):
if self._pwmpin is None:
raise ValueError(
"Object has been deinitialize and can no longer "
"be used. Create a new object."
)
# Mutable properties
def _get_period(self):
return 1.0 / self._get_frequency()
def _set_period(self, period):
if not isinstance(period, (int, float)):
raise TypeError("Invalid period type, should be int or float.")
self._set_frequency(1.0 / period)
period = property(_get_period, _set_period)
"""Get or set the PWM's output period in seconds.
Raises:
PWMError: if an I/O or OS error occurs.
TypeError: if value type is not int or float.
:type: int, float
"""
def _get_duty_cycle(self):
duty_cycle = Pin._nova.getIOpinValue(self._pwmpin)
# Convert duty cycle to ratio from 0.0 to 1.0
duty_cycle = duty_cycle / PWMOut.MAX_CYCLE_LEVEL
# convert to 16-bit
duty_cycle = int(duty_cycle * 65535)
return duty_cycle
def _set_duty_cycle(self, duty_cycle):
if not isinstance(duty_cycle, (int, float)):
raise TypeError("Invalid duty cycle type, should be int or float.")
# convert from 16-bit
duty_cycle /= 65535.0
if not 0.0 <= duty_cycle <= 1.0:
raise ValueError("Invalid duty cycle value, should be between 0.0 and 1.0.")
# Convert duty cycle from ratio to 1024 levels
duty_cycle = duty_cycle * PWMOut.MAX_CYCLE_LEVEL
# Set duty cycle
# pylint: disable=protected-access
Pin._nova.setIOpinValue(self._pwmpin, duty_cycle)
# pylint: enable=protected-access
duty_cycle = property(_get_duty_cycle, _set_duty_cycle)
"""Get or set the PWM's output duty cycle as a ratio from 0.0 to 1.0.
Raises:
PWMError: if an I/O or OS error occurs.
TypeError: if value type is not int or float.
ValueError: if value is out of bounds of 0.0 to 1.0.
:type: int, float
"""
def _get_frequency(self):
return int(PWMOut._nova.getIOpinPWMFreq(self._pwmpin).split("PWMFREQ ")[1])
def _set_frequency(self, frequency):
if not isinstance(frequency, (int, float)):
raise TypeError("Invalid frequency type, should be int or float.")
PWMOut._nova.setIOpinPWMFreq(self._pwmpin, frequency)
frequency = property(_get_frequency, _set_frequency)
"""Get or set the PWM's output frequency in Hertz.
Raises:
PWMError: if an I/O or OS error occurs.
TypeError: if value type is not int or float.
:type: int, float
"""
def _get_enabled(self):
enabled = self._enable
if enabled == "1":
return True
if enabled == "0":
return False
raise PWMError(None, 'Unknown enabled value: "%s"' % enabled)
def _set_enabled(self, value):
"""Get or set the PWM's output enabled state.
Raises:
PWMError: if an I/O or OS error occurs.
TypeError: if value type is not bool.
:type: bool
"""
if not isinstance(value, bool):
raise TypeError("Invalid enabled type, should be string.")
self._enable = value
if not self._enable:
self._set_duty_cycle(0.0)
# String representation
def __str__(self):
return "PWM%d, pin %s (freq=%f Hz, duty_cycle=%f%%)" % (
self._pin,
self._pin,
self.frequency,
self.duty_cycle * 100,
)

View file

@ -0,0 +1,218 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""SPI Class for Binho Nova"""
from adafruit_blinka.microcontroller.nova import Connection
class SPI:
"""Custom SPI Class for Binho Nova"""
MSB = 0
BUFFER_PAYLOAD_MAX_LENGTH = 64
WHR_PAYLOAD_MAX_LENGTH = 1024
def __init__(self, clock):
self._nova = Connection.getInstance()
self._nova.setNumericalBase(10)
self._nova.setOperationMode(0, "SPI")
self._nova.setClockSPI(0, clock)
self._nova.setModeSPI(0, 0)
self._nova.setIOpinMode(0, "DOUT")
self._nova.setIOpinMode(1, "DOUT")
self._nova.beginSPI(0)
self._novaCMDVer = "0"
if hasattr(self._nova, "getCommandVer"):
response = self._nova.getCommandVer().split(" ")
if response[0] != "-NG":
self._novaCMDVer = response[1]
# Cpol and Cpha set by mode
# Mode Cpol Cpha
# 0 0 0
# 1 0 1
# 2 1 0
# 3 1 1
def __del__(self):
"""Close Nova on delete"""
self._nova.close()
# pylint: disable=too-many-arguments,unused-argument
def init(
self,
baudrate=1000000,
polarity=0,
phase=0,
bits=8,
firstbit=MSB,
sck=None,
mosi=None,
miso=None,
):
"""Initialize the Port"""
self._nova.setClockSPI(0, baudrate)
self._nova.setModeSPI(0, (polarity << 1) | (phase))
# pylint: enable=too-many-arguments,unused-argument
@staticmethod
def get_received_data(lineOutput):
"""Return any received data"""
return lineOutput.split("RXD ")[1]
@property
def frequency(self):
"""Return the current frequency"""
return self._nova.getClockSPI(0).split("CLK ")[1]
def write(self, buf, start=0, end=None):
"""Write data from the buffer to SPI"""
end = end if end else len(buf)
payloadMaxLength = self.BUFFER_PAYLOAD_MAX_LENGTH
if int(self._novaCMDVer) >= 1:
payloadMaxLength = self.WHR_PAYLOAD_MAX_LENGTH
chunks, rest = divmod(end - start, payloadMaxLength)
for i in range(chunks):
chunk_start = start + i * payloadMaxLength
chunk_end = chunk_start + payloadMaxLength
if int(self._novaCMDVer) >= 1:
self._nova.writeToReadFromSPI(
0, True, False, chunk_end - chunk_start, buf[chunk_start:chunk_end]
)
else:
self._nova.clearBuffer(0)
self._nova.writeToBuffer(0, 0, buf[chunk_start:chunk_end])
self._nova.transferBufferSPI(0, chunk_end - chunk_start + 1)
if rest:
if int(self._novaCMDVer) >= 1:
self._nova.writeToReadFromSPI(0, True, False, rest, buf[-1 * rest :])
else:
self._nova.clearBuffer(0)
self._nova.writeToBuffer(0, 0, buf[-1 * rest :])
self._nova.transferBufferSPI(0, rest)
def readinto(self, buf, start=0, end=None, write_value=0):
"""Read data from SPI and into the buffer"""
end = end if end else len(buf)
if int(self._novaCMDVer) >= 1:
chunks, rest = divmod(end - start, self.WHR_PAYLOAD_MAX_LENGTH)
i = 0
for i in range(chunks):
chunk_start = start + i * self.WHR_PAYLOAD_MAX_LENGTH
chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
result = self._nova.writeToReadFromSPI(
0, False, True, chunk_end - chunk_start, write_value
)
if result != "-NG":
resp = result.split(" ")
resp = resp[2]
# loop over half of resp len as we're reading 2 chars at a time to form a byte
loops = int(len(resp) / 2)
for j in range(loops):
buf[(i * self.WHR_PAYLOAD_MAX_LENGTH) + start + j] = int(
resp[j * 2] + resp[j * 2 + 1], 16
)
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
if rest:
result = self._nova.writeToReadFromSPI(
0, False, True, rest, write_value
)
if result != "-NG":
resp = result.split(" ")
resp = resp[2]
# loop over half of resp len as we're reading 2 chars at a time to form a byte
loops = int(len(resp) / 2)
for j in range(loops):
buf[(i * self.WHR_PAYLOAD_MAX_LENGTH) + start + j] = int(
resp[j * 2] + resp[j * 2 + 1], 16
)
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
else:
for i in range(start, end):
buf[start + i] = int(
self.get_received_data(self._nova.transferSPI(0, write_value))
)
# pylint: disable=too-many-arguments,too-many-locals,too-many-branches
def write_readinto(
self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
):
"""Perform a half-duplex write from buffer_out and then
read data into buffer_in
"""
out_end = out_end if out_end else len(buffer_out)
in_end = in_end if in_end else len(buffer_in)
readlen = in_end - in_start
writelen = out_end - out_start
if readlen > writelen:
# resize out and pad with 0's
tmp = bytearray(buffer_out)
tmp.extend([0] * (readlen - len(buffer_out)))
buffer_out = tmp
if int(self._novaCMDVer) >= 1:
chunks, rest = divmod(len(buffer_out), self.WHR_PAYLOAD_MAX_LENGTH)
i = 0
for i in range(chunks):
chunk_start = out_start + i * self.WHR_PAYLOAD_MAX_LENGTH
chunk_end = chunk_start + self.WHR_PAYLOAD_MAX_LENGTH
result = self._nova.writeToReadFromSPI(
0,
True,
True,
chunk_end - chunk_start,
buffer_out[chunk_start:chunk_end],
)
if result != "-NG":
resp = result.split(" ")
resp = resp[2]
# loop over half of resp len as we're reading 2 chars at a time to form a byte
loops = int(len(resp) / 2)
for j in range(loops):
buffer_in[
(i * self.WHR_PAYLOAD_MAX_LENGTH) + in_start + j
] = int(resp[j * 2] + resp[j * 2 + 1], 16)
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
if rest:
result = self._nova.writeToReadFromSPI(
0, True, True, rest, buffer_out[-1 * rest :]
)
if result != "-NG":
resp = result.split(" ")
resp = resp[2]
# loop over half of resp len as we're reading 2 chars at a time to form a byte
loops = int(len(resp) / 2)
for j in range(loops):
buffer_in[
(i * self.WHR_PAYLOAD_MAX_LENGTH) + in_start + j
] = int(resp[j * 2] + resp[j * 2 + 1], 16)
else:
raise RuntimeError(
"Received error response from Binho Nova, result = " + result
)
print(buffer_in)
else:
for data_out in buffer_out:
data_in = int(
self.get_received_data(self._nova.transferSPI(0, data_out))
)
if i < readlen:
buffer_in[in_start + i] = data_in
i += 1
# pylint: enable=too-many-arguments,too-many-locals,too-many-branches

View file

@ -0,0 +1,87 @@
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""UART Class for Binho Nova"""
from adafruit_blinka.microcontroller.nova import Connection
class UART:
"""Custom UART Class for Binho Nova"""
ESCAPE_SEQUENCE = "+++UART0"
# pylint: disable=too-many-arguments,unused-argument
def __init__(
self,
portid,
baudrate=9600,
bits=8,
parity=None,
stop=1,
timeout=1000,
read_buf_len=None,
flow=None,
):
self._nova = Connection.getInstance()
self._id = portid
self._baudrate = baudrate
self._parity = parity
self._bits = bits
self._stop = stop
self._timeout = timeout
if flow is not None: # default 0
raise NotImplementedError(
"Parameter '{}' unsupported on Binho Nova".format("flow")
)
self._nova.setOperationMode(self._id, "UART")
self._nova.setBaudRateUART(self._id, baudrate)
self._nova.setDataBitsUART(self._id, bits)
self._nova.setParityUART(self._id, parity)
self._nova.setStopBitsUART(self._id, stop)
self._nova.setEscapeSequenceUART(self._id, UART.ESCAPE_SEQUENCE)
self._nova.beginBridgeUART(self._id)
# pylint: enable=too-many-arguments,unused-argument
def __del__(self):
"""Close Nova on delete"""
self.deinit()
self._nova.close()
def deinit(self):
"""Deinitialize"""
self._nova.writeBridgeUART(UART.ESCAPE_SEQUENCE)
self._nova.stopBridgeUART(UART.ESCAPE_SEQUENCE)
def read(self, nbytes=None):
"""Read data from UART and return it"""
if nbytes is None:
return None
data = bytearray()
for _ in range(nbytes):
data.append(ord(self._nova.readBridgeUART()))
return data
def readinto(self, buf, nbytes=None):
"""Read data from UART and into the buffer"""
if nbytes is None:
return None
for _ in range(nbytes):
buf.append(ord(self._nova.readBridgeUART()))
return buf
def readline(self):
"""Read a single line of data from UART"""
out = self._nova.readBridgeUART()
line = out
while out != "\r":
out = self._nova.readBridgeUART()
line += out
return line
def write(self, buf):
"""Write data from the buffer to UART"""
return self._nova.writeBridgeUART(buf)