par , 22/05/2020 à 11h18 (1634 Affichages)
Les technologies dites « sans contact » sont plébiscitées, surtout ces derniers temps. Que ce soient pour des paiements par carte bancaire ou des boutons d'ascenseur, les technologies sans contact permettent les gestes « barrière ».
Dans un billet précédent, je vous présentais mon prototype de capteur de proximité sur carte PSoC 4. Imaginez ce qu'on pourrait faire avec un widget comprenant DEUX capteurs de proximité : une détection de mouvement bien sûr... Par exemple, un mouvement de balayage de la main au-dessus des capteurs dans un sens ou dans l'autre.
Ci-dessous, le montage prototype avec deux bouts de fils formant une boucle chacun, et reliés aux ports dédiés à la détection capacitive de proximité. Je ne me suis pas foulé, il est très moche ce proto
En mode Tuning, on voit l'évolution des signaux quand on balaye de la main dans un sens et dans l'autre. En fonction du sens de balayage, un capteur détectera une proximité de la main avant l'autre.
Dans la vidéo de démonstration ci-dessous, j'allume ou éteins une LED progressivement en fonction du sens de balayage.
La détection se fait à travers une fonction DetectGesture() appelée en boucle et retournant l'état du système (NO_GESTURE, SENSORS_INACTIVE, DOWN_SWIPE ou UP_SWIPE).
Si le système, programmé sous la forme d'une machine à états finis (FSM ou Finite State Machine) passe successivement les états INACTIVE→UP_ACTIVE→UP_END→INACTIVE, un balayage vers le haut est détecté (UP_SWIPE).
Et si le système passe successivement les états INACTIVE→DOWN_ACTIVE→DOWN_END→INACTIVE, un balayage vers le bas est détecté (DOWN_SWIPE).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| /********************************************************************************************************
* Inspiré du projet de démonstration CY8CKIT_044_Proximity_Gestures.cywrk fourni par Cypress
* https://www.cypress.com/documentation/development-kitsboards/cy8ckit-044-psoc-4-m-series-pioneer-kit
*********************************************************************************************************/
uint8 DetectGesture(void)
{
/* variables pour l'état des capteurs haut et bas */
uint8 prox_up_state = INACTIVE;
uint8 prox_down_state = INACTIVE;
/* Déclaration 'static' pour se souvenir de l'état entre chaque appel de la fonction */
static uint8 currState = INACTIVE;
static uint8 prevState = INACTIVE;
static uint8 proxCounter = RESET;
uint8 gesture = NO_GESTURE;
/* Acquisition de l'état des capteurs haut et bas
ACTIVE si proximité détectée, INACTIVE sinon */
prox_up_state = CapSense_1_CheckIsWidgetActive(CapSense_1_PROXIMITYSENSOR0__PROX);
prox_down_state = CapSense_1_CheckIsWidgetActive(CapSense_1_PROXIMITYSENSOR1__PROX);
/* Fonctionnement de la machine à états finis */
switch(currState)
{
case INACTIVE:
if(prox_up_state == ACTIVE && prox_down_state == INACTIVE)
{
proxCounter++;
if(proxCounter > PROX_DETECT_LIMIT) /* pour confirmer l'état */
{
proxCounter = RESET;
currState = UP_ACTIVE;
}
}
if(prox_up_state == INACTIVE && prox_down_state == ACTIVE)
{
proxCounter++;
if(proxCounter > PROX_DETECT_LIMIT) /* pour confirmer l'état */
{
proxCounter = RESET;
currState = DOWN_ACTIVE;
}
}
if(prox_up_state == INACTIVE && prox_down_state == INACTIVE)
{
currState = INACTIVE;
gesture = SENSORS_INACTIVE;
}
prevState = INACTIVE;
break;
case UP_ACTIVE:
if(prox_up_state == INACTIVE && prox_down_state == ACTIVE)
{
currState = UP_END;
}
if(prox_up_state == INACTIVE && prox_down_state == INACTIVE)
{
currState = INACTIVE;
gesture = SENSORS_INACTIVE;
}
prevState = UP_ACTIVE;
break;
case UP_END:
if(prox_up_state == INACTIVE)
{
gesture = DOWN_SWIPE;
currState = INACTIVE;
}
prevState = UP_END;
break;
case DOWN_ACTIVE:
if(prox_up_state == ACTIVE && prox_down_state == INACTIVE)
{
currState = DOWN_END;
}
if(prox_up_state == INACTIVE && prox_down_state == INACTIVE)
{
currState = INACTIVE;
gesture = SENSORS_INACTIVE;
}
prevState = DOWN_ACTIVE;
break;
case DOWN_END:
if(prox_down_state == INACTIVE)
{
gesture = UP_SWIPE;
currState = INACTIVE;
}
prevState = DOWN_END;
break;
default:
/* cas d'un état inconnu détecté */
currState = INACTIVE;
gesture = SENSORS_INACTIVE;
break;
}
return(gesture);
} |