~n0mn0m/bot_commander

6bf034b59110b324c3fcbb8cfc61eec0d264efa5 — n0mn0m 7 months ago 970ba2b
Communication rework.

Changed the controller script to not initialize a class or track state for reliable operation. Classes objects take a lot of space, and the board was already constrained. State seemd to have some issues tracking and eventually crashing. Instead letting the roomba itself handle the states and if commands are valid board is just passing the commands it picks up from the radio. Added some led signalling for external observation. Updated makefile to transfer code.py
2 files changed, 96 insertions(+), 56 deletions(-)

A Makefile
M code.py
A Makefile => Makefile +15 -0
@@ 0,0 1,15 @@
all: transfer transferd

init:
	mdutil -i off /Volumes/CIRCUITPY
	cd /Volumes/CIRCUITPY
	rm -rf {fseventsd,Trashes}
	mkdir .fseventsd
	touch .fseventsd/no_log .metadata_never_index .Trashes
	cd -

transfer:
	cp -X code.py /Volumes/CIRCUITPY

transferd:
	cp -rX lib /Volumes/CIRCUITPY

M code.py => code.py +81 -56
@@ 1,72 1,97 @@
import time

import adafruit_rfm9x
import board
import busio
import digitalio
import adafruit_rfm9x
import time


class OpenInterface:
    def __init__(self, tx_pin, rx_pin, brc_pin, baud_rate=115200):
        self._board = busio.UART(tx_pin, rx_pin, baudrate=baud_rate)
        self._tx_pin = tx_pin
        self._rx_pin = rx_pin
        self._brc_pin = brc_pin
        self._brc_pin.direction = digitalio.Direction.OUTPUT
        self._baud_rate = baud_rate
        self._stopped = True

    def start(self):
        if self._stopped:
            self.wake_up()

        for command in (b"\x80", b"\x83", b"\x87"):
            self._board.write(command)

    def stop(self):
        for command in (b"\x85", b"\xAD"):
            self._board.write(command)
        self._stopped = True

    def wake_up(self):
        for i in range(3):
            self._brc_pin.value = False
            time.sleep(0.5)
            self._brc_pin.value = True
            time.sleep(0.5)
            self._brc_pin.value = False
            time.sleep(0.5)

        self._stopped = False


def start(bot):
    """
    Start sequence from the Open Interface manual.
    """
    bot.write(b"\x80")
    bot.write(b"\x83")
    bot.write(b"\x87")


def stop(bot):
    """
    Stop sequence from the Open Interface manual.
    """
    bot.write(b"\x85")
    bot.write(b"\xAD")


def wake_up(brc):
    """
    Pulse the roomba to wake it up from sleep.
    """
    for i in range(3):
        brc.value = False
        time.sleep(0.5)
        brc.value = True
        time.sleep(0.5)
        brc.value = False
        time.sleep(0.5)


def command_received(led):
    for i in range(3):
        time.sleep(0.25)
        led.value = False
        time.sleep(0.25)
        led.value = True
        time.sleep(0.25)
        led.value = False


# base board
print("Intializing board")
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
bot = busio.UART(board.TX, board.RX, baudrate=115200)
# pin out to the BRC pin on the Open Interface
brc = digitalio.DigitalInOut(board.A1)
brc.direction = digitalio.Direction.OUTPUT

# radio
print("Initializing radio")
cs = digitalio.DigitalInOut(board.RFM9X_CS)
reset = digitalio.DigitalInOut(board.RFM9X_RST)
rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 433.0)

# external observation
print("Signal to the outside world")
led = digitalio.DigitalInOut(board.D13)
led.direction = digitalio.Direction.OUTPUT
led.value = True

rfm9x = adafruit_rfm9x.RFM9x(spi, cs, reset, 433.0)

bot = OpenInterface(board.TX, board.RX, digitalio.DigitalInOut(board.A1))
bot.wake_up()


while True:
    # Wait for a packet to be received (up to 0.5 seconds)
    packet = rfm9x.receive(0.5)

    if packet is not None:
        packet_txt = str(packet, "ascii")

        if packet_txt == "0":
            bot.stop()
            led.value = False
        elif packet_txt == "1":
            led.value = False
            bot.start()
            led.value = True
        else:
    try:
        print("receiving")
        # Time to wait (in seconds) for a packet to be received
        # We could go faster, but in this scenario it's not needed
        packet = rfm9x.receive(1)

        if packet is not None:
            packet_txt = str(packet, "ascii")
            print(packet_txt)

            if packet_txt == "0":
                command_received(led)
                led.value = True
                stop(bot)
                led.value = False
            elif packet_txt == "1":
                command_received(led)
                wake_up(brc)
                start(bot)
                led.value = True
            else:
                print("\nUnknown packet: {}\n".format(packet_txt))
    # from time to time we can get corrupted packets
    # instead of hanging or completely exiting pass
    # on the errors and restart the loop listening
    # for the next signal
    except:
        pass