Blocage dans la création de classes

Bonjour à tous,
je débute en Arduino et je commence à maîtriser certaines fonctionnalités.
Je suis maintenant capable de créer un mini programme contenant des fonctions qui me donne des résultats satisfaisants.
Maintenant, je suis bloqué dans l'évolution de mon programme.
Projet: faire un décodeur permettant de lire des données binaires issues de 5 capteurs optiques à fourche et les transformer en une valeur décimale.

  • j'arrive parfaitement à réaliser cette tâche dans le main.cpp
  • je souhaiterais, comme je l'ai lu par ailleurs, transférer cette fonction dans 2 fichiers auxiliaires (decodeur.h et decodeur.cpp) mais je butte car je n'arrive pas à créer les classes, fonctions, ... qui me permettent ce déplacement de fonction.
  • j'ai consulté plusieurs sites qui décrivent cela mais je n'aboutis pas à quelque chose de concluant en terme de fonctionnement.
  • pour info, j'ai compris le tuto "morse" et ai réussi à le reproduire.

Pouvez-vous m'expliquer comment transférer et modifier ce code en créant des classes qui reprendront cette fonction.

Merci par avance

Nota: je développe avec VS Code.


ci-joint mon code:

// Récupération des fichiers d'en-tête
#include <Arduino.h>
#include <SoftwareSerial.h>

// ----------- fonction choix série début ------------- 
void Choix_serie()
{
    int cf1 = 4; // déclaration des 5 capteurs optiques
    int cf2 = 5;
    int cf3 = 6;
    int cf4 = 7;
    int cf5 = 8;

    int m_cf1; // variables lecture des valeurs des 5 capteurs optiques
    int m_cf2;
    int m_cf3;
    int m_cf4;
    int m_cf5;

    int serieNum; // Variable décimale calculée à partir des 5 capteurs optiques

    pinMode(cf1, INPUT); // déclaration des 5 capteurs optiques en entrée
    pinMode(cf2, INPUT);
    pinMode(cf3, INPUT);
    pinMode(cf4, INPUT);
    pinMode(cf5, INPUT);

    m_cf1 = digitalRead(cf1); // lecture des 5 capteurs optiques
    m_cf2 = digitalRead(cf2);
    m_cf3 = digitalRead(cf3);
    m_cf4 = digitalRead(cf4);
    m_cf5 = digitalRead(cf5);

    serieNum = m_cf1 + 2* m_cf2 +4* m_cf3 + 8* m_cf4 +16* m_cf5; // calcul de la valeur décimale
    
    Serial.print("serieNum dans Choix_serie..cpp  "); // affichage de la valeur de serieNum
    Serial.println(serieNum);
 
}

//----------- fonction choix série fin -------------

void setup()
{
Serial.begin(9600); // initialisation du moniteur série
Serial.println(F("Moniteur série initialisé"));

Choix_serie(); // lancement de la fonction dans le setup
Serial.println("SerieNumero: "); // c'est là que je veux récupérer la valeur de la série mais rien ne s'affiche.

}

Ce n'est pas une classe qu'il te faut mais une simple fonction :

int Choix_serie()
{
... rien de changé ...

    serieNum = m_cf1 + 2* m_cf2 +4* m_cf3 + 8* m_cf4 +16* m_cf5; // calcul de la valeur décimale
    return serieNum;
}

Et pour l'appel dans le setup :

Serial.print("Série Numero: ");
Serial.println(Choix_serie());

Bonsoir et Bienvenue @daniel57330

Le Bar n'est pas l'endroit approprié pour poser ce genre de quesion, je déplace le fil dans la partie principale du Forum Francophone

Bien prendre connaissance des Bonnes Pratiques du Forum Francophone qui indiquent où et comment poser les questions :

https://forum.arduino.cc/t/les-bonnes-pratiques-du-forum-francophone/861014

Cette syntaxe me donne une erreur de compilation:
src\main.cpp: In function 'void setup()':
src\main.cpp:73:27: error: invalid use of void expression
Serial.print(Choix_serie());

@daniel57330
n'aurais-tu pas laissé void Choix_serie() au lieu de int Choix_ser0ie () proposé par @lesept ?

Effectivement, je n'avais pas vu la modification du void en int.
Je vais poursuivre et essayer de bien comprendre le processus.
Ce que je ne comprends pas bien c'est que si je remplace void pat int, alors ce n'est plus une fonction mais une variable avec son processus de calcul !

si je remplace void pat int, alors ce n'est plus une fonction mais une variable avec son processus de calcul !

Non. Ce que tu nommes 'processus de calcul' est une fonction ,

Un résultat de son action est retourné dans une variable de type int au code qui a appelé la fonction
(void indique l'absence de valeur à retourner )

lire ceci : https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1042_les-bases-du-langage-c/4296_les-fonctions/#1-12890_quest-ce-quune-fonction, en particulier le paragraphe type de retour

Dans tout ce que j'ai lu, je ne suis pas tombé sur cette page fort intéressante mais, mise à part une subtilité, je trouve ambigüe cette formulation de l'exemple:

int main(void)
{
    bonjour();
    return 0;
}

J'avais bien compris, dans ta réponse, la différence entre une fonction qui retourne ou pas une valeur mais là, formuler " int main (void) " me perturbe !
Y a-t-il une subtilité qui m'échappe ?

ici la fonction main ne recoit pas de paramètres et retourne la valeur entière 0

main(void) est plus explicite que main() puisqu qu'il est écrit 'vide' dans la parenthèse = 'les points sur les i"

Type‐retourné NOM‐FONCTION (type1 paramètre1, type2 paramètre2, ...) ;

Une fonction peut :

-recevoir un ou plusieurs paramètres, (ou aucun comme ici avec le void dans la parenthèse)
-retourner une information dont le type est indiqué avant le nom de la fonction (int ici)

que ce soit pour les paramétres reçus ou pour le retour void signifie 'rien' ou 'vide'

-> Etudier la partie 'Fonction' d'un cours sur le langage C

Le C/C++ n'est pas utilisé qu'avec des microcontrôleurs, c'est même une utilisation largement minoritaire. Le C a été développé pour écrire le système d'exploitation Unix.

Cas classique : sur un ordinateur un programme lance un autre programme pour réaliser une tâche.
Quand ce programme appelé se termine et rend la main au programme appelant, il est normal qu'il informe le programme appelant, par un code de retour, si tout c'est bien passé.
C'est le rôle du "return" dans la fonction main.

Avec les microcontrôleurs le "return()" dans la fonction main() est généralement ignoré.

J'ai bien conscience que le C++ n'est pas exploité au maximum avec Arduino, mais c'est quand même une base de sa programmation, c'est pour cela que je me documente et que je suis les conseils qui me disent de m'approprier ce langage.
Débutant, je suis preneur de tous les conseils qui me permettront d'évoluer.

Je progresse bien dans mon projet et maintenant je suis bloqué a priori dans une boucle while et je ne vois pas comment m'en sortir.
Ce que je veux:
1/ attendre l'appui sur bp_cs pour continuer (ça fonctionne bien - séquence d'attente de l'appui --> clignotement rapide, ensuite, attente de la présentation d'une carte à décoder --> clignotement lent)
2/ Tant que la variable "serie" vaut "0", signe qu'aucune carte à décoder n'est présente, je veux boucler et dès que "serie" est différent de "0", donc présence d'une carte à décoder, je lance la fonction de décodage et là, la valeur de "serie" ne change plus, comme si celle-ci était figée.
J'ai essayé avec serie ==0 , serie <= 0, serie !=0 et je n'arrive jamais au résultat attendu.

Les tests des fonctions dans le setup sont concluants.

Code du loop:

void loop() 
{ 
// Début activité
// Attente du choix de la série à utiliser

while (digitalRead(bp_cs) == LOW)
  {
  clign_rapide(ledVerte);
  Serial.println(" Attente appuis sur bp_cs ");
  }
Serial.print(" bp_cs a été appuyé ");
clign_lent(ledVerte);

while (serie == 0)
  {
  Serial.print("");
  Serial.print(serie);
  Serial.print("debut decodage         ");
  decodage_capteurs_Fourche ();
  Serial.print("fin decodage ");
  valTemporaire = serie; // serie = valeur issue du décodage
Serial.println(valTemporaire);

  }
Serial.print(serie);

digitalWrite(ledRouge,HIGH);
delay(5000);
digitalWrite(ledRouge,LOW);

}

Le principe d'une boucle while avec ce genre de condition, c'est que la valeur testée soit mise à jour dans la boucle, sinon tu n'en sors jamais. Donc, il faut mettre à jour la variable série dans le bloc entre accolades du while.

J'ai bien compris ce fonctionnement de la boucle while, ce morceau de code effectue la mise à jour de la variable serie.
Quand je téléverse le code sur mon montage, la 1 ère boucle du loop se passe correctement, attente pour sortie du while que serie ait changé de valeur, par contre lors des boucles loop suivantes, la séquence d'attente d'appui sur bp_cs est correcte et après appui sur le bouton, la valeurs de série rest à 4 alors qu'elle devrait être à 0 car aucun capteur optique sollicité, ce qui fait que la boucle while ne s'éxécute plus car la valeur de serie est toujours vue à 4.

Copie du moniteur série: (j'ai supprimé des lignes redondantes pour plus de lisibilité)

23:13:53.917 ->  Attente appuis sur bp_cs 
23:13:54.339 ->  Attente appuis sur bp_cs 
23:13:54.713 ->  Attente appuis sur bp_cs 
23:13:54.761 ->  bp_cs a été appuyé 0debut decodage         fin decodage 0
23:13:56.779 -> 0debut decodage         fin decodage 0
23:13:59.726 -> 0debut decodage         fin decodage 0
23:13:59.773 -> 0debut decodage         fin decodage 0
23:13:59.819 -> 0debut decodage         fin decodage  ***4 <--Passage de serie de 0 à 4***
23:13:59.819 -> 4 Attente appuis sur bp_cs 
23:14:03.571 ->  Attente appuis sur bp_cs 
23:14:03.991 ->  Attente appuis sur bp_cs 
23:14:04.369 ->  Attente appuis sur bp_cs 
23:14:04.794 ->  Attente appuis sur bp_cs 
23:14:13.162 ->  Attente appuis sur bp_cs 
23:14:13.587 ->  Attente appuis sur bp_cs 
23:14:13.587 ->  bp_cs a été appuyé 4 Attente appuis sur bp_cs    *****<--** *Ici on voit que la boucle while ne s'éxécute pas****
23:14:19.365 ->  Attente appuis sur bp_cs `Texte préformaté`
23:14:19.788 ->  Attente appuis sur bp_cs

Dans ce cas, ton problème vient de la fonction decodage_capteurs_Fourche().
C'est plus simple de donner le code en entier que par morceaux...


// Récupération des fichiers d'en-tête
#include <Arduino.h>
#include <SoftwareSerial.h>
//#include "melange_tab.h" // fonction de melange des tableaux
//#include "lecture_mp3.h"
//#include "Decodage_capteur_fourche.h"

//SoftwareSerial mySerial(9,10); // Déclaration connexion série pour DFplayer

/* *********************************************************
************ Initialisation des tableaux  ******************
***********************************************************/

int tab [8]= {0, 1, 2, 3, 4, 5, 6, 7}; // tableau intermédiaire pour algorithme de mélange

const char* tabSerie1 [8] = {"chien","chat","lapin","renard","cheval","poney", "poule", "cochon"};
int sons_Serie1 [8] = {101, 102, 103, 104, 105, 106, 107, 108};
const char* tabSerie2 [8] = {"guitare","violon","flute","accordeon","trompette","piano","harpe", "xylophone"};
int sons_Serie2 [8] = {109, 110, 111, 112, 113, 114, 115, 116};

const char* tableauJeu [8];
int sonsJeu [8];
//char temp[8];
//int val;

/**********************************************************
* Initialisation variables d'entrée
* *********************************************************/
int bp_cs = 2; // bp choix de la série
int bp_jeu = 3; // bp lancement jeu
int cf1 = 4; // de cf1 à cf5 => 5 capteurs optiques
int cf2 = 5;
int cf3 = 6;
int cf4 = 7;
int cf5 = 8;
// Lecture des capteurs optiques 
int valcf1; 
int valcf2;
int valcf3;
int valcf4;
int valcf5;
// Variable calculée de la série
int serie;

// Initialisation variables de sortie
int ledVerte = 11;
int ledRouge = 12;
int clent = 500; // delai clignotement lent
int crap = 200; // delai clignotement rapide

int valTemporaire;
/*****************************
 * Déclaration des fonctions *
 * ***************************/

// Clignotement mixte / lent / rapide / attente carte
void clign_Mixte(int led)
{
  digitalWrite(led,HIGH);
  delay(300);
  digitalWrite(led,LOW);
  delay(300);
  digitalWrite(led,HIGH);
  delay(150);
  digitalWrite(led,LOW);
  delay(150);
}
void clign_lent(int led)
{
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led,LOW);
  delay(500);
  digitalWrite(led,HIGH);
  delay(500);
  digitalWrite(led,LOW);
  delay(500);
}

void clign_rapide(int led)
{
  digitalWrite(led,HIGH);
  delay(100);
  digitalWrite(led,LOW);
  delay(100);
  digitalWrite(led,HIGH);
  delay(100);
  digitalWrite(led,LOW);
  delay(100);
}


/*********************************************************
*************   decodage_capteurs_Fourche     ************
**********************************************************/
int decodage_capteurs_Fourche ()
{
    valcf1 = digitalRead(cf1);
    valcf2 = digitalRead(cf2);
    valcf2 = 2* valcf2;
    valcf3 = digitalRead(cf3);
    valcf3 = 4* valcf3;
    valcf4 = digitalRead(cf4);
    valcf4 = 8* valcf4;
    valcf5 = digitalRead(cf5);
    valcf5 = 16* valcf5;
    // Calcul du numéro de la série
    serie = valcf1 + valcf2+ valcf3 + valcf4 +valcf5;
    return serie ;
};

//****************** Début setup **************************************************************
void setup()
{
// Déclaration des entrées / sorties
pinMode(bp_cs, INPUT);
pinMode(bp_jeu, INPUT);
pinMode(cf1, INPUT);
pinMode(cf2, INPUT);
pinMode(cf3, INPUT);
pinMode(cf4, INPUT);
pinMode(cf5, INPUT);
pinMode(ledVerte, OUTPUT);
pinMode(ledRouge, OUTPUT);

// attention : pour les ports analogiques, ils sont automatiquement configurés comme "entrée".
Serial.begin(9600);
Serial.println();
Serial.println(F("Moniteur série initialisé"));
Serial.println(F("-------------------------"));

decodage_capteurs_Fourche ();
    Serial.print("Dans main.cpp --> Série n° : ");
    Serial.println(decodage_capteurs_Fourche ());
    Serial.println();
    

}

//****************** Début loop **************************
void loop() 
{ 
// Début activité
// Attente du choix de la série à utiliser

while (digitalRead(bp_cs) == LOW)
  {
  clign_rapide(ledVerte);
  Serial.println(" Attente appuis sur bp_cs ");
  }
Serial.print(" bp_cs a été appuyé ");
clign_lent(ledVerte);

while (serie == 0)
  {
  Serial.print("");
  Serial.print(serie);
  Serial.print("debut decodage         ");
  decodage_capteurs_Fourche ();
  Serial.print("fin decodage ");
  valTemporaire = serie; // serie = valeur issue du décodage
Serial.println(valTemporaire);

  }
Serial.print(serie);

digitalWrite(ledRouge,HIGH);
delay(5000);
digitalWrite(ledRouge,LOW);

}

Essaye sans le ;
Je ne sais pas si ça fera quelque chose mais il n'a rien à faire ici

Sans le ';' le problème persiste.
j'ai contourné celui-ci en réinitialisant "serie = 0" avant le lancement de la boucle while.
Je vais pouvoir continuer d'avancer dans mon projet.

Je pense que ça vient du fait que tu déclares serie comme une variable globale et que tu fais un return serie à la fin de ta fonction : il doit y avoir un conflit quelque part. Essaye :

void decodage_capteurs_Fourche ()
{
... rien de changé
serie = valcf1 + valcf2+ valcf3 + valcf4 +valcf5;
}

avec void à la place de int.