Micropython - jak przekazywać wartości z przerwania

0

Nie mam dużego doświadczenia w programowaniu. Proszę więc o wyrozumiałość jeśli popełniam jakiś głupi błąd w rozumowaniu.
W obsłudze interfejsu Bluetooth wykorzystuję przerwanie. Wg. informacji z tego artykułu https://www.tutorialsteacher.com/articles/how-to-pass-value-by-reference-in-python zwykłe podstawienie nie kopiuje wartości. W większości przypadków nie ma to znaczenia ale chyba nie w przerwaniu. W kodzie poniżej zmienna x na zewnątrz przerwania będzie ulegała zmianie. W jaki sposób prawidłowo przekazać coś z przerwania ?

def irq(y):
    global x
    global z
    if z==False:
        x=y
        z=True
        
while True:
    print(x)
    sleep(1)
0

Wywołujesz gdzieś w ogóle funkcję irq? Masz pętlę nieskończoną i nie wywołujesz funkcji.

1

W jaki sposób prawidłowo przekazać coś z przerwania ? Co masz na myśli? Jak na razie masz nieskończoną pętlę.

4

@szafran98: @ledi12 Wasze komentarze nie mają sensu w świecie embedded. Standardem jest pętla nieskończona (żeby mikrokontroler żył) i specyficznie nazwane funkcje, które przez atrybut lub jakąś konwencję czekają na przerwanie.

Nie widziałem w życiu micropythona, a ten post jest tylko po to, żeby zwrócić uwagę, że nie mówimy o "normalnym" Pythonie. Liczy się kontekst.

0

Przerwanie wywołuje system kiedy pojawi się jakieś zdarzenie związane z interfejsem Bluetooth. Np. włączam skanowanie BLE. Powoduje to wywoływanie irq gdy odebrana zostanie ramka rozgłoszeniowa (znalezione zostanie urządzenie Bluetooth). Przerwanie może zostać wywołane również z 30 innych przyczyn. Do przerwania przez system przekazywane są dwa parametry. Numer (rodzaj) zdarzenia i tablica z danymi (różnymi w w zależności od typu zdarzenia). Zalecenie jest aby w przerwaniu umieszczać jak najmniej kodu tak aby zdążył się on wykonać. Trzeba więc jakoś dane pojawiające się w przerwaniu przekazać do pozostałej części kodu. Zapewne istnieje jakiś mechanizm, który nie powoduje problemów jakie zasygnalizowałem.
W przykładzie jaki podałem stale powinna być wyświetlana ta sama wartość. W rzeczywistości tak nie jest. Zmienne x i y mają ten sam wskaźnik. Jeśli w kolejnym wywołaniu przerwania zmieni się wartości y to automatycznie zmieni się też wartość x

0

Zalecałbym wykorzystanie jakiejś formy kolejki i w każdym wywołaniu handlera przerwania wrzucasz nową wartość do kolejki a po stronie głównej procedury wypisującej odbierasz te wartości z kolejki i wyrzucasz na ekran. Jeśli piszesz to pod FreeRTOS-em to tam zdaje się były jakieś kolejki dostępne.

0

Użyłem heapq i wygląda, że wszystko działa jak trzeba.
Dziękuję za pomoc.

0

Niestety problem nadal występuje. W przerwaniu wyświetlam ID wartości i dodaję ją do kolejki
W pozostałej części programu też wyświetlam ID pobranych wartości. Wszystkie mają takie samo ID.

while True:
    while len(ScanData)<2:
        pass
    d=heapq.heappop(ScanData)
    print("id2:",id(d))
    e=heapq.heappop(ScanData)
    print("id3:",id(e))

W przerwaniu zamiast bezpośrednio dodać do kolejki obiekt data przekształciłem go i teraz każdy element kolejki ma już inny id.

 _, addr, _, rssi, adv_data=data
 heapq.heappush(ScanData,[addr,rssi,adv_data])

Jednak w pozostałej części programu np. addr w każdym elemencie tablicy ma taki sam Id. Więc nadal nic nie osiągnąłem

while True:
    while len(ScanData)<2:
        pass
    addr,rssi,adv_data=heapq.heappop(ScanData)
    print(id(addr))
    addr1,rssi,adv_data=heapq.heappop(ScanData)
    print(id(addr1))
0

Nie znam pythona ani tym bardziej micropythona, ale w twoim kodzie chyba należy założyć, że heap.heappop jest blokujący i czeka tak długo aż jakieś dane nie przyjdą - wtedy proces/wątek odbierający zostanie obudzony. Bo jak inaczej? Wtedy musiałbyś sprawdzać jakoś status tej metody - czy odebrano dane jakieś czy nie. Średnio podoba mi się ta druga pętla while. Czy to jest busy-loop? Czy len() zwraca ilość elementów w kolejce? Jak dużą masz tę kolejkę - na ile elementów?

0

Problemem nie jest blokowanie, kolejka itp. tylko mechanizm opisany w linku jaki podałem. Metodą prób i błędów udało mi się zmusić skrypt aby w przerwaniu przy każdym wywołaniu tworzona była nowa kopia obiektu/zmiennej. To spowodowało, że całość działa prawidłowo. Przy pisaniu programów w językach takich jak Python zwykle nikt nie zastanawia się jak zapisywane są poszczególne zmienne w pamięci RAM co dokładnie się dzieje gdy wykonywane jest podstawienie a=b.

1 użytkowników online, w tym zalogowanych: 0, gości: 1