13.3.1.2. Witaj kamero

Klasa openmv.Camera to punkt wejścia Pythona do wszystkiego, co potrafi pakiet. Każda inna strona w tym samouczku wywołuje na niej operacje. Najmniejszy użyteczny program łączy się, przesyła skrypt MicroPython i wypisuje wszystko, co skrypt zapisuje do stdout

from openmv import Camera

script = """
import time
while True:
    print('hello from the cam')
    time.sleep(1)
"""

with Camera('/dev/ttyACM0') as cam:
    cam.stop()
    cam.exec(script)

    while True:
        if text := cam.read_stdout():
            print(text, end='')

13.3.1.2.1. Kilka uwag

Wywołanie stop() przed exec() nie jest opcjonalne. Bez niego dowolny wcześniej działający skrypt nadal zapisuje do stdout, a nowy exec walczy z nim o kontrolę nad kanałem stdin.

Metoda exec() przesyła łańcuch znaków skryptu do bufora stdin kamery i uruchamia go w tym samym interpreterze MicroPython, z którym komunikuje się IDE. Skrypt importuje csi, image, ml i resztę powierzchni kamery omówionej we wcześniejszych rozdziałach – jedyna różnica polega na tym, że kod źródłowy przychodzi przez USB, zamiast z pliku main.py na kamerze lub z IDE.

13.3.1.2.2. Zatrzymywanie skryptu

Gdy program hosta chce przerwać działający skrypt, wywołuje stop(). Skrypt otrzymuje to samo przerwanie, które dostarczyłoby IDE, i kończy działanie przy najbliższej okazji. Opuszczenie menedżera kontekstu (bloku with) zamyka port szeregowy, ale nie zatrzymuje skryptu – kamera nadal wykonuje to, co ostatnio załadowano, dopóki coś go nie przerwie.

13.3.1.2.3. Błędy i wyjątki

Wszystko, co pójdzie nie tak w warstwie protokołu, zgłasza wyjątek openmv.OMVException lub jedną z jego podklas (TimeoutException, ChecksumException, SequenceException). Owinięcie bloku with w try / except OMVException to najprostszy sposób na wykrycie odłączonego kabla USB lub kamery, która przestała odpowiadać.

Protokół ponawia próby wewnętrznie przed zgłoszeniem wyjątku; zanim OMVException dotrze do aplikacji, budżet ponowień jest wyczerpany, a łącze jest naprawdę zerwane. Wartości domyślne (max_retry=3, timeout=1.0) sprawdzają się u wszystkich – dostrajaj je w konstruktorze tylko wtedy, gdy konkretna aplikacja wymaga innego zachowania.