Skocz do zawartości

Wykrywacz gestów sparkfun APDS-9960 problem


startrek1p2p

Pomocna odpowiedź

Podczas robienia projektu pojawił się problem prawdopodobnie u mnie z niewiedzą lub jakimś banalnym błędem. Jako podstawa posłużył mi kod dostarczony wraz z czujnikiem. 
Program na arduino miał po wykryciu odpowiedniej kombinacji ruchów: (lewy, prawy, góra, dół) zapalać diodę. Pomimo braku błędów przy kompilacji cały program nie działa.
Proszę o pomoc i wskazanie gdzie tutaj jest błąd lub co mogę zrobić inaczej.

/*

 3.3V         VCC              Power
 GND          GND              Ground
 A4           SDA              I2C Data
 A5           SCL              I2C Clock
 2            INT              Interrupt
  
 */
#include <Wire.h>
#include <SparkFun_APDS9960.h>

// Pins
#define APDS9960_INT    2 // Needs to be an interrupt pin

// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
int gesture = 0;

void setup() {

  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  // Initialize Serial port
  Serial.begin(9600);
  Serial.println();
  Serial.println(F("--------------------------------"));
  Serial.println(F("SparkFun APDS-9960 - GestureTest"));
  Serial.println(F("--------------------------------"));
  
  // Initialize interrupt service routine
  attachInterrupt(0, interruptRoutine, FALLING);

  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  
  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) ) {
    Serial.println(F("Gesture sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }
}

void loop() 
{
  if( isr_flag == 1 ) {
    detachInterrupt(0);
    handleGesture();
  void dioda();
    isr_flag = 0;
    attachInterrupt(0, interruptRoutine, FALLING);
  }
}
void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
      case DIR_UP:
        Serial.println("UP");
        break;
      case DIR_DOWN:
        Serial.println("DOWN");
        break;
      case DIR_LEFT:
        Serial.println("LEFT");
        break;
      case DIR_RIGHT: 
        Serial.println("RIGHT");
        digitalWrite(4, HIGH); //sprawdzenie łączeń diody
        delay(1000);
        digitalWrite(4, LOW);
        break;
      case DIR_NEAR:
        Serial.println("NEAR");
        break;
      case DIR_FAR:
        Serial.println("FAR");
        break;
      default:
        Serial.println("NONE");
    }
  }
}
 
 void dioda(){
  if((apds.readGesture() == DIR_LEFT)&&(gesture == 1)){
    digitalWrite(4, HIGH);
    delay(5000); 
    digitalWrite(4, LOW); 
    gesture=0;
  }
  
  if(apds.readGesture() == DIR_RIGHT ){
    gesture = 0;
  }
  
  if(apds.readGesture() == DIR_UP ){
    gesture = 0;
  }
  
    if(apds.readGesture() == DIR_DOWN ){
    gesture = 1;
  }
 
 }

 

Link do komentarza
Share on other sites

@startrek1p2p, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.

4 godziny temu, startrek1p2p napisał:

Pomimo braku błędów przy kompilacji cały program nie działa.
Proszę o pomoc i wskazanie gdzie tutaj jest błąd lub co mogę zrobić inaczej.

Napisz proszę czym się objawia to, że nie działa. Otrzymujesz fałszywe wyniki (jakie?) czy może nie ma żadnych wyników? Jak masz wszystko podłączone? Najlepiej pokaż jakieś zdjęcie.

Link do komentarza
Share on other sites

Samo wykrywanie gestów działa, ale już Całe Void(dioda) nie działa. Dlaczego? to nie wiem, ponieważ gesty są wykrywane i mimo dobrej kolejności nic sie nie dzieje. Dla pewności przy ruchu w prawo dałem aby dioda zapalała sie na 1 sekundę i działa za każdym razem.

IMG_20190204_224535.jpg

v2.JPG

Link do komentarza
Share on other sites

Dobrze, czyli mamy pewność, że czujnik działa, a błąd jest gdzieś w Twoim fragmencie - to dobry znak. Teraz opisz mi proszę jak według Ciebie ma działać ta funkcja:

void dioda(){
  if((apds.readGesture() == DIR_LEFT)&&(gesture == 1)){
    digitalWrite(4, HIGH);
    delay(5000); 
    digitalWrite(4, LOW); 
    gesture=0;
  }
  
  if(apds.readGesture() == DIR_RIGHT ){
    gesture = 0;
  }
  
  if(apds.readGesture() == DIR_UP ){
    gesture = 0;
  }
  
    if(apds.readGesture() == DIR_DOWN ){
    gesture = 1;
  }
 
 }

Napisz tak normalnie, słownie jak według Ciebie ona powinna działać, bo nie jestem w stanie tego rozszyfrować.

Ta funkcja może ma szansę wykryć gest w stylu w dół i w lewo, ale nie mam pojęcia jak mogłaby obsłużyć gest lewo > prawo > góra > dół.Pomijając to, że nie rozumiem tutaj Twojego podejścia do tematu, to ten kod wygląda zbyt prosto jak na możliwość wykrycia takiej sekwencji ruchów. Opisz jak to sobie wymyśliłeś to zobaczymy co dalej 🙂

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

(edytowany)

@Treker To jest tak całą funkcje już przerabiałem kilka razy to była już ostatnio wymyślona wersja wersja.  Najpierw używałem inkrementacji i gdy wynik osiągał by 4 to wtedy dioda powinna  świecić, ale niestety zawsze zwiększało stan niezależnie jaki by ruch wykryło.

Teraz miała być zmienić stałą Gesture. Dopiero po wykonaniu pierwszych 3 kroków w odpowiedniej kolejności możemy dojść do kroku 4 czyli zmianę stanu gesture , stała zmieniało by się z 0 na 1 i powodowała by zmianę stanu na diodzie. uczę się całego programowania od niedawna i jak dla mnie powinno to działać  😄 ale jak widać coś tutaj jest nie tak 

 

całość miało działać jak sejf po odpowiednim pomachaniu ma sie otwierać ukryty w pokoju zamek.

Edytowano przez startrek1p2p
Link do komentarza
Share on other sites

@startrek1p2p, wydaje mi się, że inkrementowanie zmiennej było dobrym tropem. Musiałeś chyba jednak coś tam pomieszać i dlatego u Ciebie nie działało. Ja bym proponował przykładowo taki algorytm:

0. Zmienna globalna licznik o wartości 0;

W pętli: 
1. Jeśli wykryto ruch w lewo - ustaw zmienną licznik na 1
2. Jeśli wykryto ruch w prawo, a zmienna licznik = 1, to ustaw zmienną licznik na 2. W przeciwnym wypadku ustaw zmienną licznik na 0.
3. Jeśli wykryto ruch w górę, a zmienna licznik = 2, to ustaw zmienną licznik na 3. W przeciwnym wypadku ustaw zmienną licznik na 0.
4. Jeśli wykryto ruch w dół, a zmienna licznik = 3, to ustaw zmienną licznik na 4. W przeciwnym wypadku ustaw zmienną licznik na 0.
5. Jeśli zmienna licznik równa się 4 to włącz diodę i ustaw zmienną licznik  na 0, aby możliwe było wykrywanie kolejnych sekwencji.

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

Poza tym @Belferek słusznie zauważył - wywołanie funkcji to "dioda();"  a nie "void dioda();" (w tym drugim przypadku jest to deklaracja, że gdzieś w programie istnieje funkcja dioda o bliżej nieokreślonych parametrach).

Link do komentarza
Share on other sites

@startrek1p2p to może pochwalisz się kodem lub pokażesz jakieś demo? 😉 Pewnie ktoś w przyszłości skorzysta, a do tego będziemy mogli doradzić jeszcze jakieś optymalizacje w programie.

Link do komentarza
Share on other sites

Program działa bez zarzutu, jedyny minus to opóźnienie, ale tylko 1 sekunda(od świecenia diody). Dodatkowo aby nie trzeba było za każdym razem patrzeć na monitor, dobudowałem sobie lampki wskazujące jaki ruch zrobiłem (bez oddalania i przybliżania).

/*

 3.3V         VCC              Power
 GND          GND              Ground
 A4           SDA              I2C Data
 A5           SCL              I2C Clock
 2            INT              Interrupt
  
 */
#include <Wire.h>
#include <SparkFun_APDS9960.h>

// Pins
#define APDS9960_INT    2 // Needs to be an interrupt pin

// Constants

// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;
int gesture = 0;

void setup() {

  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  pinMode(12, OUTPUT);
  digitalWrite(12, LOW);
  pinMode(11, OUTPUT);
  digitalWrite(11, LOW);
  pinMode(10, OUTPUT);
  digitalWrite(10, LOW);
  // Initialize Serial port
  Serial.begin(9600);
  Serial.println();
  Serial.println(F("--------------------------------"));
  Serial.println(F("SparkFun APDS-9960 - GestureTest"));
  Serial.println(F("--------------------------------"));
  
  // Initialize interrupt service routine
  attachInterrupt(0, interruptRoutine, FALLING);

  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  
  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) ) {
    Serial.println(F("Gesture sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }
}

void loop() 
{
  if( isr_flag == 1 ) {
    detachInterrupt(0);
    handleGesture();
    isr_flag = 0;
    attachInterrupt(0, interruptRoutine, FALLING);
  }
}
void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
  
      case DIR_UP:
        Serial.println("UP");
        digitalWrite(10, HIGH);
        delay(1000);
        digitalWrite(10, LOW);
    if((gesture == 0)||(gesture == 1)){
      gesture ++;
    }
    else{
      gesture = 0;
    }
        break;
    
      case DIR_DOWN:
        Serial.println("DOWN");
        digitalWrite(11, HIGH);
        delay(1000);
        digitalWrite(11, LOW);
      gesture = 0;
        break;
    
      case DIR_LEFT:
        Serial.println("LEFT");
        digitalWrite(12, HIGH);
        delay(1000);
        digitalWrite(12, LOW);
    if(gesture == 2){
      gesture ++;
    }
    else{
      gesture = 0;
    }
        break;
    
      case DIR_RIGHT:
        Serial.println("RIGHT");
        digitalWrite(13, HIGH);
        delay(1000);
        digitalWrite(13, LOW);
    if(gesture == 3){
      digitalWrite(4, HIGH);
      delay(5000); 
      digitalWrite(4, LOW);
      gesture = 0;
    }
    else{
      gesture = 0;
    }
        break;
    
      case DIR_NEAR:
        Serial.println("NEAR");
    gesture = 0;
        break;
    
      case DIR_FAR:
        Serial.println("FAR");
    gesture = 0;
        break;
    
      default:
        Serial.println("NONE");
    }
  }
}

 

IMG_20190217_170634.jpg

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

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...

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.