Fi-BOT na PyStok-u

W dniu 21.05.2025 r. braliśmy udział w comiesięcznym spotkaniu miłośników programowania w języku python. Co mamy wspólnego z pythonem? Niewiele 😉 Ale tematyką główną było programowanie elektroniki – hobbystyczne roboty i drony. Skorzystaliśmy z zaproszenia i było super! Plan 73 edycji PyStoka był następującY:

  • Roboty Sztucznie Inteligentne – Nikodem Bartnik
  • Drony, Python vs Podstawa programowa – Adam Jurkiewicz;
  • Zgarnij książki, licencje Jetbrains oraz Rpi Pico 2 W;
  • After Party + pizza party;

A w licznym tłumie nasi Fi-BOTciarze 😉

PyStok to Białostocka Grupa Użytkowników Pythona organizująca comiesięczne spotkania.

Światłolub: OCZY – dobór rezystora do dzielnika napięcia – OCZYWISTY?

Światłolub ma oczy… fotorezystory! Ale Arduino nie odczytuje rezystancji, tylko napięcia. Dlatego wykorzystujemy dzielnik napięcia według schematu:

Analizujemy prosty dzielnik napięcia, wykorzystywany do odczytu wartości z czujnika za pomocą Arduino. Napięcie odczytywane na pinie A0 będzie dane wzorkiem V_A0 (kolor czarny na obrazku powyżej). Celem jest znalezienie takiej wartości rezystora stałego (R_fixed), która zapewni najlepsze rozróżnienie między warunkami jasnymi a ciemnymi, tak aby Arduino mogło najlepiej wykrywać różnicę. Chcemy:

  • Zmierzyć opory R_foto w warunkach jasnych i ciemnych – miernik (multimetr)
  • Obliczyć V_A0 dla różnych wartości R_fixed w dwóch przypadkach: jasno i ciemno
  • Określić różnicę napięć (ΔV)
  • Przeskalować tę różnicę do zakresu analogRead() Arduino (0–1023)
  • Narysować odpowiednie wykresy, aby określić, która wartość rezystora działa najlepiej

Mierzymy opór czujnika w warunkach jasnych i ciemnych – następnie definiujemy stałe: napięcie wejściowe (5V) oraz opór czujnika w warunkach jasnych i ciemnych warunkach.

import matplotlib.pyplot as plt
# Stałe
V_in = 5 # Napięcie wejściowe w woltach
R_sensor_light = 60 # Opór czujnika w jasności (kiloomy)
R_sensor_dark = 180 # Opór czujnika w ciemności (kiloomy)

Przygotowujemy tablice (czyli listy w języku Python) do przechowywania wyników dla każdej testowanej wartości rezystora.

# Listy do przechowywania wyników
R_fixed_values = list(range(1, 1000))
V_out_light_values = []
V_out_dark_values = []
delta_V_values = []

Przechodzimy pętlą przez wartości R_fixed (od 1 do 999 kiloomy) i obliczamy:

  • Napięcie wyjściowe, gdy czujnik jest w jasności (V_out_light)
  • Napięcie wyjściowe, gdy czujnik jest w ciemności (V_out_dark)
  • Różnicę napięć między tymi dwoma wartościami (delta_V)

for R_fixed in R_fixed_values:
V_out_light = V_in * (R_sensor_light / (R_sensor_light + R_fixed))
V_out_dark = V_in * (R_sensor_dark / (R_sensor_dark + R_fixed))
delta_V = V_out_dark - V_out_light
V_out_light_values.append(V_out_light)
V_out_dark_values.append(V_out_dark)
delta_V_values.append(delta_V)

Znajdujemy taką wartość R_fixed, która daje największą różnicę napięć (ΔV). Oznacza to, że czujnik będzie w tym punkcie najbardziej „czuły”.

# Szukanie optymalej wartości R_fixed (maksymalna delta_V)
max_delta = max(delta_V_values)
max_delta_index = delta_V_values.index(max_delta)
optimal_R = R_fixed_values[max_delta_index]

Rysujemy napięcie wyjściowe dla warunków jasnych i ciemnych oraz „cieniujemy” obszar między dwiema funkcjami napięcia. To pokazuje w którym miejscu i jak bardzo zmienia się sygnał z czujnika.

# Wykres 1: V_out dla jasności i ciemności
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, V_out_light_values, '--b', label='V_out (Jasność)')
plt.plot(R_fixed_values, V_out_dark_values, '--r', label='V_out (Ciemność)')


# Wypełnienie obszaru między dwiema krzywymi
where_condition = [dark > light for dark, light in zip(V_out_dark_values, _out_light_values)]
plt.fill_between(R_fixed_values, V_out_light_values, V_out_dark_values,where=where_condition,color='gray', alpha=0.3, label='Obszar ΔV')
plt.title('Napięcie wyjściowe dzielnika w warunkach jasnych i ciemnych')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('V_out (V)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Rysujemy różnicę napięć (ΔV) i zaznaczamy rezystor, który daje największe rozdzielenie sygnału

# Wykres 2: ΔV z zaznaczoną optymalną wartością R_fixed
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, delta_V_values, color='red', label='ΔV (Jasność - Ciemność)')
plt.axvline(optimal_R, color='gray', linestyle=':', label=f'Optymalne R_fixed = {optimal_R} kΩ')
plt.scatter([optimal_R], [max_delta], color='black', zorder=5)plt.text(optimal_R + 10, max_delta, f'Max ΔV ≈ {max_delta:.2f} V\nprzy R = {optimal_R} kΩ', fontsize=9)
plt.title('Różnica napięć (ΔV) w zależności od R_fixed')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('ΔV (V)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Mapujemy różnicę napięć ΔV do skali analogRead() Arduino (0–1023)

# Szukanie najlepszej wartości R_fixed pod względem różnicy odczytu ADC
delta_ADC_values = [(v / V_in) * 1023 for v in delta_V_values]
max_delta_ADC = max(delta_ADC_values)
max_adc_index = delta_ADC_values.index(max_delta_ADC)
optimal_R_adc = R_fixed_values[max_adc_index]

Rysujemy ΔV przeskalowaną do zakresu analogRead oraz zaznaczamy rezystor dający największą różnicę odczytu cyfrowego

# Wykres ΔADC
plt.figure(figsize=(10, 5))
plt.plot(R_fixed_values, delta_ADC_values, color='purple', label='ΔADC (przeskalowane z ΔV)')
plt.axvline(optimal_R_adc, color='gray', linestyle=':', label=f'Optymalne R_fixed = {optimal_R_adc} kΩ')
plt.scatter([optimal_R_adc], [max_delta_ADC], color='black', zorder=5)
plt.text(optimal_R_adc + 10, max_delta_ADC, f'Maks. ΔADC ≈ {max_delta_ADC:.0f}\nprzy R = {optimal_R_adc} kΩ', fontsize=9)
plt.title('Różnica odczytu analogRead (ΔADC) w zależności od R_fixed')
plt.xlabel('R_fixed (kiloomy)')
plt.ylabel('ΔADC (0–1023)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()

Wyświetlamy optymalną wartość rezystora dla skali Arduino, gdzie różnica odczytów analogRead() jest największa.

print(f"Optymalne R_fixed = {optimal_R_adc} kΩ, przy którym maks. ΔADC ≈ {max_delta_ADC:.0f}")
Optymalne R_fixed = 104 kΩ, przy którym maks. ΔADC ≈ 274

(c) Przemysław Baj, K.G. 2025

Światłolub – (znowu) programowanie

Trwa szlifowanie kodu… a raczej tworzenie go tak, by działał poprawnie 😉 Okazuje się bowiem, że w różnych miejscach testowanej podłogi jest różne oświetlenie (zastane) – o dziwo! 😀 Wbite na sztywno wartości odczytane z czujników nie pracują 😉 Na tym właśnie polega ta zabawa! Rozwiązanie? aktualizować światło zastane co 1s? Tak działa jeden zespół. Drugi kombinuje z hardware – wprowadza jakąś przeszkodę blokującą światło zastane – ciekawe, co z tego wyjdzie.

Zawody

Jeśli sterowanie będzie działać, to sprawdzimy to w ekstremalnej sytuacji- postawimy dwie przeszkody, będzie trzeba je objeżdźać – kręcąc tzw. ósemki. Zmierzymy czas trzech okążeń i się okaże, który zespół jest lepszy 😉

(c) K.G. 2025

pre-KRON 2025

Przedłużone zostały zapisy do wydarzenia-konkursu „pre-KRON 2025”, które odbędzie się 29 kwietnia 2025 roku, o godzinie 17:00, w sali C02 Wydziału Nauk o Edukacji UwB.

Pre-KRON 2025 to konkurs, w którym zmierzyć się mogą koła naukowe, działające na Uniwersytecie w Białymstoku. Formuła jest prosta – każde koło ma do dyspozycji 10 minut. W ich trakcie ma za zadanie przedstawienie jakiejś naukowej treści w przystępnej, kreatywnej i innowacyjnej formie.


Śmieszna prezentacja z kotami? Tak!
Skecz? Może być.
Krótkie przedstawienie? Czemu nie!
Koła ograniczone są wyłącznie przez własną wyobraźnię. A, no i oczywiście przez czas!

Tematem tegorocznego KRONu jest: „pochodzenie – wstyd czy mit?”. I to właśnie do tego hasła powinny w luźny sposób nawiązywać prezentacje.

Trzy najlepsze prezentacje – wyboru dokona jury wraz z publicznością – zostaną nagrodzone dotacjami ze środków Parlamentu Studenckiego (za I miejsce – aż 1200 złotych!). Wystąpią także na tegorocznym KRONie.

Zgłoś się i daj sobie szansę!

Zapisy trwają do 18 kwietnia.

Formularz zgłoszeniowy: https://forms.gle/DTwoKdNLBtdJu84AA
Regulamin: https://docs.google.com/document/d/1qvTP87n2eJnkLmRQCPJbSzrY3qU0BY8Cw5rBT_crDKs/edit?usp=drivesdk

(c) K.G. 2025

Dni Otwarte UwB

15-04-2025

Odbyły się Dni Otwarte UwB – członkowie koła Fi-BOT dzielnie uczestniczyli w wydarzeniu. Prezentowali grę REFLEX (Arduino) oraz silniki DC (mostek H, układ L298N).

(c) K.G. 2025

Światłolub – programowanie

komunikacja I2C i hd44780

Aby widzieć odczyty z fotorezystorów wykorzystujemy ekran LCD16x2 — nie chcemy jednak tracić cennych portów cyfrowych (chyba trzeba użyć 7-miu do obsługi), więc stosujemy moduł I2C hd44780.

testy, testy, testy…

Czyli najprzyjemniejsza część zabawy – prototyp już mamy, teraz trzeba go mądrze oprogramować. Zaczynamy!

Trzeba odczytać wskazania obu fotorezystorów gdy światło jest przed pojazdem, z jednego boku, z drugiego… Zapisać do notepada.exe by następnie wpisać w ino 🙂

Kiszka. Stoi. Albo kręci się nie w tą stronę, co trzeba. A niby miało działać 😛 więc znowu do kompa i wprowadzamy zmiany w kodzie /w parametrach.

Nawet kłótni nie było 🙂 nikt nie zrzucał winy na drugiego – nie działa dobrze, więc trzeba poprawić! Świetny team-work !

Zawody

Za tydzień kody będą już dopieszczone, więc będzie można przystąpić do sprawdzenia algorytmów w akcji – postawimy dwie przeszkody, będzie trzeba je objeżdźać – kręcąc tzw. ósemki. Zmierzymy czas trzech okążeń i się okaże, który zespół jest lepszy 😉

(c) K.G. 2025

Młodzieżowe Podlaskie Lokalne – dofinansowanie

Wystartował projekt konkursowy Młodzieżowe Podlaskie Lokalne – jest możliwość uzyskania dofinansowania w kwocie 2000 – 6000 zł na projekt samorządów studenckich i doktoranckich, uczelnianych organizacji studenckich i doktoranckich (np. kół naukowych, chóru itp.).

Próbujemy! The Mecanum Mavericks

Ostatnio budujemy pojazdy sterowane latarką… ale czemu nie spróbować czegoś bardziej atrakcyjnego? Niech to dalej będzie „światłolub” ale z ciekawszą mechaniką ruchu? Chcemy kupić koła mecanum, dzięki czemu pojazdy będą poruszać się dość nietypowo 😉

Taki projekt można świetnie rozbudowywać – dodawać inny rodzaj sterowania (radiowe!), a także zrobić z tego zabawę „w berka” – o ile posiadamy dwa takie pojazdy. My wnioskujemy o 5 zestawów i planujemy… sza, cicho-sza 😉 Zobaczymy 😉

Aktualizacja – wyniki konkursu

YYYY, nie udało się. Nasz projekt znalazł się blisko finałowej grupy, nawet został wpisany na listę rezerwowych ale… nie udało się. Cóż – będziemy próbować za rok!

(c) K.G. 2025

Oczy światłoluba

Ciągle budujemy pojazd sterowany latarką – wykorzystamy fotorezystory jako „oczy”. Dziś wracamy do konstrukcji pojazdu i będą pierwsze próby. Ale nie chcemy mieć płytki prototypowej na pokładzie więc… poznajemy lutownicę 😉

Przygotowujemy sobie wielokrotne wyjścia GND i 5V, a także lutujemy rezystor z fotorezystorem w szereg – z dodatkowym przewodem do pinu analogowego Arduino UNO. Wszystko proste, tylko trzeba trochę się pobawić… na tym to chyba polega, prawda? 😉

No i dobrze, że się ucząc się także się bawimy!

Udało się! Oczy skierowane są na podłogę (trochę za bardzo) więc rozpoczyna się faza testowa oprogramowania – część „hardwareowa” chwilowo zakończona.

(c) K.G. 2025

fotorezystor – oczy światłoluba

Czyli budujemy pojazd sterowany latarką – wykorzystamy fotorezystor jako „oczy”. Czyli muszą być dwa, aby porównywać ilość światła z jednego czujnika i drugiego i na tej podstawie jechać do przodu, zatrzymywać się czy skręcać. Niby proste – choć cała magia tkwi w odpowiednim doborze parametrów decyzyjnych.

analogRead()

Studenci jeszcze nie mieli omawianej tej funkcji na zajęciach z Arduino – więc zaczynamy od podstaw. Uczymy się więc co mierzymy, jakie są ograniczenia Arduino UNO, sprawdzamy odczyty napięcia 3.3V oraz 5V z płytki Arduino, a także baterie AAA.

Przechodzimy dalej do fotorezytora i uczymy się go najlepiej wykorzystać. Skoro Aruino idczytuje napięcie a nie opór – to wykorzystujemy dzielnik napięcia i odczytujemy napięcie. Ale jaka wartość stałego rezystora w dzielniku dla naszego fotorezystora? Testujemy z wykorzystaniem thinkercada!

Dziś bez podłączenia jeżdzącej platformy – to będzie za tydzień!

(c) K.G. 2025

dwa kółka

Kontynuujemy przygodę z L298N – tym razem podłączamy dwa kółka do tymczasowej platformy (udającej podwozie pojazdu). Trzeba się „namęczyć” tworząc konstrukcje prototypową, być kreatywnym i wykorzystywać to, co się ma w zasięgu ręki 😉

Konstrukcje gotowe więc programujemy – zaczynamy od Arduino UNO. Bardzo prymitywny kod sterujący kołami: 1 sek jazdy do przodu, skręcanie 1 sek i tak powtarzane w kółko.

Skoro działa na biurku to… jak działa „w realu”?

Zadowoloenie jest 😉 ale i smuteczek, że pojazdy nie są sterowane… wykonują najprostrze czynności, wcześniej zaplanowane. Dlatego podjeliśmy decyzję, że będziemy sterować latarką – czyli budujemy światłoluba 😉 Zamierzamy prowadzić światło latarki przed pojazdem, a pojazd ma podążać za nim. Do dzieła!

(c) K.G. 2025