ESP32 i klon Dual shock przez BT.

Przez nieuwagę kupiłem Pada BigBen RFLX BB5152 (PS3) myśląc, że podłączę go do interfejsu TOM2 (liczyłem na to, że będzie działał lepiej od Logitecha F710). Niestety w obecnie dostępnej wersji ten pad jest tylko na bluetooth, więc nie będzie działał wcale.

A gdyby tak przez bluetooth z ESP32 podłączyć pada z PS3 do Atari? 🙂

https://github.com/greblus/esp32_ps3_bt_pad

Może się uda. W projekcie Usb Host Shield dla Arduino autor obsługuje nawet czujniki ruchu, więc jest się od kogo uczyć.

Reklamy

Szeregowanie kooperacyjne w Micropythonie na ESP8266.

Ku mojemu zdziwieniu Micropython na esp8266 nie obsługuje wątków, a potrzebna mi była funkcja „sleep()”, która będzie się wykonywać równolegle do głównego wątku. Dziwne to, bo z FreeRTOS SDK wątki ponoć działają, choć całkiem możliwe, że kosztują zbyt wiele cennych zasobów potrzebnych Micropythonowi do życia. Znalazłem też info, że wynika to z ograniczeń zestawu instrukcji procesora. Cóż, FreeRTOS działa super na esp32 i niech tak zostanie. Niestety bez wątków funkcja zawłaszcza procesor licząc czas w pętli i jak chciałoby się wcześniej zasterować podłączonymi do esp8266 ustrojstwami, to trzeba by to zrobić manualnie ;). Na szczęście dostępna ilość pamięci pozwala na użycie modułu uasyncio i nieblokujących się socketów, bo to też istotne jeśli chcemy obsługiwać sprzęt przez requesty http typu <adres_ip>/onoff czy <adres_ip>/sleep=czas. Jedyny minus, to upip, którym nie zainstalujemy uasyncio ze względu na zbyt małą ilość pamięci. Trzeba to zrobić ręcznie.

import network
import usocket as socket
import errno

sta_if = network.WLAN(network.STA_IF)
addr = socket.getaddrinfo(sta_if.ifconfig()[0], 8000)[0][-1]
s = socket.socket()
s.setblocking(False)
s.bind(addr)
s.listen(1)
print('listening on', addr)

import machine
pin = machine.Pin(5, machine.Pin.OUT)
status = True; timeout = None
pin.value(status)

import uasyncio as asyncio
loop = asyncio.get_event_loop()

async def sleep(newtm):
    global status, timeout
    if timeout == newtm:
        return
    if timeout != None:
        timeout = newtm
        return
    else:
        timeout = newtm
    while timeout > 0:
        await asyncio.sleep(60)
        timeout = timeout - 60
    status = False; timeout = None
    pin.value(status)

async def worker():
    global status
    while True:
        line = None
        try:
            cl, addr = s.accept()
            print('client connected from', addr)
            cl_file = cl.makefile('rwb', 0)
            while not line:
                line = cl_file.readline()
        except OSError as exc:
            if exc.args[0] in [errno.ETIMEDOUT, errno.EAGAIN]:
                await asyncio.sleep(0)
                continue
        print(line, status)
        if 'onoff' in line:
            status = not status
            pin.value(status)
        if 'sleep' in line:
            s1 = line.find(b'sleep')+6
            s2 = line.find(b'H')-1
            try:
                timeout = int(line[s1:s2])
                loop.create_task(sleep(timeout*60))
            except ValueError:
                print('/sleep needs a numeric timeout')
        cl.close()

loop.create_task(worker())
loop.run_forever()

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

Ten sam skrypt na esp32 z użyciem _thread. Esp32 to już jednak potężna bestia, z ogromną ilością pamięci, zwłaszcza z PSRAM na pokładzie, oraz sporym zapasem mocy procesora dual-core ;).