Skocz do zawartości

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy


Komentator

Pomocna odpowiedź

@Belferek Dzięki za pomoc.

Dnia 16.02.2020 o 22:34, Belferek napisał:

W monitorze portu szeregowego zaznacz opcję "Bez zakończenia linii" - napisz czy pomogło, a jeśli tak to zastanów się czym jest to "zakończenie linii"?

Czyli "zakończenie linie" jest jakimś dodatkowym znakiem (pewnie kropką), którą arduino odczytywało jako kolejną komendę, dobrze rozumiem?

Link do komentarza
Share on other sites

@Georgio Tak, jest dodatkowym znakiem ale jednak nie kropką 🙂 Bo w linii możesz mieć np. kilka zdań i gdybyś tak interpretował każdą kropkę to taki tekst miałbyś pocięty na pojedyncze zdania.

Znak końca linii możesz dodać pisząc na końcu znak specjalny "\n". Odwrócony slash "baskslash" w linii tekstu powoduje, że kolejny znak będzie pełnił jakąś inną funkcję. W tym przypadku zamiast dodania znaku 'n' dodany zostanie znak końca linii. 

Link do komentarza
Share on other sites

Zadanie 6.1, tylko zjednym fotorezystorem bo, wiecej nie mam😉

#define przycisk 7 // Pin 7 jako "przycisk"

int fRezystor = 0;//Naswietlenie fotorezystora
int potencjometr = 0;//Pozycja potencjometru
int Przycisk = 0;//Stan przycisku

void setup() {
  Serial.begin(9600);//Nawiazanie komunikacji
  pinMode(7, INPUT_PULLUP);//Pin "7" jako wejscie
}

void loop() {
  fRezystor = analogRead(A1);//Odczytujemy dane z ADC
  potencjometr = analogRead(A5);
  if (digitalRead(przycisk) == LOW) {//Kiedy wcisnieto przycisk
    delay(50);//Opoznienie dla niwelacji drgan swicza
    Przycisk = Przycisk + 1;//Po kazdym wcisnieciu zwieksz liczbe o "1"
    Serial.print(" Fotorezystor: " );//Drukuj tekst
    Serial.print(fRezystor );
    Serial.print(", potencjometr: ");
    Serial.print(potencjometr );
    Serial.print(", przycisk wcisnieto ");
    Serial.print(Przycisk );
    Serial.print(" razy ");
  } while (digitalRead(7) == LOW) {} //Czekamy na wcisniecie przycisku
}

 

Edytowano przez Vova
  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

Dnia 18.01.2020 o 19:27, ethanak napisał:

Spróbujmy przeanalizować co ten program robi.

Załóżmy, że wpisałeś "zielona", program zrobi swoje, zapalił zielona diodę, zgasił i skończył pętlę. Do tej pory jest OK.

Teraz nie wpisałeś nic. Program sprawdza, co siedzi w zmiennej odebraneDane. Ponieważ Arduino nie odebrało żadnych danych, jest tam wciąż "zielona". Tak więc zmienna "kolor" ustawia się na wartość 1, dioda zielona zapala się na sekundę, gaśnie... ale zanim zdążysz to zauważyć, znów następuje sprawdzenie, porównanie, wstawienie jedynki do "kolor" i dioda się zapala...

Przy okazji: break to w tym przypadku wyjście ze switcha, z jakiej niby pętli chcesz wyjść jeśli żadnej w Twoim programie nie ma?

 

Ale dałeś do myślenia tym nakierowaniem. Ale właśnie dzięki niemu udało się rozwiązać zadanie 6.2 tak, żeby kod działał jak należy

Moja wersja zadania 6.2 (przy mocnym wsparciu forum i podglądzie innych rozwiązań )😉

#define zielona 8 //Pin 8 jako dioda zielona
#define czerwona 9 //Pin 9 jako dioda czerwona

String odebraneDane = ""; //Pusty ciag odebranych danych
int kolor = 0; // Zmienna dla przypisania numerow warunkom

void setup () {
  Serial.begin(9600);// Nawiazanie komunikacji z UART
  pinMode(zielona, OUTPUT);// Piny 8 i 9 jako wyjscia
  pinMode(czerwona, OUTPUT);
}
void loop() {
  while (Serial.available() <= 0) {};//Oczekiwanie na wprowadzenie danych
  if (Serial.available() > 0) {//Gdy wprowadzono dane
    odebraneDane = Serial.readStringUntil('\n');//Zapisz dane do zmiennej
  } if (odebraneDane == "czerwona") { //Gdy odebrano "czerwona"
    kolor = 1;//Warunek nr.1
  } else if (odebraneDane == "zielona") { //Gdy odebrano "zielona"
    kolor = 2;//Warunek nr.2h
  } else { //Gdy nie odebrano "czerwona" ani "zielona"
    kolor = 3;//Warunek nr.3
  }

  Serial.println(odebraneDane);//Podglad wprowadzonych danych
  switch (kolor) {//Sprawdz warunki
    case 1://Gdy spelniony warunek 1
      digitalWrite(czerwona, HIGH);//Wlaczdiode czerwona na 1 sek
      delay(1000);
      digitalWrite(czerwona, LOW);
      break;

    case 2://Gdy spelniony warunek 2
      digitalWrite(zielona, HIGH);//Wlacz diode zielona na 1 sek
      delay(1000);
      digitalWrite(zielona, LOW);
      break;

    default://Gdy zaden z warunkow nie jest spelniony drukj tekst
      Serial.println("Nie prawidlowy wybor, wisz czerwona lub zielona");
      break;
  }
}

 

  • Lubię! 1
Link do komentarza
Share on other sites

9 minut temu, Gieneq napisał:

Ciekawie masz zrealizowane oczekiwanie na odebrane dane

Zamień słowo "ciekawie" na "błędnie".

Jest: "czekaj na dane blokując procesor":

while (Serial.available() <= 0) {};

Powinno być: "jeśli dane nie przyszły nie rób nic".

if (!Serial.available()) return; // available zwraca wynik nieujemny

Jako pracę domową polecam znalezienie odpowiedzi, czym się skoczy uruchomienie tego kodu na ESP8266 (oczywiście po zmianie pinów np. na 4 i 5). W końcu Espduino czy Huzzah to też Arduino, nie?

  • Lubię! 1
Link do komentarza
Share on other sites

15 godzin temu, Gieneq napisał:

Ciekawie masz zrealizowane oczekiwanie na odebrane dane. Fajnie że pochwaliłeś się kodem programu, komuś też na pewno się przyda. Powodzenia z dalszymi zadaniami 💪😁

Dziekuje. A z tym "oczekiwaniem" to  było nie świadome. Myślałem że to standardowe rozwiązanie (chyba gdzieś to widziałem)🤔

 

15 godzin temu, ethanak napisał:

Zamień słowo "ciekawie" na "błędnie".

Jest: "czekaj na dane blokując procesor":


while (Serial.available() <= 0) {};

Powinno być: "jeśli dane nie przyszły nie rób nic".


if (!Serial.available()) return; // available zwraca wynik nieujemny

Jako pracę domową polecam znalezienie odpowiedzi, czym się skoczy uruchomienie tego kodu na ESP8266 (oczywiście po zmianie pinów np. na 4 i 5). W końcu Espduino czy Huzzah to też Arduino, nie?

Dziękuje za podpowiedź.  Ja  jestem jeszcze tak "zielony" w temacie, że nawet nie mam pojęcia co to "ESP8266"   " Espduino " czy " Huzzah ". . .

kod już poprawiłem.

#define zielona 8 //Pin 8 jako dioda zielona
#define czerwona 9 //Pin 9 jako dioda czerwona

String odebraneDane = ""; //Pusty ciag odebranych danych
int kolor = 0; // Zmienna dla przypisania numerow warunkom

void setup () {
  Serial.begin(9600);// Nawiazanie komunikacji z UART
  pinMode(zielona, OUTPUT);// Piny 8 i 9 jako wyjscia
  pinMode(czerwona, OUTPUT);
}
void loop() {
  if (!Serial.available())return {};//Oczekiwanie na wprowadzenie danych
  if (Serial.available() > 0) {//Gdy wprowadzono dane
    odebraneDane = Serial.readStringUntil('\n');//Zapisz dane do zmiennej
  } if (odebraneDane == "czerwona") { //Gdy odebrano "czerwona"
    kolor = 1;//Warunek nr.1
  } else if (odebraneDane == "zielona") { //Gdy odebrano "zielona"
    kolor = 2;//Warunek nr.2h
  }else{
    kolor = 3;
  }

  Serial.println(odebraneDane);//Podglad wprowadzonych danych
  switch (kolor) {//Sprawdz warunki
    case 1://Gdy spelniony warunek 1
      digitalWrite(czerwona, HIGH);//Wlaczdiode czerwona na 1 sek
      delay(1000);
      digitalWrite(czerwona, LOW);
      break;

    case 2://Gdy spelniony warunek 2
      digitalWrite(zielona, HIGH);//Wlacz diode zielona na 1 sek
      delay(1000);
      digitalWrite(zielona, LOW);
      break;

    default://Gdy zaden z warunkow nie jest spelniony drukj tekst
      Serial.println("Nie prawidlowy wybor, wisz czerwona lub zielona");
      break;
  }
}

   

Edytowano przez Vova
Link do komentarza
Share on other sites

Dnia 23.03.2020 o 08:28, Gieneq napisał:

@Vova fajnie, działa jak powinno 🙂 ale zamiast szeregu printów może spróbuj poeksperymentować z dodawaniem Stringów? Możesz zapoznać się z dokumentacją na stronie Arduino.

Witam. Czy mniej-więcej tak może to wyglądać String  zamiast Print? Jeszcze nie sprawdzałem czy kod działa , musiałbym jeszcze raz złożyć cały układ . . . 

#define przycisk 7 // Pin 7 jako "przycisk"

int fRezystor = 0;//Naswietlenie fotorezystora
int potencjometr = 0;//Pozycja potencjometru
int Przycisk = 0;//Stan przycisku

String stringJeden , stringDwa , stringTrzy , stringCztery , stringPiec , stringSzesc , stringSiedem , stringOsiem;
void setup() {
  Serial.begin(9600);//Nawiazanie komunikacji
  pinMode(7, INPUT_PULLUP);//Pin "7" jako wejscie

  stringJeden = String ( " Fotorezystor: " );
  stringDwa = " fRezystor ";
  stringTrzy =  String (" , potencjometr: " );
  stringCztery = " potencjometr ";
  stringPiec = String (" , przycisk wcisnieto: ");
  stringSzesc = " przycisk ";
  stringSiedem = String ( " razy " );

  Serial.println("/ n / n " );
  Serial.println();
}
void loop() {
  fRezystor = analogRead(A1);//Odczytujemy dane z ADC
  potencjometr = analogRead(A5);
  if (digitalRead(przycisk) == LOW) {//Kiedy wcisnieto przycisk
    delay(50);//Opoznienie dla niwelacji drgan swicza
    Przycisk = Przycisk + 1;//Po kazdym wcisnieciu zwieksz liczbe o "1"
    stringOsiem = stringJeden + stringDwa + stringTrzy + stringCztery + stringPiec + stringSzesc + stringSiedem;
    Serial.println ( stringOsiem);
  } while (digitalRead(7) == LOW) {} //Czekamy na wcisniecie przycisku
}

 

Link do komentarza
Share on other sites

Oj, jakieś dziwne rzeczy się podziały. Koledze @Gieneq raczej chodziło pewnie o dodawanie stringów w funkcji print, aby ograniczyć ich ilość. 

Zamiast pisać: 

Serial.print(" Fotorezystor: " );//Drukuj tekst
Serial.print(fRezystor );
Serial.print(", potencjometr: ");
Serial.print(potencjometr );
Serial.print(", przycisk wcisnieto ");
Serial.print(Przycisk );
Serial.print(" razy ");

Możesz napisać: 

Serial.print("Fotorezystor: " + String(fRezystor));
Serial.print(" potencjometr: " + String(potencjometr));
Serial.println(" przycis wciśnięto: " + String(Przycisk) + " razy"); 

 Już masz połowę linijek mniej. Na upartego mógłbyś to zapisać nawet w jednej linijce dodając wszystko do siebie. 

Chodzi o konwersję zmiennych liczbowych na zmienną typu string "w locie", przez co nie musisz dla stringów i intów pisać oddzielnych funkcji print. 

Edytowano przez BHBmacieg
  • Lubię! 1
Link do komentarza
Share on other sites

@BHBmacieg Jakoś po przeczytaniu podlinkowanego artykułu mi tak wyszło. Kod się skomlilował, myślałam ze jest ok. Dzisiaj jeszcze raz złożyłem układ a tu lipa.

Sposób który podałeś próbowałem wykorzystać na początku  ale z niewiedzy pisałem 

"przycisk wcisnieto;" + (przycisk) + "razy"

A nie 

("przycisk wcisnieto: " + String (Przycisk) + "razy")

  No i wiadomo że tonie działało...

Kod poprawiłem

#define przycisk 7 // Pin 7 jako "przycisk"

int fRezystor = 0;//Naswietlenie fotorezystora
int potencjometr = 0;//Pozycja potencjometru
int Przycisk = 0;//Stan przycisku

void setup() {
  Serial.begin(9600);//Nawiazanie komunikacji
  pinMode(7, INPUT_PULLUP);//Pin "7" jako wejscie
}
void loop() {
  fRezystor = analogRead(A1);//Odczytujemy dane z ADC
  potencjometr = analogRead(A5);
  if (digitalRead(przycisk) == LOW) {//Kiedy wcisnieto przycisk
    delay(50);//Opoznienie dla niwelacji drgan swicza
    Przycisk = Przycisk + 1;//Po kazdym wcisnieciu zwieksz liczbe o "1"
    Serial.print( " Fotorezystor: " + String(fRezystor));
    Serial.print(" , potencjometr: " + String (potencjometr));
    Serial.print(" , przycisk wcisnieto: " + String (Przycisk) + " razy");
  } while (digitalRead(7) == LOW) {} //Czekamy na wcisniecie przycisku
}

 

Link do komentarza
Share on other sites

Witam wszystkich, właśnie zaczynam naukę (programowania w ogóle, oraz zabawy z elektroniką/mikrokontrolerami

Poniżej mój kod do zadania 6.1

#define potenc A5
#define fotorezystor_1 A4
#define fotorezystor_2 A3
#define przycisk 8

int potencjometr = 0;
int fotorezystor1 = 0;
int fotorezystor2 = 0;
int wcisniecia = 0;

void setup() {
Serial.begin(9600);
pinMode(przycisk, INPUT_PULLUP);
pinMode(potencjometr, INPUT);
pinMode(fotorezystor_1, INPUT);
pinMode(fotorezystor_2, INPUT);
}

void loop() {
potencjometr = analogRead(potenc);
fotorezystor1 = analogRead(fotorezystor_1);
fotorezystor2 = analogRead(fotorezystor_2);
wcisniecia == digitalRead(przycisk);
if(digitalRead(przycisk)==LOW){
Serial.print("Fotorezystor 1: ");
Serial.print(fotorezystor1);
Serial.print("\t, Fotorezystor 2: ");
Serial.print(fotorezystor2);
Serial.print("\t Potencjometr: ");
Serial.print(potencjometr);
Serial.print("\t Przycisk wcisnieto  ");
Serial.print(wcisniecia);
Serial.println("\t razy");
++wcisniecia;
while(digitalRead(przycisk)==LOW);
}
delay(50);
}

Chciałem juz napisać całkowicie sam no i prawię się udało, minimalnie sobie pomogłem rozwiązaniami z komentarzy.

Link do komentarza
Share on other sites

@pawelmackowski po pierwsze witam na forum 🙂 

Po drugi kod wygląda dobrze, fajnie że się nim podzieliłeś. Powodzenia w dalszych zadaniach.

Ewentualnie możesz spróbować zrobić coś z tym zablokowaniem programu. Wiem że działa ale da się może inaczej to zrobić:

while(digitalRead(przycisk)==LOW);

 

Edytowano przez Gieneq
Link do komentarza
Share on other sites

Witam ponownie 🙂 jako dodatkowe zadanie chciałem sobie wykonać załączanie serwa przyciskiem dotykowym poniewaz mam taki i miałem problem ponieważ 0-180 stopni działało jak trzeba, lecz 180-0 lecialo samoczynnie, nieważne czy przycisk był wcisnięty czy nie. Z braku pomysłów jak to rozwiązać wspomogłem się komentarzami i całkowicie zmieniłem kod i zastosowałem zmienną bool tak jak tutaj ktoś to rozwiązał 🙂

#include <Servo.h>


Servo serwomechanizm;
byte pozycja=0;
int zmiana = 6;
bool kierunek = false;
void setup(){
  serwomechanizm.attach(9);
  pinMode(8, INPUT_PULLUP);
  Serial.begin(9600);

}

void loop() {
 while (digitalRead(8)==HIGH){
  if (pozycja == 180){
    kierunek = true; }
    if (pozycja==0){
      kierunek=false;}

   if (kierunek==false){
    pozycja=pozycja + zmiana;
    serwomechanizm.write(pozycja);

  Serial.println(pozycja);
  delay(50);}
    if (kierunek==true){
      pozycja = pozycja - zmiana;
  
  serwomechanizm.write(pozycja);

  Serial.println(pozycja);
  delay(50);
}

}
}

a efekt jest taki:

https://youtu.be/oZbdW8bkuQ8

  • Lubię! 1
Link do komentarza
Share on other sites

(edytowany)

Zad. 6.1.

#define przycisk 8
  void setup() 
  {
    Serial.begin(9600);
    pinMode(przycisk, INPUT_PULLUP);
  }
  int ile=0;
  void loop() 
  {
    if(digitalRead(przycisk)==LOW)
    {
      delay(100);
      ile++;
      Serial.print("Fotorezystor 1: ");
      Serial.print(analogRead(A1));
      Serial.print("\t Fotorezystor 2: ");
      Serial.print(analogRead(A2));
      Serial.print("\t Potencjometr: ");
      Serial.print(analogRead(A0));
      Serial.print("\t przycisk wciśnięto: ");
      Serial.print(ile);
      Serial.println(" razy");
    }
  }

IMG_4346.jpg

Zad. 6.2.

#define biala     8
#define zielona   9
#define niebieska 10
 
char odebraneDane;
 
void setup() 
{
  Serial.begin(9600);
  pinMode(biala,OUTPUT);
  pinMode(zielona,OUTPUT); 
  pinMode(niebieska,OUTPUT);
  digitalWrite(biala,LOW);
  digitalWrite(zielona,LOW); 
  digitalWrite(niebieska,LOW);
}
 
void loop() {
  if(Serial.available() > 0) 
  {
    odebraneDane = Serial.read();
  }
    switch(odebraneDane)
    {
      case 'b':
        digitalWrite(biala,HIGH); 
        delay(1000);
        digitalWrite(zielona,LOW); 
        digitalWrite(niebieska,LOW);
        break;
      case 'z':
        digitalWrite(zielona,HIGH); 
        delay(1000);
        digitalWrite(biala,LOW); 
        digitalWrite(niebieska,LOW);
        break;
      case 'n':
        digitalWrite(niebieska,HIGH); 
        delay(1000);
        digitalWrite(biala,LOW); 
        digitalWrite(zielona,LOW);
        break; 
      default:      
        digitalWrite(niebieska,LOW); 
        digitalWrite(biala,LOW); 
        digitalWrite(zielona,LOW);
        delay(1000);
        break;   
    }
}

IMG_4347.thumb.jpg.a7ecf2d9f7c54a1977fa28ff22d7b4c8.jpg

Edytowano przez ceiem
dodanie zadania 6.2
  • Lubię! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

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

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

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

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

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

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

×
×
  • Utwórz nowe...

Ważne informacje

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