sequence sur le portd

bonjour

je voudrais executer une fonction à condition que le portD (en entree) recoive 4 séquences à la suite.

00000001
00000010
00000011
00000100

Je ne sais pas comment proceder

merci d avance

Salut

J'ai vu que tu avais posté la même question sur le forum anglais.
Ta question est très vague.

Tu pourrais la résoudre par une suite de while :

void setup() {
  DDRD = B00000000;  // sets Arduino pins 0 to 7 as input
}

void loop() {
  while (!(PORTD & B00000001));
  while (!(PORTD & B00000010));
  while (!(PORTD & B00000011));
  while (!(PORTD & B00000100));
  // ...
}

Mais tant que la séquence ne sera pas respectée, le code sera bloqué en attendant une entrée correcte.

@+

bonsoir

oui , j'avais pas vu que la version FR existait

que veux dire while (!
que se passe t il si la deuxième séquence n'est pas correcte ?
combien de temps met le programme à executer toute la boucle loop ?

merci pour votre aide

que veux dire while (!

Tant que PORTD ne vaut pas la valeur attendue.

que se passe t il si la deuxième séquence n'est pas correcte ?

Le code attend que la valeur soit correcte.

combien de temps met le programme à executer toute la boucle loop ?

Le temps que la séquence soit entrée correctement.

@+

merci pour votre aide

je me suis mal exprimé, combien de temps met le programme pour passer d'une ligne à l'autre si la condition est ok ?

bonne soiree

Aucune idée
peut-être une micro-seconde ?
Probablement moins.

ce code n’attend pas la séquence des 4 à la suite - je ne sais pas si c’est que l’OP veut dire par la notion de séquence

Pour le timing c’est sans doute 3 à 6 ticks d’horloge pour le while donc environ 250 nano secondes... (1 tick lecture registre, 1 tick le chargement du registre (et le compilo doit optimiser donc peut être fait une fois) et 1 tick compare et un branchement)

De plus je crois que les entrées D0 et D1 sont les ports digitaux 0 et 1 RX et TX.
Cela risque de poser des problèmes.

bonsoir J-M-L et hbachetti , et merci pour vos réponses.

en faite je reçois des infos sur le port D , très exactement sur les entrées D3,D4,D5,D6

il faut que, dans l'ordre chronologique, ces 4 bits aient uniquement les valeurs ci dessous :

0000 à T0
0001 à T1
0010 à T2
0011 à T3

ensuite si et seulement si on execute la suite du programme.

cordialement

KDH

Ok dans ce cas c’est typiquement une définition de programme qui se prête bien à la programmation par machine à états si vous voulez pouvoir gérer autre chose en même temps
(cf mon tuto éventuellement)

bonsoir

interessant tout ca, je vais relire encore .

merci, je vous fais un retour prochainement,

bonne soiree

cordialement,

KDH

En gros vous avez 6 états
{Attente0000, Attente0001, Attente0010, Attente0011, SequenceInvalide, SequenceValide} (et éventuellement un 7eme état : FinDuProcess)

Et un seul évènement qui est la détection de changement des 4 bits

Vous commencez à l’état Attente0000, tant que vous ne recevez pas 0000 vous restez dans cet état, si vous recevez 0000 vous passez à Attente0001

Dans l’état Attente0001 dès que vous détectez un changement (tant que ça reste 0000 c’est OK) sur les 4 bits vous testez si c’est 0001. Si oui vous passez en Attente0010, si non vous passez en SequenceInvalide

Dans l’état Attente0010 dès que vous détectez un changement sur les 4 bits vous testez si c’est 0010. Si oui vous passez en Attente0011, si non vous passez en SequenceInvalide

Dans l’état Attente0011 dès que vous détectez un changement sur les 4 bits vous testez si c’est 0011. Si oui vous passez en SequenceValide, si non vous passez en SequenceInvalide

Dans l’état SequenceValide vous faites ce qu’il faut quand tout va bien et soit vous passez à un autre état FinDuProcess, soit si vous devez attendre une nouvelle séquence vous remettez en état Attente0000

Dans l’état SequenceInvalide vous traitez l’erreur de séquence et soit vous passez à un autre état FinDuProcess, soit si vous devez attendre une nouvelle séquence vous remettez en état Attente0000

J-M-L:
En gros vous avez 6 états ...

Bonsoir J-M-L

[HUM]

absolument !

et il ne faut surtout jamais oublier de se demander à chaque fois :

Dans quel état j'erre?

--->

Il est bien tard :slight_smile:

J-M-L:
Il est bien tard :slight_smile:

:grin:

Je sais , mais c'est comme çà que je traite les effets " jet lag"

combien de temps met le programme à executer toute la boucle loop ?

Impossible de répondre, on ne connait pas le temps d'évolution des signaux en entrée

C'est toujours la même histoire.
On n'a aucune idée de ce qui est branché sur les entrées. Est-ce un clavier, des boutons, un ou des modules ?
Le programme a t-il d'autres choses a faire pendant l'attente de la séquence ?
Le flou total ...
Comment répondre efficacement ?

@+

Bonjour KdH76

KdH76:
je voudrais executer une fonction à condition que le portD (en entree) recoive 4 séquences à la suite.

Bonjour KdH76

Joli petit problème!

Je me suis attelé à la tâche en utilisant un tableau de valeurs (masques) à surveiller (sequValeurs) et d’un compteur de séquences (sequEnCours) ce qui oblige à respecter la chronologie désirée.
Cette méthode, contrairement à l’utilisation de while, ne bloque pas la boucle loop(), ce qui permet de faire autre chose en attendant qu’une des condition soit remplie.
Ainsi, on peut surveiller la variable boolean sequAtteinte qui indique que toutes les séquences ont passé dans l’ordre.
Un petit tuyau, il faut utiliser PIND et non pas PORTD pour lire les bits du port.

Un petit bout de code:

#define sequNombre 4                                                           // Nombre de séquences
byte sequEnCours;                                                              // Séquence en cours
boolean sequAtteinte;                                                          // Si séquences atteintes
byte sequValeurs[] = {B00010000, B00100000, B00110000, B01000000};             // Valeurs des séquences, sur les bits de poids fort du registre D
                                                                           // Pour ne pas toucher, spécialement les bits 0 et 1 (Tx et Rx)


void setup() {
 Serial.begin(115200);
 DDRD = B0000000;                                                           // Port B en entrée
 sequEnCours = 0;
 sequAtteinte = false;
}

void loop() 
{
 byte pindVal = PIND & B11110000;                                           // Pour cacher les bits inutiles
 if ((pindVal == sequValeurs[sequEnCours]) && !sequAtteinte)                 // On met le masque sequValeurs[n] sur la valeur lue pour comparer
 {
 Serial.println("Sequ. attendue :\t" + String(sequValeurs[sequEnCours], BIN) + "\t "  + String(sequValeurs[sequEnCours])+ "\t "  + String(sequEnCours));
 sequEnCours ++;                                                        // On passe à la séquence suivante, les autres sont ignorées

 if (sequEnCours >= sequNombre)                                         // Si toutes les séquences sont passées.
 {
 sequAtteinte = true;
 Serial.println("\nBingo !!!");
 }
 }
 delay(250);
}

Bonne journée
Cordialement
jpbbricole

@JP

Il y a quelques soucis:

  • c’est pas genial d’utiliser Serial et de toucher les pins 0 et 1
Serial.begin(115200);
DDRD = B0000000;

digital pins 0 (RX) et 1 (TX) ont besoin d’être en Input/Output

  • Si un des codes à attendre était 0 le test ne fonctionnera pas

jpbbricole:
ce qui oblige à respecter la chronologie désirée.

  • en fait non... le code ne correspond pas au cahier des charges il faut que, dans l'ordre chronologique, ces 4 bits aient uniquement les valeurs ci dessous
    — Tel que c’est écrit si vous avez des entrées inexactes entre la bonne séquence votre code dira bingo

  • le delay(250) est inutile et contre productif si la séquence attendue arrive en quelques millis ou microsecondes

(En note annexe et même si dans ce cas ce n’est pas du tout un soucis c’est pas top non plus d’indiquer aux nouveaux qu’utiliser la classe String pour des simple impressions comme celle là est OK. En général sur les petits systèmes on evite cette classe et on imprime par morceaux. ça permet de prendre de bonnes habitudes pour des codes plus compliqués)

@J-M-L

Bonjour J-M-L

En effet, il y avait une erreur (un malheureux changement de dernière minute :confused:)

J'ai corrigé en remplaçant:
if ((pindVal & sequValeurs
par
if ((pindVal == sequValeurs

Pour les autres commentaires, pas de commentaire....

Cordialement
jpbbricole