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 275 wyników

  1. 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.
  2. 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!
  3. 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....
  4. 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?
  5. 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
  6. 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
  7. Witam, przy wypalaniu bootloadera pojawił mi się taki komunikat: avrdude: Yikes! Invalid device signature Double check connections and try again, or use -F to override this check. Wie ktoś co może być nie tak i jak to naprawić?
  8. Witam Niedawno zakupiłem kolna Arduino mega 2560 udało mi się zainstalować sterowniki i w środowisku arduino działa poprawnie. Jednak z doświadczenia wiem, że aplikacja arduino jest bardzo ograniczona i dlatego wszystkie programy piszę w Visual Studio Code Platform IO. Niestety pojawia mi się tutaj problem z wyborem płytki podczas tworzenia programu. W platfotmIO do wyboru arduino mega są setki i nie mam zielonego pojęcia jaką opcję wybrać . Na klonie jest chip Atmega256J 16U-TH. Czy ktoś pracuje w tym środowisku i jest w stanie mi coś poradzić podpowiedzieć ? Za pomoc byłbym bardzo wdzięczny.
  9. Witam, Od 1,5 miesiąca uczę się programować Arduino Uno rev3 korzystając z zakupionego zestawu Forbot Arduino na Botlandzie. Przerobiłem tutoriale oraz spędziłem sporo godzin tworząc przykładowe projekty, jednakże nie potrafię ogarnąć jednej kwestii związanej z GSM AT Commands. Aktualnie staram się stworzyć urządzenie sprawdzające zasięg GSM i wysłać tę informację na ThinkSpeak (albo inny serwis/php/excel sheets itp). Wysyłanie danych do ThinkSpeak, MySql, Google Sheets etc udało mi się osiągnąć, jednakże mam problem z wysłaniem mojej zmiennej, czyli zasięgu (który wywołuję komendą AT+CSQ i otrzymuję wartość w postaci +CSQ:18,99 , z której tylko cyfra 18 mnie interesuje). Kod programu przesyłam poniżej. Arduino Uno rev 3 wyposazyłem w DFRobot Shield GPRS SIM800C Aktualnie arduino wysyła z "ręki" wpisaną stałą wartość 18, jednakże tutaj chciałbym aby pobierał dane z +CSQ i otrzymaną wartość dodał w wysyłany link. z góry dziękuję za pomoc! //testing GSM signal strenght and sending it to ThingSpeak #include <SoftwareSerial.h> // I am using DFRobot Shield GPRS SIM800C therefore need to redirect RX and TX #define SIM_800_RX 2 #define SIM_800_TX 3 SoftwareSerial MySerial(SIM_800_RX, SIM_800_TX); int delayShort=1000; //time delays = 1 second int delayMedium=3000; //time delays = 3 seconds int delayLong=60000; //time delays = 60 seconds void setup() { Serial.begin(9600); // Open serial communications and wait for port to open: while (!Serial); MySerial.begin(9600); // set the data rate for the SoftwareSerial port delay(delayShort); MySerial.println("AT"); // checking communication with GSM printGSMreply(); //expecting answer is OK delay(delayMedium); MySerial.println("at+csq"); delay(delayShort); printGSMreply(); //expecting answer is +CSQ:18,99 MySerial.println("at+cipshut"); //Close the GPRS PDP context - if deleted I am getting error message delay(delayShort); printGSMreply(); //expecting answer is OK } void loop() { sendToGsm(); //Start the GSM-Modul and start the transmisson delay(delayMedium); //Wait one minute } void sendToGsm() { MySerial.println("at+csq"); printGSMreply(); //expecting answer is arround +CSQ:18,99 and would like to send number 18 to ThingSpeak delay(delayShort); MySerial.println("at+cstt=\"internet\",\"\",\"\""); printGSMreply(); MySerial.println("at+ciicr"); //brings up the GPRS connection printGSMreply(); MySerial.println("at+cifsr");//enquire my IP address allocated printGSMreply(); MySerial.println("at+cipstart=\"TCP\",\"184.106.153.149\",\"80\"");//connect to the ThingSpeak IP address which will be translated as update URL (https://api.thingspeak.com) printGSMreply(); MySerial.println("at+cipsend=72");//declare the number of characters I want to send to ThinkSpeak plus +3 => in my case 69+3=72 printGSMreply(); MySerial.print("GET /update?");//this is a constant beginning for the GET command and is as provided by ThingSpeak printGSMreply(); MySerial.print("api_key=ABCDEFGHIJKLMNOP");//the channel API key provided by ThingSpeak printGSMreply(); MySerial.print("&field1="); printGSMreply(); MySerial.println("18");//!!HERE I WOULD LIKE TO GET MY AT+CSQ VALUE!! printGSMreply(); MySerial.println("at+cipack");//ask for acknowledge details printGSMreply(); MySerial.println("at+CIPCLOSE");//close the IP connection (mozna uzyc CIPSHUT printGSMreply(); } void printGSMreply() //Print GSM Status { while (MySerial.available()) { Serial.write(MySerial.read()); } }
  10. Witam!!! Wczoraj otrzymałem zamówieniem z serwem 360 towerPro sg90 360 stopni. Podłączyłem je do arduino, Wgrałem program z biblioteką servo.h, a serwo ani drgnie. Zasilanie serwomechanizmu mam z pakietu 4,8v do odbiorników rc, płytka arduino nano. Kod jakiego użyłem: #include <Servo.h> Servo serwomechanizm; void setup() { // put your setup code here, to run once: attach.serwomechanizm(9) } void loop() { // put your main code here, to run repeatedly: write.serwomechanizm(180) } Czy zna może ktoś przyczynę problemu???
  11. 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ć
  12. Dobry wieczór, Jestem "świeży" w sprawach programowania kontrolerów takich jak arduino, ale musiałem zrobić projekt na uczelnie. Wybrałem sobie sterowany przez moduł bluethooth XM-15 czołg. Podłączyłem wszystko z lekką pomocą stworzyłem połączenie z telefonem, przy użyciu terminala arduino "odpowiadało mi". Więc dodałem bibliotekę do silników dodałem kilka linijek kodu i wtedy zaczął się problem. Używam shielda z L293D i póki arduino jest połączone z komputerem czołg się porusza, ale jeśli podepnę zasilanie do złącza DC, nic nie działa. Używam Arduino Leonardo, a moduł bluethooth jest połączony do pinów 10,11. Czy to wina płytki czy coś w kodzie mam nie tak? Drugie pytanie czy da się zamiast terminala sterować za pomocą "gotowych kontrolerów" z google marketu. Poniżej kod programu: #include <SoftwareSerial.h> #include <MotorDriver.h> //Deklaracja portu szeregowego dla Bluetootha SoftwareSerial Bluetooth(10, 11); //Utworz instancje Bluetooth 10-RX 11-TX int buffer_in[200]; int i=0; int BluetoothDane; //do zmiennej int będą zapisywane odebrane dane MotorDriver m; int jade=0; void setup() { //i=0; // jade=0;//uruchomienie transmisji z terminalem while(!Serial); Serial.begin(9600); Bluetooth.begin(9600); //uruchom SerialSoftware z prędkością 9600 baud //Serial.println("Polaczyles sie z modulem Bluetooth czolgiem"); // digitalWrite(13,LOW); } void loop() { if (Bluetooth.available()) //Jeśli są jakieś dane { i=0; while (Bluetooth.available()>0) //Odczytujemy dane z bluetooth aż odczytamy wszystko { buffer_in[i]=Bluetooth.read(); //kopiuje dane z bluetooth do bufora i++; } digitalWrite (13,HIGH); Serial.println("Odebrano =\n"); Serial.print(i); //Serial.print("Zawartosc bufora\n"); for(int j=0;j<i-5;j++) Serial.println(buffer_in[j]); Serial.print("Koniec bufora\n"); if (i>0) //sprawdzamy czy cokolwiek odebraliśmy { //jesli tak to sprawdzamy co w buforze if (buffer_in[0]==1) { Serial.println("jade do przodu"); m.motor(1,FORWARD,255); m.motor(4,FORWARD,255); } if (buffer_in[0]==2) { Serial.println("jade do tylu"); m.motor(1,BACKWARD,255); m.motor(4,BACKWARD,255); } if (buffer_in[0]==3) { Serial.println("prawo"); m.motor(1,FORWARD,255);; m.motor(4,BRAKE,0); } if (buffer_in[0]==4) { Serial.println("lewo"); m.motor(4,FORWARD,255); m.motor(1,BRAKE,0); } if (buffer_in[0]==5) { Serial.println("Stop"); m.motor(1,BRAKE,0); m.motor(4,BRAKE,0); } //jak już sprawdzilismy co w buforze to trzeba go wyczyscic // i w następnym przebiegu petli znowu czekamy na coś co przyjdzie z blue memset(buffer_in, 0, sizeof(buffer_in)); } delay(1); //odczekaj 1ms } }
  13. Od dawna interesowały mnie pomiary warunków meteorologicznych w mojej miejscowości, pierwsza stacja meteorologiczna, którą zbudowałem około roku 2010, wykonana była na mikrokontrolerze Atmega32. Do komunikacji z światem wykorzystywała moduł LAN Wiznet 7010a. Stacja ta była oprogramowana w języku BASCOM. Projekt który chcę zaprezentować dzisiaj działa już od roku 2018 i został oprogramowany w środowisku Arduino. Stacja została podzielona na 2 moduły, pierwszy pomiarowy oparty jest na klonie Arduino Nano oraz drugi odbiorczy którego sercem jest ESP8266 NodeMCU v3, służy on również do wyświetlania aktualnych pomiarów na wyświetlaczu LED dot matrix o wymiarach 8x56 punktów. Na pracach stolarskich się nie będziemy skupiać napiszę tylko że klatka meteorologiczna została wykonana z drewna sosnowego i umieszczona na wysokości 2 m. Moduł Pomiarowy Czujniki jakie zastosowałem to dwie sztuki DS18B20 pierwszy zajmuje się pomiarem temperatury przy gruncie na wysokości 5cm, drugi pełni rolę zapasowego czujnika temperatury na wypadek uszkodzenia się głównego czujnika BME280. Do pomiaru prędkości wiatru wykorzystuję wiatromierz firmy Maplin na jeden obrót wiatromierza przypadają 2 impulsy z kontaktronu który jest w nim zamontowany, producent dostarcza również odpowiedni wzór według którego można obliczyć rpm oraz prędkość wiatru w km/h. Dane mierzone przez wiatromierz możemy podzielić na dwie wartości, pierwsza to chwilowa prędkość, druga prędkość w porywach, aby uśrednić wartości mierzone program zlicza impulsy z 5s a następnie dokonuje odpowiednich obliczeń. Zebrane dane przesyłane są do drugiego urządzenia poprzez moduły radiowe które działają na częstotliwości 433,92 MHz. W tym celu zastosowana została biblioteka RCSwitch. Każda mierzona wartość jest wysyłana jako osobna transmisja. aby rozróżnić pomiary z konkretnych czujników mierzona wartość mnożona jest przez 100 a następnie dodawana jest liczba 100 000 dla pierwszego czujnika, 200 000 dla drugiego itd. Przykład kodu który realizuje tę funkcję poniżej: // temperatura sensor BME codetosend = temp * 100 + (1 * 100000); mySwitch.send(codetosend, 24); // wilgotnosc sensor BME codetosend = hum * 100 + (2 * 100000); mySwitch.send(codetosend, 24); Moduł Wewnętrzny Obudowa, która idealnie nadawała się do implementacji wewnętrznego modułu pochodzi z tunera IPTV Motorola VIP1910-9. Przedni panel został wykonany z ciemnego półprzepuszczalnego plastiku który idealnie nadaje się do umieszczenia w nim wyświetlacza. Sercem urządzenia jest układ ESP8266. "Moduł wewnętrzny" został również wyposażony w czujnik temperatury oraz wilgotności DHT22, dodatkowo w celu prezentacji zmierzonych wartości dołączone zostało 7 szt. modułów wyświetlacza LED dot matrix z układem MAX7219. Do obsługi tej matrycy zastosowałem bibliotekę Max72xxPanel.h która współpracuje z biblioteką Adafruit_GFX.h w ten sposób nie byłem zmuszony implementować do rozwiązania własnych czcionek. Matryca ta oprócz modułowej konstrukcji umożliwia również sterowaniem jasnością podświetlania, w tym celu aby uprzyjemnić użytkowanie w porach nocnych odbiornik został wyposażony w fotorezystor dzięki któremu potrafi określić natężenie oświetlenia otoczenia i odpowiednie ustawienie podświetlenia. Na wyświetlaczu w pierwszej kolejności wyświetlam aktualną godzinę oraz temperaturę wewnątrz pomieszczenia oraz wilgotność, po około jednej minucie wyświetlane są informacje odczytane z stacji meteo czyli temperatura wilgotność i ciśnienie, postanowiłem nie wyświetlać tutaj informacji dotyczących prędkości wiatru oraz temperatury przy gruncie. Decyzję tą podjąłem na podstawie użytkowania innego podobnego rozwiązania, akurat jak chcemy odczytać godzinę to wyświetlane są inne informacje. Dodatkowo w godzinach nocnych, które zostały ustawione w sztywnych ramach czasowych między 21:00 a 7:00 informacje odczytane z stacji meteo zostały okrojone tylko do temperatury. W projekcie zostały zastosowane 2 rodzaje animacji pierwsza z nich, przesuwa tekst z prawej strony wyświetlacza na lewą, z możliwością zatrzymania w interesujących momentach. Drugi rodzaj to pionowa animacja. Mikrokontroler również poprzez protokół NTP i bibliotekę time.h pobiera aktualną godzinę i datę. Za odbiór danych z pierwszego układu odpowiedzialny jest moduł radiowy którego obsługą tak jak w poprzednim module zajmuje się biblioteka RCswitch. Poniżej fragment programu który demonstruje w jaki sposób odbierane i dekodowane są dane: rc = mySwitch.getReceivedValue(); // czujnik temperatury powietrza BME280 if (abs(rc)>=50000&& abs(rc)<150000) { rc=(rc-100000)/100; if (rc > -50 and rc < 60) { temp1 = rc; Serial.print("Czujnik BME280 - temperatura: \t"); Serial.println(rc); matrix.drawPixel(55,0,1); matrix.write(); } } // czujnik wilgotności BME280 if (abs(rc)>=150000 && abs(rc)<250000) { rc=(rc-200000)/100; if (rc > 5 and rc <= 100) { hum = rc; Serial.print("Czujnik BME280 - wilgotnowsc: \t"); Serial.println(rc); matrix.drawPixel(55,1,1); matrix.write(); } } Dzięki zastosowaniu zewnętrznej anteny oraz odbiornika opartego na superheterodynie, zasięg w otwartym terenie to około 250 m. Po odebraniu danych z pierwszego układu poprzez moduł radiowy następuje przekazanie ich do serwera z systemem Domoticz. Domoticz to bardzo lekki system automatyki domowej, który pozwala monitorować i konfigurować różne urządzenia, przełączniki, czujniki takie jak temperatura, opady deszczu, wiatr, promieniowanie ultrafioletowe (UV), zużycie energii elektrycznej, zużycie gazu, zużycie wody i wiele więcej. Wykresy dostępne są również na stronie www http://meteo.palowice.net Poniżej film z działania odbiornika, smużenie animacji które występuje na filmiku ludzie oko nie rejestruje. Gdyby kogoś interesował kod to również zamieszczam: meteo.zip
  14. Pojawił mi się mały problem, a mianowicie gdy chce, żeby po wciśnięciu przycisku zaczął obracać się silnik, to nie mogę wyświetlić na wyświetlaczu(w tym samym momencie gdy silnik się kręci) "#" w pętli while (żeby był efekt ładowania), który co 1s pojawia "#", ponieważ najpierw silnik się obraca a później wyświetla "#" na wyświetlaczu.
  15. Witam serdecznie. Mam program napisany w Pythonie, działa. Mam jedno wejście, zwykły przycisk, który przekazuje 5V. No i tutaj pojawia się problem, bo przekazując 5V jest ok podaje True, ale jak nie daje sygnału to daje losowo True albo False. Jak odłącze przewód od wejścia to jest False, jak daje kabelek na wejście i wisi w powietrzu to też szaleje True/False. Jak podłącze ten wiszący kabelek do GND to jest dobrze - False. No i tutaj pojawia się pytanie czy tak powinno być- domyślam się, że nie, no bo jak ma teraz prawidłowo działać układ? Kiedyś też miałem z tym problem tylko wejście było analogowe -> podłączyłem wiszący kabelek do wejścia i zmieniało się samo losowo w wartościach od 0.22 do 1.0 mimo braku sygnału. Jakieś rady? Pozdrawiam :)
  16. Cześć wszystkim! Po raz pierwszy pytam się tutaj o coś więc z góry przepraszam jeżeli dałem złą kategorię. Ale przechodząc do mojego problemu ostatnio postanowiłem zrobić sobie stację lutowniczą, kupiłem do niej kolbę wep 907A. Po dłuższych poszukiwaniach znalazłem w internecie że w tej kolbie jest termopara typu K, ale po podpięciu jej pod układ max6675 dostaje bardzo przekłamane wartości. Podejrzewam, że jest tam po prostu inny rodzaj termopary i stąd moje pytanie - jak określić jaki to typ termopary i jak ją podłączyć do arduino? Uszkodzenie układu max6675 raczej wykluczam bo inne termopary dają na nim realne wartości. Tego że nie jest to termopara nie wykluczam, ale ma rezystancje około 1 ohma i generuje napięcie gdy kolba się grzeje więc raczej nic innego to nie może być (chyba, że się mylę) Z góry wielkie dzięki za jakąkolwiek pomoc
  17. Jest to mój pierwszy post więc witam wszystkich forumowiczów i proszę o pomoc bo jestem już mocno zdesperowany. Przeszukałem forum i internet ale nie natknąłem się na rozwiązanie mojego problemu. Zbudowałem w oparciu o podróbę Arduino Uno czujnik kąta obrotu zaginarki. Sprawa ma się następująco potencjometr wieloobrotowy, na ekranowanym przewodzie o długości 50cm, w roli dzielnika napięcia za pomocą kół zębatych odczytuje aktualną pozycję i na wyświetlaczu 7segmentowym wyświetla przyporządkowaną wartość kąta. Program się zgadza wszystko działa tak jak zaplanowałem. Problem polega na wartościach przetwornika ADC. Przy podpiętym zasilaniu po USB z laptopa czy komputera wartości przetwornika są w miarę stałe. Natomiast gdy podpinam zasilanie zewnętrzne z zasilacza impulsowego wartości wachają się +/- 4 co sprawia olbrzymi problem. Wykluczam ułożenie kabli ponieważ: przewód USB podpięty pod laptop - wszystko OK, ten sam przewód USB tak samo ułożony podpięty pod zasilacz 5v/power bank daje już spore zakłócenia. Objawy są te same przy wykorzystywaniu regulatora napięcia z płytki czyli podając zasilanie +9v na Arduino. Czy ktoś jest mnie wstanie naprowadzić jak rozwiązać problem a raczej jak stworzyć te same warunki zasilania zewnętrznego co przy zasilaniu z laptopa? Czyżby napięcie zasilania zasilaczy impulsowych +/-5% w ten sposób by się objawiało? Płytka nie jest oryginalna to fakt ale czy oryginalne Arduino w czymś by tu pomogło jeśli po zasilaniu z laptopa wszystko jest OK? W sumie to jestem trochę zdesperowany i jestem wstanie zasilać urządzenie przy pomocy uśpionego laptopa co raczej mija się z celem. A może po prostu zamiast zasilacza impulsowego zastosować trafo i wyprostować napięcie? Dziękuje za zainteresowanie i proszę o jakieś podpowiedzi rozwiązania problemu.
  18. Witam Od kilku dni bawię się arduino. Chciałem napisać program odpowiadający za sterowanie diodą i silnikiem a wielowątkowość zastąpić timerem. Niestety nie działa. Czy ktoś mógłby mi wytłumaczyć co robię źle? #include <Timers.h> //implementacja biblioteki Timers <2> watek; void migaj() { //funkcja diody digitalWrite(2, HIGH); } void silniki() { //funkcja silnika digitalWrite(3, HIGH); digitalWrite(4, LOW); } void setup() { pinMode(2, OUTPUT); //definicje pinów pinMode(3, OUTPUT); pinMode(4, OUTPUT); watek.attach(0, 2000, migaj); //wątki watek.attach(1, 5000, silniki); } void loop() { }
  19. Witam. Od niedawna zacząłem interesować się programowaniem oraz Arduino, i chciałbym zrobić takie coś (ale kompletnie nie wiem jak to zrobić): Klikam przycisk => silnik kręci się w prawo (3s) => przerwa (2s) => silnik kręci się w lewo (3s) => Stop. I kiedy kliknę przycisk znowu to samo od poczatku. *Arduino Leonardo *Silnik (zwykły, chiński z samochodu RC) Proszę o pomoc, będę bardzo wdzięczny.
  20. 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.
  21. Witam, mam problem z płytką arduino uno którą kupiłem w zestawie do kursu. Podczas pisania programu nie mogę nadać funkcji pinu, ponieważ program nie zauważa numeru, np pinMode(8, OUTPUT), - podświetla się wszystko oprócz 8.
  22. Cześć wszystkim. Udało mi się skompletować wszystkie potrzebne rzeczy do stworzenia pewnego mechanizmu. W skrócie mówiąc jest to mechanizm, który ma za zadanie po naciśnięciu przycisku otwierać klapkę. Pozycja otwarcia/zamknięcia klapki ustawiana jest za pomocą krańcówek. Niestety pojawił mi się problem z serwem (PowerHD LF-20MG-360 standard - praca ciągła 360 stopni). W momencie kiedy ma ono otwierać/zamykać klapkę potrafi nierówno pracować. Swój układ testowy zasilam z zasilacza ustawionego na 12V, ponieważ z takiego napięcia mam zasilane krańcówki. Reszta układu zasilana jest z przetwornicy 12V/5V (Pololu D24V22F5 - przetwornica step-down - 5V 2,5A). Spróbowałem sprawdzić, czy może pojedyncze elementy w moim układzie wpływają na pracę serwa. W tym celu napisałem program, który miał załączać serwo, gdy arduino otrzymywało sygnał albo z jakiegoś przycisku, albo z jakiejś krańcówki. Z każdego sygnału serwo chodziło równo. Niestety na docelowym programie serwo cały czas chodzi nierówno, a problem potęguje się jeżeli nastawię niską prędkość obrotową (np. 94 stopnie -serwo stoi przy 91*). Próbowałem naprawić problem poprzez wstawienie na wyjściu z przetwornicy kondensatora 470uF, ale jego obecność nic nie daje. Ostatecznie zauważyłem, że zmieniając wartość "delay" w kodzie programu udaje się trochę poprawić pracę serwo. Przy delay na poziomie 225ms serwo chodzi lepiej niż na 25ms, ale nadal nie jest to praca płynna. Ustawiając duże wartości delay, tracę możliwośc precyzyjnego sterowania klapką, bo zanim sygnał z krańcówki wyłączy serwo, to silnik nadal będzie się kręcił właśnie o tą wartość "delay". Poniżej przedstawiam swój kod, schemat układu i filmiki z pracy serwa (jeden na delay 25ms, drugi na 225ms). #include<Servo.h> Servo servo; void setup() { pinMode(10, INPUT); //przelacznik M pinMode(9, INPUT); //przelacznik D pinMode(8, INPUT); //krancowka na otwarciu pinMode(7, INPUT); //krancowka na zamknieciu pinMode(3, OUTPUT); //servo pin } void loop() { //ruch przesłony if(((digitalRead(10)==HIGH || digitalRead(9)==HIGH)&&(digitalRead(8)==LOW))) { servo.attach(3); servo.write(80); delay(25);} //servo otwiera przesłone else { digitalWrite(3,LOW);} //servo nie działa if((digitalRead(10)==LOW && digitalRead(9)==LOW && digitalRead(7)==LOW)) { servo.attach(3); servo.write(100); delay(25);} //servo zamyka przesłone else { digitalWrite(3,LOW);} //servo nie działa } Jeżeli filmiki są za mało wyraźne to postaram się je wrzucić w lepszej jakości. praca uklad.rar
  23. Witam, Jestem w trakcie budowy robota typu line follower na bazie Arduino. Do wykonania przedniego panelu z czujnikami zdecydowałem się wykorzystać sensory CNY70 oraz komparatory LM311P które za zadanie mają zamieniać sygnał analogowy na cyfrowy zależnie od progu decyzji wysłanego z arduino poprzez PWM. Wiem że sygnał PWM trzeba przefiltrować i myślałem o pasywnym filtrze RC, ale nie mam pojęcia jakie powinny być wartości kondensatorów i rezystora, żeby wszystko dobrze działało i pytanie czy taki filtr jest w ogóle w stanie dobrze spełniać swoje zadanie? Jeśli nie to czym można go zastąpić? Drugie pytanie, czy wygenerowany jeden sygnał PWM z mikrokontrolera może "obskoczyć" wszystkie komparatory wyznaczając dla nich taki sam próg decyzji?
  24. Cześć, ponieważ I2C jest jednym z najprostszych szeregowych protokołów komunikacyjnych (i jest bardzo często stosowany) postanowiłem sprawdzić jak wygląda przykładowa implementacja na zestawie FPGA. Zacząłem od prostszej rzeczy, czyli implementacji "I2C slave" (poniekąd też slave jest mi bardziej przydatny do moich eksperymentów). Ponieważ projekt jest stosunkowo prosty i nie zajmuje dużo zasobów postanowiłem go przetestować na zestawie FPGA ElbertV.2 (ten używany w kursie FPGA Forbot'a). Masterem I2C będzie zwykłe "Arduino UNO" - z poziomu Arduino bardzo prosto można oprogramować komunikację po I2C z użyciem biblioteki Wire. Punktem wyjścia do implementacji "I2C Slave" jest darmowy projekt zamieszczony na stronie opencores.org. Tutaj link do projektu: https://opencores.org/projects/i2cslave Projekt ma stosunkowo prostą budowę i jest właściwie tylko szkieletem do budowy na jego podstawie bardziej skomplikowanych układów (będzie to wyjaśnione dalej). Jak przeważnie się to zdarza trzeba było dodać nowy zegar (DCMs 1 ze Spartan3A) 48 MHz (pętla PLL), ponieważ oryginalny projekt pracował z takim zegarem. Po wykonaniu potrzebnych przeróbek projekt zajmuje niecałe 30% zasobów układu Spartan3 z Elberta - patrz screen: Jak można zobaczyć na podglądzie RTL - top entity projektu ma bardzo prosty interfejs - patrz screen: Tutaj kod w Verilog'u głównego modułu projektu (już po dodaniu zegara PLL 48 MHz) `include "i2cSlave_define.v" module i2cSlaveTop ( clk, rst, sda, scl, myReg0 ); input clk; input rst; inout sda; input scl; output [7:0] myReg0; wire clk48Mhz, clkBufg; // Instantiate the module PLL clock PLL_clock PLL_48Mhz ( .CLKIN_IN(clk), .RST_IN(~rst), .CLKFX_OUT(clk48Mhz), .CLKIN_IBUFG_OUT(clkBufg) ); i2cSlave u_i2cSlave( .clk(clk48Mhz), .rst(~rst), .sda(sda), .scl(scl), .myReg0(myReg0), .myReg1(), .myReg2(), .myReg3(), .myReg4(8'h12), .myReg5(8'h34), .myReg6(8'h56), .myReg7(8'h78) ); endmodule Jak widać "i2cSlaveTop" ma trzy wejścia: clk - główny zegar projektu (w Elbercie 12 Mhz) rst - reset asynchroniczny - stanem High więc dla naszej płytki FPGA trzeba go było zanegować scl - zegar magistrali I2c , jedno wejście/wyjście (inout) sda - dane magistrali I2C i jedno wyjście (wektor 8 bitów) myReg0 - na tym wyjściu równoległym będą się pojawiać dane wysłane przez mastera I2C (Arduino UNO), dlatego podłączymy je do diod LED w zestawie Elbert, aby móc te dane łatwo obserwować. Tutaj treść pliku ucf (user constraints) dla płytki FPGA Elbert: NET "clk" LOC = P129 | IOSTANDARD = LVCMOS33 | PERIOD = 12MHz; NET "rst" PULLUP; NET "rst" LOC = P76; NET "sda" LOC = P31 | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 12; NET "scl" LOC = P32 | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 12; # myReg0 - 8 bit data NET "myReg0[7]" LOC = P46 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[6]" LOC = P47 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[5]" LOC = P48 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[4]" LOC = P49 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[3]" LOC = P50 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[2]" LOC = P51 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[1]" LOC = P54 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; NET "myReg0[0]" LOC = P55 | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; Jak widać zdefiniowany jest domyślny pin zegara (12 MHz), reset - dolny z pięciu switchy, diody LED (myReg0 - dane przesłane po I2C do płytki Elbert), scl i sda 2 piny magistarli I2C (pierwsze dwa piny złącza P1 na płytce Elbert - patrz rysunek: Jeśli chodzi o piny magistrali I2C (scl, sda) od strony Arduino UNO to zaznaczyłem je fioletową obwódką na rysunku pinout'u dla UNO: Oczywiście pomiędzy zestawem FPGA (poziom logiki 3,3V) a Arduini UNO (poziom logiki 5V) trzeba wstawić na tych dwóch liniach (scl, sda) konwertery poziomów logicznych.Ja zrobiłem to za pomocą takiego konwertera poziomów (bo tylko taki miałem pod ręką) https://botland.com.pl/pl/konwertery-napiec/2523-konwerter-poziomow-logicznych-dwukierunkowy-4-kanalowy-pololu.html Tutaj zdjęcie całego układu (konwerter poziomów na płytce stykowej): Skoro połączenia mamy omówione wróćmy może do kodu projektu (Verilog). Przejdżmy do pliku "i2cSlave_define.v" plik ten jest dołączany (dyrektywa include) za pomocą linii: `include "i2cSlave_define.v" do wszystkich plików żródłowych projektu (Verilog) podobnie jak w języku C. W pliku tym mamy zdefiniowane bardzo ważne parametry modulów - patrz źródła: // ----------------------- i2cSlave_define.v -------------------- // stream states `define STREAM_IDLE 2'b00 `define STREAM_READ 2'b01 `define STREAM_WRITE_ADDR 2'b10 `define STREAM_WRITE_DATA 2'b11 // start stop detection states `define NULL_DET 2'b00 `define START_DET 2'b01 `define STOP_DET 2'b10 // i2c ack and nak `define I2C_NAK 1'b1 `define I2C_ACK 1'b0 // ---------------------------------------------------------------- // ------------- modify constants below this line ----------------- // ---------------------------------------------------------------- // i2c device address `define I2C_ADDRESS 7'h3c // System clock frequency in MHz // If you are using a clock frequency below 24MHz, then the macro // for SDA_DEL_LEN will result in compile errors for i2cSlave.v // you will need to hand tweak the SDA_DEL_LEN constant definition `define CLK_FREQ 48 // Debounce SCL and SDA over this many clock ticks // The rise time of SCL and SDA can be up to 1000nS (in standard mode) // so it is essential to debounce the inputs. // The spec requires 0.05V of hysteresis, but in practise // simply debouncing the inputs is sufficient // I2C spec requires suppresion of spikes of // maximum duration 50nS, so this debounce time should be greater than 50nS // Also increases data hold time and decreases data setup time // during an I2C read operation // 10 ticks = 208nS @ 48MHz `define DEB_I2C_LEN (10*`CLK_FREQ)/48 // Delay SCL for use as internal sampling clock // Using delayed version of SCL to ensure that // SDA is stable when it is sampled. // Not entirely citical, as according to I2C spec // SDA should have a minimum of 100nS of set up time // with respect to SCL rising edge. But with the very slow edge // speeds used in I2C it is better to err on the side of caution. // This delay also has the effect of adding extra hold time to the data // with respect to SCL falling edge. I2C spec requires 0nS of data hold time. // 10 ticks = 208nS @ 48MHz `define SCL_DEL_LEN (10*`CLK_FREQ)/48 // Delay SDA for use in start/stop detection // Use delayed SDA during start/stop detection to avoid // incorrect detection at SCL falling edge. // From I2C spec start/stop setup is 600nS with respect to SCL rising edge // and start/stop hold is 600nS wrt SCL falling edge. // So it is relatively easy to discriminate start/stop, // but data setup time is a minimum of 100nS with respect to SCL rising edge // and 0nS hold wrt to SCL falling edge. // So the tricky part is providing robust start/stop detection // in the presence of regular data transitions. // This delay time should be less than 100nS // 4 ticks = 83nS @ 48MHz `define SDA_DEL_LEN (4*`CLK_FREQ)/48 Dla nas najważniejsze są dwa parametry: `define I2C_ADDRESS 7'h3c Pierwszy to adres naszego slave'a w magistrali I2C (jest dostepnych 128 różnych adresów) - wynosi on 3C zapisany heksadecymalnie. Drugi to częstotliwość zegara - 48 MHz: `define CLK_FREQ 48 Teraz drugi plik "registerInterface": `include "i2cSlave_define.v" module registerInterface ( clk, addr, dataIn, writeEn, dataOut, myReg0, myReg1, myReg2, myReg3, myReg4, myReg5, myReg6, myReg7 ); input clk; input [7:0] addr; input [7:0] dataIn; input writeEn; output [7:0] dataOut; output [7:0] myReg0; output [7:0] myReg1; output [7:0] myReg2; output [7:0] myReg3; input [7:0] myReg4; input [7:0] myReg5; input [7:0] myReg6; input [7:0] myReg7; reg [7:0] dataOut; reg [7:0] myReg0; reg [7:0] myReg1; reg [7:0] myReg2; reg [7:0] myReg3; // --- I2C Read always @(posedge clk) begin case (addr) 8'h00: dataOut <= myReg0; 8'h01: dataOut <= myReg1; 8'h02: dataOut <= myReg2; 8'h03: dataOut <= myReg3; 8'h04: dataOut <= myReg4; 8'h05: dataOut <= myReg5; 8'h06: dataOut <= myReg6; 8'h07: dataOut <= myReg7; default: dataOut <= 8'h00; endcase end // --- I2C Write always @(posedge clk) begin if (writeEn == 1'b1) begin case (addr) 8'h00: myReg0 <= dataIn; 8'h01: myReg1 <= dataIn; 8'h02: myReg2 <= dataIn; 8'h03: myReg3 <= dataIn; endcase end end endmodule Plik ten jest o tyle ważny, że widać w nim iż w projekcie jest używanych 8 rejestrów 8-mio bitowych (cztery wejściwe i cztery wyjściowe). Ale tylko jeden rejestr jest w głównym module (implementacja jest trochę niepełna - o czym autor pisze, że jest to punkt wyjścia do własnych implementacji). Dla nas jest jedynie istotne, że dla adresu 8'h00 (czyli 0 dziesiętnie rejestr myReg0 jest obsługiwany poprawnie), będzie to istotne przy pisaniu mastera I2C na Arduino UNO. Tutaj zamieszczam działający projekt " I2C slave" (dla Elbert'a) - Xilinx ISE 14.7: I2CSlave01.zip Jeśli ktoś nie chce uruchamiać syntezy może od razu załadować za pomocą programu "Elbert V2 Configurator" plik "i2cslavetop.bin" do zestawu FPGA. Po wgraniu do zestawu FPGA Elbert pliku konfiguracji i wykonaniu połączeń z Arduino UNO możemy przejść do programu dla Arduino. Najpierw warto programem "I2C scanner" sprawdzić, czy Arduino z załadowanym programem skanera wykryje nam slave'a i2C pod adresem 0x3C. Tutaj kod progrmu "I2C scanner" - program należy skompilować za pomocą "Arduino IDE" i wgrać do płytki Arduino UNO. Kod programu: #include <Wire.h> void setup() { Wire.begin(); Serial.begin(9600); while (!Serial); // Leonardo: wait for serial monitor Serial.println("\nI2C Scanner"); } void loop() { byte error, address; int nDevices; Serial.println("Scanning..."); nDevices = 0; for(address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address<16) Serial.print("0"); Serial.print(address,HEX); Serial.println(" !"); nDevices++; } else if (error==4) { Serial.print("Unknown error at address 0x"); if (address<16) Serial.print("0"); Serial.println(address,HEX); } } if (nDevices == 0) Serial.println("No I2C devices found\n"); else Serial.println("done\n"); delay(5000); // wait 5 seconds for next scan } Tak wygląda prawidłowe wykrycie slave'a (FPGA) pod adresem 0x3C na magistrali I2C przez Arduino: Jeśli to zadziała, to możemy wgrać taki krótki program mastera I2C na Arduino UNO: #include <Wire.h> void setup() { Wire.begin(); // join i2c bus (address optional for master) } byte x = 0; void loop() { Wire.beginTransmission(0x3C); // transmit to device #3C Wire.write(0); //wysylamy adres rejestru 0 (ten odczytany w kodzie Verilog) Wire.write(x); // wysylamy jeden bajt - wartosc x Wire.endTransmission(); // stop transmitting x++; delay(500); } Jeśli wszystko poszło OK, możemy obserwować na diodach zestawu Elbert zmienijącą się wartość x (inkrementowaną co jeden obieg pętli głównej programu) przesyłaną z mastera (Arduino) do slave'a (FPGA). Patrz filmik (sorry nie mogę przesłać na forbot pliku mp4 z filmem). Pozdrawiam
  25. Dzień dobry, Próbuję stworzyć platformę jeżdżącą dzięki dwóm silnikom DC sterowanym dzięki sterownikowi TB 6612 FNG. Resztę czujników mam oprogramowaną, brakuje mi tylko właśnie tego stesrownika z DC Silniki: https://botland.com.pl/pl/silniki-dc-katowe-z-przekladnia/3696-kolo-silnik-65x26mm-5v-z-przekladnia-481.html Sterownik: https://botland.com.pl/pl/sterowniki-silnikow-moduly/32-pololu-tb6612fng-dwukanalowy-sterownik-silnikow-135v1a.html Zdjęcie sterownika: Sterownik - Pin z arduino do którego jest wpięty PWMA - Digital 5 AIN2 - Digital 7 AIN1 - Digital 6 PWMB - Digital 10 BIN2 - Digital 9 BIN1 - Digital 8 STBY - Digital 13 Wszystkie GND - GND VCC - 5V z arduino. A/B[01/02] -- silniki VMOT - 5V z arduino Kod: #include <SparkFun_TB6612.h> //Motor 1 int pinAIN1 = 6; //Direction int pinAIN2 = 7; //Direction int pinPWMA = 5; //Speed //Motor 2 int pinBIN1 = 8; //Direction int pinBIN2 = 9; //Direction int pinPWMB = 10; //Speed //Standby int pinSTBY = 13; //Constants to help remember the parameters static boolean turnCW = 0; //for motorDrive function static boolean turnCCW = 1; //for motorDrive function static boolean motor1 = 0; //for motorDrive, motorStop, motorBrake functions static boolean motor2 = 1; //for motorDrive, motorStop, motorBrake functions void setup() { //Set the PIN Modes pinMode(pinPWMA, OUTPUT); pinMode(pinAIN1, OUTPUT); pinMode(pinAIN2, OUTPUT); pinMode(pinPWMB, OUTPUT); pinMode(pinBIN1, OUTPUT); pinMode(pinBIN2, OUTPUT); pinMode(pinSTBY, OUTPUT); } void loop() { //Drive both motors CW, full speed motorDrive(motor1, turnCW, 255); motorDrive(motor2, turnCW, 255); //Keep driving for 2 secs delay(2000); //Turn towards motor1: Stop Motor1, slow Motor2 motorStop(motor1); motorDrive(motor2, turnCW, 192); //Keep turning for 2 secs delay(2000); //Turn in opposite direction: Stop Motor2, slow Motor1 motorDrive(motor1, turnCW, 192); delay(250); motorStop(motor2); //Keep turning for 2 secs delay(2000); //Straighten up motorDrive(motor2, turnCW, 192); delay(500); //Put motors into Standby motorsStandby(); delay(1000); //Do a tight turn towards motor1: Motor2 forward, Motor1 reverse motorDrive(motor1, turnCCW, 192); motorDrive(motor2, turnCW, 192); //Keep turning for 2 secs delay(2000); //Apply Brakes, then into Standby motorBrake(motor1); motorBrake(motor2); motorsStandby(); //Stand still for 5 secs, then we do it all over again... delay(5000); } void motorDrive(boolean motorNumber, boolean motorDirection, int motorSpeed) { /* This Drives a specified motor, in a specific direction, at a specified speed: - motorNumber: motor1 or motor2 ---> Motor 1 or Motor 2 - motorDirection: turnCW or turnCCW ---> clockwise or counter-clockwise - motorSpeed: 0 to 255 ---> 0 = stop / 255 = fast */ boolean pinIn1; //Relates to AIN1 or BIN1 (depending on the motor number specified) //Specify the Direction to turn the motor //Clockwise: AIN1/BIN1 = HIGH and AIN2/BIN2 = LOW //Counter-Clockwise: AIN1/BIN1 = LOW and AIN2/BIN2 = HIGH if (motorDirection == turnCW) pinIn1 = HIGH; else pinIn1 = LOW; //Select the motor to turn, and set the direction and the speed if(motorNumber == motor1) { digitalWrite(pinAIN1, pinIn1); digitalWrite(pinAIN2, !pinIn1); //This is the opposite of the AIN1 analogWrite(pinPWMA, motorSpeed); } else { digitalWrite(pinBIN1, pinIn1); digitalWrite(pinBIN2, !pinIn1); //This is the opposite of the BIN1 analogWrite(pinPWMB, motorSpeed); } //Finally , make sure STBY is disabled - pull it HIGH digitalWrite(pinSTBY, HIGH); } void motorBrake(boolean motorNumber) { /* This "Short Brake"s the specified motor, by setting speed to zero */ if (motorNumber == motor1) analogWrite(pinPWMA, 0); else analogWrite(pinPWMB, 0); } void motorStop(boolean motorNumber) { /* This stops the specified motor by setting both IN pins to LOW */ if (motorNumber == motor1) { digitalWrite(pinAIN1, LOW); digitalWrite(pinAIN2, LOW); } else { digitalWrite(pinBIN1, LOW); digitalWrite(pinBIN2, LOW); } } void motorsStandby() { /* This puts the motors into Standby Mode */ digitalWrite(pinSTBY, LOW); } W kodzie nic nadzwyczajnego nie powinno się znajdować. Korzystam z biblioteki "Sparkfun'a". Sam kodo pochodzi z jego gita. @up kod działa. Jest ok. Piny są podpięte jak w zestawieniu powyżej. Z kodem się zgadzają, z tego co rozumiem ten kod. To silniki powinny się uruchomić, wykonać sekwencję opisane w komentarzach w kodzie i się zatrzymać. Nie mam pojęcia co może być nie tak. Kable do silników są przylutowane. Napięcie w bateriach, na płytce się zgadza, sprawdzone multimetrem. Mogę jeszcze spróbować dać 6V (z 4 paluszków) na sterownik, jako napięcie dla silników i może wtedy ruszy. (Zakres dla sterownika to od 4.5V do 13.5V, na napięcie dla silników). Czy możliwe, że mam złą bibliotekę do sterownika? Próbowałem napisać własne funkcje sterownika. Które ustawiały bity i sterowały silnikami przez mostki na sterowniku (nawiązując do tabelki ze strony 4 ze specyfikacji producenta -> https://www.sparkfun.com/datasheets/Robotics/TB6612FNG.pdf) @up Problem rozwiązałem. Zlutowałem piny w sterowniku (gdzieś w internecie widziałem jak ktoś tak korzystał bez zlutowanych, no mu to jakoś wyszło, nie polecam). Źródło zasilania silników zmieniłem na 4baterie AA, potem na 6baterii AA i zaczęło działać. W razie pytań zapraszam do kontaktu PW. @@up Temat do zamknięcia
×
×
  • Utwórz nowe...