Skocz do zawartości

Kurs Arduino - #6 - kontynuacja UART, serwomechanizmy


Pomocna odpowiedź

zadanie 6.2

Nie do końca chciałem tak zrobić chciałem by moc wpisywać cala nazwę np. czerwony i wyświetlał diodę ale nie znam zmiennej , funkcji która by na to pozwoliła wiec zrobiłem tak ;/ (W przyszłości jak przejdę ten kurs to wrócę do zadania i zrobię tak jak bym chciał 🙂)

A o to kod

#define zielona 8
#define czerwona 9
int czas = 1000;
int dane = 0;
void setup() {
 Serial.begin(9600);//połącz się z komputerem
 pinMode(zielona, OUTPUT);// nadaj pinom wyjścia
 pinMode(czerwona, OUTPUT);
 digitalWrite(zielona, LOW);// nadaj pinom stan niski 
 digitalWrite(czerwona, LOW);
}

void loop() {
 if(Serial.available() > 0){// sprawdź czy coś jest w buforze
   dane = Serial.read();// odczytaj jeden znak
   switch(dane){// porównaj czy dane jest z lub c jeśli nie 
     case 'z':
      digitalWrite(zielona, HIGH);
      delay(czas);
      digitalWrite(zielona, LOW);
     break;
     case 'c':
      digitalWrite(czerwona, HIGH);
      delay(czas);
      digitalWrite(czerwona, LOW);
     break;
     default:
     Serial.println("Niema takiego koloru");// wpisz niema takiego koloru
     break;
   }
 }

}

zadanie 6.1

#define przycisk 8

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

float napieciepotencjometr = 0;
float napieciefotorezystor1 = 0;
float napieciefotorezystor2 = 0;


void setup() {

  Serial.begin(9600);
  pinMode( przycisk, INPUT_PULLUP);

}

void loop() {

 potencjometr = analogRead(A5);
 fotorezystor1 = analogRead(A4);
 fotorezystor2 = analogRead(A3);

 napieciepotencjometr = potencjometr*(5.0/1023.0);
 napieciefotorezystor1 = fotorezystor1*(5.0/1023.0);
 napieciefotorezystor2 = fotorezystor2*(5.0/1023.0);

while(digitalRead(przycisk) == LOW){
  Serial.print("Odczyt napiecie: ");
  Serial.print("potencjometr ");
  Serial.print(napieciepotencjometr);
  Serial.print("\tfotorezystor1 ");
  Serial.print(napieciefotorezystor1);
  Serial.print("\tfotorezystor2 ");
  Serial.println(napieciefotorezystor2);
  delay(1000);
}   

  delay(1000);

}

może być, czy jakieś rady bo da się łatwiej prościej?? Z góry dziękuję za rady

PawełD, wydaje mi się, że drugie opóźnienie (delay(1000)) nie jest potrzebne - nie wnosi zbyt wiele do programu. Jedynie opóźnia reakcję na wciśnięcie przycisku - chyba, że tak chciałeś? Oprócz tego zawsze warto dodać trochę komentarzy, aby kod był czytelniejszy dla innych 😉

Uwazam, ze nalezy sie uczyc pisac bez jakiegokolwiek delay. Powoduja tylko problemy. Może nie na poczatku, przy banalnych sketchach, ale pozniej juz tak. Nawet moj sposob millis()- czas jest zly. Troche sie przejechałem przy BLYNKu. Musialem przerabiac na czasaktualny-czaspoprzedni. Zbyt czeste wywolywanie funkcji millis() blokowalo wysylanie danych z apki do procka

zadanie 6.3 i 6.4
#include <Servo.h>
Servo serwomechanizm;// nadaje nazwe serwu
byte pozycja = 0;// wstepna pozycja
int pozycjaPoprzednia = 0;// zapamietywanie poprzedniej pozycji
void setup() {
 serwomechanizm.attach(11);// nadanie pina serwu
 Serial.begin(9600);
}

void loop() {
 int odczyt = analogRead(A5);// odczyt wyniku z dzielnika
 Serial.println(odczyt);// wypisz dane by zkalibrowac serwo
 pozycja = map(odczyt, 0,1000,180,0);// nadanie przedzalow serwu 
   if (abs(pozycja-pozycjaPoprzednia) > 5){//ustawiam ruznice by serwo nie startowalo od 0 
   serwomechanizm.write(pozycja);//wpisuje mu pozycje i wykonuje ruch
   pozycjaPoprzednia = pozycja;// zapis pozycji
 }
 delay(300);// czas reakcji by nie spalic serwa
}

Trochę mało światła mam muszę lepsza żarówkę kupić ;D

[ Dodano: 20-01-2018, 09:43 ]

zadanie 6.2

Nie do końca chciałem tak zrobić chciałem by moc wpisywać cala nazwę np. czerwony i wyświetlał diodę ale nie znam zmiennej , funkcji która by na to pozwoliła wiec zrobiłem tak ;/ (W przyszłości jak przejdę ten kurs to wrócę do zadania i zrobię tak jak bym chciał 🙂)

A o to kod

#define zielona 8
#define czerwona 9
int czas = 1000;
int dane = 0;
void setup() {
 Serial.begin(9600);//połącz się z komputerem
 pinMode(zielona, OUTPUT);// nadaj pinom wyjścia
 pinMode(czerwona, OUTPUT);
 digitalWrite(zielona, LOW);// nadaj pinom stan niski 
 digitalWrite(czerwona, LOW);
}

void loop() {
 if(Serial.available() > 0){// sprawdź czy coś jest w buforze
   dane = Serial.read();// odczytaj jeden znak
   switch(dane){// porównaj czy dane jest z lub c jeśli nie 
     case 'z':
      digitalWrite(zielona, HIGH);
      delay(czas);
      digitalWrite(zielona, LOW);
     break;
     case 'c':
      digitalWrite(czerwona, HIGH);
      delay(czas);
      digitalWrite(czerwona, LOW);
     break;
     default:
     Serial.println("Niema takiego koloru");// wpisz niema takiego koloru
     break;
   }
 }

}

Wróciłem do zadania 6.2 i próbowałem po wpisie Soyera ale dalej nic z tego próbuje zamienić z String na int (toINT lub int(zmiena); i ciągle co pisze kolor to odczytuje 0

liczby of szem czyta a napisów nie

Już sił mi brakuje oraz brat google nie potrafi mi pomoc ;/

  • Lubię! 1

Witam,
mam pytanko czy jest jakaś możliwość ustawienia wolniejszej/płynniejszej pracy serva? Czy te ruchy muszą być takie nerwowe...?

Pozdrawiam.

Oczywiście. Zamiast jednej pozycji końcowej do której serwo zmierza z maksymalną prędkością (bo do tego jest zaprojektowane i przecież chcemy żeby było szybkie, płacimy za to spore pieniądze) wysyłaj wiele pozycji pośrednich rozłożonych równomiernie w czasie.

Zamiast zwykłego pokazania pozycji docelowej:

serwo.write(100);

zrób np. tak:

for (uint8_t p=0; p<100; p++)
{
  serwo.write( p);
  delay(10);
}

I wtedy osiągasz pozycję docelową dużo spokojniej, zużywając na to sekundę. To tylko prosty przykład zatrudniający procesor na cała sekundę do głupiej roboty w odliczanie czasu, ale pokazuje ideę. Tylko bardzo drogie serwa cyfrowe mają wewnętrzne programowanie prędkości. W przypadku wszystkich analogowych i większości cyfrowych musisz to robić samodzielnie pisząc lepszy program.

  • Lubię! 2
  • 2 tygodnie później...

Dziękuję za odpowiedź, słusznie drugie opóźnienie nie jest potrzebne.

zadanie 6.2 Trochę wybiedzone bez układu zbudowanego z diodami, ale chodzi o switch case przecież.

int odebranedane = 0;


void setup(){

 Serial.begin(9600); //komunikacjia z com
 delay(200); //opóźnienie konieczne aby nie wyskakiwaly dziwne znaki przed tekstem 
 Serial.println("Wybierz kolor diody do zapalenia poprzez podanie numeru");
 Serial.println("1) zielony");
 Serial.println("2) czerwony");


}

void loop(){

 if(Serial.available()>0){ //jezeli odebrano dane
   odebranedane = Serial.read(); //zapisanie tych danych do zmiennej

   switch(odebranedane){ // sprawdzaj zmienna odebranedane
     case '1': //jezeli odebrano 1 to...
     Serial.println("zapalono diode zielona");
     break;

     case '2'://jezeli odebrano 2 to...
     Serial.println("zapalono diode czerwona");
     break;

     default: // oderbano inne niz 1 i 2
     Serial.println("wybrany kolor niedostepny");
     break;
   }
 }
}

wzorując się na instrukcji switch case chciał bym żeby program wykonywał komendę z bluetooth którą wyślę do arduino.

odczyt z bluetooth na słowo czerwona z terminala na androidzie to:

99

122

114

199

111

110

97

13

10

jak taką wartość zapisać w case ??

Może nie tyle case co switch(zmienna). Jeśli chcesz sprawdzać za pomocą switch() wartość zmiennej x to:

switch(x)
{
 case 99:
 //tu kod dla x==99
 break;

case 122:
  //tu kod dla x==122
break;

case 114:
  //tu kod dla x==114
break;
//i tak dalej, a na końcu

default:
//a jeśli x nie jest obsługiwane przez case to program przejdzie tu i dzięki break wyjdzie ze switch()
break;
}

Belferek,

tylko że komenda " czerwona" na terminalu przedstawia się jako ciąg tych wszystkich liczb razem jedna po drugiej

void loop() {

 if (Serial.available()> 0){
   data = Serial.read();

  Serial.println(data);
  delay (100);
 }



 switch(data)
 case 'czerwona':
         {
           stanCzerwonej = !stanCzerwonej;
           Serial.println("bluetooth");
           Serial.println(stanCzerwonej);
           digitalWrite(czerwona,stanCzerwonej);
           if (stanCzerwonej == 1)
            {
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("ZAPALONO");
             lcd.setCursor(0,1);
             lcd.print("DIODA CZERWONA");

            }
           else
            {
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("ZGASZONO");
             lcd.setCursor(0,1);
             lcd.print("DIODA CZERWONA");
            }

           break;

U mnie to wygląda tak

99

122

114

199

111

110

97

13

10

No to gdzieś robisz literówki. Liczby te to kod ASCII i wcale nie tworzą stringu "czerwona". Ostatnie 2 liczby to znaki sterujące 13 - CR 10 - LF. Jeśli sprawdzasz TE LICZBY ze stringiem "czerwona" to wynik musi być FALSE. Pozbądź się tych CR i LF.

[ Dodano: 11-02-2018, 14:13 ]

a tak wogóle to przeczytaj tu: https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

switch() i case operują na zmiennych typu int i char, a nie na stringach. Może więc być case 'c': lecz case 'czerwona': już raczej nie.

Najprościej problem rozwiązać to sprawdzić za pomocą odpowiedniej funkcji klasy String co odebrano i zapamiętać w dodatkowej zmiennej np. komenda, a zmienną tę sprawdzać w switch(). Ja bym tak zrobił.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...