Skocz do zawartości

BHBmacieg

Użytkownicy
  • Zawartość

    24
  • Rejestracja

  • Ostatnio

Reputacja

11 Dobra

O BHBmacieg

  • Ranga
    2/10

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

  1. Ruszam z druga częścią kursu :). Lubie jak projekty są w jakimś stopniu interaktywne. Zatem użyłem dwóch potencjometrów do manipulowania wartościami dwóch kolorów. Wartość trzeciego koloru manipulowana jest z wykorzystaniem fotorezystora aby nadać "trochę przypadkowości". Dodałem tez dwa przyciski, jeden pozwala zmienić tryb świecenia - stałe vs zapalnie kolejnych Ledów po kolei. Drugi z przycisków ma swoje zastosowanie w trybie "stałym". Z jego wykorzystaniem możemy zmienić ilość zapalonych diod. Poniżej kod i film z działania układu. #include <Adafruit_NeoPixel.h> //dołączenie bilioteki dla paska LED #define fotorezystor A1 //definicje dla komponentów #define potencjometr1 A5 #define potencjometr2 A4 #define przyciskTrybu 2 #define przyciskIlosci 3 boolean tryb = false; //zmienna określająca aktualny tryb pracy int fotorezystorW; //zmienna dla fotorezystora int potencjometr1W; //zmienne dla potencjometrow int potencjometr2W; int kolor1; //zmienna dla koloru pierwszego int kolor2; //zmienna dla koloru drugiego int kolor3; //zmienna dla koloru trzeciego int ilosc = 8; //ide diod ma sie świecić //konfiguracja linijkki Adafruit_NeoPixel linijka = Adafruit_NeoPixel(8, A0, NEO_GRB + NEO_KHZ800); void setup() { pinMode(przyciskTrybu, INPUT_PULLUP); //zdefiniowanie piny dla przycisku trybu pinMode(przyciskIlosci, INPUT_PULLUP); //zdefioniowanie pinu dla przycisku linijka.begin(); //Inicjalizacja paska LED linijka.show(); } void loop() { if (ilosc <= 8 && ilosc >= 0) { //sprawdzenie czy wartosc ilosci diod miescie sie w zakresie wczytanieKolorow(); //wywołanie funkcji wczytującej kolory z ADC if (tryb == true) { //sprawdzenie, którego trybu chcemy użyć kilkaNaRaz(ilosc); //wywołanie funkcji kilku diod świecących na raz zmianaIlosci(); //wywołanie funkcji dla zmiany ilości diod } else { wszystkiePoKolei(); //wywołanie funkcji dla kolejno zapalających się diod } } else { //gdy ilosc wyjscie z zakresu ilosc = 8; } zmianaTrybu(); //wywołanie funkcji pozwalającej na zmianę trybu } void wczytanieKolorow() { //funkcja wczytująca kolotry z ADC potencjometr1W = analogRead(potencjometr1); potencjometr2W = analogRead(potencjometr2); fotorezystorW = analogRead(fotorezystor); kolor1 = map(potencjometr1W, 0, 1024, 0, 255); kolor1 = constrain(kolor1, 0, 255); kolor3 = map(fotorezystorW, 0, 1024, 0, 255); kolor3 = constrain(kolor3, 0, 255); kolor2 = map(potencjometr2W, 0, 1024, 0, 255); kolor2 = constrain(kolor2, 0, 255); } void kilkaNaRaz(int ile) { //funkcja zapewniająca świecene kilku diod jednocześnie int i = 0; for (i = 0; i < ile; i++) { linijka.setPixelColor(i, kolor1, kolor2, kolor3); } linijka.show(); delay(200); linijka.clear(); } void wszystkiePoKolei() {//funkcja zapewniająca zapalanie diod po kolei int i = 0; for (i = 0; i < 8; i++) { linijka.setPixelColor(i, kolor1, kolor2, kolor3); linijka.show(); delay(200); } linijka.clear(); } void zmianaTrybu() { //funkcja zapewniajaca zmianę trybu while (digitalRead(przyciskTrybu) == LOW) { tryb = !tryb; delay(1500); } } void zmianaIlosci() { //funkcja zapewniające zmianę ilości świecących diod while (digitalRead(przyciskIlosci) == LOW) { ilosc--; delay(1500); } }
  2. Pogrzebałem trochę, przeszedłem z funkcji switch case na zwykłe funkcje warunkowe if i o dziwo działa bez problemu. Wygląda tak jakby nie podwójne zagnieżdżanie odczytywania znaków było problemem. W wolnej chwili postaram się wrócić do switch case i naprawić kod tak aby działał poprawnie. Póki co prace domowe: 9.1. Obliczanie pola powierzchni wybranej figury String figura = ""; //odczytanie jaka figure chcemy wyliczyc String dlugoscBoku1 = ""; //zmienna dla dlugosci boku podana int dlugoscBoku1INT = 0; //zmienan dla dlugosic boku INT String dlugoscBoku2 = ""; //zmienna dla dlugosci boku podana int dlugoscBoku2INT = 0; //zmienan dla dlugosic boku INT String promien = ""; //zmienna dla promienia podana int promienINT = 0; //zmienna dla promienia String wysokosc = ""; //zmienan dla wysokosci podana int wysokoscINT = 0; //zmienna dla wysokosci void setup() { Serial.begin(9600); //rozpoczecie komunikacji z pc } void loop() { Serial.println("Pole jakiej figury checsz obliczyc? Prostokąt - p, Koło - k, Trójkąt - t"); //zapytanie jaka figure chcemy obliczyc czekaj(); if (Serial.available() > 0) { //jesli uzytkownik podal cos z klawiatury figura = Serial.readStringUntil('\n'); } if (figura == "k") { //jesli wybieramy koło Serial.println("Podaj długość promienia."); //prosimy użytkownika o podanie długości promienia czekaj(); if (Serial.available() > 0) { //odczytanie wartości podanej przez użytkownika promien = Serial.readStringUntil('\n'); promienINT = promien.toInt(); } double poleKolo = kolo(promienINT); //obliczenie pola za pomocą funkcji Serial.println("Pole twojego koła to: " + String(poleKolo) + " [mm^2]"); } else if (figura == "p") { //jesli wybieramy prostokąt Serial.println("Podaj długość pierwszego boku."); //prosimy o podanie długości pierwszego boku czekaj(); if (Serial.available() > 0) { //odczytanie wartości podanej przez użytkownika dlugoscBoku1 = Serial.readStringUntil('\n'); dlugoscBoku1INT = dlugoscBoku1.toInt(); } Serial.println("Podaj długość drugiego boku."); czekaj(); if (Serial.available() > 0) { //odczytanie wartosci podanej przez użytkownika dlugoscBoku2 = Serial.readStringUntil('\n'); dlugoscBoku2INT = dlugoscBoku2.toInt(); } int poleProstokat = prostokat(dlugoscBoku1INT, dlugoscBoku2INT); //obliczenie pola za pomocą funkcji Serial.println("Pole twojego prostokąta to: " + String(poleProstokat) + " [mm^2]"); } else if (figura == "t") { //jesli wybieramy trójkąt Serial.println("Podaj wysokość."); //prosimy użytkownika o podanie wysokości czekaj(); if (Serial.available() > 0) { //odczytanie wartości podanej przez użytkownika wysokosc = Serial.readStringUntil('\n'); wysokoscINT = wysokosc.toInt(); } Serial.println("Podaj dlugość podstawy."); czekaj(); if (Serial.available() > 0) { //odczytanie wartosci podanej przez użytkownika dlugoscBoku1 = Serial.readStringUntil('\n'); dlugoscBoku1INT = dlugoscBoku1.toInt(); } double poleTrojkat = trojkat(dlugoscBoku1INT, wysokoscINT); //obliczenie pola za pomoca funkcji Serial.println("Pole twojego trójkąta to: " + String(poleTrojkat) + " [mm^2]"); } else { Serial.println("Podałeś zły argument!"); } } int prostokat(int a, int b) { //funkcja odpowiedzialna za obliczanie pola kwardratu int poleProstokat = 0; poleProstokat = a * b; return poleProstokat; } double kolo(double r) { //funkcja odpowiedzialna za obliczanie pola kola double poleKolo = 0; poleKolo = 3.14 * r * r; return poleKolo; } double trojkat(double a, double h) { //funkcja odpowiedzialna za obliczanie pola trojkata double poleTrojkat = 0; poleTrojkat = 0.5 * a * h; return poleTrojkat; } void czekaj() { while (Serial.available() == 0) { delay(50); } } 9.2. program z funkcją umożliwiającą zdefiniowanie pinu, na którym znajduje się dioda, czas przez jaki dioda ma świeci, czas przez jaki dioda ma być wyłączona oraz ile razy sekwnencja ma się powtórzyć. void setup() { zamigajLED(3, 2000, 1000, 5); zamigajLED(13, 2000, 1000, 5); } void loop() { } void zamigajLED(int PIN, int czasWlaczenia, int czasWylaczenia, int ile) { pinMode(PIN, OUTPUT); //konfiguracja pinu wyjscia for (int a = 0; a < ile; a++) { digitalWrite(PIN, HIGH); // zapalenie diody delay(czasWlaczenia); //wlaczenie na okreslony czas digitalWrite(PIN, LOW); //wylaczenie diody delay(czasWylaczenia); //wylaczenie na okreslony czas } } 9.3. Tutaj zbudowałem sobie prosty czujnik parkowania. Użyłem tutaj również buzzera, którego częstotliwość pikania jest zależna od odległości w jakiej znajduje się przedmiot. #define czerwona1 3 #define czerwona2 2 #define zolta1 5 #define zolta2 4 #define zielona1 7 #define zielona2 6 #define buzzer 8 #define echo 11 #define trigger 12 void setup() { pinMode(czerwona1, OUTPUT); //deklaracja pinów dla ledów pinMode(czerwona2, OUTPUT); pinMode(zolta1, OUTPUT); pinMode(zolta2, OUTPUT); pinMode(zielona1, OUTPUT); pinMode(zielona2, OUTPUT); pinMode(buzzer, OUTPUT); pinMode(echo, INPUT); pinMode(trigger, OUTPUT); Serial.begin(9600); //rozpoczęcie komunikacji z PC } void loop() { if (zmierzOdleglosc() > 60) { //jesli powyzej metra diod0(); //wywołaj funkcje diod0 } else if ((zmierzOdleglosc() <= 60) && (zmierzOdleglosc() > 50)) { //jesli odleglosc w pierwszym zakresie diod1(); } else if ((zmierzOdleglosc() <= 50) && (zmierzOdleglosc() > 40)) { //jesli odlegosc w drugim zakresie diod2(); } else if ((zmierzOdleglosc() <=40) && (zmierzOdleglosc() > 30)) { //jesli odlegloscw trzecim zakresie diod3(); } else if ((zmierzOdleglosc() <= 30) && (zmierzOdleglosc() > 20)) { //jesli odlegosc w czwartym zakresie diod4(); } else if ((zmierzOdleglosc() <= 20) && (zmierzOdleglosc() > 10)) { //jesli odlegosc w piatym zakresie diod5(); } else if (zmierzOdleglosc() <= 10) { //jeśli odległość w szóstym zakresie diod6(); } delay(100); } void pikanieBuzzera(int czas) { //funkcja odpowiedzialna za pikanie buzzera digitalWrite(buzzer, HIGH); delay(czas); digitalWrite(buzzer, LOW); delay(czas); } void diod0() { //wszystkie zgaszone digitalWrite(zielona1, LOW); digitalWrite(zielona2, LOW); digitalWrite(zolta1, LOW); digitalWrite(zolta2, LOW); digitalWrite(czerwona1, LOW); digitalWrite(czerwona2, LOW); } void diod1() { //jedna zielona digitalWrite(zielona1, HIGH); digitalWrite(zielona2, LOW); digitalWrite(zolta1, LOW); digitalWrite(zolta2, LOW); digitalWrite(czerwona1, LOW); digitalWrite(czerwona2, LOW); } void diod2() { //dwie zielone digitalWrite(zielona1, HIGH); digitalWrite(zielona2, HIGH); digitalWrite(zolta1, LOW); digitalWrite(zolta2, LOW); digitalWrite(czerwona1, LOW); digitalWrite(czerwona2, LOW); pikanieBuzzera(1000); } void diod3() { //dwie zielone, jedna zolta digitalWrite(zielona1, HIGH); digitalWrite(zielona2, HIGH); digitalWrite(zolta1, HIGH); digitalWrite(zolta2, LOW); digitalWrite(czerwona1, LOW); digitalWrite(czerwona2, LOW); pikanieBuzzera(600); } void diod4() { //dwie zielone, dwie zolte digitalWrite(zielona1, HIGH); digitalWrite(zielona2, HIGH); digitalWrite(zolta1, HIGH); digitalWrite(zolta2, HIGH); digitalWrite(czerwona1, LOW); digitalWrite(czerwona2, LOW); pikanieBuzzera(400); } void diod5() { //dwie zielone, dwie zolte, jedna czerwona digitalWrite(zielona1, HIGH); digitalWrite(zielona2, HIGH); digitalWrite(zolta1, HIGH); digitalWrite(zolta2, HIGH); digitalWrite(czerwona1, HIGH); digitalWrite(czerwona2, LOW); pikanieBuzzera(150); } void diod6() { //wszystkie digitalWrite(zielona1, HIGH); digitalWrite(zielona2, HIGH); digitalWrite(zolta1, HIGH); digitalWrite(zolta2, HIGH); digitalWrite(czerwona1, HIGH); digitalWrite(czerwona2, HIGH); digitalWrite(buzzer, HIGH); } int zmierzOdleglosc() { //funkcja do pomiaru odległosci long czas, dystans; //deklaracja zmiennych digitalWrite(trigger, LOW); delayMicroseconds(2); digitalWrite(trigger, HIGH); delayMicroseconds(10); digitalWrite(trigger, LOW); czas = pulseIn(echo, HIGH); //odczytanie czasu potrzebnego na odbicie i powrot dźwięku dystans = czas / 58; //przeliczenie czasu na dystans return dystans; } Film z działania czujnika: Zestaw do drugiej części kursu już leży i czeka na swoją kolej
  3. Cześć, piszę sobie zadanie 9.1 i mam mały problem. Z jakiegoś powodu nie działa mi poprawnie warunek switch.. case... Otóż poprawnie wykonuje się tylko "pierwszy" case wyszczególniony w kodzie. Przy wpisaniu litery odpowiedzialnej za drugi case program jakby starował od nowa i znów prosi o podanie litery. Prześledziłem kod parę razy ale nie widzę błędu. Może "cudze oko" wyłapie gdzie coś jest nie tak. Wysyłam kod: int figura = ""; //odczytanie jaka figure chcemy wyliczyc String dlugoscBoku1 = ""; //zmienna dla dlugosci boku podana int dlugoscBoku1INT = 0; //zmienan dla dlugosic boku INT String dlugoscBoku2 = ""; //zmienna dla dlugosci boku podana int dlugoscBoku2INT = 0; //zmienan dla dlugosic boku INT String promien = ""; //zmienna dla promienia podana int promienINT = 0; //zmienna dla promienia String wysokosc = ""; //zmienan dla wysokosci podana int wysokoscIN = 0; //zmienna dla wysokosci void setup() { Serial.begin(9600); //rozpoczecie komunikacji z pc } void loop() { Serial.println("Pole jakiej figury checsz obliczyc? Prostokąt - p, Koło - k, Trójkąt - t"); //zapytanie jaka figure chcemy obliczyc czekaj(); if (Serial.available() > 0) { //jesli uzytkownik podal cos z klawiatury figura = Serial.read(); } switch (figura) { case 'k': //jesli uzytkownik chce obliczyc pole kola Serial.println("Podaj długość promienia."); czekaj(); if (Serial.available() > 0) { promien = Serial.readString(); promienINT = promien.toInt(); } double poleKolo = kolo(promienINT); Serial.println("Pole twojego koła to: " + String(poleKolo) + " [mm^2]"); break; case 'p': //jesli uzytkownik chce obliczyc pole prostokąta Serial.println("Podaj długość pierwszego boku."); czekaj(); if (Serial.available() > 0) { dlugoscBoku1 = Serial.readStringUntil('\n'); dlugoscBoku1INT = dlugoscBoku1.toInt(); } Serial.println("Podaj długość drugiego boku."); czekaj(); if (Serial.available() > 0) { dlugoscBoku2 = Serial.readString(); dlugoscBoku2INT = dlugoscBoku2.toInt(); } int poleProstokat = prostokat(dlugoscBoku1INT, dlugoscBoku2INT); Serial.println("Pole twojego prostokąta to: " + String(poleProstokat) + " [mm^2]"); break; default: Serial.println("podałeś złą literę!"); break; } } int prostokat(int a, int b) { //funkcja odpowiedzialna za obliczanie pola kwardratu int poleProstokat = 0; poleProstokat = a * b; return poleProstokat; } double kolo(double r) { //funkcja odpowiedzialna za obliczanie pola kola double poleKolo = 0; poleKolo = 3.14 * r * r; return poleKolo; } double trojkat(double a, double h) { //funkcja odpowiedzialna za obliczanie pola trojkata double poleTrojkat = 0; poleTrojkat = 0.5 * a * h; return poleTrojkat; } void czekaj() { while (Serial.available() == 0) { delay(50); } }
  4. Botland posiada w ofercie sterownik Pololu DRV8835. Poczytam o nim i może okaże się lepszy. Serdecznie dziękuję za pomoc.
  5. A co proponujesz w zamian za L298? Większość poradników i tutoriali w internecie wspomina właśnie taki sterownik. Jakaś przetwornica stepdown może być też dobrym pomysłem. Polecasz jakąś konkretną czy to w zasadzie wszystko będzie to samo?
  6. @Treker zrobiłem już jakiś czas temu szybki przegląd tego kursu. Na pewno go nie ominę, jednak na tą chwilę chciałbym wykorzystać czujnik zbliżeniowy HC-SR04 do tego SHIELD z L293D lub wykorzystać sterownik z L298N. Do tego dwa proste silniki i jedno serwo. Taki naprawdę najprostszy. Ma mieć po prostu korpus wykonany z tektury (pracuję w firmie produkującej tekturę) oraz nadruk z logiem firmy. Zastanawiam się jeszcze nad źródłem zasilania, czy wykorzystać LiPO czy może jakiś zestaw baterii AA. Mam też możliwość bezkosztowo spróbować wykorzystać ogniwa 18650, ponieważ mam w szafce koszyk na dwa takie akumulatory oraz kilka wysokoprądowych akumulatorów. Czy ich wysoki maksymalny amperaż (30A) nie będzie problemem? Układ i tak powinien pobrać sobie tylko taki prąd jak potrzebuje.
  7. Bardzo przydatna część kursu, szczególnie, że w niedalekiej przyszłości szykuje mi się budowa prostego robota omijającego przeszkody jako gadżet firmowy. zadania domowe: 8.1 #define PWM1 6 #define PWM2 9 #define input1Silnika1 7 #define input2Silnika1 8 #define input1Silnika2 10 #define input2Silnika2 11 void setup() { pinMode(PWM1, OUTPUT); //Sygnał PWM silnika nr 1 pinMode(PWM2, OUTPUT); //Sygnał PWM silnika nr 2 digitalWrite(PWM1, HIGH); //UStawienie na stałe stanów wysokich na PWM silników digitalWrite(PWM2, HIGH); pinMode(input1Silnika1, OUTPUT); //Sygnały sterujące kierunkiem obrotów silników pinMode(input2Silnika1, OUTPUT); pinMode(input1Silnika2, OUTPUT); pinMode(input2Silnika2, OUTPUT); } void loop() { digitalWrite(input1Silnika1, HIGH); //obrot silnika 1 w lewo digitalWrite(input2Silnika1, LOW); digitalWrite(input1Silnika2, HIGH); //obrot silnika 2 w lewo - razem z pierwszy daje jazde do przodu digitalWrite(input2Silnika2, LOW); delay(3000); digitalWrite(input1Silnika1, HIGH); //obrot silnika 1 w lewo digitalWrite(input2Silnika1, LOW); digitalWrite(input1Silnika2, LOW); //obrot silnika 2 w prawo - silniki kręcą się przewinie digitalWrite(input2Silnika2, HIGH); delay(3000); digitalWrite(input1Silnika1, LOW); //obrot silnika 1 w prawo digitalWrite(input2Silnika1, HIGH); digitalWrite(input1Silnika2, LOW); //obrot silnika 2 w prawo - razem z pierwszym daje jazdę do tyłu digitalWrite(input2Silnika2, HIGH); delay(3000); } 8.4 połączone z 8.2. Wykorzystałem ledy, które symulują silnik. Mamy tutaj stopniowe i asynchroniczne rozpędzanie, stopniowe i synchroniczne hamowanie. Powtarzanie całej sekwencji zadaną ilość razy i przycisk do restartowania całego programu, aby wykonywał się od nowa. #define PWM1 6 #define PWM2 9 #define input1Silnika1 7 #define input2Silnika1 8 #define input1Silnika2 10 #define input2Silnika2 11 #define przycisk 2 void setup() { pinMode(PWM1, OUTPUT); //Sygnał PWM silnika nr 1 pinMode(PWM2, OUTPUT); //Sygnał PWM silnika nr 2 pinMode(przycisk, INPUT_PULLUP); //ustawienie pinu na przycisku pinMode(input1Silnika1, OUTPUT); //Sygnały sterujące kierunkiem obrotów silników pinMode(input2Silnika1, OUTPUT); pinMode(input1Silnika2, OUTPUT); pinMode(input2Silnika2, OUTPUT); } void loop() { for (int i = 0; i < 2; i++) { // okreslenie ilosci powtórzeń sekwnecji do wykonania for (int a = 0; a < 255; a++) { double b = a * 1.4; b = constrain(b, 0, 255); analogWrite(PWM1, a); //stopniowe rozpedzanie silnika analogWrite(PWM2, b); //asynchroniczne rozpędanie drugiego silnika digitalWrite(input1Silnika1, HIGH); //silnik 1 w lewo digitalWrite(input2Silnika1, LOW); digitalWrite(input1Silnika2, HIGH); //silnk 2 w lewo digitalWrite(input2Silnika2, LOW); delay(25); } for (int a = 255; a >= 0; a--) { analogWrite(PWM1, a); //stopniowe wyhamowywanie silników analogWrite(PWM2, a); digitalWrite(input1Silnika1, HIGH); //zachowanie kierunków oborotu w stosunku do poprzedniej pętli digitalWrite(input2Silnika1, LOW); digitalWrite(input1Silnika2, HIGH); digitalWrite(input2Silnika2, LOW); delay(25); } } while (digitalRead(przycisk) == HIGH) { //oczekiwanie na wcsinięcie przycisku w celu restartu sekwencji delay(50); } } 8.3. Cały program zintegrowałem z wyświetlaczem, który pokazuje jaką liczbę wpisaliśmy do portu oraz wypisuje w drugiej linijce odpowiednią ilość gwiazdek. Pokazuje też odpowiednią informację jeśli podana przez nas liczba jest za duża w stosunku do ilości pól wyświetlacza. #include <LiquidCrystal.h> //dolaczenie biblioteki wyswietlacza String pobraneDane = ""; //zmienna do odczytu danych podanych przez użytkownika LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //informacja o pinach wyswietlacza int pobranaCyfraINT = 0; //zmienna mowiaca o ilosci gwiazdek do wydruku int pozycja = 0; //zmienna dla pozycji kursora wyswietlacza void setup() { Serial.begin(9600); lcd.begin(16, 2); // deklaracja typu wyswietlacza Serial.println("Podaj liczbę z zakresu 0-16."); //info dla uzytkownika } void loop() { lcd.setCursor(0, 0); //ustawienie kursora lcd.print("Wpisales: "); //wyswietlenie tekstu while (Serial.available() == 0) { //oczewikawnie na wpisanie danych delay(50); } if (Serial.available() > 0) { //jesli uzytkownik podal dane pobraneDane = Serial.readString(); //pobranie info od uzytkownika pobranaCyfraINT = pobraneDane.toInt(); //zamiana string na int pozycja = 0; if (pobranaCyfraINT >= 0 && pobranaCyfraINT <= 16) { //jesli miescimy sie w polach wyswietlacza lcd.print(pobranaCyfraINT); // wypisanie na wywietlaczu info wpisanego przez uzytkownika for (int i = 0; i < pobranaCyfraINT; i++) {//petla do wypisywania gwiazdek lcd.setCursor(pozycja, 1); //ustawienie kursora w odpowiedniej pozycji lcd.print("*"); //wydruk gwiazdki na lcd pozycja++; //zmiana pozycji Serial.print("*"); //wydruk gwiazdki do portu } Serial.println(""); //przejscie do nowej linijki } else { //jeśli jesteśmy poza zakresem lcd.print(pobranaCyfraINT); // wypisanie na wywietlaczu info wpisanego przez uzytkownika lcd.setCursor(0, 1); lcd.print("Poza zakresem!"); Serial.println("Podałeś liczbę z poza zakresu!"); } } Serial.println("Podaj liczbę z zakresu 0-16."); //info dla uzytkownika while (Serial.available() == 0) { //ponowne oczekiwanie na podanie danych delay(50); } lcd.clear(); //wyczyszczenie lcd } I krótki film z działania całego zestawu.
  8. Kolejna część kursu za mną. Super dawka wiedzy. Prace domowe: 7.1: Tutaj raczej nic innowacyjnego 7.2. Przy całkowitym usunięciu opóźnienia widać jakby wyświetlane wyniki "falowały" rysując się z góry na dół. 7.3. U mnie nie dało to w zasadzie żadnych zmian, tekst w pierwszej linijce był cały czas na swoim miejscu, a w drugiej zmieniał się normalnie. Chyba, że mówimy tu o bardzo niskim czasie odświeżania. 7.4. to trochę pokombinowałem. Zrezygnowałem ze stopera. Postanowiłem wykorzystać pomiar napięcia na fotorezystorze. Dołożyłem opcje regulacji jasności wyświetlacza przy pomocy potencjometru, do tego dołożyłem analogowy wskaźnik jasności podświetlenia oraz dwa przyciski. Jeden do zatrzymania pomiaru i drugi do ponownego wystartowania. Jedyna wada to taka, że w momencie zatrzymania pomiaru nie działa regulacja podświetlenia. Musiałbym po prostu zdefiniować odpowiednią funkcję na zmianę podświetlenia i wrzucić ją w pętle while w momencie zatrzymania. Jednak tworzenie funkcji to coś co muszę sobie przypomnieć, a dziś już niestety zabrakło czasu. Mógłbym oczywiście w pętle while wrzucić cały kod odpowiedzialny za zmianę podświetlenia, ale czy jest sens tak sztucznie wydłużać kod? Jeśli udoskonalę kod i regulacja podświetlenia będzie również działać po zatrzymaniu pomiaru to oczywiście się nim podzielę . #include <LiquidCrystal.h> //dołączenie biblioteki ekranu #include <Servo.h> //implementacja serva #define fotorezystor A5 #define wyswietlacz 11 #define potencjometr A4 #define przyciskStart 8 #define przyciskStop 9 Servo serwomechanizm; //utworzenie obiektu serwo LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //informacja o podłączeniu nowego wyświetlacza double odczyt = 0; //deklaracja zmiennej dla odczytu byte jasnosc = 0; //deklaracja zmiennej do sterowania jasnoscia wyswietlacza int wartoscPotencjometr = 0; //zmienna do odczytu wartosci z potencjometru byte pozycja = 0; //zmienna odpowiedzialna za pozycje serwa byte poprzedniaPozycja = 40; //zmienna potrzebna do likwidacji zbyt małych zmian pozycji serva void setup() { serwomechanizm.attach(10); //serwinecgabuzn na pinie 10 lcd.begin(16, 2); //Deklaracja typu lcd.setCursor(0, 0); //ustawienie kursora lcd.print("Nap. odczytane:"); //wyswietlenie tekstu pinMode(przyciskStart, INPUT_PULLUP); //zdefiniowanie pinow dla przyciskow pinMode(przyciskStop, INPUT_PULLUP); } void loop() { odczyt = analogRead(A5) * 5.0 / 1024.0; // odczytanie wartosci napiecia lcd.setCursor(0, 1); //ustawienie kursosa lcd.print(String(odczyt) + "V"); wartoscPotencjometr = analogRead(potencjometr); //odczytanie wartosci z potencjometru pozycja = map(wartoscPotencjometr, 0, 1024, 180, 40); //wykorzystanie odczytu z potencjometru do sterowania serverm jasnosc = map(wartoscPotencjometr, 0, 1024, 0, 255); //wykorzystanie odczytu z potencjometru do sterowanie jasnoscia LCD analogWrite(11, jasnosc); //generuje sygnal PWM dla podswietlenia if (abs(poprzedniaPozycja - pozycja) > 5) {//usunięcie zbyt małych zmian położenia ramienia serva serwomechanizm.write(pozycja); //zmiana pozycji ramienia poprzedniaPozycja = pozycja; //zapamiętanie nowej poprzedniej pozycji } while (digitalRead(przyciskStop) == LOW) { //wcisniecie przycisku stop delay(50); while (digitalRead(przyciskStart) == HIGH) { //oczekiwanie na wcisniecie przycisku start delay(50); } } delay(100); }
  9. Trzeba by to na spokojnie przeanalizować. Spójnik & działa tuaj pewnie jako Bitwise AND, czyli działa jako operator bitowy. Mądrzejsze głowy muszą się wypowiedzieć, bo ja też dopiero zaczynam przygodę z programowaniem w c++
  10. Odpowiednikiem spójnika logicznego 'AND' jest '&&' a nie '&'. Pewnie o to chodzi
  11. Arduino IDE ma przypisane skróty klawiszowe pod alt+s czy alt+c. Trzeba by je zmienić (nie wiem czy się da), nie używać polskich znaków lub zmienić program do edycji kodu a do Arduino IDE tylko go wklejać. Ja używam ostatniej opcji a kody pisze w Visual Studio.
  12. Cześć. kolejna super część kursu. Chciałbym podzielić się moimi rozwiązaniami zadań domowych: 6.1 #define potencjometr A5 #define fotorezystor1 A4 #define fotorezystor2 A3 #define przycisk 8 int potencjometrW = 0; //zmienna dla potencjometru int fotorezystor1W = 0; // zmienna na fotorezystora 1 int wcisniecia = 0; //zmienna dla ilosci wcisniec int fotorezystor2W = 0; // zmienna na fotorezystora 1 void setup() { Serial.begin(9600); //rozpoczescie komuniacji z PC pinMode(przycisk, INPUT_PULLUP); //zdefiniowanie pinu przycisku } void loop() { while (digitalRead(przycisk) == HIGH) { //kiedy przycisk nie wcisniety delay(50); } wcisniecia++; //zwiekszecznie ilosci wcisniec fotorezystor1W = analogRead(fotorezystor1); //odczytanie wartosci z 1 fotorezystora fotorezystor2W = analogRead(fotorezystor2); //odczytanie wartosci z 2 fotorezystora potencjometrW = analogRead(potencjometr); //odczytanie wartosci z potencjometru Serial.print("Potencjometr: "); Serial.print(potencjometrW); Serial.print(",\t"); Serial.print("Fotorezytor 1: "); Serial.print(fotorezystor1W); Serial.print(",\t"); Serial.print("Fotorezytor 2: "); Serial.print(fotorezystor2W); Serial.print(",\t"); Serial.print("Liczba klikniec: "); Serial.print(wcisniecia); Serial.print("\n"); delay(500); } 6.2 #define czerwona 2 #define zielona 3 int odebraneDane = 0; //zmienna do odczytu podanych danych void setup() { Serial.begin(9600); //rozpoczescie komunikacji z PC pinMode(czerwona, OUTPUT); //określenie trybów pinów pinMode(zielona, OUTPUT); digitalWrite(czerwona, LOW); //stan poczatkowy diod digitalWrite(zielona, LOW); } void loop() { Serial.println("Którą diodę zaświecić? (z - zielona, c - czerwona)"); while (Serial.available() == 0) { //jesli nic nie wpisane delay(50); } odebraneDane = Serial.read(); //odczytanie wartosci wpisanej przez uzytkownika switch (odebraneDane) { //funkcja switch case na swiecenie odpowiedniej diody case 'z': Serial.println("Wybrałeś zieloną diodę!"); digitalWrite(zielona, HIGH); delay(1000); digitalWrite(zielona, LOW); break; case 'c': Serial.println("Wybrałeś czerwoną diodę!"); digitalWrite(czerwona, HIGH); delay(1000); digitalWrite(czerwona, LOW); break; default: Serial.println("Podałeś błędne dane!"); break; } } 6.3 Tutaj można by dodać dwie metody kalibracji - poprzez ADC, na przykład potencjometr lub z wykorzystaniem przycisków, ja wybrałem drugą opcję :). Wciśnięcie jednego z przycisków ustawia wartość minimalną, drugi zaś maksymalną. Poniżej kod i film z działania układu. #include <Servo.h> //zaimplementowanie bilbioteki serwa #define fotorezystor A5 #define przyciskMIN 2 #define przyciskMAX 3 Servo serwomechanizm; //utworzenie obiektu serwo byte pozycja = 0; //zmienna pozycji serwomechanizmu int pozycjaPoprzednia = 0; //zmienna mowiaca o poprzednim polozeniu serwa int wartoscMIN = 0; //zmienna wartosci minimalnego swiatla int wartoscMAX = 1024; //wartosc maksymalnego swiatla void setup() { serwomechanizm.attach(9); //serwomechanizm na pinie numer 9 Serial.begin(9600); //rozpoczescie komunikacji z PC pinMode(przyciskMIN, INPUT_PULLUP); //zdefiniowanie pinów dla przycisków pinMode(przyciskMAX, INPUT_PULLUP); } void loop() { int odczytCzujnika = analogRead(fotorezystor); //odczyt wartosc z fotorezystora while (digitalRead(przyciskMIN) == LOW) { //kiedy przycisk wartosci minimalnej wcisniety wartoscMIN = odczytCzujnika; delay(100); } while (digitalRead(przyciskMAX) == LOW) { //kiedy przycisk wartosci maksymalnej wcisniety wartoscMAX = odczytCzujnika; delay(100); } pozycja = map(odczytCzujnika, wartoscMIN, wartoscMAX, 180, 40); pozycja = constrain(pozycja, 40, 180); if (abs(pozycjaPoprzednia - pozycja) > 5) { //usunięcie zbyt małych zmian serwomechanizm.write(pozycja); pozycjaPoprzednia = pozycja; //zapamiętanie nowej poprzedniej pozycji } Serial.println("Aktualne wskaznie fotorezystora to: " + String(odczytCzujnika)); //info dla uzytkownika delay(200); }
  13. Dziękuję za link. Czytałem o funkcji map ale widocznie w złym miejscu, bo tam brakowało informacji o tym co się dzieje gdy liczba jest poza zakresem. O i to też dużo wyjaśnia! Źle patrzyłem na tę funkcję. A mianowicie pierwszą wartość w nawiasie traktowałem jako wskazanie, którą zmienną ma mapować a nie jako konkretną wartość. Strona, na której czytałem o funkcji map niezbyt jasno to przedstawiła. Dziękuje i idę walczyć dalej Póki co wrzucam kody z prac domowych 5.2 #define dioda 5 int wypelnienie = 0; //zmienna wypelnienia sygnalu int zmiana = 5; //stopien zmiany void setup() { pinMode(dioda, OUTPUT); //konfiguracja wyjsc } void loop() { while (wypelnienie < 255) { //kiedy jestesmy ponizej maksimum wypelnienie += zmiana; analogWrite(dioda, wypelnienie); delay(60); //odczekanie chwile } while (wypelnienie <= 255 && wypelnienie != 0) { //gdy osiagniemy maksimum wypelnienie -= zmiana; analogWrite(dioda, wypelnienie); delay(60); } } 5.4: #include <Servo.h> // biblioteka odpowiedzialna za serwa Servo serwomechanizm; //towrzenie obiektu do odwłoania int pozycja = 0; //aktualna pozycja serwa 0-100 int zmiana = 6; // co ile ma sie zmienic pozycja String podanaWartosc = ""; //zmienna podana przez uzytkownika int podanaWartoscINT = 0; //zmiena podawaWartosc w INT void setup() { Serial.begin(9600); serwomechanizm.attach(9); //serwomechanizm na pinie 9 } void loop() { Serial.println("Podaj kąt obrotu serwa! (0-180)"); while (Serial.available() == 0) { delay(25); } podanaWartosc = Serial.readStringUntil('\n'); // odczytanie wartosci z klawiatury podanaWartoscINT = podanaWartosc.toInt(); //zamiana na INT if (podanaWartoscINT <=180 && podanaWartoscINT >=0) { //jesli miesciemy sie w zakresie serwomechanizm.write(podanaWartoscINT); Serial.println("aktalny kąt serwomechanizmu to: " + podanaWartosc); } else { Serial.println("Podano kąt z poza zakresu!"); } delay(50); } 5.5 #define potencjometr A5 #include <Servo.h> // biblioteka odpowiedzialna za serwa Servo serwomechanizm; //towrzenie obiektu do odwłoania int pozycja = 0; //aktualna pozycja serwa 0-100 int ustawieniePotencjometru = 0; //odczytanie z ADC void setup() { Serial.begin(9600); serwomechanizm.attach(9); //serwomechanizm na pinie 9 } void loop() { ustawieniePotencjometru = analogRead(potencjometr); //odczytanie wartosci z potencjometru pozycja = map(ustawieniePotencjometru, 0, 1024, 0, 180); //przeliczenie wartosci ADC na kat serwomechanizm.write(pozycja); //ustawienie serwa w zadany kat delay(50); }
  14. Wracam, Póki co na tarczy a nie z tarczą. Generalnie mam problem z funkcją map w momencie, gdy stosuję ją w sposób map(x, 0, 1024, 255, 0) - wyniki takiego mapowania są strasznie dziwne - otrzymuję nawet wartości rzędy -3000. Czy z założenia wartości tej zmiennej po zmapowaniu nie powinny przyjąć wartości z przedziały 0 - 255? Bo gdy wpiszę x = map(x, 0, 1024, 0, 255) wydaje się, że wszystko działa jak należy. Takie rozwiązanie jednak powoduje odwrotne działanie układu niż bym chciał - im więcej światła tym LED świeci mocniej. Metoda z mapowaniem przedziału podana wyżej nie przynosi rezultatów. Przykład: odczytany próg to: 490, wartość odczytana z potencjometru to: 466, czyli jesteśmy tylko delikatnie poniżej progu, a wartość poziomSwiecenia to 255. Jak to się dzieje, że wartości 466 odczytanej z fotorezystora, czyli wartości nawet poniżej połowy wartości maksymalnej jaką może przyjąć ta zmienna program przypisuje wartość 255 w wyniku mapowania? Nie powinno być coś w okolicach 100-120, żeby i tu być w połowie przedziału? Powoduje to, że dla większości ustawień potencjometru po przekroczeniu progu dioda od razu pali się maksymalnym światłem. Są pewnie położenia dla których układ działa poprawnie, ale trzeba się nieźle wysilić żeby się w nie wstrzelić. Częściowo pomaga sztuczne przesunięcie przedziału mapowania, to jest na przykład: poziomSwiecenia=map(odczytanaWartosc, prog, 1024, 255, -500);. Wtedy tych "poprawnych ustawień" potencjometru jest kapkę więcej. Kurcze mam wrażenie, że piszę to bardzo zawile ale ciężko to opisać ładnie słowami #define dioda 5 #define fotorezystor A5 #define potencjometr A4 #define potencjometr2 A3 int wypelnienie = 0; //zmienna wypelnienia sygnalu int zmiana = 5; //stopien zmiany int odczytanaWartosc = 0; //wartosc z ADC int prog = 0; //prog wlaczenia swiatla int poziomSwiecenia = 0; //jasnosc diody int poziomJasnosci = 0; void setup() { pinMode(dioda, OUTPUT); //konfiguracja wyjsc Serial.begin(9600); } void loop() { prog = analogRead(A4); odczytanaWartosc = analogRead(A5); //odczytanie wartosci z fotorezystora Serial.println("prog: " + String(prog)); if (odczytanaWartosc < prog) { Serial.println("OdczytanaWartosc: " + String(odczytanaWartosc)); poziomSwiecenia = map(odczytanaWartosc, prog, 1024, 255, 0); poziomSwiecenia = constrain(poziomSwiecenia, 0, 255); Serial.println("Poziom swiecenia: " + String(poziomSwiecenia)); analogWrite(dioda, poziomSwiecenia); delay(1000); } else { analogWrite(dioda, 0); delay(1000); } } Problem występuje przy niskich warunkach progu. przy wartości progu 800 w górę jest całkiem ok pod warunkiem zrezygnowania z ograniczania przedziału mapowania.
  15. Super, dziękuję za szybką odpowiedź. Jutro po pracy sprawdzę w praktyce i dam znać co mi z tego wyszło. Rozumiem, że równie dobrze, zamiast wartość 500 w funkcji map mogę podać po prostu zmienną "próg", tak aby przedział ustalał się automatycznie bez konieczności zmiany go ręcznie w kodzie?
×
×
  • Utwórz nowe...