• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Programowanie przycisku - Romeo V2
#1
Witam, posiadam płytkę Dfrobot Romeo V2. Chciałem wykorzystać zamontowane na niej przyciski. W instrukcji na stronie producenta jest przykład ich użycia - Pod sekcją "Example use of Button S1-S5"
Nie rozumiem w pełni tego kodu. Zamontowałem diodę led na pin 13 i ten program owszem działa.
Chcę go zmodyfikować by po wciśnięciu konkretnego przycisku wykonał jakąś akcję. Zmodyfikowałem go trochę i wygląda tak: 
Kod:
char msgs[5][15] = {
 "Right Key OK ",
 "Up Key OK    ",
 "Down Key OK  ",
 "Left Key OK  ",
 "Select Key OK" };
char start_msg[15] = {
 "Start loop "};
int  adc_key_val[5] ={
 30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
void setup() {
 pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat
 pinMode(12, OUTPUT);
 pinMode(11, OUTPUT);
 Serial.begin(9600);

 /* Print that we made it here */
 Serial.println(start_msg);
}

void loop()
{
 adc_key_in = analogRead(0);    // read the value from the sensor
 digitalWrite(13, HIGH);
 /* get the key */
 key = get_key(adc_key_in);    // convert into key press
 if (key != oldkey) {   // if keypress is detected
   delay(50);      // wait for debounce time
   adc_key_in = analogRead(0);    // read the value from the sensor
   key = get_key(adc_key_in);    // convert into key press
   if (key != oldkey) {
     oldkey = key;
     if (key >=0){
       Serial.println(adc_key_in);
       Serial.println(msgs[key]);
       if(adc_key_in==0){
         digitalWrite(11,LOW);
         digitalWrite(12,HIGH);
       }
       else if(adc_key_in==143){
         digitalWrite(12,LOW);
         digitalWrite(11,HIGH);
       }
     }
   }
 }
 digitalWrite(13, LOW);
}
// Convert ADC value to key number
int get_key(unsigned int input)
{
 int k;
 for (k = 0; k < NUM_KEYS; k++)
 {
   if (input < adc_key_val[k])
   {
     return k;
   }
 }
 if (k >= NUM_KEYS)
   k = -1;     // No valid key pressed
 return k;
}
Dodałem tylko dwie instrukcje "IF" pozwalające mi odpalać diody LED.
Przechodząc do sedna, chcę jakoś uszczuplić ten program by nie był taki obszerny. Musi być jakieś prostsze wyjście aby odwołać się do konkretnego przycisku.
Dziękuję z góry za pomoc.
 
Odpowiedź
#2
Klawiaturka jest analogowa. Na początek dla każdego przycisku ustal jakie ma widełki wskazań ADC
Serial.println(analogRead(0));
Przykładowo nominalnie przycisk UP może mieć rezystor ustalający odczyt ADC na 150, a odczyty będą pływać w zakresie 120-180.
Kod może być prostszy albo bardziej rozbudowany, zależy co chcesz dalej z nim robić.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
Gdy odpalę kod i wcisnę każdy przycisk po kolei w konsoli wyskoczy mi coś takiego:
Kod:
0
Right Key OK
143
Up Key OK    
327
Down Key OK  
503
Left Key OK  
741
Select Key OK
Te numery to (wydaje mi się) wartości adc_key_in. 
Co więcej, umieściłem to pytanie na angielskim forum i pewna osoba podała mi taki kod: 
Kod:
const char* msgs[] = {
 "Right Key",
 "Up Key",
 "Down Key",
 "Left Key",
 "Select Key"
};

// Convert ADC value to key number
const int adc_key_val[] = {30, 150, 360, 535, 760};
const byte NUM_KEYS = 5;
int8_t oldkey = -1;

int8_t get_key()
{
 int input = analogRead(A0);
 for (int8_t k = 0; k < NUM_KEYS; k++)
   if (input < adc_key_val[k])
     return k;
 return -1; // no key
}


void setup() {
 Serial.begin(115200);
 Serial.println(F("Starting loop "));
}


void loop()
{
 int8_t key = get_key();      // convert into key press
 if ((key != -1) && (key != oldkey)) {   // if keypress is detected
   Serial.println(msgs[key]);
   delay(50); // wait for debounce time (poor's man debounce :-) )
   oldkey = key;
 } else if (key == -1) oldkey = -1; // released
}
Niestety nie działa jak powinien. Gdy wcisnę jeden przycisk pojawiają mi się takie (albo wcale) komunikaty:
Kod:
Up Key OK
Right Key OK
Up Key OK
Left Key OK
Down Key OK
Left Key OK
 
Odpowiedź
#4
Pewnie warunki masz ustawione odwrotnie, po wykryciu że ADC<100 już nie powinien sprawdzać czy ADC<200, itd. No i debounce trzeba też ogarnąć, np. sprawdzasz co 5ms i jeśli przycisk jest wciśnięty przez 5-10 kolejnych sprawdzeń to jest wciśnięty, inaczej to były drgania po wciśnięciu/puszczeniu.
Możesz też po prostu użyć byblioteki: https://github.com/MatCat/AnalogDebounce.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
Jestem początkujący i nie ukrywam, że nie umiem używać bibliotek. Muszę poczytać jakieś poradniki na ten temat.
 
Odpowiedź
#6
Wgrałem bibliotekę oraz użyłem szkicu przykładowego.
Klikam przyciskami to wyświetlają się ich numery (w załączniku). Teraz tylko jak zaprogramować te przyciski to jakiś funkcji.[Obrazek: edfaaa9cc6456.png]
 
Odpowiedź
#7
Masz na sumieniu jakiś kurs programowania? Z Youtube, bloga, książki? Arduino jest najłatwiejsze na początek, ale jakieś podstawy trzeba mieć. Może zerknij tutaj na początek: link.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#8
Przeczytałem wiele kursów na internecie. Zrobiłem kilka projektów z serwomechanizmami, sensorem dystansu, nawet robota który sam jeździ i omija przeszkody lub na bluetooth. Ale jestem osobą która mało czyta poradników a woli działać. Chyba nie w tym droga więc zaczynam czytać książki do C++, które dostałem od znajomego. Osobiście miałem styczność z wieloma językami programowania jako technik informatyk, który skończył szkołę w tym roku, ale jeżeli chcę pisać w arduino to muszę się jeszcze wiele nauczyć. Dzięki za odpowiedź.
 
Odpowiedź
#9
Udało mi się napisać działający kod, tak aby diody led świeciły się po wciśnięciu danego przycisku. Dziękuję za pomoc wszystkim. Umieszczam tutaj działający kod:
Kod:
char msgs[5][15] = {
 "Right Key OK ",
 "Up Key OK    ",
 "Down Key OK  ",
 "Left Key OK  ",
 "Select Key OK" };
char start_msg[15] = {
 "Start loop "};
int  adc_key_val[5] ={
 30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
void setup() {
 pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat
 pinMode(12, OUTPUT);
 pinMode(11, OUTPUT);
 Serial.begin(9600);

 /* Print that we made it here */
 Serial.println(start_msg);
}

void loop()
{
 adc_key_in = analogRead(0);    // read the value from the sensor
 digitalWrite(13, HIGH);
 /* get the key */
 key = get_key(adc_key_in);    // convert into key press
 if (key != oldkey) {   // if keypress is detected
   delay(50);      // wait for debounce time
   adc_key_in = analogRead(0);    // read the value from the sensor
   key = get_key(adc_key_in);    // convert into key press
   if (key != oldkey) {
     oldkey = key;
     if (key >=0){

// here is where you know that a button is pushed
// should be a unique number for each button


  Serial.println((String)key);//get the number that represents each button !!!



// do stuff here
if(key == 0){ digitalWrite(11,HIGH);digitalWrite(12,LOW);}
if(key == 1){ digitalWrite(12,HIGH);digitalWrite(11,LOW);}

     }
   }
 }
 digitalWrite(13, LOW);
}
// Convert ADC value to key number
int get_key(unsigned int input)
{
 int k;
 for (k = 0; k < NUM_KEYS; k++)
 {
   if (input < adc_key_val[k])
   {
     return k;
   }
 }
 if (k >= NUM_KEYS)
   k = -1;     // No valid key pressed
 return k;
}
 
Odpowiedź
#10
Jak chcesz użyć biblioteki to po prostu ją czytasz i analizujesz. Czasami jest dużo przykładów i wyjaśnień, ale że ta biblioteka jest   banalna, to i wiele nie ma.
Wszystko dostałeś w jednej zmiennej Button, to ją drukujesz w funkcji callback:
Kod:
// Callback function
void ButtonPush(byte Button) {
 Serial.print("Button Pushed: ");
 Serial.println(Button);
 /* Will return 255 on release of a button
    Or 0 to 4 corrisponding to a specific button
    Depending on the resistors used to make your
    keypad you may need to adjust the analog value
    for each button, to do this you can change
    Buttons.adc_key_val[0-4] to a slightly higher number
    then the highest number you get on a direct analog read.
   
    If you need more or less then 5 buttons, you can
    adjust the values accordingly in the library files.
   
    Library works out of the box for Cytron LCD and
    Keypad shield, and should work for SainsSmart one as well.
 */
}
Jeśli biblioteka nie działałby prawidłowo wystarczyłoby zmienić progi podanych w niej wartości ADC, ewentualnie dodać/odjąć wartości i dopasować tablice do innej ilości przycisków. 
W przykładowym callback'u drukujesz zmienną Button, co za problem przypisać tą zmienną do swojej zmiennej uint8_t "WcisnietyPrzycisk=Button", zamiast drukować Button.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości