Morse key - bouton poussoir ?

Oui effectivement @J-M-L, il manque la fluidité dans les accélérations et les ralentissements.

Je comprends que si j’accélère trop vite ou je ralenti trop vite, l’algorithme ne suit pas. C’est ce que @terwal m’a expliqué et que vous avez confirmé :+1: bêtement je n’ai pas compris de suite ce que @terwal m’expliquait.

Bon je pense que ça ne va pas être simple du tout.
On peut continuer comme on avait prévu, je commence par expliquer votre code avec un schéma Keynote et ensuite on travaille à l’élaboration d’un algorithme ?
@terwal pourra se joindre à nous si il le souhaite :wink:

Bonne soirée et merci.

PS : dans la réalité du terrain vous avez un opérateur qui communique avec un autre et si il y en a un qui va trop vite et que l’autre ne comprend pas, le moins rapide demande au plus rapide de ralentir. Nous il faut qu’on fasse en sorte que l’ordinateur s’adapte en temps réel à la vitesse de l’opérateur. Pas simple du tout en tout cas pour moi :wink:

Un parallèle pourrait être le port série réglé à une certain débit et le terminal série réglé sur un autre débit. On reçoit n’importe quoi les 1 et 0 ne sont pas bien reconnus

Certains appareils intègrent une fonction d’auto-bauding pour détecter automatiquement la vitesse de transmission en analysant des caractères spécifiques comme 0x55 ou 0xAA, qui présentent des motifs binaires réguliers permettant de mesurer facilement les transitions du signal et de déterminer la vitesse de communication.

Bonjour concernant mon programme et à titre d'exemple je manipule en accélérant ma vitesse que je peux très bien stabiliser sans problème, voici une augmentation de la vitesse sans bug. je passe de temps = 150 à temps = 139 puis à temps = 117.

temps = 150 :

BONJOUR LE FORUM BONJOUR LE FORU
nmr : 0 0

nmr : 1 84

nmr : 2 92

nmr : 3 100

nmr : 4 102

nmr : 5 104

nmr : 6 106

nmr : 7 112

nmr : 8 117

nmr : 9 119

nmr : 10 120

nmr : 11 121

nmr : 12 121

nmr : 13 121

nmr : 14 121

nmr : 15 121

nmr : 16 122

nmr : 17 123

nmr : 18 124

nmr : 19 124

nmr : 20 125

nmr : 21 131

nmr : 22 131

nmr : 23 132

nmr : 24 132

nmr : 25 135

nmr : 26 136

nmr : 27 136

nmr : 28 138

nmr : 29 139

nmr : 30 140

nmr : 31 140

nmr : 32 142

nmr : 33 145

nmr : 34 145

nmr : 35 148

nmr : 36 148

nmr : 37 151

nmr : 38 151

nmr : 39 155

nmr : 40 155

nmr : 41 156

nmr : 42 158

nmr : 43 158

nmr : 44 159

nmr : 45 164

nmr : 46 176

nmr : 47 177

nmr : 48 177

nmr : 49 180

nmr : 50 183

nmr : 51 195

nmr : 52 199

nmr : 53 200

nmr : 54 217

nmr : 55 246

nmr : 56 260

temps médian : 139
M

temps = 139 :

BONJOUR LE FORUM BONJOUR LE FORU
nmr : 0 74

nmr : 1 80

nmr : 2 83

nmr : 3 84

nmr : 4 84

nmr : 5 84

nmr : 6 89

nmr : 7 91

nmr : 8 91

nmr : 9 93

nmr : 10 94

nmr : 11 94

nmr : 12 95

nmr : 13 95

nmr : 14 96

nmr : 15 97

nmr : 16 97

nmr : 17 98

nmr : 18 101

nmr : 19 106

nmr : 20 107

nmr : 21 107

nmr : 22 110

nmr : 23 110

nmr : 24 110

nmr : 25 111

nmr : 26 113

nmr : 27 115

nmr : 28 116

nmr : 29 117

nmr : 30 117

nmr : 31 117

nmr : 32 119

nmr : 33 119

nmr : 34 121

nmr : 35 124

nmr : 36 125

nmr : 37 125

nmr : 38 127

nmr : 39 127

nmr : 40 128

nmr : 41 128

nmr : 42 129

nmr : 43 129

nmr : 44 130

nmr : 45 130

nmr : 46 134

nmr : 47 137

nmr : 48 139

nmr : 49 147

nmr : 50 151

nmr : 51 154

nmr : 52 155

nmr : 53 162

nmr : 54 171

nmr : 55 181

nmr : 56 260

temps médian : 117
M

Voilà ce n'est pas compliqué d'augmenter sa vitesse ni de la stabiliser (du moins techniquement avec l'algorithme... ). Maintenant je suis vieux et j'ai moins le rythme dans la peau.

Là où ça se complique c'est lorsqu'on veut diminuer la vitesse. Il faut avoir une certaine maîtrise de la manipulation mais ça se fait grâce à la marge de manoeuvre :

if (bouton.vientDEtreEnfonce() && (espace < seuilDePriseEnCompte(temps) )) { // Recupère les silences jusqu'à ce seuil
    valeurMediane[x] = espace;
    x++;
    if (x == 56)  {
      algorithmeT(valeurMediane);
      x = 0;
    }
  }

C'est la variable seuilDePriseEnCompte qui permet de diminuer la vitesse :
exemple d'un passage de temps = 150 à temps = 206. c'est vraiment très lent pour moi ...

BONJOUR LE FORUM BONJOUR LE FOR
nmr : 0 0

nmr : 1 81

nmr : 2 86

nmr : 3 99

nmr : 4 101

nmr : 5 103

nmr : 6 106

nmr : 7 120

nmr : 8 121

nmr : 9 123

nmr : 10 132

nmr : 11 134

nmr : 12 135

nmr : 13 141

nmr : 14 145

nmr : 15 149

nmr : 16 164

nmr : 17 165

nmr : 18 171

nmr : 19 172

nmr : 20 175

nmr : 21 179

nmr : 22 180

nmr : 23 180

nmr : 24 182

nmr : 25 188

nmr : 26 193

nmr : 27 194

nmr : 28 205

nmr : 29 206

nmr : 30 211

nmr : 31 211

nmr : 32 214

nmr : 33 216

nmr : 34 219

nmr : 35 221

nmr : 36 221

nmr : 37 221

nmr : 38 224

nmr : 39 229

nmr : 40 232

nmr : 41 235

nmr : 42 243

nmr : 43 244

nmr : 44 246

nmr : 45 248

nmr : 46 248

nmr : 47 255

nmr : 48 258

nmr : 49 262

nmr : 50 265

nmr : 51 269

nmr : 52 275

nmr : 53 276

nmr : 54 277

nmr : 55 332

nmr : 56 388

temps médian : 206
U

conclusion : mon algorithme fonctionne mais il faut avoir les bases nécessaires en matière de manipulation et de plus il faut être en mesure de faire la corrélation entre le temps fixé par le programme et la façon de manipuler en fonction de ce temps.
En fait il dépend du manipulateur et de son aptitude à s’adapter à la vitesse fixée par temps. Il ne permet pas à la machine de s’adapter au manipulateur mais plutôt l’inverse… il retranscrit parfaitement le code si la bonne vitesse est respectée :wink:
Demain je laisse tomber mon programme et j'attaque le schéma du programme de @J-M-L .

Bonne journée.

J'ai surement fait une erreur, j'aurais découper comme toi chaque élément, plutôt que faire une ligne indigeste.

Je n'ai pas regardé cette partie de l'algo, mais si la base de temps glisse vers 126, alors ce n'est pas bon non plus, je pense sur deux points, toujours sur l'inter-lettre et les symbols(point, trait).

Pour l'inter-lettre(pas en fin de mot), si temps = 126 et que l'on a un relâchement, inférieur à la moyenne (ex 125 ou plutôt 376).
Alors 376 ne sera pas supérieur à 3*temps=378.
Donc on garde le même problème.

Pour un point/trait, si temp=126 et que l'on a un appuis supérieur à la moyenne (ex=127)
Alors 127 est supérieur à temp donc sera reconnu comme un trait au lieu d'un point.

Je ne sais pas si je suis claire?
En fait ce que je veux exprimer, c'est que je ne vois pas comment on peut mélanger médiane, seuil minimal, seuil maximal, avec une seul valeur.
si on garde la base comme la valeur de la médiane, les seuils devrait être par exemple:
"seuil minimal" devrait être 90% de médiane, soit pour 126, une valeur de 113.4
"seuil maximal" devrait être 110% de médiane, soit pour 126, une valeur de 138.6

Dans ce cas ou aura:
pour le point toutes valeurs inférieur au seuil maximal 138.6
pour le trait les valeurs entre 3113.4=340 et 3138.6=416, que l'on peut simplifier de 138.6 à 416, mais qui n'est pas juste si on prend la règle officiel.
pour une lettre qui n'est pas en fin de mot , toutes valeurs entre 3113.4 et 3138.6, que l'on peut simplifier en supérieur au seuil minimal(3*113.4).

Un dernier exemple avec une série de A et de B.
Point de depart : temps = 150

  • temps prend comme valeur 114
  • enfin temps = 101 mais je n'ai pas testé car en limite de vitesse minimum et je n'aurai pu tenir le tempo :

ABABAB ABABAB ABABAB ABABAB ABA
nmr : 0 0

nmr : 1 56

nmr : 2 60

nmr : 3 60

nmr : 4 63

nmr : 5 63

nmr : 6 66

nmr : 7 67

nmr : 8 67

nmr : 9 71

nmr : 10 72

nmr : 11 73

nmr : 12 77

nmr : 13 78

nmr : 14 86

nmr : 15 96

nmr : 16 99

nmr : 17 100

nmr : 18 100

nmr : 19 101

nmr : 20 103

nmr : 21 103

nmr : 22 104

nmr : 23 106

nmr : 24 107

nmr : 25 109

nmr : 26 110

nmr : 27 111

nmr : 28 112

nmr : 29 114

nmr : 30 117

nmr : 31 117

nmr : 32 120

nmr : 33 121

nmr : 34 123

nmr : 35 124

nmr : 36 125

nmr : 37 127

nmr : 38 129

nmr : 39 132

nmr : 40 138

nmr : 41 142

nmr : 42 151

nmr : 43 152

nmr : 44 158

nmr : 45 159

nmr : 46 162

nmr : 47 165

nmr : 48 166

nmr : 49 167

nmr : 50 168

nmr : 51 171

nmr : 52 174

nmr : 53 175

nmr : 54 178

nmr : 55 179

nmr : 56 181

temps médian : 114
B ABABAB ABABAB ABABAB ABABAB ABA
nmr : 0 45

nmr : 1 50

nmr : 2 54

nmr : 3 55

nmr : 4 57

nmr : 5 58

nmr : 6 61

nmr : 7 63

nmr : 8 63

nmr : 9 64

nmr : 10 68

nmr : 11 69

nmr : 12 71

nmr : 13 76

nmr : 14 76

nmr : 15 80

nmr : 16 85

nmr : 17 85

nmr : 18 86

nmr : 19 87

nmr : 20 88

nmr : 21 89

nmr : 22 90

nmr : 23 90

nmr : 24 94

nmr : 25 94

nmr : 26 95

nmr : 27 96

nmr : 28 99

nmr : 29 101

nmr : 30 101

nmr : 31 102

nmr : 32 103

nmr : 33 104

nmr : 34 105

nmr : 35 105

nmr : 36 106

nmr : 37 108

nmr : 38 110

nmr : 39 110

nmr : 40 111

nmr : 41 112

nmr : 42 114

nmr : 43 114

nmr : 44 115

nmr : 45 119

nmr : 46 121

nmr : 47 126

nmr : 48 126

nmr : 49 126

nmr : 50 127

nmr : 51 131

nmr : 52 132

nmr : 53 134

nmr : 54 140

nmr : 55 181

nmr : 56 204

temps médian : 101
B

PS : ce qui s’affiche dans le moniteur série correspond exactement à ce que je tape à la pioche. Tout est dans la manière dont l’opérateur s’adapte à la vitesse attendue par temps. Ici on passe de 150 à 114 et on aboutit à 101.
En fait et c'est vrai que je ne le précise pas assez, ce sont les relâchements inter-symboles collectés qui permettent de fixer une augmentation de vitesse ou au contraire une diminution mais si l'opérateur va au-delà de la marge que temps lui impose ça ne fonctionne pas. C'est ce que @terwal et @J-M-L ont conclu à juste titre. Pour moi j'ai fait le tour du problème. Reste a améliorer cet algorithme ...

Comme tu affiche uniquement ce que tu collectes, laps de temps inférieurs à 3*temps.
il ne me semble que l'on ne peut pas voir les relâchements correspondant à la fin d'une lettre ou d'un mot ?
Ce serait-il possible de refaire le même tests avec en plus l'affichage des fins de lettre et de mot ?

Pas pour l’instant en tout cas car je viens de me faire recadrer par ma femme qui ne supporte plus d’entendre le morse :joy: c’est pas une blague, en plus je lui ai cassé la vitre d’un tableau ancien qui a beaucoup de valeur …
Je souhaite tourner la page concernant mon programme d’autant plus que celui de @J-M-L est bien conçu :wink: Autant passer à un autre algorithme plus performant.
Ce que j’ai publié correspond exactement à ce que j’ai fait. Fin de lettre correspond à 3*t et est gérée par la librairie. Fin de mot c’est 9t géré par la librairie également et si tu regardes bien tu peux partir une heure ou plus pour finir tes manipulations ce qui signifie que fin de mot n’a aucun intérêt.
Tu avais raison dans le sens où les variations ne peuvent être effectives que si tu restes dans la marge d’évolution que fixe la variable temps. Si je sors de cette marge alors il y a des incohérences. Le manipulateur doit tenir compte de cette contrainte :wink:
Demain j’attaque dés que possible avec le programme de @J-M-L.Tu peux participer à l’élaboration d’un algorithme si tu veux.
Bonne soirée à toi
Merci pour ta coopération

Oui il faut rester dans le tempo et pas trop s’éloigner du rythme du point.

Philippe qui est un pro fait sans doute cela sans problème, moi j’en suis incapable

Mettez un casque, faut être gentil avec Madame

Sur mon programme une modification initiale à effectuer serait d’enregistrer toutes les séquences (le r(xxx) et a(xxx) dans un tableau dans l’ordre ou les points traits et espaces sont reçus plutôt que dans 3 tableaux comme je le fais car on perd la sequentialité

C’est ce tableau qu’il faudrait ensuite analyser

D’accord @J-M-L, je vais voir ça :wink:

J’ai été un pro mais la dernière fois que je l’ai été c’était en 1983. Je viens tout juste de me remettre à la manipulation. Mon niveau a beaucoup baissé. C’est vraiment dommage qu’il n’y ait pas d’autres manipulateurs morse sur le forum…

Rassure toi, je prépare la relève :wink:
Je ne cause ni ne manipule pas du tout le morse mais chaque année avec mes élèves de 6e ils réalisent un télégraphe morse (lumineux pas sonore, sinon je te laisse imaginer le boucan)
Plein d’avantages pédagogiques :

  • un circuit électrique assez simple sans être trivial
  • les bases du traitement du signal et de l’information

Il y en a peut-être un qui deviendra radioamateur :sweat_smile:

1 Like

un post qui parle du morse

L’idée de la visualisation sous forme de graphe de décision est marrante - je n’ai pas le temps aujourd’hui mais ce ne serait pas difficile de rajouter ça à mon wokwi

1 Like

merci beacoup !! :slight_smile:

Oui mais du coup on ne réinvente pas la roue ?
Pourquoi ne pas commencer par créer notre propre algorithme ?
Ensuite on pourrait voir pour le décodeur morse avec table de leds et utiliser la bibliothèque proposée.

Enfin moi je vois ça comme un moyen d'apprendre et de mieux comprendre.
Personnellement je préfère ne pas me disperser, chaque chose en son temps. Encore une fois je n'ai pas tout vôtre savoir faire.
Vous en pensez quoi ?

@yo2ldk pas de soucis mais je préfère voir ça plus tard. C'est juste une question de temps...

1 Like

Oui, j'avoue que ma femme n'aurait pas était si patiente je pense :slight_smile:

Le point que je t'indique n'est pas tant pour améliorer ton programme, que le fait de mélanger les seuils minimun, maximun et médiane(ou moyenne), qui produit selon moi un algorithme qui ne correspond pas à la norme, mais cela ne veut pas dire qu'il ne marche pas pour toi :slight_smile:

Je n'ai absolument pas dit ça, mais ce n'est pas grave :slight_smile:
Par contre bien sûre ce que tu dis est vrai.

Non, justement, ce n'est pas exactement ce que je dis.
Ce que je note c'est que si tu prends un seuil de détermination fixe pour des minium(point, trait) et maximun(trait, lettre, mot), l'opérateur ne peut pas respecter la norme.

Puisque pour une cadence moyenne x et un seuil y avec x < y.
un point est définit par x < y.
un trait est définit y < 3x < 3y
une lettre pas en fin de mot 3x > 3*y, ce qui n'est pas logique(on ne peut pas avoir x < y et x > y), si l'opérateur arrive à faire une lettre, c'est qu'il ne respecte pas sa cadence.

De plus si on fait tendre y vers x, en admettant que l'opérateur arrive à maintenir la cadence moyenne.
Donc je simplifie en disant que y=x, ce qui précède devient
un point est définit par x < x
un trait x < x < 3x
une lettre 3x > 3x

on peut traduire que si on utilise la cadence moyenne(ou la médiane), comme la valeur du seuil y.
L'algorithme ne va prendre:
pour le point, que les valeurs inférieur à la moyenne de la cadence de l'opérateur.
pour le trait il ne prendra aussi que les valeurs inférieurs en 3 fois la moyenne de la cadence.
pour les lettres, il prendra que les valeurs supérieur à la moyenne de la cadence.

Ce qui est dû, au fait que l'on utilise la même valeur pour les seuils de minimal et maximal.

Comme je l'ai indiqué en générale par rapport à la valeur moyenne(ou médiane), on définit une marge en pourcentage ou marge brute et pour le seuil minimal on retire cette marge à la valeur de base, pour le seuil maximal on ajoute la même marge à la valeur de base.

Donc on pars sur une cadence moyenne de 100 et une marge de 50% on aura:
50 pour le seuil minimal.
150 pour le seuil maximal.

ce qui donne:
pour le point x < 150
pour le trait 350 < 3x < 3150
pour la lettre 3x > 3*50

et si du coup la médiane change la valeur de base à 126(50% =63, 189)
pour le point x(126) < 189
pour le trait 363 < 3x(3126) < 3189
pour la lettre 3x(3
126) > 3*63

@J-M-L j'espère avoir été plus clair :see_no_evil:

voilà j'ai augmenté la taille du tableau à 50 maintenant il ne reste plus qu'à différencier les appuis des relâches :

.-➜ A
➜ ESPACE
-...➜ B
➜ ESPACE
-.-.➜ C
➜ ESPACE
-..➜ D
➜ ESPACE
.➜ E
➜ ESPACE
..-.➜ F
➜ ESPACE
--.➜ G
➜ ESPACE
....➜ H
➜ ESPACE
..➜ I
➜ ESPACE
.--74
167
237
277
129
43
109
75
52
77
253
131
62
154
279
126
57
265
131
45
108
61
111
47
138
68
101
298
129
34
249
118
220
146
39
77
134
47
110
62
113
64
62
118
78
47
171
228
130
264
-➜ J
➜ ESPACE

1 Like

Je suppose que tu ne veux pas forcément les classer ?
Si c'est le cas, tu peux jouer sur le signe

attends d'abord je finis de faire ce que @J-M-L demande ...

@J-M-L
avec ce code :

const byte brochePioche = 2;
const byte brocheBuzzer = 3;

struct Morse {
  uint16_t caractere : 7;  // Code ASCII (7 bits)
  uint16_t longueur : 3;     // Longueur du code Morse (3 bits)
  uint16_t code : 6;       // Code Morse (6 bits) - le point est représenté par un 1 - le trait par un 0
};

const Morse codeMorse[] PROGMEM = { // soit 38 éléments - pour chaque caractère j'ai mis la représentation graphique
  { 'A', 2, 0b10 },    // .-    (2)       // ainsi que la valeur décimale de la valeur binaire
  { 'B', 4, 0b0111 },  // -...  (7)
  { 'C', 4, 0b0101 },  // -.-.  (5)
  { 'D', 3, 0b011 },   // -..   (3)
  { 'E', 1, 0b1 },     // .     (1)
  { 'F', 4, 0b1101 },  // ..-.  (13)
  { 'G', 3, 0b001 },   // --.   (1)
  { 'H', 4, 0b1111 },  // ....  (15)
  { 'I', 2, 0b11 },    // ..    (3)
  { 'J', 4, 0b1000 },  // .---  (8)
  { 'K', 3, 0b010 },   // -.-   (2)
  { 'L', 4, 0b1011 },  // .-..  (11)
  { 'M', 2, 0b00 },    // --    (0)
  { 'N', 2, 0b01 },    // -.    (1)
  { 'O', 3, 0b000 },   // ---   (0)
  { 'P', 4, 0b1001 },  // .--.  (9)
  { 'Q', 4, 0b0010 },  // --.-  (2)
  { 'R', 3, 0b101 },   // .-.   (5)
  { 'S', 3, 0b111 },   // ...   (7)
  { 'T', 1, 0b0 },     // -     (0)
  { 'U', 3, 0b110 },   // ..-   (6)
  { 'V', 4, 0b1110 },  // ...-  (14)
  { 'W', 3, 0b100 },   // .--   (4)
  { 'X', 4, 0b0110 },  // -..-  (6)
  { 'Y', 4, 0b0100 },  // -.--  (4)
  { 'Z', 4, 0b0011 },  // --..  (3)
  { '0', 5, 0b00000 }, // ----- (0)
  { '1', 5, 0b10000 }, // .---- (16)
  { '2', 5, 0b11000 }, // ..--- (24)
  { '3', 5, 0b11100 }, // ...-- (28)
  { '4', 5, 0b11110 }, // ....- (30)
  { '5', 5, 0b11111 }, // ..... (31)
  { '6', 5, 0b01111 }, // -.... (15)
  { '7', 5, 0b00111 }, // --... (71)
  { '8', 5, 0b00011 }, // ---.. (3)
  { '9', 5, 0b00001 }, // ----. (1)
  { ',', 6, 0b110111}, // ..-... (55)
  { '.', 6, 0b010101}, // -.-.-. (21)
};

const byte nbCodes = sizeof codeMorse / sizeof * codeMorse;

const unsigned long dureeDeBase = 150;            // Durée habituelle d'un point en millisecondes
unsigned long dureePoint = dureeDeBase;           // Durée d'un point en millisecondes
unsigned long dureeTrait = dureePoint * 3;        // Durée d'un trait
unsigned long dureeIntraLettre = dureePoint;      // Durée entre les symboles d'une même lettre
unsigned long dureeInterLettre = dureePoint * 3;  // Durée entre les lettres
unsigned long dureeInterMot = dureePoint * 7;     // Durée entre les mots

enum EtatBouton : uint8_t {DEBUT, PIOCHE_DOWN, PIOCHE_UP, ERREUR_DOWN, LONG_UP};
enum TypeDuree  : uint8_t {POINT, TRAIT, INTERVALLE, TOTAL};

const byte nbEchantillonsMax = 50;  // Taille maximale des échantillons
const byte nbTypeEchantillonsMax = 50; 
//unsigned long echantillons[TOTAL][nbEchantillonsMax];  // Tableau des durées
char aOouR[nbEchantillonsMax];
unsigned long echantillons[nbEchantillonsMax];
byte indexEchantillons = 0;

EtatBouton etatCourant = DEBUT;

void ajusterTiming(const unsigned long d) {
  dureePoint = d;
  dureeTrait = dureePoint * 3;
  dureeIntraLettre = dureePoint;
  dureeInterLettre = dureePoint * 3;
  dureeInterMot = dureePoint * 7;
}

// Fonction pour ajuster dynamiquement la durée des symboles Morse
// on capture les temps considérés comme points, traits et Intervalles
void ajusterDureeAdaptative(unsigned long deltaT, TypeDuree td) {
  if (td == POINT || td == TRAIT) aOouR[indexEchantillons] = 'a';
  else if (td == INTERVALLE) aOouR[indexEchantillons] = 'r';
  echantillons[indexEchantillons] = deltaT;
  indexEchantillons++;

  // Vérifier si le tableau est plein
  if (indexEchantillons >= nbEchantillonsMax) {
    // si le tableau est plein, on affine les timing
    Serial.print('\n');
    for (indexEchantillons = 0 ; indexEchantillons < nbEchantillonsMax  ; indexEchantillons++) {
       Serial.print(aOouR[indexEchantillons]) ; Serial.print("("); 
       Serial.print(echantillons[indexEchantillons]) ;  Serial.println(")"); 
    }
    indexEchantillons = 0;  // Réinitialiser l'index

    // Ajuster les durées en fonction d'un algo spécifique

    // *********************************
    // ************ A FAIRE ************
    // *********************************


  }
}

inline uint32_t seuilPoint() {
  return dureePoint * 1.2;
}

inline uint32_t seuilTrait() {
  return dureeTrait * 1.2;
}

bool trouverCaractere(Morse& recherche) {
  Morse unCode;
  for (uint8_t i = 0; i < nbCodes; i++) {
    memcpy_P(&unCode, &codeMorse[i], sizeof unCode);
    if (unCode.longueur == recherche.longueur && unCode.code == recherche.code) {
      recherche.caractere = unCode.caractere;
      return true;
    }
  }
  return false;
}

void ecouter() {
  static unsigned long debut = 0;
  static Morse morseRecu = { '\0', 0, 0 };

  int etatPioche = digitalRead(brochePioche);
  unsigned long maintenant = millis();

  switch (etatCourant) {
    case DEBUT:
      if (etatPioche == LOW) { // début appui
        debut = maintenant; // prise en compte du temps d'appui
        tone(brocheBuzzer, 1000); //son buzzer
        etatCourant = PIOCHE_DOWN; // on change d'état
      }
      break;

    case PIOCHE_DOWN:
      if (etatPioche == HIGH) { // on vient de relâcher
        noTone(brocheBuzzer); // plus de son
        unsigned long deltaT = maintenant - debut; // deltaT = durée entre un appui et un relaché
        debut = maintenant; //debut prend la valeur de millis()
        morseRecu.longueur++; // longueur + 1
        etatCourant = PIOCHE_UP; // si on vient de relacher (etatPioche == HIGH) et on passe à PIOCHE_UP dans la prochaine loop()
        // on rajoute le symbole au code courant ou erreur
        if (deltaT <= seuilPoint()) {
          Serial.write('.');
          morseRecu.code = (morseRecu.code << 1) | 0b1;  // Ajouter un point
          ajusterDureeAdaptative(deltaT, POINT);  // Ajustement de la durée pour un point
        } else if (deltaT <= seuilTrait()) {
          Serial.write('-');
          morseRecu.code = (morseRecu.code << 1);  // Ajouter un trait
          ajusterDureeAdaptative(deltaT, TRAIT);  // Ajustement de la durée pour un trait
        } else {
          Serial.println('?');            // Erreur si le temps est trop long
          morseRecu = { '\0', 0, 0 };   // Réinitialiser après le caractère trouvé
          ajusterTiming(dureeDeBase);   // Réinitialisation en cas d'erreur
          etatCourant = ERREUR_DOWN;
        }
      }
      else if (maintenant - debut >= dureeInterLettre) {
        Serial.println('?');            // Erreur si le temps est trop long
        morseRecu = { '\0', 0, 0 };   // Réinitialiser après le caractère trouvé
        ajusterTiming(dureeDeBase);   // Réinitialisation en cas d'erreur
        etatCourant = ERREUR_DOWN;
      }
      break;

    case PIOCHE_UP:
      if (etatPioche == LOW) { // début appui
        tone(brocheBuzzer, 1000);
        unsigned long deltaT = maintenant - debut;
        debut = maintenant;
        ajusterDureeAdaptative(deltaT, INTERVALLE);  // Ajustement de la durée pour un intervalle
        etatCourant = PIOCHE_DOWN;
      } else {
        unsigned long deltaT = maintenant - debut;
        if (deltaT >= dureeInterLettre) {
          if (trouverCaractere(morseRecu)) {
            Serial.print("➜ ");
            Serial.println((char)morseRecu.caractere);  // Affichage du caractère décodé
          } else {
            Serial.print("➜ inconnu : ");
            byte nbBits = morseRecu.longueur;
            for (int8_t i = nbBits - 1; i >= 0; i--) {
              Serial.write(bitRead(morseRecu.code, i) ? '1' : '0');  // Afficher chaque bit
            }
            Serial.println();
          }
          morseRecu = { '\0', 0, 0 };  // Réinitialiser après le caractère trouvé
          etatCourant = LONG_UP;
        }
      }
      break;

    case ERREUR_DOWN:
      if (etatPioche == HIGH) { // on vient de relâcher
        noTone(brocheBuzzer);
        etatCourant = DEBUT;
      }
      break;

    case LONG_UP:
      if (etatPioche == LOW) { // début appui
        tone(brocheBuzzer, 1000);
        unsigned long deltaT = maintenant - debut;
        debut = maintenant;
        ajusterDureeAdaptative(deltaT, INTERVALLE);  // Ajustement de la durée pour un intervalle
        etatCourant = PIOCHE_DOWN;
      } else {
        unsigned long deltaT = maintenant - debut;
        if (deltaT >= dureeInterMot) {
          Serial.println("➜ ESPACE");
          etatCourant = DEBUT;
        }
      }
      break;
  }
}


void setup() {
  pinMode(brochePioche, INPUT_PULLUP);
  pinMode(brocheBuzzer, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  ecouter();
}

on obtient ça :

.-➜ A
➜ ESPACE
-...➜ B
➜ ESPACE
-.-.➜ C
➜ ESPACE
-..➜ D
➜ ESPACE
.➜ E
➜ ESPACE
..-.➜ F
➜ ESPACE
--.➜ G
➜ ESPACE
....➜ H
➜ ESPACE
..➜ I
➜ ESPACE
.--
a(72)
r(157)
a(237)
a(258)
r(141)
a(48)
r(121)
a(49)
r(102)
a(48)
a(218)
r(148)
a(54)
r(154)
a(230)
r(189)
a(45)
a(231)
r(131)
a(43)
r(115)
a(57)
a(108)
a(74)
r(119)
a(70)
r(76)
a(300)
r(267)
a(20)
a(258)
r(98)
a(225)
r(138)
a(63)
a(102)
r(133)
a(50)
r(137)
a(78)
r(131)
a(46)
a(71)
r(128)
a(77)
a(36)
r(156)
a(206)
r(133)
a(247)
-➜ J
➜ ESPACE

Maintenant pour le traitement on pourrait utiliser une structure ?

Oui @terwal pour l'instant on enregistre tous les appuis et relâchement dans un seul tableau pour plus d'efficacité. Par la suite on verra pour l'algorithme ...

PS : Bon je suis obligé de m'absenter.