Skocz do zawartości

Problem z poprawnym odczytem max. min. analogowego pada. Micropython micro:bit


Pomocna odpowiedź

Witam,

Uczę się dopiero programowania i chciałbym spytać kolegów z większym doświadczeniem o zdanie.

Jestem na etapie odczytywania wartości analogowego pada w micropythonie na platformie micro:bit.

Czy można skrócić ten kod ? Zależy mi na ustaleniu i zapisaniu ( do późniejszego użycia ) w tym kodzie pozycji zero joystick-a, oraz pozycji maks. i min. dla każdej z osi aby potem w programie prawidłowo pozycjonować serwo na podstawie ustalonych zakresów. 

Jak zmapować poznane zakresy wychyłu pada na pełny zakres wychyłu serva ? Jest jakaś funkcja w micropythonie. Zaznaczam, że jeszcze nie szukałem. Na razie borykałem się z tym programem.

Dziękuję wszystkim za ewentualne sugestie i pomoc. Jeżeli stosuję gdzieś złe praktyki programowania proszę o napisanie. Człowiek uczy się na błędach 🙂

linie "print" i "sleep" w pętlach wew. są tylko dla kontroli co mam akurat w zmiennych.

 

from microbit import *

max_x = 0
max_y = 0
min_y = 0
min_x = 0
zero_y = int(pin0.read_analog())
zero_x = int(pin1.read_analog())

while True:
    click = pin2.read_digital()
    while not(click):

        value = pin0.read_analog()

        while value > zero_y and value > max_y:
            max_y = value
            print(str(max_y))
            sleep(100)
            min_y = max_y/2

        while value < zero_y and value < min_y:
            min_y = value
            print(str(min_y))
            sleep(100)
        
        value = pin1.read_analog()
        
        while value > zero_x and value > max_x:
            max_x = value
            print(str(max_x))
            sleep(100)
            min_x = max_x/2

        while value < zero_x and value < min_x:
            min_x = value
            print(str(min_x))
            sleep(100)
        click = pin2.read_digital()
    break

print('min x: '+str(min_x)+' max x: '+str(max_x))
print('min y: '+str(min_y)+' max y: '+str(max_y))
print('zero x: '+str(zero_x)+' zero y: '+str(zero_y))
sleep(100)

 

Link to post
Share on other sites

A mógłbyś opisać co twoim zdaniem ten kod ma robić, tak linijka po linijce? Bo jest co najmniej dziwny i trudno zgadnąć co poszło nie tak.

Link to post
Share on other sites
(edytowany)

To co robi na tą chwilę. Podpiąłem do micro:bit-a taki Joystick. Ale mam jeszcze kilka innych i każdy z nich ma inny zakres wartości w min. i maks. wychyleniu gałki w osi X i Y. Ten program ma być taką powiedzmy " kalibracją " posiadanych joystick-ów. Oś Y jest podpięta do pin0 w micro:bit, oś X do pin1 w microbit, a przycisk do pin2. Po uruchomieniu programu program określa pozycję "neutral" ( zero ) joystick-a i zapisuje w zmiennych zero_x i zero_y. Pierwsza i druga pętla wew. while, mam za zadanie, przy maksymalnym i minimalnym wychyleniu gałki w osi Y odczytać i zapisać min. i maks. wartość odczytaną na pin0 i zapisać w zmiennych min_y i max_y. Analogicznie z osią X trzecia i czwarta pętla ma to samo zadanie tylko w osi X i zapis w zmiennych max_x i min_x.

W ten sposób otrzymane zakresy wartości wychyłu i pozycji neutral, chciałbym przełożyć na wartości pracy takiego serwo i przesłać je bezprzewodowo do drugiego microbita w celu wychylenia obu serw. Ma to sterować wskaźnikiem laserowym dla kota 🙂

lub każdym innym mechanizmem który zbuduję na serwach.

Mam to wykonywać podobną funkcję jak na załączonym filmiku ( zrobiłem przemieszczanie pixelem na ekranie ) tylko bardzo dokładnie.

Edytowano przez maniackk
Link to post
Share on other sites
16 minut temu, maniackk napisał:

Pierwsza i druga pętla wew. while, mam za zadanie, przy maksymalnym i minimalnym wychyleniu gałki w osi Y odczytać i zapisać min. i maks. wartość odczytaną na pin0 i zapisać w zmiennych min_y i max_y.

Problem w tym, że wewnątrz tych pętli nic nie odczytujesz — odczyt robisz raz, na zewnątrz pętli, a potem tylko dzielisz go przez 2 aż się pętla nie skończy. Trochę mnie to zmyliło, muszę przyznać.

Link to post
Share on other sites
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Masz rację. Źle się wyraziłem, pętle służą tylko określeniu skrajnych wartości wychylenia pada i zapisaniu ich.

Postarałem się opisać kod i trochę go poprawiłem, bo faktycznie nie ma sensu przypisywać w pętli za każdym razem zmiennym min_x i min_y wartości maksymalnej skoro mam tą wartość w zmiennych "zero". Dodałem też opisy żeby było wiadomo co miałem na myśli.

Tak jak pisałem chciałbym używać tego kodu jako funkcji, w różnych moich projektach dla różnych joystick-ów. To ma być taka pseudo "kalibracja" systemu sterowania bez ręcznego sprawdzania w konsoli.

Dlatego zależy mi na mały i jak najprostszym kodzie. Micro:bit niestety nie grzeszy ilością pamięci.

Da się to uprościć twoim zdaniem ? Albo zrobić w inny sposób ?

from microbit import *

min_x = 0                          # deklaracja zmiennych przechowujących zakresy wartości odczytywanych na osi X joysticka
max_x = 0                          
min_y = 0                          # deklaracja zmiennych przechowujących zakresy wartości odczytywanych na osi Y joysticka
max_y = 0

zero_x = int(pin1.read_analog())   # zapisanie w zmiennej pozycji neutralnej osi X. Potencjomter jest podpięty do pin1
zero_y = int(pin0.read_analog())   # zapisanie w zmiennej pozycji neutralnej osi Y. Potencjomter jest podpięty do pin0
min_x = zero_x                     # wstępne ustalenie wartości zmiennej dla pętli szukającej stanu min osi X
min_y = zero_y                     # wstępne ustalenie wartości zmiennej dla pętli szukającej stanu min osi y 

while True:
    click = pin2.read_digital()        # zapisanie w zmiennej stanu nacisnięcia przycisku w joysticku. Switch jest podpięty do pin2
    while not(click):                  # wykonuj pętlę dopóki nie wciśnięto przycisku w joysticku.

        value = pin0.read_analog()     # zapis w zmiennej wartości odczytanej przy wychyleniu joysticka w dowolnym kierunku osi Y

        while value > zero_y and value > max_y:  # jeżeli joystick wychylono w górę ( zakres od zero_y do ??? ) i wartość
            max_y = value                        # zmiennej value jest większa od aktualnej wartości zapisanej max_y
                                                 # aktualizuj wartość zmiennej max_y
                                                 # w ten sposób ustalam maks. wartości osi Y dla podłączonego joysticka

        while value < zero_y and value < min_y:  # jeżeli joystick wychylono w dół ( zakres ??? do zero_y ) i wartość
            min_y = value                        # zmiennej value jest mniejsza od aktualnej wartości zapisanej min_y
                                                 # aktualizuj wartość zmiennej min_y
                                                 # w ten sposób ustalam maks. wartości osi Y dla podłączonego joysticka

        value = pin1.read_analog()               # zapis w zmiennej wartości odczytanej przy wychyleniu joysticka w dowolnym kierunku osi X

        while value > zero_x and value > max_x:  # analogicznie jak przy osi Y i zmiennej max_y
            max_x = value
            

        while value < zero_x and value < min_x:  # analogicznie jak przy osi Y i zmiennej min_y
            min_x = value
            
        click = pin2.read_digital()              # zapisanie w zmiennej stanu nacisnięcia przycisku w joysticku. Switch jest podpięty do pin2
    break                                        # przerwanie wykonywania pętli głównej

print('min x: '+str(min_x)+' max x: '+str(max_x))      # wypisanie w konsoli pełnego zakresu wartości dla osi X i Y oraz pozycji neutral 
print('min y: '+str(min_y)+' max y: '+str(max_y))
print('zero x: '+str(zero_x)+' zero y: '+str(zero_y))
sleep(100)

 

Link to post
Share on other sites

Dobra, to bardzo pomaga. W zasadzie teraz kod jest dobry, ale można go jeszcze trochę poprawić:

  • zamiast pętli "while" powinieneś używać instrukcji "if" dla wewnętrznych warunków
  • zamiast używać zmiennej "click", możesz odczytywać stan pinu od razu w warunku pętli: while not pin2.read_digital(): ...
  • jeśli początkowe wartości dla max/min_x/y ustawisz, zamiast na 0, na zero_x/y, to możesz się pozbyć pierwszej części w każdym z warunków
  • możesz użyć operatora % do formatowania stringów, zamiast robić +str(...)+, poszukaj w jakimś tutorialu do pythona jak
Link to post
Share on other sites

Dzięki za zwrócenie uwagi na te kilka rzeczy. Poprawiłem kod i faktycznie działa super i jest mały.

Tylko nie rozumiem jednej rzeczy. Po modyfikacjach zmieniły się zakresy wartości zakresów obu osi i pozycja neutral.

Wcześniej neutral miał wartości  X: 498 Y: 511 ; Zakres X 4 - 1023; Zakres Y 4 - 1023; 

Teram mam neutral X: 400 Y: 409 ; Zakres X 4 - 824; Zakres Y 4 - 824;

O co chodzi ? Nie kumam. Na dole dołączyłem zrzut ekranu.

from microbit import *

min_x = max_x = zero_x = int(pin1.read_analog())
min_y = max_y = zero_y = int(pin0.read_analog())

while True:
    
    while not pin2.read_digital():

        value = pin0.read_analog()

        if value > max_y:
            max_y = value
        elif value < min_y:
            min_y = value
         
        value = pin1.read_analog()

        if value > max_x:
            max_x = value
        elif value < min_x:
            min_x = value
            
    break

print('min x: %s  max x: %s ' % (min_x, max_x))
print('min y: %s  max y: %s ' % (min_y, max_y))
print('zero x: %s  zero y: %s' % (zero_x, zero_y))
sleep(100)

 

po_zmianach.jpg

Link to post
Share on other sites

Zagadka rozwiązana.

Tamte zakresy miałem dla zasilania Joystick-a napięciem 3,3V na karcie rozszerzeń, a pod servo zmieniłem napięcie na 5V no i zmieniły się wartości.

Biorę się za serwa.

Znasz może jakiś fajny tutorial do pobawienia się serwer na micro:bit w micropythonie. Znalazłem kilka na ich forum, ale nie do końca je rozumiem. Dla serwa też chciałbym napisać funkcję sprawdzającą pełny zakres jego pracy, ale nie bardzo wiem od czego zacząć.

Link to post
Share on other sites

Uważaj! Micro:bit jest urządzeniem 3.3V i jak mu podłączysz 5V do pinów, to prędzej czy później się coś spali.

Co do serw, to nie ma wielkiej filozofii — ustawiasz częstotliwość PWM na 50Hz i dajesz duty cycle 1500ms +/- ~700ms — zależy od konkretnego serwa i jego mechanicznej konstrukcji. Bawiłem się tym na micro:bicie dawno temu, tu masz przykład mojego kodu: https://hackaday.io/project/19936-marvin

Link to post
Share on other sites

Ok, będę zwracał uwagę na te napięcie. A do tego serwa mam Hextronik-a HXT900 i jakieś chińskie badziewie z kupionego KIT-u 9G. Mam do obu datasheet

Tylko nie rozumiem czemu piszą w manualu, że ten Hextronic mam 90st. Jak kręce ośką to wyraźnie jest 180st. ? Podają od pozycji zerowej w jedną stronę czy co ?

A jest metoda map do pinów w micropython. Po prostu pins.map(millig, -1023, 1023, 0, 180). Mam już wzór, ale fajnie, że jest.

Na marginesie, fajny robocik 🙂 👍

 

Link to post
Share on other sites
2 godziny temu, maniackk napisał:

Tylko nie rozumiem czemu piszą w manualu, że ten Hextronic mam 90st. Jak kręce ośką to wyraźnie jest 180st. ? Podają od pozycji zerowej w jedną stronę czy co ?

90° jest gwarantowane, przy zakresie od 1000ms do 2000ms — reszta jest w bonusie i zależy od konkretnej sztuki serwa, nie gwarantowane przez producenta.

  • Lubię! 1
Link to post
Share on other sites

Dzięki za wyjaśnienie. Tylko doprecyzuj proszę. Mam mało do czynienia z serwomechanizmami. Czy to chodzi o to, że w zakresie od - 45st.  do 45st. producent gwarantuje dokładność zachowania kątów ? Np. powrót zera jest zawsze w tą samą pozycję bez przesunięć ?

 

Link to post
Share on other sites

Zakres 90° ma praktycznie każde serwo modelarskie i taki jest standard. Ale nie ma powodu, żeby sztucznie ograniczać ten zakres, więc większość serw będzie działać z większym zakresem — tylko każde z innym i nie ma na to gwarancji.

Powrót zawsze będziesz mieć do zera tak samo, chyba, że jest uszkodzony potencjometr w serwie. Dokładność zachowania kątów jest żadna niezależnie od zakresu — jak potrzebujesz dokładne kąty, to każde serwo musisz sobie sam skalibrować.

Link to post
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.