Skocz do zawartości

Przeszukaj forum

Pokazywanie wyników dla tagów 'arduino'.

  • Szukaj wg tagów

    Wpisz tagi, oddzielając przecinkami.
  • Szukaj wg autora

Typ zawartości


Kategorie forum

  • Elektronika i programowanie
    • Elektronika
    • Arduino i ESP
    • Mikrokontrolery
    • Raspberry Pi
    • Inne komputery jednopłytkowe
    • Układy programowalne
    • Programowanie
    • Zasilanie
  • Artykuły, projekty, DIY
    • Artykuły redakcji (blog)
    • Artykuły użytkowników
    • Projekty - roboty
    • Projekty - DIY
    • Projekty - DIY (początkujący)
    • Projekty - w budowie (worklogi)
    • Wiadomości
  • Pozostałe
    • Oprogramowanie CAD
    • Druk 3D
    • Napędy
    • Mechanika
    • Zawody/Konkursy/Wydarzenia
    • Sprzedam/Kupię/Zamienię/Praca
    • Inne
  • Ogólne
    • Ogłoszenia organizacyjne
    • Dyskusje o FORBOT.pl
    • Na luzie
    • Kosz

Szukaj wyników w...

Znajdź wyniki, które zawierają...


Data utworzenia

  • Rozpocznij

    Koniec


Ostatnia aktualizacja

  • Rozpocznij

    Koniec


Filtruj po ilości...

Data dołączenia

  • Rozpocznij

    Koniec


Grupa


Znaleziono 291 wyników

  1. Witam serdecznie, robię coś "ala inteligentny dom" i brakowało mi gpio na malince. Podłączyłem mcp23017 i działa:) Działa jako wyjście:/ Jak zrobić żeby działało jako wyjście? A takie ważniejsze i chyba trudniejsze pytanie (jak dla mnie) to: Jak połączyć malinkę z arduino przez usb?? tak żeby arduino działało jako we/wy?? Nie liczę na gotowca, ale jakieś wskazówki. Nie jestem też jakimś tam hiper, biper, diker informatykiem. Skoro potrafiłem podłączyć mcp23017 i "ledami mrugać" to myślę że arduino podłączę jako we/wy do malinki;) Pozdrawiam serdecznie;) p.s. Zapomniałem dodać, że to wszystko obsługuję na domoticz.
  2. czy można zrobić takie coś że jak się kliknie na guzik (zamontowany na płytce stykowej taki zwykły kwadratowy takie jak na załączonym obrazku) to np. będzie to równo znaczne z naciśnięciem klawisza A na klawiaturze dziękuję z góry za odpowiedzi
  3. Układ do sterowania 5 silnikami za pomocą USB oraz bluetooth Proszę o sprawdzenie ewentualnie uwagi schemat.zip
  4. Witam chciał bym zaprezentować , drugą "lepszą wersję " kierownicy do komputera opartej na Arduino Leonardo. Film pokazujący jak dziala kierownica i Force Feedback: Jest to wersja elektronicznie taka sama jak poprzednia, wszystko opisane wcześniej link do poprzedniej tutaj : W tej wersji zmieniłem obudowę na znacznie mniejszą , lżejszą , łatwa do zamocowania przy stole, biurku itp. Obudowa została wykorzystana z kupionej przeze mnie za 50 zł kierownicy Logitech Formula Force Ex o obrocie 180* i Force Feedback. Dzięki temu że kierownica miała już przekładnie i ogólnie jest prosta w budowie , bardzo łatwo i tanio można ją przerobić tak aby miala kąt skrętu taki jak ustawimy sobie w programie np 720*,900* i Force Feedback do tego kąta obrotu. Tutaj link do gotowego software na Arduino Leonardo , od razu mówię że na Arduino Uno nie zadziała , link do pobrania w opisie filmu: Ja zrobiłem to tak: Na początku przez środek starej przekładni , dodałem pręt gwintowany o średnicy 10mm ,do którego z jednej strony mocowana jest kierownica, a z drugiej enkoder z drukarki canon ip2770. Aby zamocować enkoder musiałem wyciąć dziure jak widać na zdjęciu poniżej : Aby enkoder nie tarł o blat , dodałem plastikowe podkładki : A tak wygląda już gotowa sama kierownica: Wyjścia enkodera i do silnika , zostały przerobione na standardowych wyjściach które były w kierownicy i wchodzą do dodatkowej skrzynki w której znajduje się reszta elektroniki czyli w sumie tylko Arduino Leonardo i sterownik silników BTS7960: Jeszcze pedal box został przerobiony na taki aby miał 3 jednakowe pedały więc musiałem dokupić drugie takie same i wyciąć jeden i dokleić tak jak na zcjeciach . Schemat podłączenia wszystkiego w linku do wcześniejszej wersji. Efekt końcowy (pedały jeszcze stare): To by było na tyle , jeśli czegoś ktoś potrzebuje , śmiało pisać
  5. Dzień dobry , zrobiłem proste , a nawet bardzo proste urządzenie do pomiaru temperatury i wilgotności powietrza za pomocą dht11 . Może nie jest piękne ale mi się podoba. Użyte przeze mnie części to : -arduino pro mini -dht11 -przetwornica step-up - akumulatorek 18650 -wyświetlacz LCD -konwerter I2C Opis działania : Czujnik wysyła dane do Arduino poprzez interfejs 1-wire . Arduino odczytuje i konwertuje dane za pomocą biblioteki "DHT.h". Na końcu za pomocą biblioteki "LiquidCrystal_I2C" wysyła dane magistralą I2C i wyświetla je na wyświetlaczu.
  6. Cześć, jestem w trakcie robienia projektu mini pająka opartego na silnikach wibracyjnych, w załączniku jest fragment, z którym mam problem. Silnik 2 (ten po prawej) zupełnie nie działa, mimo że osobno oba działały. Czy jest to spowodowane złym ustawieniem oporników, czy gdzieś indziej jest błąd? Z góry dzięki. ;)
  7. Cześć, jestem czytelnikiem Forbota od dłuższego czasu interesuje się elektroniką ale tylko hobbystycznie przez co mam wiedzę znikomą w wielu tematach - proszę o wyrozumiałość Robiłem kilka przymiarek to automatyki domowej zanim odkryłem że są „gotowe” rozwiązania takie jak: Supla, HomeAssistant, OpenHab, Domoticz i inne. Szukałem porównania, możliwości skalowalność i nie znalazłem odpowiedzi na pytanie który system by sprostał tematowi jaki mam, a jest ono dość proste: - Arduino (kilka sztuk) - komunikacja z Arduino tylko LAN (moduł Ethernet lub Serial + moduł Wifi) - Arduino jako klient, przekażniki czujniki sterowane przewodowo przez Arduino - serwerze własny z Linuxem (offline !) jak Domoticz, OpenHab itp. Teraz mam „zrobiony” od podstaw taki system bardzo prosty i działa dobrze ale ciągle rozbudowuje go o kolejne dodatki i tak się zastanawiam - jak było wiele razy powtarzane żeby nie wyważać otwartych drzwi - lepiej pomóc już działającej społeczności niż samemu ją tworzyć od nowa. Nie oczekuje gotowego rozwiązania tylko wskazania drogi którą pójść czy rozwijać swój projekt? czy jest rozwiąznie które wyżej wymienione wymagania ogarnie? Z Domoticzem przez chwilę było dobrze ale nie po kablu. Jeżeli będzie zainteresowanie tematem mogę rozpisać co teraz zostało zrobione i jak to działa teraz, może mam dobry pomysł tylko go trzeba opakować sensowniej i nie pakować się w gotowe (ogromne programowo) rozwiązania. Dziękuję za przeczytanie.
  8. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu » Python to język wysokopoziomowy, który ma bardzo szerokie zastosowanie. Można w nim napisać grę (PyGame) albo zrobić komunikację mikrokontrolera z programem na komputerze/laptopie (PySerial), aby na przykład wysyłać komendy. W tym kursie zajmiemy się tą drugą biblioteką. W starszych komputerach istnieją porty szeregowe RS-232. W nowszych komputerach portu tego raczej się nie uraczy. Jest jednakże światełko w tym ciemnym tunelu, gdyż sterowniki niektórych urządzeń USB emulują port szeregowy COM umożliwiając tym samym proste komunikowanie się z takim urządzeniem na nowszych maszynach. Do takich urządzeń należą płytki rozwojowe Arduino RS-232(rys. 1) Prosta komunikacja pomiędzy uC (mikrokontrolerem) a PC (rys. 2) 1.Wysyłanie informacji z mikrokontrolera do komputera/laptopa. Konfiguracja połączenia z portem COM Zanim zacznie się przygodę z komunikacją za pośrednictwem portu COM konieczne jest zapoznanie się z podstawami jego działania. Port ten przesyła dane dwukierunkowo za pomocą jednego pinu przesyłającego i jednego odczytującego dane. Dane przesyłane są zawsze z określoną prędkością mierzoną w bitach na sekundę. Standardowe ustawienie prędkości transmisji z urządzeniem wynosi 9600 bitów na sekundę. Ważne aby, wysyłać i odbierać dane z taką samą częstotliwością w przeciwnym przypadku dane nie będą odbierane przez urządzenie w sposób poprawny jak również program nie będzie w stanie poprawnie odbierać danych. Przy podstawowej konfiguracji konieczne jest również posiadanie wiedzy o nazwie portu. Pod Windowsem nazwy portów zaczynają się od COM i kończą liczbą określającą numer portu. Można sprawdzić w systemie, jakie porty COM są dostępne w Menadżerze urządzeń co też i widać na poniższym rysunku (rys. 3) rys. 3 Przygotowanie środowiska na komputerze/laptopie Tak jak już mówiłem, będziemy potrzebować biblioteki PySerial omówię jej instalację w środowisku PyCharm: Wchodzimy w terminal, następnie wpisujemy: "pip install pyserial" Naciskamy enter Powinniśmy zobaczyć coś takiego (rys. 4) rys. 4 teraz przejdzmy do Arduino. Przygotowywanie Arduino (oczywiście zadziała komunikacja zadziała wszędzie gdzie użyjemy UART'a, nie tylko Arduino) Na razie jedyne co napiszemy to: void setup() { Serial.begin(9600); // Ustawienie Baud Rate(prędkość transmisji) na 9600Hz } void loop() { Serial.println("Proba Komunikacji"); delay(1000); } Wgrywamy nasz program, uruchamiamy Monitor Portu Szeregowego gdzie powinno sie pojawić się (rys. 5) rys. 5 i tak co około sekundę (przy okazji widzimy, że funkcja delay nie jest taka dokładna (dlatego nie stosuje sie jej gdy robimy na przykład zegar)) Teraz można przejść do PyCharma import serial arduino = serial.Serial('COM5', 9600, timeout=0.1) while True: data = arduino.readline() if data: data = data.decode() print(data) Można powiedzieć, że właśnie zrobiliśmy monitor portu szeregowego z ArduinoIDE Omówienie kodu: Importujemy bibliotekę, Ustawiamy port do któego mamy podłączone Arduino oraz Baud Rate, Przypisujemy do zmiennej to co aktualnie jest przesyłane, Jeżeli zmienna nie jest pusta to ją dekodujemy i wyświetlamy na ekranie. ZAWSZE MUSIMY PAMIĘTAĆ O ZDEKODOWANIU (tylko na komputerze)!!! Wyłączamy monitor portu szeregowego (ten z ArduinoIDE), kompilujemy program i naszym oczom powinno ukazać się (rys. 6) rys. 6 2. Wysyłanie komend z komputera/laptopa do mikrokontrolera. Przejdźmy do PyCharma import serial import time arduino = serial.Serial('COM5', 9600, timeout=0.01) while True: arduino.write('wlacz'.encode()) time.sleep(1) arduino.write('wylacz'.encode()) time.sleep(1) Importujemy bibliotekę time (nie trzeba jej instalować) oraz wysyłamy "wiadomości": "wlacz" oraz "wylacz" To by było na tyle w PyCharmie, przejdźmy więc do ArduinoIDE rys. 7 Jako że robimy komunikację używając UART'a, który może wysyłać maksymalnie jeden znak, ponieważ (rys. 7) jeden znak to jeden bajt (bajt ma 8bitów) a my wysyłamy komendy: "wlacz" oraz "wylacz" to musimy zrobić taki mały myczek elektryczek i użyć zmiennej oraz pętli. Będzie wyglądać to tak: wysyłamy: w Arduino: "odbiera" i zapisuje do zmiennej wysyłamy: l Arduino: "odbiera" i zapisuje do zmiennej wysyłamy: a Arduino: "odbiera" i zapisuje do zmiennej wysyłamy: c Arduino: "odbiera" i zapisuje do zmiennej wysyłamy: z Arduino: "odbiera" i zapisuje do zmiennej nie wysyłamy nic Arduino: wychodzi z pętli oraz porównuje zawartość zmiennej z komendami które ma zapisane Arduino: wykonuje komendę Arduino: czyści zawartość zmiennej z komendą Takie wybrnięcie z sytuacji int i = 12; //pin do którego podłączymy diodę String komenda=""; void setup() { Serial.begin(9600); pinMode(i, OUTPUT); digitalWrite(i, HIGH); } void loop() { if(Serial.available() > 0) { while(Serial.available() > 0) { komenda += char(Serial.read()); } Serial.println(komenda); if(komenda == "wlacz") { digitalWrite(i, HIGH); } if(komenda == "wylacz") { digitalWrite(i, LOW); } komenda = ""; } delay(100); } Oczywiście można wysłać do komputera/laptopa "informację zwrotną" na przykład: Dioda jest wlaczona Dioda jest wylaczona Tylko musimy pamiętać aby użyć .decode(), ale tak jak mówiłem, tylko w programie na komputrzez/laptopie Jeżeli nasze komendy będą miały tylko 1 znak na przykład: a, A, 1, B, c, C ,4 (ogólnie to dowolny znak z tabeli ASCII) nie trzeba używać pętli tylko: if(Serial.read() == 's') oczywiście też w tym ifie: if(Serial.available() > 0) Jeżeli wstawilibyśmy tam więcej znaków dostalibyśmy taki komuniukat: warning: multi-character character constant [-Wmultichar]. 3. Podsumowanie Wysyłanie oraz odbieranie informacji jest bardzo przydatne, nie musi być to tylko pomiędzy uC, a komputerem. Może to być komunikacja pomiędzy dwoma uC na przykład: karta microSD ma w sobie procesor który komunikuje sie z uC używając SPI, termometr DS18B20 który komunikuje z uC używając protokołu komunikacji OneWire (rys. 8), czujnik podczerwieni, procesor w naszych komputerach z mostkiem, pamięcią i GPU, ładowarka z telefonem, aby ustalić jaki prąd i napięcie. Komunikacja jest wszędzie (można powiedzieć, że urządzenia są bardziej komunikatywne od nas ). rys. 8
  9. Witam serdecznie, chciałem zbudować mały pojazd, którym mógłbym sterować za pomocą telefonu. Przed złożeniem sprawdziłem czy wszystko działa i przy próbie komunikacji z telefonem potrafiłem sterować diodą (tzn. włączać i wyłączać) i wszystko działało. Niestety, po złożeniu pojazdu, silniki nie reagowały na polecenia przesyłane przez bluetooth, odłączyłem moduł i znowu spróbowałem sterować sama dioda, jednak tym razem komunikacja nie przebiegła pomyślnie. Mam napisany taki krótki program, oraz aplikacje i nie wiem w czym jest problem, więc proszę o pomoc
  10. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu » Słowem wstępu, wyobraźmy sobie że jesteśmy na słonecznej, piaszczystej plaży wzdłuż której rosną wysokie, bogate w orzechy kokosowe palmy. Pod jedną z nich stoi lokalny, doświadczony, zbieracz kokosów, u którego mamy zamiar nauczyć się tego ciężkiego rzemiosła. Jako zaledwie początkujący adepci tej trudnej sztuki, nie mamy jednak zielonego pojęcia jak się do tego zabrać. Dlatego nasz nowy mentor musi nam wytłumaczyć co i jak powinniśmy zrobić. Może on nam wytłumaczyć wszystko krok po kroku. Opisać dokładne pozycje naszych kończyn, prędkość z jaką będziemy się wspinać i sposób odbierania kokosu. Oczywiście opisanie nam tego na tyle dokładnie, byśmy mogli bezbłędnie przystąpić do pracy wymagałoby dużo czasu i energii. Zamiast tego, może pokazać nam osobiście jak to zrobić i dać nam przystąpić do pracy. W krótkim i bogatym w informacje czasie, będziemy wiedzieli jak przystąpić do pracy. Po tym ciut przydługawym wstępie, którym starałem się nakreślić pewien problem, możemy przystąpić do właściwego omówienia tematu. Istnieje wiele metod programowania robotów przemysłowych (manipulatorów). Wykonują one precyzyjne prace, wymagające wielu skomplikowanych ruchów. Jednak poza nimi, roboty mogą też wykonywać mniej skomplikowane ruchy np. podczas zmiany pozycji lub przełączenia między poszczególnymi pracami. O ile do wykonania operacji precyzyjnych niezbędny jest szczegółowo opracowany program, o tyle podczas ruchów mniej skomplikowanych czas programowania można ukrócić do metod Online Programming. Krótki film przedstawiający podział metod programowania Metody te pozwalają operatorowi manualnie lub za pomocą odpowiedniego kontrolera ustawić poszczególne pozycje robota, które zostaną przez niego zapamiętane w czasie bieżącym oraz odtworzone w postaci pożądanego przez nas ruchu. Programowanie robota spawalniczego przy pomocy metody teach-in Programowanie robota Festo BionicCobot przy pomocy metody play-back Programowanie play-back opiera się na sczytywaniu przez oprogramowanie pozycji robota, zapisywanie ich oraz odtwarzanie poprzez bezpośrednie poruszanie jego konstrukcją. Aby było to możliwe, każdy stopień swobody robota musi posiadać sensor umożliwiający określenie jego dokładnej pozycji. Oprócz tego napęd robota musi działać w wyrachowany i delikatny sposób, aby konstrukcja była jednocześnie sztywna i można było nią poruszać ręcznie. Programowanie teach-in z kolei polega na ustawieniu robota w ustalonych pozycjach za pomocą odpowiedniego kontrolera, za pomocą którego te pozycje zostaną zapisane a następnie odtworzone. Odtwarzanie kolejno zapisanych pozycji daje w efekcie płynny, ciągły ruch maszyny. Wyżej wspomniane metody omówimy na realnym przykładzie. Za pomocą kontrolera będziemy mogli stosować na prostym manipulatorze metodę teach-in. Robot napędzany jest serwami modelarskimi oraz wykonany w technice druku 3D. Serwa posiadają wbudowane potencjometry sczytujące pozycje kątowe wałów, jednak bez ingerencji w ich budowę ciężko będzie korzystać z tych potencjometrów do określania pozycji robota. Dlatego manualne ustawienie pozycji manipulatora metodą play-back wypada z puli naszych opcji. Poza tym istniałaby duża szansa na uszkodzenie stosowanych w robocie serw. Zamiast tego, posłużymy się kontrolerem, który będzie kinetycznym modelem naszego manipulatora i pozwoli także zahaczyć o ideę play-back. Ramię manipulatora wydrukowane w 3D, poniżej link do źródła https://www.thingiverse.com/thing:1015238 Kontroler odpowiada kinematyce prezentowanego robota i ma umieszczone potencjometry w każdym jego punkcie swobody. Poruszając nim, możemy ustalić rzeczywistą pozycję naszego manipulatora. Budując r obota o mniej skomplikowanej budowie, możemy pozostać przy samych potencjometrach np. zamontowanych na płytce stykowej. Jednak w przypadku tego robota korzystanie z tego rozwiązania byłoby trudniejsze i mniej wygodne w użytku. Model kinematyczny manipulatora Znając już budowę kontrolera oraz manipulatora, należy je już tylko do siebie podłączyć. Oprócz tego do układu dodane zostaną przyciski nagrywania oraz odtwarzania ruchu. Elektronika opiera się o mikrokontroler atmega328p. Zasilanie układu odbywa się z sieci napięciem 230 V. W obudowie znajduje się układ prostujący, przetwornica step-down zasilająca serwomechanizmy oraz płytka arduino ze wspomnianym wcześniej mikrokontrolerem. Dla wygody wszystkie piny arduino zostały wyprowadzone na zewnątrz obudowy. Cały schemat przedstawianej konstrukcji znajduje się poniżej: Schemat układu Lista opisanych komponentów: -S1 – włącznik główny, -S2 – przycisk nagrywania, -S3 – przycisk odtwarzania, -D1 – mostek Graetza 400V ; 4A, -D2 – zielona dioda LED, -C1 – kondensator elektrolityczny 1000µF ; 50V, -C2 – kondensator elektrolityczny 220µF ; 25V, -C3 – kondensator elektrolityczny 22µF ; 25V, -C4 – kondensator ceramiczny 100nF, -C5 – kondensator ceramiczny 22pF, -C6 – kondensator ceramiczny 22pF, -C7 – kondensator ceramiczny 100nF, -R1 – rezystor 150 Ω, -R2, R3, R4 – rezystor 1 kΩ, -POT 1, POT 2, POT 3, POT 4, - 10 kΩ, -Stabilizator napięcia LM7805, -Przetwornica step-down LM2596, -X1 – kwarc 16 MHz, Połączenie układu Po podłączeniu całej elektroniki można przystąpić do omówienia kodu arduino. Program ten został już zaopatrzony w bogatą ilość komentarzy, które na pewno pomogą osobom dopiero rozpoczynającym swoją przygodę z arduino: //biblioteka umożliwiająca nie tylko sterowanie serwami, ale także ich prędkością //nie jest ona koniecznością, wystarczy standardowa biblioteka <servo.h> oraz pozbycie się zmiennej 'predkosc' z koduć #include <VarSpeedServo.h> //definiujemy serwa używane w robocie: VarSpeedServo servo1; VarSpeedServo servo2; VarSpeedServo servo3; VarSpeedServo servo4; //definiujemy przyciski nagrywania i odtwarzania: const int przycisk_A = 2; const int przycisk_B = 3; //definiujemy wartości dla wciśniętych przycisków nagrywania i odtwarzania: int przycisk_A_ON = 0; boolean przycisk_B_ON = false; //definiujemy potencjometry: const int potencjometr1 = A0; const int potencjometr2 = A1; const int potencjometr3 = A2; const int potencjometr4 = A3; //definiujemy zmienne służące do odczytu wartości napięć z potencjometrów: int potencjometr_1_odczyt; int potencjometr_2_odczyt; int potencjometr_3_odczyt; int potencjometr_4_odczyt; //definiujemy zmienne służące do zapisu wartości kąta położenia poszczególnego serwa: int potencjometr_1_zapis; int potencjometr_2_zapis; int potencjometr_3_zapis; int potencjometr_4_zapis; //definiujemy tablice zapisujące położenie serwa: int Pozycja_serva1[]={1,1,1,1,1}; int Pozycja_serva2[]={1,1,1,1,1}; int Pozycja_serva3[]={1,1,1,1,1}; int Pozycja_serva4[]={1,1,1,1,1}; void setup() { //definiujemy piny do których podłączone są serwa: servo1.attach(6); servo2.attach(9); servo3.attach(10); servo4.attach(11); //definiujemy piny wejściowe przycisków nagrywania i odtwarzania: pinMode(przycisk_A, INPUT_PULLUP); pinMode(przycisk_B, INPUT_PULLUP); //inicjalizacja portu szeregowego do podglądu działania programu: Serial.begin(9600); } void loop() { //ustalanie prędkości serw w zakresie od 0 do 180: int predkosc = 90; //zapis formuły umieszczania odczytanej z potencjometrów wartości do tabeli: potencjometr_1_odczyt = analogRead(potencjometr1); potencjometr_1_zapis = map (potencjometr_1_odczyt, 0, 1023, 20, 175); potencjometr_2_odczyt = analogRead(potencjometr2); potencjometr_2_zapis = map (potencjometr_2_odczyt, 0, 1023, 5, 175); potencjometr_3_odczyt = analogRead(potencjometr3); potencjometr_3_zapis = map (potencjometr_3_odczyt, 0, 1023, 5, 175); potencjometr_4_odczyt = analogRead(potencjometr4); potencjometr_4_zapis = map (potencjometr_4_odczyt, 0, 1023, 20, 160); //serwa przyjmują pozycje zapisane w tabelach: servo1.write(potencjometr_1_zapis, predkosc); servo2.write(potencjometr_2_zapis, predkosc); servo3.write(potencjometr_3_zapis, predkosc); servo4.write(potencjometr_4_zapis, predkosc); //przy kolejnym wciśnięciu przycisku nagrywania tabela każdego serwa zostanie //nadpisana, zapamiętując obecną pozycję serwa: if(digitalRead(przycisk_A) == HIGH) { przycisk_A_ON++; switch(przycisk_A_ON) { case 1: Pozycja_serva1[0] = potencjometr_1_zapis; Pozycja_serva2[0] = potencjometr_2_zapis; Pozycja_serva3[0] = potencjometr_3_zapis; Pozycja_serva4[0] = potencjometr_4_zapis; Serial.println("Pozycja pierwsza zapisana"); break; case 2: Pozycja_serva1[1] = potencjometr_1_zapis; Pozycja_serva2[1] = potencjometr_2_zapis; Pozycja_serva3[1] = potencjometr_3_zapis; Pozycja_serva4[1] = potencjometr_4_zapis; Serial.println("Pozycja druga zapisana"); break; case 3: Pozycja_serva1[2] = potencjometr_1_zapis; Pozycja_serva2[2] = potencjometr_2_zapis; Pozycja_serva3[2] = potencjometr_3_zapis; Pozycja_serva4[2] = potencjometr_4_zapis; Serial.println("Pozycja trzecia zapisana"); break; case 4: Pozycja_serva1[3] = potencjometr_1_zapis; Pozycja_serva2[3] = potencjometr_2_zapis; Pozycja_serva3[3] = potencjometr_3_zapis; Pozycja_serva4[3] = potencjometr_4_zapis; Serial.println("Pozycja czwarta zapisana"); break; case 5: Pozycja_serva1[4] = potencjometr_1_zapis; Pozycja_serva2[4] = potencjometr_2_zapis; Pozycja_serva3[4] = potencjometr_3_zapis; Pozycja_serva4[4] = potencjometr_4_zapis; Serial.println("Pozycja piąta zapisana"); break; } } //po wciśnięciu przycisku odtwarzania serwa będą przyjmować zapisane w tabelach pozycje //z odczekaniem 1.5 sekund w każdej pozycji: if(digitalRead(przycisk_B) == HIGH) { przycisk_B_ON = true; } if(przycisk_B_ON) { for(int i=0; i<5; i++) { servo1.write(Pozycja_serva1[i],predkosc); servo2.write(Pozycja_serva2[i],predkosc); servo3.write(Pozycja_serva3[i],predkosc); servo4.write(Pozycja_serva4[i],predkosc); Serial.println("Odtwórz ruchy"); delay(1500); } } //czas opóźnienia działania programu, od jego nastawy zależy płynnośc pracy robota: delay(200); } Program działa w sposób następujący: Po uruchomieniu programu, za pomocą modelu kinematycznego będzie można bezpośrednio kontrolować ruch manipulatora, Jeżeli wciśniemy przycisk S2 (nagrywania), obecnie ustawiona pozycja robota zostanie zapisana, Program umożliwia zapisanie pięciu różnych pozycji, Jeżeli wybierzemy przycisk S3 (odtwarzania), robot zacznie odtwarzać wybrane przez nas pozycje w nieskończonej pętli, Aby wytyczyć nową sekwencję ruchów należy zresetować układ. Efekt działania powyższego kodu przedstawia się następująco: Dzięki funkcji monitora szeregowego w arduino można obserwować pracę manipulatora bezpośrednio: Przepraszam wszystkich czytelników za jakość nagrań wideo, niestety ograniczały mnie możliwości sprzętowe. Przedstawiony wyżej kod jest prosty a przykład nieskomplikowany, jednak doskonale pokazuje podstawy działania tej metody. Nie mniej jednak mam nadzieję, że artykuł okaże się dla wielu osób pomocny. Oprócz tego zostawiam jeszcze bibliotekę <VarSpeedServo> VarSpeedServo-master.zip Powodzenia we wszelkich przyszłych projektach i przygodach z elektroniką!
  11. Cześć. Chciałbym zaprezentować projekt sterownika pieca dwufuncyjnego na paliwo ciekłe - gaz ziemny. Założenia projektowe: utrzymanie zadanej temperatury w pomieszczeniu/ mieszkaniu w okresie zimowym; wyświetlanie temperatur pomieszczenia, nastaw, godziny daty, stanu pracy pieca. BOM:arduino uno, serwo modelarskie sg90, czujnik temperatury lm335, wyświetlacz LCD 1.8" ST7735 waveshare, zegar rtc, obudowa wydruk 3d, materiał easy PET-G, zasilacz 9V DC, śruby, nakrętki, magnesy neodymowe. Działanie: urządzenie mierzy temperaturę otoczenia a następnie dostosowuje położenie pokrętła w celu załączania pieca. Jest to rozwiązanie najmniej ingerujące w jego działanie. Wykorzystanie przekaźnika przerywającego zasilanie powoduje natychmiastowe wyłącznenie pompy. Powyższe rozwiązanie powoduje tylko przekręcenie pokrętła do pozycji "0", przez co piec wygasza się zgodnie ze swoim cyklem pracy. Modyfikacja w piecu polegała na wymontowaniu oryginalnego pokrętła i włożeniu w jego miejsce ramienia połączonego z serwomechanizmem. Całość zmontowano w samodzielnie zaprojektowanej obudowie, wydrukowanej w technologii 3d. Korpus utrzymywał się na obudowie pieca za pomocą magnesów neodymowych, przez co nie ma konieczności wiercenia otworów.
  12. Ten wpis bierze udział w konkursie na najlepszy artykuł o elektronice lub programowaniu, którego partnerem jest firma PCBWay (popularny producent prototypów PCB). W puli nagród karty podarunkowe Allegro o wartości 2300 zł. Sprawdź więcej informacji na temat konkursu » Wprowadzenie W artykule zostanie przedstawiony sposób na optymalizację układów mikroprocesorowych pod względem wykorzystania zasilania. Celem jest przedstawienie prostych metod, które nie wymagają znacznych ingerencji w konstruowany układ, a jednocześnie dających wymierne korzyści. Efekty uzyskane na podstawie lektury tego artykułu pozwolą na lepsze zrozumienie konstrukcji procesora w kwestii budowy układu zegarowego. Zaczynamy na 8 bitach Na potrzeby zobrazowania toku myślenia zostaną wplątane w rozważania losy hipotetycznego młodego człowieka, którego nazwiemy Adam. Adam jest młodym elektronikiem, z pewnością przyszłym inżynierem, który od swoich rówieśników słyszał, że oni projektują, programują i uruchamiają. Adam zasięgnął informacji o co tu chodzi. Zakupił płytkę Arduino UNO, zasilacz sieciowy i pełen zapału zainstalował środowisko Arduino IDE. Chcąc wiedzieć jak pokierować swoim rozwojem, zapisał się do odpowiedniej grupy dyskusyjnej i zadał pytanie „mam arduino i co mogę na nim zrobić?” . Odpowiedź pełna sarkazmu, którego nie wyczuł, brzmiała: „Zamrugać diodą LED”. Ów młody człowiek znalazł przykład „blink.ino”, wczytał, skompilował i wgrał do płytki. Ku swemu wielkiemu zaskoczeniu na płytce zaczęła migać dioda LED. Z uśmiechem na twarzy, nie wiedząc tak naprawdę co zrobił, stwierdził: „Jestem programistą”. setup(){ pinMode(13, output); } main() { digitalWrite(13, HIGH); dely(1000); digitalWrite(13. LOW); delay(1000); } Rysunek 1. Arduino UNO Na listingu nr 1 znajduje się cały program, napisany w Arduino (zobacz ramkę „Dlaczego Arduino?”), mrugający diodą LED. Czy ten kod jest optymalny? Patrząc z punktu widzenia programisty, który nie wie jak jest zbudowany mikroprocesor: TAK, ten kod jest optymalny. Z punktu widzenia inżyniera, dobrze znającego architekturę wewnętrzną procesora oraz możliwości jakie daje programowanie niskopoziomowe: NIE, ponieważ to co powstanie po kompilacji będzie bardzo nadmiarowe. Prześledźmy co procesor będzie robić: W funkcji setup zostaje skonfigurowany pin nr 13 procesora jako wyjście. Nr 13 to tylko symboliczna nazwa jednego z wyjść płytki Arduino UNO. Nr 13 odnosi się w tym przypadku do PortB.5 procesora. Do tego pinu jest podłączona dioda LED poprzez rezystor o wartości 500 Ohm. W funkcji main, w pierwszej linii pin 13 jest ustawiany w stan wysoki, dioda LED świeci. Następnie, przez 1000 ms, procesor czeka, aż upłynie 1000 ms. Procesor zajmuje się tylko sobą, czekając aż upłynie 1000 ms. Po tym czasie pin 13 ustawiany jest w stan niski, dioda LED gaśnie. I znowu procesor nic innego nie robi, tylko czeka aż upłynie kolejne 1000 ms. I tak na okrągło, przez ponad 99,9% czasu procesor nic nie robi, tylko sprawdza, czy skończyło się 1000 ms. Schemat nr 1. Zobrazowanie podłączenia diody LED na płytce Arduino UNO W czasie oczekiwania na upłynięcie 1000 ms procesor mógłby robić pożyteczniejsze rzeczy niż tylko zajmowanie się samym sobą. Jeżeli już nie damy mu żadnego konkretnego zadania, to niech nic nie robi, dosłownie nic. Młodzi ludzie, tacy jak Adam, mając nikłą wiedzę elektronika, nie zważają na wykorzystanie energii. Podłączają zasilacz sieciowy do Arduino i nie przejmują się ile to zużyje energii. Płytka arduino UNO sama z siebie, bez procesora, pobiera 19,2 mA. Gdy włożymy procesor, który nie był jeszcze zaprogramowany, pobór prądu wzrośnie do 36,7 mA, a podłączona diod LED będzie pobierała kolejne 2,7mA. W tym momencie Adam się relaksuje. Natomiast my zajmiemy się optymalizacją układu, to będzie praca dla inżyniera. Wykorzystamy przy okazji notę katalogową naszego procesora. Optymalizacja W celu optymalizacji zużycia energii możemy zastosować diodę LED, która potrzebuje mniejszy prąd by świecić, możemy zmniejszyć zużycie energii przez procesor, a nawet możemy wymontować zbędne elementy z płytki Arduino UNO. To ostatnie nie jest wskazane, bo płytka ta jeszcze nie raz zostanie zapewne użyta. Z diodą LED jest tak, że została ona wlutowana z rezystorem na płytce i jej wymiana będzie kłopotliwa. Pozostaje nam zoptymalizowanie procesora, zmontowanie układu np. na płytce stykowej. Będziemy potrzebować procesor, rezonator kwarcowy 16MHz, diodę led, kilka rezystorów o różnej wartości, oczywiście płytkę stykową, kabelki, zasilacz, stabilizatory i programator AVR ISP lub dowolny inny pozwalający na programowanie procesora. Schemat nr 2. Podłączenie samego procesora Ale dlaczego prowadzimy takie rozważania? Nie zawsze będziemy mieli obok naszego urządzenia gniazdko zasilania o nieograniczonej energii i napięciu 230V. Wtedy zasilimy nasze urządzenie z baterii lub akumulatora. Co zrobić, żeby urządzenie pracowało nieprzerwanie przez 1 miesiąc? Należy dać taką baterię, która ma odpowiednią pojemność. To prawda. A co zrobić, żeby urządzenie pracowało przez cały rok? Czy należy dać 12 takich baterii? Po dobrej optymalizacji może się okazać, że nie musi to być konieczne. Przeanalizujemy, na przytoczonym wcześniej przykładzie Blink, jak optymalizacja programowa i sprzętowa przyczyni się do zmniejszenia zużycia energii. W tym celu zamiast używać płytki Arduino UNO użyjemy samego procesora Atmega328 i zasilimy go napięciem 6V poprzez stabilizator 5V, a wszystko będziemy montować na płytce stykowej. Pobór prądu w naszym układzie będzie wyglądał jak przebieg prostokątny o wypełnieniu 50%. Dolny poziom prądu będzie odpowiadał stanowi, gdy dioda LED jest zgaszona (poziom L), natomiast poziom górny będzie odpowiadał stanowi, gdy dioda LED świeci (poziom H).Sam procesor pobiera 14.5 mA, a dioda LED 2.7 mA. Będą to dla nas dane odniesienia. Średni prąd pobierany przez układ to 15,8mA. W ciągu doby układ pobierze 380 mAh. Chcąc zasilić układ z baterii 4 x 1.5V (np. AA o pojemności ok 2000 mAh) układ będzie pracować 5dni i 6 godzin. (dla płytki Arduino będzie to 2 dni i 4 godziny). W ten oto prosty sposób wydłużyliśmy czas pracy o ponad 100%. Optymalizacja nr 1: zmieniamy diodę LED na bardziej energooszczędną, zastosujemy inny rezystor. Zastosujemy diodę, która by świecić potrzebuje zaledwie 0,15 mA. W ten sposób zmniejszyliśmy prąd pobierany przez diodę. Czas pracy na baterii wydłuży się do 5 dni i 16 godzin. W ten sposób, niejako w gratisie, otrzymaliśmy 10 godzin pracy w stosunku do układu podstawowego na płytce stykowej oraz 84h w porównaniu do układu na oryginalnym Arduino. Wykres nr 1. Zależność prądu zasilania od napięcia zasilania dla dwóch przykładowych częstotliwości zegara Optymalizacja nr 2: zmniejszamy napięcie zasilania do 4.5 V, czyli wykorzystamy tylko 3 ogniwa AA. Nie używamy w tym momencie już żadnego stabilizatora Zwiększamy wartość rezystora zachowując parametry świecenia diody LED, możemy zauważyć że zmniejszył się prąd pobierany przez procesor. Teraz nasz układ pobiera średnio 11,35 mA i będzie pracował 7 dni i 8 godzin. Optymalizacja nr 3. Przełączymy pracę procesora na wewnętrzny układ zegarowy 8MHz. Wcześniej oczywiście należy zmodyfikować parametr funkcji delay, aby zachować odpowiednią częstotliwość migania diody LED. W tym przypadku, ponieważ zmniejszyliśmy częstotliwość o połowę, więc musimy ten parametr także zmniejszyć o połowę, czyli użyjemy delay(500). Nasz układ będzie pobierał średnio 7,55 mAh, a czas pracy na bateriach wydłuży się do 11 dni i 1 godzinę. Wykres nr 2. Pobór prądu w zależności od częstotliwości zegara i napięcia zasilania Optymalizacja nr 4. Procesor atmega328 ma możliwość zmiany konfiguracji, aby częstotliwość rezonatora była zmniejszona ośmiokrotnie. Wymagana jest tylko odpowiednia konfiguracja Fuse bitów. W tak prostym programie jak blink, nie musimy mieć tak szybkiego procesora. Ustawmy Fuse bit CKDIV8 na aktywny. Spowoduje to, że procesor będzie pracować z częstotliwością ośmiokrotnie mniejszą. Aby uzyskać tę samą częstotliwość migania diody LED musimy troszkę zmienić nasz program. W miejsce oryginalnego delay(1000) wstawmy delay(500/8) lub delay(65). Po kompilacji, wgraniu i przestawienie fuse bitu, dioda nadal miga, tak jak wcześniej, ale średni prąd pobierany przez układ zmniejszył się do 3.7 mA . W efekcie optymalizacji nr 4 nasz układ będzie pracować 22 dni i 13 godzin W nocie katalogowej, wykres powyżej, możemy zobaczyć, że napięcie zasilania możemy zmniejszyć aż do 1.8V. Niestety nie mamy takiej baterii, ale możemy odłączyć kolejną. Wykres nr 3. Maksymalna częstotliwość w zależności od napięcia zasilania Optymalizacja nr 5. Zasilamy nasz układ tym razem z dwóch baterii AA, czyli napięciem 3V. Oczywiście zmieniamy rezystor przy diodzie, aby zasilać ją tym samym prądem co poprzednio. Program, zegar i fuse bity zostawiamy niezmienione. Tym razem otrzymujemy zapotrzebowanie na prąd przez procesor na poziomie 1.1 mA. Nasz układ będzie pracować przez 75 dni i 22 godzin. Optymalizacja nr 6. Wykorzystamy wbudowany w procesor wewnętrzny układ zegarowy o częstotliwości 128kHz. W naszym przypadku, po korekcie w funkcji delay, nadal układ będzie migać diodą LED. Oczywiście pozostawiamy CKDIV8 aktywny uzyskując częstotliwość zegara 16kHz. Średni pobór prądu przez nasz układ wyniesie 0,5 mA, a czas pracy na dwóch bateriach AA, wyniesie 166 dni i 15 godziny. Można wykonać optymalizację nr 7 poprzez zmniejszenie napięcia zasilania do 2.4V, wykorzystując dwa ogniwa akumulatorków o pojemności 2000 mAh. Dioda LED już przestanie prawie świecić, ale układ nadal będzie pracować pobierając średnio 0.35 mA, a czas pracy osiągnie 238 dni i 2 godziny. Idąc dalej można wykonać optymalizacja nr 8. I wykorzystać wbudowany w procesor tryb zmniejszonego pobory prądu poprzez jego usypianie. Taki zabieg spowoduje, że procesor będzie pobierać jeszcze mniej prądu, ale to zadanie pozostawiam czytelnikowi. Krótkie podsumowanie tego co zrobiliśmy Tabela nr 1. Podsumowanie optymalizacji Atmega328 Dzięki zastosowaniu kilku optymalizacji wydłużyliśmy czas pracy naszego, bardzo prostego, układu. Poza tym zmniejszyliśmy o połowę ilość potrzebnych ogniw do zasilania, co zmniejszyło koszty eksploatacji. Wydłużyliśmy czas pracy naszego urządzenia 76 krotnie, wykorzystując o połowę mniej baterii. A jeżeli już kupimy 4 baterie, tak jak to miało miejsce w pierwszej wersji, ale podłączając je równolegle w pakiecie 2 x 2 baterie, to uzyskujemy ponad 150 krotne wydłużenie czasu pracy naszego układu w porównaniu do użycia oryginalnego Arduino UNO. Czytelnik może pokusić się o zgłębienie wiedzy o możliwościach procesorów w omawianej kwestii. Jest dostępna literatura omawiająca to zagadnienie. Ten artykuł ma za zadanie tylko przybliżyć to zagadnienie szerszemu gronu odbiorców, którzy dopiero zaczynają przygodę z mikroprocesorami. Można jeszcze zastosować bardziej ambitne metody zarządzania energią[ii], ale to już zostawiam czytelnikowi. Rozwinięcie na 32 bitach Nasz Adam o tym wszystkim co zrobiliśmy nie wiedział. Ale jego ambicja przerastała jego wiedzę. Napisał, czyli przekopiował swój pierwszy program i stwierdził: „ale przecież to tylko 8-bitowy procesor, użyję 32-bitowego”. Jak pomyślał, tak zrobił, zakupił Arduino M0, skorzystał ze swojego pierwszego programu, skompilował go, wgrał i…. dioda LED miga. Radość wielka, Adam „napisał” swój pierwszy program na procesor 32-bitowy. Znów jest szczęśliwy, choć nadal nie wie co robi procesor. Program wygląda identycznie jak poprzednio. Więc przypomnę co robi procesor. Procesor w funkcji main, w pierwszej linii pin 13 ustawia w stanie wysokim, dioda LED świeci. Następnie, przez 1000ms, procesor SAMD21G18 czeka, aż upłynie 1000ms, robi to szybciej, bo jest szybszy od Atmega328. Procesor zajmuje się tylko sobą, czekając aż upłynie 1000ms. Nudzi się. Po tym czasie pin 13 ustawiany jest w stanie niskim, dioda LED gaśnie. I znowu procesor nic innego nie robi, tylko czeka aż upłynie kolejne 1000ms. I tak na okrągło, przez 99,99% czasu procesor nic nie robi, tylko bardzo szybko sprawdza, czy skończyło się 1000ms. Rysunek 2. Arduino M0 Płytka Arduno M0 została zasilona z 4 baterii AAA, tak jak poprzednio. Średni pobór prądu wynosił 26.8 mA, a czas pracy układu, na używanych wcześniej bateriach, wynosi 3 dni i 2 godzin. Optymalizacja W przypadku procesora SAMD21G18 również możemy przeprowadzić podobną optymalizację. Ograniczymy się tylko dwóch etapów, w którym zasilimy płytkę z 2 baterii AAA . Optymalizacja nr 1. Aby ograniczyć zużycie prądy przez elementy dodatkowe na płytce wykorzystamy podobnie jak poprzednio sam procesor oraz tylko te elementy, które będą niezbędne do pracy. Po optymalizacji otrzymaliśmy średni prąd zasilania wynoszący 9,6 mA. Nasz układ będzie nieprzerwalnie pracować przez 8 dni i 14 godzin. Optymalizacja nr 2. Przy użyciu trybu pracy SLEEP dla omawianego procesora możemy obniżyć pobór prądu do ok 6uA. Mając takie możliwości możemy w czasie gdy dioda LED ma być zgaszona uśpimy procesor. Przy wcześniejszej optymalizacji osiągnęliśmy średni pobór prądu na poziomie 9,6 mA, teraz usypiając procesor przez połowę czas uzyskamy 4,8 mA. Wynik może nie powala bo i tak spora wartość, ale pamiętajmy, to jest o 50% mniej. Po tej optymalizacji otrzymaliśmy średni prąd zasilania wynoszący 4,8 mA. Nasz układ będzie nieprzerwalnie pracować przez 17 dni i 4 godzin. Jeżeli chodzi o optymalizację częstotliwości zapraszam do analizy noty katalogowej producenta i wykonania własnych testów. Krótkie podsumowanie tego co zrobiliśmy Tabela nr 2. Podsumowanie optymalizacji SAMD21G18 Podsumowanie Porównajmy teraz obie płytki Arduino. Obie posiadają podobną ilość pinów do wykorzystania, obie można zasilić albo z USB, albo z zewnętrznego zasilacza, obie pracują na maksymalnych prędkościach zegara jakie udostępnia producent. Procesor w Arduino Uno ma piny, które można obciążyć większym prądem niż w procesor w Arduino M0. Oba procesory mają możliwość korzystania z metod zarządzania zasilaniem, tym samym zmniejszania prądu zasilania procesora. Dla naszego Adama, jest bez znaczenia, która płytkę wykorzysta, ale dla czytelnika tego artykułu zapewne już nie. Nie zawsze jest sens używać najmocniejszy procesor, skoro słabszy i tańszy zrobi dokładnie to samo. Dla prostych aplikacji, które nie wymagają „super szybkości” procesor Atmega328 wydaje się być lepszym rozwiązaniem w porównaniu do SAMD21G18. Natomiast gdy budujemy aplikację bardzo skomplikowaną, wymagającą szybkich operacji i krótkich czasów reakcji to SAMD21G18 tym razem będzie lepszy od Atmega328. Wszystko należy przekalkulować. Jeżeli zoptymalizujemy nasz układ sprzętowo i programowo, to możemy podkusić się o zrobienie układu, który będzie niezależny od zasilania zewnętrznego. Możemy zasilać układ np. z energii słonecznej, która zostanie dostarczona przez ogniwo słoneczne. Podczas dnia nadmiar energii wytworzonej przez ogniwo można gromadzić w akumulatorze, z którego układ będzie zasilany nocą. Dobór ogniwa i akumulatora zależy już od tego jak skomplikowany mamy układ i jakie ma zapotrzebowanie na energię, ale ważne jest by układ działał cały czas. Ktoś mógłby powiedzieć perpetuum mobile, ale my powiemy że korzystamy z energii odnawialnej. Dlaczego Arduino Nie ma wątpliwości, że rozwój elektroniki sprawił, że wiele narzędzi i produktów stało się bardziej dostępnych dla zwykłego użytkownika. Idea Arduino doprowadziła to stanu, w którym to każdy może spróbować, w naszym przypadku, programowania i konstruowania elektroniki. Programowanie w Arduino jest bardzo proste, a programista nie musi znać budowy wewnętrznej procesorów, co w przypadku innych środowisk jest konieczne. Samo środowisko jest bezpłatne. Moduły Arduino stały się bardzo dostępne na naszym rynku, a za sprawą „specjalistów” z Chin również cenowo bardzo atrakcyjne. Wsparcie producenta i dostępność dokumentacji jest szczególnym ułatwieniem w budowaniu i programowaniu układów. Rozpowszechnienie Arduino na całym świecie sprawiło, że użytkowników i osób w nim programujących jest wielu. Jest bardzo wiele grup dyskusyjnych, forum internetowych czy repozytoriów na których jest omawianych całe mnóstwo problemów i ich rozwiązań, bibliotek napisanych przez użytkowników, czy po prostu opisów typu „jak zrobić…”. To wszystko sprawia, że zamieszczony w tym artykule opis dotyczy Arduino, od którego to zaczyna przygodę z programowaniem najwięcej osób.
  13. Witam wszystkich czytelników. Zainspirowałem się w wakacje postem użytkownika @Krzysiek97, który przedstawił swoją kierownice do gier na bazie arduino leonardo: Kierownica PC - wersja 2. Z racji tego że lubię grać w gry wyścigowe i symulatory postanowiłem zbudować własną kierownicę z dodatkowymi akcesoriami. Nie chciałem przerabiać starej gotowej kierownicy do komputera, więc wpadłem na pomysł aby zbudować całe stanowisko. Materiał o tym stanowisku/ projekcie znajduję się na moim kanale na YT do którego was zapraszam Kierownica do komputera na bazie arduino Chciałem aby w tym stanowisko znajdowała się kierownica o kącie obrotu 900 stopni, sprzęgło, gaz, hamulec, 8 biegów + wsteczny (8 biegów ponieważ tyle mają niektóre samochody np. w Forza Horizon 4), hamulec ręczny, 2 joystiki (do sterowania maszynami w Farming Simualtor), button matrix 4x5 = 20 przycisków (przypisanych do rożnych akcji w grach) i zegary do wyświetlania prędkości i obrotów. Tak więc gdzieś w połowie lipca zacząłem szukać potrzebne części. Pierwszym problemem z którym się spotkałem była niewystarczająca ilość wejść w arduino leonardo. Ktoś na tym forum podsunął mi płytki Nucleo 64 na STM32, obawiałem się jednak czy programy które wcześniej znalazłem w internecie będą z nimi współpracować. Bawiłem się naco wcześniej arduino lecz nucleo nie stąd moja niepewność ponieważ zaczynałem dopiero wtedy zabawę z tym wszystkim. Zdecydowałem się jednak zostać przy arduino i zakupiłem 3 płytki, po jednej dla każdego programu który obsługuję inną część stanowiska, ponieważ i tak nie ma prgoramu który ogarnie wszystkie moje rzeczy na raz. A więc tak: Arduino Leonardo - program EMC Utility Lite (z początku korzystałem z RFR Whell Configuration elcz sprawiał on problemy) - obsługuję kierownicę, pedały, hamulec ręczny - Link do programu EMC, Jak zainstalować program Pierwsze Arduino Pro Micro - program MMJoy2 - obsługuję button matrix i 2 joysticki - Link do programu MMJoy2, Jak zainstalować program Drugie Arduino Pro Micro - program SimHub - obsługuję zegary/wyświetlacze - Link do programu SimHub Zamówiłem też 20 guzików (push button), 10 styczników krańcowych, 2 joysticki, 2 wyświetlacze Tm1638, 1 wyświetlacz Max7219 (zamówiłem też sterownik silnika BTS7960 lecz na razie nie zakładałem FFB). Rzeczy które miałem w domu to: 2 potencjometry 10k Ohm, stycznik krańcowy ls-11s, kable kawałki plastiku, materiału i gumy. Za postawę stanowiska posłużyła mi deska rozdzielcza i fotel od mazdy mx-5 i kierownica od mazdy 626. Całość jest przyspawana do rurki i przykręcona do euro palety. Z racji tego że deska pochodzi z anglika to nie mogłem zamontować zwykłych zegarów w miejscu poduszki pasażera. Zamieszczam tutaj scheamty podłączeń danych elementów: Drugim problemem który chce tu opisać, było przeniesienie/ zczytanie obrotu z kierownicy do arduino. Na początku chciałem wykorzystać enkoder optyczny z swojej starej drukarki, lecz gubił się on często i nie działał dokładnie, więc kupiłem enkoder inkrementalny 600ppr. Nie będę się już tak rozpisywał co jak i gdzie jest skręcone dlatego wszystko pokazane i omówione jest w filmiku do którego link jest na początku posta. Więc to jest dodatkowy materiał dla ciekawych. Podsumowując: koszt budowy stanowiska zamknął się dla mnie w kwocie 300zl, czas realizacji od pierwszego pomysłu do zbudowania całości i upewnienia się że wszystko jest sprawne to 6 miesięcy. Tak oto prezentuję się kierownica i jej działanie w grze Forza Horizon 4 Na koniec pytanie głownie do administratora, czy i kiedy będzie znowu dostępny konkurs Opisz elektroniczne DIY i odbierz 50 zł rabatu do Botland?
  14. Cześć razem z kolegą pracujemy nad robotem na konkurs RoboRave w łęgowie. Robot będzie startował w kategori firefighting. Będzie miał za zadanie zgaszenie 4 losowo rozmieszczonych świeczek na wysokości od 10cm do 45cm. Jest opart na arduino a za szkielet posłużą nitowane płytki. Dodatkowe elementy takie jak zaokrąglenia rogów podstawy pochodzą z drukarki 3d. Gdy robot będzie gotowy wstawię dokładniejszy opis.
  15. Cześć, od jakiegoś czasu pracuję nad projektem, który polega na zaprojektowaniu, zbudowaniu i zaprogramowaniu plotera do skanowania pola magnetycznego. Elektronika układu to Arduino Uno R3 oraz CNC Shield ze sterownikami A4988, czujnik to magnetometr GY-271. Problem polega na tym, że kod który napisałem dziś przestał działać a nie modyfikowałem go od ostatniego razu kiedy wszystko było w porządku, nie wiem gdzie może być błąd ale wydaje mi się, że w kodzie dotyczącym obsługi czujnika magnetycznego próbowałem go zmienić ale niestety bez powodzenia tak jakby kod utkną w pętli while. Kod do obsługi czujnika zapożyczyłem od Jastrzębskiego ze strony : http://www.jarzebski.pl/arduino/czujniki-i-sensory/3-osiowy-magnetometr-hmc5883l.html Całość kodu poniżej. #include <Wire.h> //biblioteka do komunikacji z czujnikiem przez I2C #include <HMC5883L.h> //biblioteka do obsługi czujnika #define dirPin_X 5 #define stepPin_X 2 #define dirPin_Y 6 #define stepPin_Y 3 #define enable 8 int kroki_X = 400; //kroki silnika osi X, 400 kroków = przesunięcie o 1mm int kroki_Y = 80; //kroki silnika ois Y, 80 kroków = przesuięcie o 1mm int rozmiar_X = 2; //liczba wykoania pętli for ruchu silnika osi X int rozmiar_Y = 20; //liczba wykoania pętli for ruchu silnika osi Y int predkosc_X = 2000; //szybkości z jaką będzie obracał się silnik osi X int predkosc_Y = 2000; //szybkości z jaką będzie obracał się silnik osi X int LiczbaProbek = 1; //liczba pomiarów do wykanania wzdłuż osi Y int koniec = 6; //warunek kończący pracę skanera int pozycja_x; //pusty zbiór do zapisu pozycji silnika osi X int pozycja_y; //pusty zbiór do zapisu pozycji silnika osi Y String odebraneDane = ""; // pusty ciąg odebranych danych HMC5883L czujnik; //zmienna globalna void setup() { Serial.begin(9600); //rozpoczęcie komunikacji // Inicjalizacja HMC5883L Serial.println("Initialize HMC5883L"); while (!czujnik.begin()) { Serial.println("Nie odnaleziono HMC5883L, sprawdz polaczenie!"); delay(500); } // Ustawienie zakresu pomiarowego // +/- 0.88 Ga: HMC5883L_RANGE_0_88GA // +/- 1.30 Ga: HMC5883L_RANGE_1_3GA (domyslny) // +/- 1.90 Ga: HMC5883L_RANGE_1_9GA // +/- 2.50 Ga: HMC5883L_RANGE_2_5GA // +/- 4.00 Ga: HMC5883L_RANGE_4GA // +/- 4.70 Ga: HMC5883L_RANGE_4_7GA // +/- 5.60 Ga: HMC5883L_RANGE_5_6GA // +/- 8.10 Ga: HMC5883L_RANGE_8_1GA czujnik.setRange(HMC5883L_RANGE_1_3GA); // Ustawienie trybu pracy // Uspienie: HMC5883L_IDLE // Pojedynczy pomiar: HMC5883L_SINGLE // Ciagly pomiar: HMC5883L_CONTINOUS (domyslny) czujnik.setMeasurementMode(HMC5883L_CONTINOUS); // Ustawienie czestotliwosci pomiarow // 0.75Hz: HMC5883L_DATARATE_0_75HZ // 1.50Hz: HMC5883L_DATARATE_1_5HZ // 3.00Hz: HMC5883L_DATARATE_3HZ // 7.50Hz: HMC5883L_DATARATE_7_50HZ // 15.00Hz: HMC5883L_DATARATE_15HZ (domyslny) // 30.00Hz: HMC5883L_DATARATE_30HZ // 75.00Hz: HMC5883L_DATARATE_75HZ czujnik.setDataRate(HMC5883L_DATARATE_15HZ); // Liczba usrednionych probek // 1 probka: HMC5883L_SAMPLES_1 (domyslny) // 2 probki: HMC5883L_SAMPLES_2 // 4 probki: HMC5883L_SAMPLES_4 // 8 probki: HMC5883L_SAMPLES_8 czujnik.setSamples(HMC5883L_SAMPLES_1); pinMode(stepPin_X, OUTPUT); //Ustawienie stepPin_X jako wyjście pinMode(dirPin_X, OUTPUT); //Ustawienie dirPin_X jako wyjście pinMode(stepPin_Y, OUTPUT); //Ustawienie stepPin_Y jako wyjście pinMode(dirPin_Y, OUTPUT); //Ustawienie dirPin_X jako wyjście pinMode(enable, HIGH); //Ustawienie stanu wyskoiego na enable } void loop(){ if(Serial.available() > 0) { //Czy arduino odebrało dane? //jeżeli tak to odczytaj je do znaku końca linii i zapisz w zmiennej odebrane dane odebraneDane = Serial.readStringUntil('\n'); for(int i = 0;odebraneDane == "start";i++){ //Jeżeli odebrane słowo to start rozpocznij program poniżej if (pozycja_x < koniec){ //Warunek zatrzymania programu for (int i = 0; i < rozmiar_Y; i++){ //Pętla odpowiedzialna za ruch silnika wzdłuż osi Y+ kroki_plus1mm_Y(); Vector norm = czujnik.readNormalize(); //pomiar pola magnetycznego wykonywany co 1mm pozycja_y = pozycja_y + LiczbaProbek; //Zapisywanie pozycji silnika osi Y Serial.print("x_"); //Wyświetlenie aktualnej pozycji osi X Serial.print(pozycja_x); Serial.print(" Y_"); //Wyświetlenie aktualnej pozycji osi Y Serial.print(pozycja_y); Serial.print(" pomiar = "); //Wyświetlenie wyniku pomiaru pola magnetycznego Serial.print(norm.ZAxis); Serial.println( ); } for (int i = 0; i < rozmiar_X; i++){ //Pętla odpowiedzialna za ruch silnika wzdłuż osi x+ kroki_plus1mm_X(); pozycja_x = pozycja_x + 1; //Zapisywanie pozycji silnika osi X } for (int i = 0; i < rozmiar_Y; i++){ //Pętla odpowiedzialna za ruch silnika wzdłuż osi Y- kroki_minus1mm_Y(); Vector norm = czujnik.readNormalize(); //pomiar pola magnetycznego wykonywany co 1mm pozycja_y = pozycja_y - LiczbaProbek; //Zapisywanie pozycji silnika osi Y Serial.print("x_"); //Wyświetlenie aktualnej pozycji osi X Serial.print(pozycja_x); Serial.print(" Y_"); //Wyświetlenie aktualnej pozycji osi Y Serial.print(pozycja_y); Serial.print(" pomiar = "); //Wyświetlenie wyniku pomiaru pola magnetycznego Serial.print(norm.ZAxis); Serial.println( ); } for (int i = 0; i < rozmiar_X; i++){ //Pętla odpowiedzialna za ruch silnika wzdłuż osi x+ kroki_plus1mm_X(); pozycja_x = pozycja_x + 1; //Zapisywanie pozycji silnika osi X } } else{ Serial.println("SKANOWANIE ZAKOŃCZONO"); delay(5000); } } } } void kroki_plus1mm_X(){ digitalWrite(dirPin_X, HIGH); //ustwaienie kierunku wirowania silnika x zgodnie ze wskazówkami zegara for (int i = 0; i <kroki_X; i++) { //400 kroków przesunięcie o +1mm digitalWrite(stepPin_X, HIGH); //jeden krok silnika delayMicroseconds(predkosc_X); digitalWrite(stepPin_X, LOW); delayMicroseconds(predkosc_X); } } void kroki_plus1mm_Y(){ digitalWrite(dirPin_Y, HIGH); //ustwaienie kierunku wirowania silnika Y zgodnie ze wskazówkami zegara for (int i = 0; i <kroki_Y; i++) { //5 kroków przesunięcie o +1mm digitalWrite(stepPin_Y, HIGH); //jeden krok silnika delayMicroseconds(predkosc_Y); digitalWrite(stepPin_Y, LOW); delayMicroseconds(predkosc_Y); } } void kroki_minus1mm_X(){ digitalWrite(dirPin_X, LOW); //ustwaienie kierunku wirowania silnika X przeciwnie do ruchu wskazówek zegara for (int i = 0; i <kroki_X; i++) { //400 kroków przesunięcie o -1mm digitalWrite(stepPin_X, HIGH); //jeden krok silnika delayMicroseconds(predkosc_X); digitalWrite(stepPin_X, LOW); delayMicroseconds(predkosc_X); } } void kroki_minus1mm_Y(){ digitalWrite(dirPin_Y, LOW); //ustwaienie kierunku wirowania silnika y przeciwnie do ruchu wskazówek zegara for (int i = 0; i <kroki_Y; i++) { //5 kroków przesunięcie o -1mm digitalWrite(stepPin_Y, HIGH); //jeden krok silnika delayMicroseconds(predkosc_Y); digitalWrite(stepPin_Y, LOW); delayMicroseconds(predkosc_Y); } }
  16. Witam! Mam problem z tym projektem ponieważ mam podpięte wszystkie kabelki prawidłowo program i biblioteki również a działa tylko sensor (wykrywa ruch) i servomotor ("kręci tylko głową")a nie wysyła żadnego sygnału do silników. Proszę o pomoc! (Film na którym się wzorowałem https://www.youtube.com/watch?v=4CFO0MiSlM8 ) <---SCHEMAT #include <Servo.h> //Servo motor library. This is standard library #include <NewPing.h> //Ultrasonic sensor function library. You must install this library //our L298N control pins const int LeftMotorForward = 5; const int LeftMotorBackward = 4; const int RightMotorForward = 3; const int RightMotorBackward = 2; //sensor pins #define trig_pin A1 //analog input 1 #define echo_pin A2 //analog input 2 #define maximum_distance 200 boolean goesForward = false; int distance = 100; NewPing sonar(trig_pin, echo_pin, maximum_distance); //sensor function Servo servo_motor; //our servo name void setup(){ pinMode(RightMotorForward, OUTPUT); pinMode(LeftMotorForward, OUTPUT); pinMode(LeftMotorBackward, OUTPUT); pinMode(RightMotorBackward, OUTPUT); servo_motor.attach(11); //our servo pin servo_motor.write(90); delay(2000); distance = readPing(); delay(100); distance = readPing(); delay(100); distance = readPing(); delay(100); distance = readPing(); delay(100); } void loop(){ int distanceRight = 0; int distanceLeft = 0; delay(50); if (distance <= 20){ moveStop(); delay(300); moveBackward(); delay(400); moveStop(); delay(300); distanceRight = lookRight(); delay(300); distanceLeft = lookLeft(); delay(300); if (distance >= distanceLeft){ turnRight(); moveStop(); } else{ turnLeft(); moveStop(); } } else{ moveForward(); } distance = readPing(); } int lookRight(){ servo_motor.write(10); delay(500); int distance = readPing(); delay(100); servo_motor.write(90); return distance; } int lookLeft(){ servo_motor.write(170); delay(500); int distance = readPing(); delay(100); servo_motor.write(90); return distance; delay(100); } int readPing(){ delay(70); int cm = sonar.ping_cm(); if (cm==0){ cm=250; } return cm; } void moveStop(){ digitalWrite(RightMotorForward, LOW); digitalWrite(LeftMotorForward, LOW); digitalWrite(RightMotorBackward, LOW); digitalWrite(LeftMotorBackward, LOW); } void moveForward(){ if(!goesForward){ goesForward=true; digitalWrite(LeftMotorForward, HIGH); digitalWrite(RightMotorForward, HIGH); digitalWrite(LeftMotorBackward, LOW); digitalWrite(RightMotorBackward, LOW); } } void moveBackward(){ goesForward=false; digitalWrite(LeftMotorBackward, HIGH); digitalWrite(RightMotorBackward, HIGH); digitalWrite(LeftMotorForward, LOW); digitalWrite(RightMotorForward, LOW); } void turnRight(){ digitalWrite(LeftMotorForward, HIGH); digitalWrite(RightMotorBackward, HIGH); digitalWrite(LeftMotorBackward, LOW); digitalWrite(RightMotorForward, LOW); delay(500); digitalWrite(LeftMotorForward, HIGH); digitalWrite(RightMotorForward, HIGH); digitalWrite(LeftMotorBackward, LOW); digitalWrite(RightMotorBackward, LOW); } void turnLeft(){ digitalWrite(LeftMotorBackward, HIGH); digitalWrite(RightMotorForward, HIGH); digitalWrite(LeftMotorForward, LOW); digitalWrite(RightMotorBackward, LOW); delay(500); digitalWrite(LeftMotorForward, HIGH); digitalWrite(RightMotorForward, HIGH); digitalWrite(LeftMotorBackward, LOW); digitalWrite(RightMotorBackward, LOW); } Filmik jak działa.rar
  17. Witam. Chciałbym się tutaj zapytać czy jest taka możliwość, aby wyświetlacz podpięty przewodowo przerobić tak, aby był on bezprzewodowo ( oczywiście dokładając odpowiednie moduły)? Chodzi dokładnie o wyświetlacz przy drukarce 3D, a dokładniej chodzi o drukarkę Anet A8. Drukarka nie posiada oryginalnej płyty głównej, gdyż została ona zmieniona na MKS GEN L v1.0. Chodzi dokładniej o to, aby sygnały wychodzące z tej płytki na wyświetlacz podać na Arduino, a następnie wysłać je poprzez np. moduł bluetooth na drugie,które by je przetworzyli i wysłało na wyświetlacz podpięty do niego.
  18. Witam, Od dłuższego czasu próbuje rozwiązać problem z modułem ESP-01 podpiętym pod Arduino Mega. Mianowicie kiedy wysyłam dane przez serwer MQTT do ESP np. z telefonu i wyślę tych danych zbyt dużo w czasie od 1 do 5 sekund, to cały program przestaje reagować na kolejne dane przez najbliższe 20-40 sekund lub następuje ponowne uruchomienie Arduino. Program nie jest jakoś super skomplikowany (ponieważ służył mi tylko do testów ESP) więc myślę, że nie będzie on trudny do zrozumienia. Moduł jest podpięty do Arduino przez konwerter poziomów logicznych. Myślę, że problemem nie będzie połączenie, ponieważ wysyłanie danych działa bez problemu, a kiedy dane są wysyłane do ESP w odstępach 1-2 s to wszystko działa bez problemu. Kod: #include <LiquidCrystal.h> #include <WiFiEsp.h> #include <WiFiEspClient.h> #include <WiFiEspUdp.h> #include <PubSubClient.h> #include <SPI.h> char ssid[] = "My-WiFi"; // your network SSID (name) char pass[] = "1234567890"; // your network password char server[] = "broker.hivemq.com"; // your network password int status = WL_IDLE_STATUS; // the Wifi radio's status // Initialize the Ethernet client object WiFiEspClient espClient; PubSubClient client(espClient); LiquidCrystal lcd(7, 6, 5, 4, 3, 2); void setup() { lcd.begin(16, 2); lcd.clear(); lcd.print("Loading: "); delay(1500); lcd.clear(); // initialize serial for debugging Serial.begin(115200); // initialize serial for ESP module Serial1.begin(115200); // initialize ESP module lcd.setCursor(0, 0); lcd.print("ESP initialize "); lcd.setCursor(0, 1); lcd.print("40%"); WiFi.init(&Serial1); lcd.setCursor(0, 0); lcd.print("Connect to WiFi "); lcd.setCursor(0, 1); lcd.print("65%"); // check for the presence of the shield if (WiFi.status() == WL_NO_SHIELD) { Serial.println("WiFi shield not present"); // don't continue while (true); } // attempt to connect to WiFi network while (status != WL_CONNECTED) { Serial.print("Attempting to connect to WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network status = WiFi.begin(ssid, pass); } lcd.setCursor(0, 0); lcd.print("Connect to MQTT "); lcd.setCursor(0, 1); lcd.print("80%"); Serial.println("You're connected to the network"); //connect to MQTT server client.setServer(server , 1883); client.setCallback(callback); lcd.setCursor(0, 0); lcd.print("Connect to MQTT "); lcd.setCursor(0, 1); lcd.print("100%"); delay(400); lcd.clear(); } //print any message received for subscribed topic void callback(char* topic, byte* payload, unsigned int length) { payload[length] = '\0'; String value = String((char*)payload); Serial.println(value); lcd.clear(); lcd.print(value); if (value == "State" || value == "state") { lcd.clear(); lcd.print("ESP is ready"); client.publish("km/esp/data", "ESP is still ready"); } else { client.publish("km/esp/data", "OK"); } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); delay(250); } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting connection "); // Attempt to connect, just a name to identify the client if (client.connect("AMega")) { Serial.println("connected"); // Once connected, publish an announcement… client.publish("km/esp/data","ESP is ready"); // … and resubscribe client.subscribe("km/esp/input", 0); } else { Serial.print("failed"); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } Z góry dziękuje za pomoc.
  19. Zacznę od tego że jest to mój pierwszy post tutaj także liczę na konstruktywną krytykę Chciałem opisać jak zabrałem się za automatyzowanie swojego pokoju. Zaczęło się od tego, że chciałem kupić sobie jakieś inteligentne gniazdka - lecz na budżet studencki jedno gniazdko w cenie ponad 50zł brzmi niezbyt dobrze. Także zacząłem myśleć jak zrobić to samemu no i oczywiście czy wyjdzie taniej korzystając z tego, że siedzę w tematach związanych z elektroniką i arduino. Jak to działa ? Wykorzystane materiały w tym projekcie to: - Moduł z 4 przekaźnikami - Płytka wemos nodemcu - bądź inna dowolna na bazie esp8266 -Zasilacz 5v ( ja użyłem znalezionego w domu zasilacza - recykling hah ) -przewody silikonowe do łączenia wyjść arduino z wejściami sterowania modułu z przekaźnikami -listwa zaciskowa też w sumie dowolna (także wykorzystana jakaś znaleziona w odmętach szafek) -no i puszka natynkowa do której wszystko się zmieści - wykorzystałem jeszcze także diodę która zapewniała niewielki spadek napięcia z zasilacza ( zasilacz miał 5,2V i układ miał problem z normalną pracą, musiał być zasilany lekko poniżej 5v) Najpierw skonfigurowałem na platformie https://remoteme.org/ połączenie dzięki któremu będę mógł zarządzać zmiennymi ( w tym przypadku odpowiadającymi za zapalanie się poszczególnych lamp w pokoju za pomocą przekaźników). Platformę te wykorzystywałem już wcześniej do projektów także wiedziałem, że jest to coś czego potrzebuję. Zacząłem od dodania nowego urządzenia. Na kolejnych zrzutach ekranu pokażę jak przejść przez proces dodawania/konfiguracji urządzenia. Następnie przechodzimy do zakładki Variables i tworzymy nową zmienną za pomocą "Add" w prawym górnym rogu. Można stworzyć tyle zmiennych ile będzie potrzebnych - w moim przypadku są to 4 zmienne( 4 przekaźniki, oraz 1 dodatkowa do sterowania wszystkimi na raz) Następnie wracamy do zakładki devices aby dodać zmienne do naszego urządzenia(połączyć je) i wygenerować kod. Dodajemy zmienne które mają sterować wyjściami w danym urządzeniu. Łączymy oczywiście urządzenie do naszej sieci domowej w której będzie odbywać się sterowanie i generujemy nowy token. Tutaj możemy pobrać kod, w tym wypadku używać będę płytki nodemcu(wemos) więc jest to na bazie esp8266. Tutaj jest kod wygenerowany przez stronę- bez żadnych modyfikacji SmartLight-download.rar Tutaj kod po lekkich modyfikacjach (dodanie zmiennych pomocniczych/zadeklarowanie wyjść) SmartLights.rar Taki kod wgrałem na płytkę nodemcu Następnie jak połączyć remote me z google assistant zapytacie ? No ja użyłem do tego https://ifttt.com/ Zaczynamy od tworzenia nowego appletu If - czyli czym będziemy wyzwalać działanie. W tym przypadku będzie to komenda otrzymana przez google assistent. Wpisujemy na jaką komendę ma oczekiwać i co ma odpowiedzieć po jej rozpoznaniu. Teraz wybierzemy co ma się stać gdy rozpozna komendę. W tym momencie musimy wrócić na chwilę do remote me, aby wygenerować link który będzie wyzwalać ifttt Zaznaczamy metodę post następnie kopiujemy link i wklejamy w odpowiednie pole w ifttt Teraz trochę o hardware. To jest moduł przekaźnika i przymocowane do niego nodemcu. Połączenia są następujące Nodemcu moduł D0-> IN1 D1-> IN2 D2-> IN3 D3-> IN4 VIN->VCC GND->GND Moduł razem z zasilaczem przymocowałem do płytki miedzianej aby łatwiej było wszystko montować( w moim przypadku przykręcić do drewnianej belki) Tak się prezentuje zmontowany i zamontowany moduł Połączenie jest zrobione tak, że w przypadku problemów z internetem/układem dalej można wł/wył światło za pomocą przełącznika na ścianie. Tutaj jeszcze filmik z testowania Mam nadzieję, że ten opis komuś się przyda Jeżeli czegoś zapomniałem, coś jest źle/za mało wyjaśnione to chętnie poprawię i coś dodam !
  20. Witam, realizuje w swoim pokoju projekt złożony z taśm led ws2812b, podzielonych na dwa niezależne paski ze względu na to że są różnej długości, a chce żeby efekty wyglądały na nich dobrze (jeden ma 640 diod, drugi 54 diod, aby efekt tęczy na obydwu miał pełne spektrum mam dwa oddzielne kody nadające paskom ten sam efekt). Mój problem pojawia się przy próbie sterowania tym, chcę aby wszystko było sterowane za pomocą pilota na podczerwień. Nie rozumiem kompletnie biblioteki IRemote, chciałbym aby wyglądało to tak, że po włączeniu włącza się efekt 1 (jakby animacja włączania), który jak się zakończy wyłącza się i włącza się efekt 2 (tęcza), który trwa cały czas, dopiero po przełączeniu pilotem na efekt 3 i tak samo z powrotem, pilotem na efekt 2. Efekt 4 (jeżel jest takie coś możliwe) po naciśnięciu przycisku na pilocie kolor zmienia sie powiedzmy z czerwonego na pomarańczowy, po ponownym nacisnieciu na żółty, dalej na zielony itd. Tak samo z jasnością efektu jeden przycisk na jasniej, drugi na ciemniej. I efekt 5 tak aby reagowało na muzykę, mam czujnik dzwieku ( https://allegro.pl/oferta/czujnik-dzwieku-8244890546 ) jeżeli się przyda, aby go wykorzystać do tego, bo podłączenie przez kabel jack odpada. Więc prosiłbym o pomoc z połączeniem tego wszystkiego, tak aby dało się to sterowac pilotem i napisanie tych 2 ostatnich efektów. dziękuję za wszystkie odpowiedzi Efekt 1 pasek 1 #include <Adafruit_NeoPixel.h> Adafruit_NeoPixel pasek1 = Adafruit_NeoPixel(640, 6, NEO_GRB + NEO_KHZ800); void setup() { pasek1.begin(); pasek1.show(); } void loop() { int i = 0; for (i = 0; i < 640; i++) { if (i < 640 ) { pasek1.setPixelColor(i, pasek1.Color(255, 0, 0)); } pasek1.show(); delay(10); } pasek1.clear(); } Efekt 1 pasek 2 #include <Adafruit_NeoPixel.h> Adafruit_NeoPixel pasek1 = Adafruit_NeoPixel(54, 6, NEO_GRB + NEO_KHZ800); void setup() { pasek1.begin(); pasek1.show(); } void loop() { int i = 0; for (i = 0; i < 54; i++) { if (i < 54 ) { pasek1.setPixelColor(i, pasek1.Color(255, 0, 0)); } pasek1.show(); delay(185); } pasek1.clear(); } efekt 2 pasek 1 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(640, 6, 640, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Rainbow - LEDS: 640 // Steps: 640 - Delay: 20 // Colors: 3 (255.0.0, 0.255.0, 0.0.255) // Options: rainbowlen=640, toLeft=true, if(millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00; float factor1, factor2; uint16_t ind; for(uint16_t j=0;j<640;j++) { ind = strip_0.effStep + j * 1; switch((int)((ind % 640) / 18)) { case 0: factor1 = 1.0 - ((float)(ind % 640 - 0 * 18) / 18); factor2 = (float)((int)(ind - 0) % 640) / 18; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 640 - 1 * 18) / 18); factor2 = (float)((int)(ind - 18) % 640) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 640 - 2 * 18) / 18); factor2 = (float)((int)(ind - 36) % 640) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 640) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 2 pasek 2 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(54, 6, 54, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Rainbow - LEDS: 54 // Steps: 54 - Delay: 20 // Colors: 3 (255.0.0, 0.255.0, 0.0.255) // Options: rainbowlen=54, toLeft=true, if(millis() - strip_0.effStart < 20 * (strip_0.effStep)) return 0x00; float factor1, factor2; uint16_t ind; for(uint16_t j=0;j<54;j++) { ind = strip_0.effStep + j * 1; switch((int)((ind % 54) / 18)) { case 0: factor1 = 1.0 - ((float)(ind % 54 - 0 * 18) / 18); factor2 = (float)((int)(ind - 0) % 54) / 18; strip_0.strip.setPixelColor(j, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2); break; case 1: factor1 = 1.0 - ((float)(ind % 54 - 1 * 18) / 18); factor2 = (float)((int)(ind - 18) % 54) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2, 0 * factor1 + 255 * factor2); break; case 2: factor1 = 1.0 - ((float)(ind % 54 - 2 * 18) / 18); factor2 = (float)((int)(ind - 36) % 54) / 18; strip_0.strip.setPixelColor(j, 0 * factor1 + 255 * factor2, 0 * factor1 + 0 * factor2, 255 * factor1 + 0 * factor2); break; } } if(strip_0.effStep >= 54) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 3 pasek 1 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(640, 6, 640, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Fade - LEDS: 640 // Steps: 5000 - Delay: 1 // Colors: 2 (0.0.0, 255.255.255) // Options: duration=5000, every=1, if(millis() - strip_0.effStart < 1 * (strip_0.effStep)) return 0x00; uint8_t r,g,b; double e; e = (strip_0.effStep * 1) / 5000; r = ( e ) * 255 + 0 * ( 1.0 - e ); g = ( e ) * 255 + 0 * ( 1.0 - e ); b = ( e ) * 255 + 0 * ( 1.0 - e ); for(uint16_t j=0;j<640;j++) { if((j % 1) == 0) strip_0.strip.setPixelColor(j, r, g, b); else strip_0.strip.setPixelColor(j, 0, 0, 0); } if(strip_0.effStep >= 5000) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; } efekt 3 pasek 2 #include <Adafruit_NeoPixel.h> class Strip { public: uint8_t effect; uint8_t effects; uint16_t effStep; unsigned long effStart; Adafruit_NeoPixel strip; Strip(uint16_t leds, uint8_t pin, uint8_t toteffects, uint16_t striptype) : strip(leds, pin, striptype) { effect = -1; effects = toteffects; Reset(); } void Reset(){ effStep = 0; effect = (effect + 1) % effects; effStart = millis(); } }; struct Loop { uint8_t currentChild; uint8_t childs; bool timeBased; uint16_t cycles; uint16_t currentTime; Loop(uint8_t totchilds, bool timebased, uint16_t tottime) {currentTime=0;currentChild=0;childs=totchilds;timeBased=timebased;cycles=tottime;} }; Strip strip_0(54, 6, 54, NEO_GRB + NEO_KHZ800); struct Loop strip0loop0(1, false, 1); //[GLOBAL_VARIABLES] void setup() { //Your setup here: strip_0.strip.begin(); } void loop() { //Your code here: strips_loop(); } void strips_loop() { if(strip0_loop0() & 0x01) strip_0.strip.show(); } uint8_t strip0_loop0() { uint8_t ret = 0x00; switch(strip0loop0.currentChild) { case 0: ret = strip0_loop0_eff0();break; } if(ret & 0x02) { ret &= 0xfd; if(strip0loop0.currentChild + 1 >= strip0loop0.childs) { strip0loop0.currentChild = 0; if(++strip0loop0.currentTime >= strip0loop0.cycles) {strip0loop0.currentTime = 0; ret |= 0x02;} } else { strip0loop0.currentChild++; } }; return ret; } uint8_t strip0_loop0_eff0() { // Strip ID: 0 - Effect: Fade - LEDS: 54 // Steps: 5000 - Delay: 1 // Colors: 2 (0.0.0, 255.255.255) // Options: duration=5000, every=1, if(millis() - strip_0.effStart < 1 * (strip_0.effStep)) return 0x00; uint8_t r,g,b; double e; e = (strip_0.effStep * 1) / 5000; r = ( e ) * 255 + 0 * ( 1.0 - e ); g = ( e ) * 255 + 0 * ( 1.0 - e ); b = ( e ) * 255 + 0 * ( 1.0 - e ); for(uint16_t j=0;j<54;j++) { if((j % 1) == 0) strip_0.strip.setPixelColor(j, r, g, b); else strip_0.strip.setPixelColor(j, 0, 0, 0); } if(strip_0.effStep >= 5000) {strip_0.Reset(); return 0x03; } else strip_0.effStep++; return 0x01; }
  21. Cześć mam problem z zaprogramowaniem analogowego czujnika płomieni Waveshare. Jest to czujnik z botlandu za 10.99zł. Buduje robota na konkurs RoboRave w kategorii fire fighting. Jeżeli znacie jakiś poradnik to o podanie linku czy nazwy. Z góry dziękuje.
  22. Witam, Od niedawna jestem na forum, pisze w związku z problemem, który napotkałem przy projekcie. Projektem jest skaner szczątkowego pola magnetycznego, to znaczy chodzi o zbudowanie urządzenia które będzie poruszało się w trzech osiach X,Y,Z tak jak ploter, drukarka 3D, itd. zamiast frezu czy hotendu ma być moduł czujnika pola magnetycznego GY-271. Urządzenie ma skanować wybrany obiekt ,zapisać dane do pliku a na podstawie zapisanych danych będzie stworzony wykres 3D rozkładu szczątkowego pola magnetycznego. Problem polega na tym, że nie jestem dobry w programowaniu, potrafię sobie poradzić z odczytem danych z czujnika ale mam zbyt małą wiedzę by napisać program do obsługi trzech silników które pozwalałyby wprowadzić w ruch czujnik. Myślałem nad wykorzystaniem oprogramowania GRBL ale musiałbym użyć dwóch procesorów, jedna płytka arduino obsługiwała by czujnik a druga ploter, próbowałem połączyć dwa programy ale niestety nie udało mi się. I tu pojawia się moje pytanie do was bardziej doświadczonych użytkowników arduino, czy można było by rozwiązać ten problem w inny sposób?, czy może ktoś mógłby pomóc mi w napisaniu kodu do obsługi skanera? Za wszelką pomoc dziękuję wam z góry.
  23. Witam Chciałbym napisać kod dzięki któremu gdy kliknę przycisk, na wyświetlaczu pokazuje licznik który liczy do 100%, a w tym samym czasie obraca się silnik krokowy. Niestety nie wiem jak to zrobić żeby w tym samy czasie wszytko to się działo. Jak próbowałem to zrobić, to najpierw wyświetlacz liczył do 100%, a potem kręcił się silnik. Pomocy!
  24. Witam Zakupiłem sobie arduino uno r3 i zestaw ( https://botland.com.pl/pl/zestawy-startowe-dla-arduino/1726-starterkit-rozszerzony-dla-arduino.html ) I kilka innych dodatków , nieważne ... Problem polega na tym ,że jak za czołem kurs z forbota ( miganie diody za pomocą przycisku ) 2 czy jakoś tak ... to przy zrobieniu pracy domowej ( 1.2 ) próbowałem napisać program i nie wyszło wiec wgrałem nowy dobry ( miganie diody co 1000ms i 1000ms przerwy ) i tu problem arduino już nie chciało reagować , z pc wszystko w porzątku program arduino.cc sprawdza , wgrywa wszystko i dobrze ale nie reaguje , nie działa .... przed wykonaniem pracy domowej program sprawdzajacy ( miganie diody L i dioda świeci ciagle ON ) a teraz niestety cały czas świeci sie ( dioda L i ON ) a po wgraniu dowolnego kodu dioda L , TX i RX migaja przez chwile i ( diody TX I RX gasną ) a dioda L zaczyna świecić ciągle .... Z góry dzięki za pomoc w rozwiązaniu problemu. PS. reset arduino daje efekt ( przez chwile miganie diody L i potem świeci ciągle ) a ON cały czas ciągle....
  25. Wstęp Na wstępie opiszę krótko projekt: Będzie to prosty układ, projekt głównie opiera się na kodzie w Arduino IDE (zamiana tekstu na alfabet morse'a i zapalanie diody) oraz którkim kodzie w Python do komunikacji arduino z PC. Potrzebne rzeczy: Potrzebne elementy: Arduino Uno/Leonardo, Płytka stykowa, dioda LED, rezystor min. 230 Ohm (u mnie 330 Ohm), 2x przewód męsko-męski Układ jest bardzo prosty do zmontowania Program w Arduino IDE: //zmienne String aM[25] = { //Kod alfabetu: 1-kropka, 2-kreska, 0-koniec (dla kodów o ilości kropek i kresek mniejszej od 4, optymalizacja) //A B C D E "1200", "2111", "2121", "2110", "1000", //F G H I J "1121", "2210", "1111", "1100", "1222", //K L M N O "2120", "1211", "2200", "2100", "2220", //P Q R S T "1221", "2212", "1210", "1110", "2000", //U W X Y Z "1120", "1220", "2112", "2122", "2211" }; char alfabet[25] = { //Alfabet łaciński - index aM[] i alfabet[] jest taki sam dla każdego znaku "abcdefghijklmnopqrstuwxyz" }; char message[100]; //Wiadomość otrzymana z komputera String msgGet; //Zmienna pomocnicza int aM_Delay = 300; //Czas kropki, wg zasad alfabetu morse'a kresta to 3x kropka int ledPin = 13; //Pin diody void setup() { // put your setup code here, to run once: pinMode(ledPin, OUTPUT); //ustawienie pinu diody na OUTPUT } void loop() { delay(2500); //Opóźnienie między komendami, nie jest wymagane for(int x=0; x<100; x++) //Wyczyszczenie całej wiadomości message[x] = '0'; bool waiting = true; //Zmienna pomocnicza while(waiting) { if(Serial.available() > 0) //Jeśli otrzymano wiadomość { msgGet = Serial.readString(); //Odczytanie wiadomości if(msgGet.length() > 100) //jeśli wiadomości jest za długa, zignoruj iteracje pętli - oczekiwanie na kolejną wiadomość continue; for(int i=0; i < msgGet.length(); i++) //Zapisanie wiadomości ze zmiennej string do tablicy char - ułatwia nadanie wiadomości message[i] = msgGet.charAt(i); msgGet = '0'; //Wyczyszczenie otrzymanej wiadomości waiting = false; //Koniec pętli while } } for(int m=0; m < 100; m++) //Pętla dla każdego znaku wiadomości { for(int i=0; i<=25; i++) //Pętla dla każdego znaku alfabetu { if(message[m] == alfabet[i]) //znalezienie indeksu znaku wiadomości w alfabecie { for(int x=0; x < 4; x++) //Znak może mieć max 4 kropki lub kreski { if('2' == aM[i].charAt(x)) //Jeśli 2 (kreska) - zapala diodę na aM_Delay * 3 - aM_Delay to też odstęp między sygnałami { digitalWrite(ledPin, HIGH); delay(aM_Delay * 3); digitalWrite(ledPin, LOW); delay(aM_Delay); } else if('1' == aM[i].charAt(x)) //Jesli 1 (kropka) -;;- { digitalWrite(ledPin, HIGH); delay(aM_Delay); digitalWrite(ledPin, LOW); delay(aM_Delay); } else if('0' == aM[i].charAt(x)) //Jeśli 0 - zakończ pętlę (koniec znaku) { delay(aM_Delay); break; } } } } } } Myślę, że komentarze w kodzie pozwolą wszystkim zrozumieć, o co chodzi Program w Python: import serial #biblioteka do komunikacji port = input("Enter port: ") #zmienna z ustawionym przez użytkownika portem do komunikacji ser = serial.Serial(port, 9600) #zainicjowanie płytki na wybranym porcie myMessage = "" #zmienna do zapisu wiadomości while 1: #pobieranie wiadomości w nieskończoność, dopóki nie wyłaczymy programu myMessage = input("Enter a message: ") #zapisanie wiadomości w zmiennej ser.write(myMessage.encode('UTF-8')) #wysłanie wiadomości przez port, z kodowaniem UTF-8 Aby poprawnie wprowadzić nazwę portu, najłatwiej podłączyć arduino do komputera i w arduino IDE sprawdzić port, u mnie np. jeszt to COM5 (Arduino Leonardo) - wpisujemy więc COM5 A tak wygląda program w Pythonie po odpaleniu, jednak aby nie odpalać go za każdym razem z poziomu CMD, ułatwimy sobie zadanie kolejnym plikiem: run.bat w którym podajemy ścieżkę do pliku python (wraz z rozszerzeniem!) @echo off start G:\ArduinoProjects\MorseCodeNadajnik\MorseCode_Nadajnik.py Plik .bat nie jest wymagany, ale ułatwia odpalanie komunikacji Należy również pamiętać, że każdu port USB w komputerze to inny port w do wpisanie w Pythonie (wielu o tym zapomina) Mam nadzieję, że komuś to pomoże
×
×
  • Utwórz nowe...