Je suis nouveau dans le langage C/C++ et je suis sur un programme pour démultiplier le nombre de sorties sur l’Arduino.
Pour ce faire j'ai créer une classe pour manipuler une liste doublement chaînée et une classe pour faire le parallèle entre les sorties de l'arduino et les Elements créés en liste.avec l'utilisation d'un 74HC164 (registre à decalage à entrée séries 8 bits) et un 74HC374(bascule octale de type D).
ce premier n'utilisant que 3 sorties et acceptant derrière lui autant de 74HC374 que voulu qui n'utilise quant à eux q'une sortie ici.
ces Element comportent chaqun un tableau de taille 8 et initialiser à "false" .Or ce tableau me renvois des valeurs supérieurs à 1.
De plus je l'ai tésté ce ce même code sur codeblocks et tout semble bon (niveau valeur,pas niveau construction du programme) et le tableau est initialiser en "false"
Liste *Nouvelle_Liste = NULL; Nouvelle_Liste =(Liste*) malloc(sizeof(*Nouvelle_Liste)); nb_pointeurs_liste++; Nouvelle_Liste->precedent=NULL; Nouvelle_Liste->suivant=NULL; Nouvelle_Liste->index = 0;//ici on met a 0 l'index pour permettre de savoir combien d'elements sont presents dans la liste compteur_de_liste++;
///*** ici on affecte le premier et le dernier pointeur d'element sur NULL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! return Nouvelle_Liste;
///**** Ici on doit dabord verifier qu'il n'y ait plus aucun element avant de supprimer la liste!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! free(Liste_EC); nb_pointeurs_liste--; compteur_de_liste--;
} /*void Listes_chainees::insertion(string index1, Liste *Liste_EC) {
} void Listes_chainees::insertion(char index1, Liste *Liste_EC) {
}*/
void Listes_chainees::insertion( int index1, Liste *Liste_EC) {
Element *tempon_element_precedent; Element *tempon_element_suivant; //Element *conserve_pointeur_element; //vérifier pourquoi il est inutile!!!!!!!!!!!!!!!! Element *tempon1 = NULL; Element *nouveau = NULL; nouveau = ( Element*)malloc(sizeof(*nouveau)); nb_pointeurs_element++;
// conserve_pointeur_element = nouveau; ///** Pour le premier on verife si le premier et le dernier element sont null!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
///*** Ici on gere le premier element! if ((Liste_EC->precedent == 0) && (Liste_EC->suivant == 0)) { nouveau->suivant = nouveau; nouveau->precedent = nouveau;
Liste_EC->precedent = nouveau; Liste_EC->suivant = nouveau; nouveau->index = index1; Liste_EC->index = Liste_EC->index + 1;//on actualise le nombre d'elements dans la liste
//cout <<"************************Creation du premier element************************ \n"; //cout <<"Nouveau->index="<<nouveau->index<<endl; //cout <<"Nouveau->precedent="<<nouveau->precedent<<endl; //cout <<" Nouveau="<<nouveau<<endl; //cout <<"Nouveau->suivant="<<nouveau->suivant<<endl; //cout <<"************************Fin creation du premier element***************************** \n";
return ; } //ici on peut affecter avec une fonction tempon1=Liste_EC->precedent;// on recupere le premier element de la liste
do
{ if (index1>(tempon1->index)) //on recherche ou on peut l'intercaler { tempon1 = tempon1->suivant; //cout<<"\n on passe au suivant "<< endl;
} //si il est deja existant alors on change sa valeur pour le mettre en dernier if ((index1==(tempon1->index)) ) { nouveau->index=index1;//on incremente d'un l'index du dernier element de la liste puisque l'index etait erroné tempon_element_precedent=tempon1;//on recupere l'element precedent du dernier element tempon_element_suivant=tempon1->suivant;//on recupere l'element suivant du dernier element nouveau->suivant = tempon_element_suivant;//on affecte l'element suivant dans le nouveau nouveau->precedent = tempon_element_precedent;//on affecte l'element precedent dans le nouveau tempon_element_suivant->precedent=nouveau;//on modifie l'element precedent dans l element precedent tempon_element_precedent->suivant=nouveau;//on modifie l'element suivant dans l element suivant // on n'oublie pas d'incrementer le nombre d'element de la liste if ((Liste_EC->suivant)==tempon1) { Liste_EC->suivant=nouveau; }
Liste_EC->index = Liste_EC->index + 1;
break; /**il faut modifier le suivant ou le precedent de la liste en colurs!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ } if (index1>(Liste_EC->suivant->index)) { tempon1=Liste_EC->suivant ;//on recupere le dernier element de la liste
nouveau->index=index1;//on incremente d'un l'index du dernier element de la liste puisque l'index etait erroné tempon_element_precedent=tempon1;//on recupere l'element precedent du dernier element tempon_element_suivant=tempon1->suivant;//on recupere l'element suivant du dernier element nouveau->suivant = tempon_element_suivant;//on affecte l'element suivant dans le nouveau nouveau->precedent = tempon_element_precedent;//on affecte l'element precedent dans le nouveau tempon_element_suivant->precedent=nouveau;//on modifie l'element precedent dans l element precedent tempon_element_precedent->suivant=nouveau;//on modifie l'element suivant dans l element suivant Liste_EC->suivant=nouveau;//on modifie le dernier element de la liste // on n'oublie pas d'incrementer le nombre d'element de la liste Liste_EC->index = Liste_EC->index + 1; break; }
if (index1<(tempon1->index)) { //"cas ou on intercale "<< endl; tempon_element_precedent=tempon1->precedent;//on recupere l'element precedent du dernier element tempon_element_suivant=tempon1;//on recupere l'element suivant du dernier element nouveau->index=index1; nouveau->suivant = tempon_element_suivant;//on affecte l'element suivant dans le nouveau nouveau->precedent = tempon_element_precedent;//on affecte l'element precedent dans le nouveau tempon_element_suivant->precedent=nouveau;//on modifie l'element precedent dans l element precedent tempon_element_precedent->suivant=nouveau;//on modifie l'element suivant dans l element suivant // on n'oublie pas d'incrementer lecout<<"<tempon->precedent = "<<tempon->precedent<<endl; nombre d'element de la liste if ((Liste_EC->precedent->index)>index1) { Liste_EC->precedent=nouveau; } Liste_EC->index = Liste_EC->index + 1; //cout <<"************************Creation d'un element avec index a intercaler************************ \n"; //cout <<"Nouveau->index="<<nouveau->index<<endl; //cout <<"Nouveau->precedent="<<nouveau->precedent<<endl; //cout <<" Nouveau="<<nouveau<<endl; //cout <<"Nouveau->suivant="<<nouveau->suivant<<endl; //cout <<"************************Fin creation d'un element avec index a intercaler**************************** \n";
//et TOC ,on a inseré un element au milieu!
break; }
}while(true);//tempon1==Liste_EC->precedent);
}
void Listes_chainees::cherche_element_a_trouver( int place , Liste *Liste_EC) {
Element *element_a_chercher = Liste_EC->precedent;
do {
element_a_chercher = element_a_chercher->suivant;
}while(Liste_EC->precedent->index >= place); }
Element *Listes_chainees::recuperation_d_un_element(int place, Liste *Liste_EC) {
Element *element_recuperer = Liste_EC->precedent;
do {
element_recuperer = element_recuperer->suivant;
}while(element_recuperer->index != place);
return (element_recuperer);
}
void Listes_chainees::insertion_de_plusieurs_elements(int nombre_d_element, int index_du_premier, Liste *Liste_EC) { ///** etudier l'utilisation et la realisation de cette fonction........ int tempon = 0; //struct Element *conserve_pointeur_element = NULL; //struct Element *tempon1 = NULL;
tempon = 0;
do { insertion(index_du_premier, Liste_EC); tempon++; index_du_premier++;
Element *a_afficher = Liste_EC->precedent; do { cout<<"\n l'index est egal a "<<a_afficher->index<<endl; cout<<"adresse du pointeur precedent est : "<< a_afficher->precedent <<endl; cout<<"adresse du pointeur est : "<< a_afficher<<endl ; cout<<"adresse du pointeur suivant est : "<< a_afficher->suivant<<endl ;
a_afficher = a_afficher->suivant;
}while(Liste_EC->precedent != a_afficher);
cout<<"*****************************adresse du pointeur precedent dans la liste est : "<< Liste_EC->precedent <<endl; cout<<"*****************************adresse du pointeur suivant dans la liste est : "<< Liste_EC->suivant <<endl;
cout<<"\n\n****fin affichage***********"<<endl;
}*/
void Listes_chainees::supression_d_un_element(int index1, Liste *Liste_EC) {
Element *tempon1 = Liste_EC->precedent; Element *a_suprimmer = NULL; Element *tempon_element_precedent; Element *tempon_element_suivant; // recherche du pointeur a suprimer penser a relancer la recherche si il y a plusieurs fois le meme index do { if (index1==tempon1->index) { a_suprimmer=tempon1; //cout<<"a_suprimmer="<<a_suprimmer <<endl; tempon_element_precedent=tempon1->precedent; tempon_element_suivant=tempon1->suivant; tempon_element_precedent->suivant=tempon_element_suivant; tempon_element_suivant->precedent=tempon_element_precedent; free(a_suprimmer); nb_pointeurs_element--; Liste_EC->index=(Liste_EC->index)-1; } tempon1=tempon1->suivant; }while(tempon1!=Liste_EC->precedent);
}
void Listes_chainees::supression_de_toute_la_liste ( Liste *Liste_EC) { Element *a_suprimmer = Liste_EC->suivant;//Recuperation du dernier element de la liste while((a_suprimmer) != Liste_EC->precedent) { a_suprimmer = Liste_EC->suivant ; Liste_EC->suivant = a_suprimmer->precedent; free (a_suprimmer); nb_pointeurs_element--; }
} /* void Listes_chainees::affichage_d_un_element(int index1, Liste *Liste_EC) { Element *a_afficher = Liste_EC->suivant; do { a_afficher = a_afficher->precedent;
}while(a_afficher->index != index1); cout<<"\nl'index est egal a "<<a_afficher->index<<endl; cout<<"adresse du pointeur suivant est : "<< a_afficher->suivant<<endl ; cout<<"adresse du pointeur est : "<< a_afficher<<endl ; cout<<"adresse du pointeur precedent est : "<< a_afficher->precedent <<endl; cout<<"\n***********fin de l'affichage d un element***************" <<endl; }*/
//Listes_chainees.hpp
#include"Arduino.h"
#include "Sorties_series.h"
#ifndef LISTES_CHAINEES_H
#define LISTES_CHAINEES_H
typedef struct Element Element;
struct Element
{
int index;
Element *precedent;
Element *suivant;
int validation_des_sorties_ds_element = 9;
bool les_8_sorties[8]#include <iostream>
using namespace std;
#include "Sorties_series.h"
#include "Listes_chainees.h"
/*sorties_series sorties_22_a_29(0, 0, 0, 22);
sorties_series sorties_30_a_37(0, 0, 0, 30);
sorties_series sorties_38_a_45(0, 0, 0, 38);
sorties_series sorties_46_a_54(0, 0, 0, 46);*/
void create_new_sorties(int, bool);
//_num_ref_de_la_sortie est le numero de la premiere sortie que vous rajoutée
//ligne pour initialiser les sorties registre_bit_suivant, clean, etat_bit_a_intergrer, "_num_ref_de_la_sortie", validation_des_sorties)
int _num_ref_de_la_sortie = 14;
Sorties_series sorties_14_a_21;
int main(int argc,const char * argv[])
{
//void Sorties_series::configure_sortie_serie( int registre_bit_suivant,int clean, int etat_bit_a_intergrer, int num_ref_de_la_sortie, int validation_des_sorties1)
sorties_14_a_21.configure_sortie_serie( 11 , 10 , 12 , _num_ref_de_la_sortie, 9 ,7);
cout<<"changement de tableau"<<endl;
cout<<"changement de tableau"<<endl;
create_new_sorties(17 , 1);
//create_new_sorties(18 , 1);
//create_new_sorties(19 , 1);
cout<<"changement de tableau"<<endl;
cout<<"changement de tableau"<<endl;
create_new_sorties(29 , 1);
cout<<"changement"<<endl;
return(0);
}
void create_new_sorties(int num_de_la_sortie, bool val_a_integrer)
{
if (num_de_la_sortie >= _num_ref_de_la_sortie)
{
sorties_14_a_21.val_a_ecrire_sur_sorties( num_de_la_sortie , val_a_integrer);
}
} = {false};
/* les_8_sorties[0] = 0;
les_8_sorties[1] = 0; ///,0,0,0,0,0,0,0
les_8_sorties[2] = 0;
les_8_sorties[3] = 0;
les_8_sorties[4] = 0;
les_8_sorties[5] = 0;
les_8_sorties[6] = 0;
les_8_sorties[7] = 0;*/
};
typedef struct Element Liste ;
class Listes_chainees
{
public:
Listes_chainees();
virtual ~Listes_chainees();
int comptexit=0;
Element test();
void supression_d_un_element( int, Liste*);
void supression_de_toute_la_liste(Liste*);
//void affichage_de_la_liste(Liste*);
void affichage_d_un_element(int, Liste*);
void insertion_de_plusieurs_elements( int, int, Liste* );
void cherche_element_a_trouver( int, Liste*);
Element *recuperation_d_un_element(int , Liste*);
void insertion(int , Liste*);
//void insertion(char , Liste*);
//void insertion(string , Liste*);
//void insertion(double , Liste*);
//void insertion(float , Liste*);
Liste *Creation_Liste();
void Suppression_Liste(Liste *);
int nb_pointeurs_element;
int nb_pointeurs_liste;
/**
IL faut supprimer le pointeur de liste dans le main
**/
protected:
private:
int compteur_de_liste;
/*struct Element conserve_pointeur_element1;
struct Element *P_conserve_pointeur_element1 = &conserve_pointeur_element1; // struct Element *P_conserve_pointeur_element = liste.suivant;
struct Element tempon_element_precedent1;
struct Element *P_tempon_element_precedent1 = &tempon_element_precedent1; //struct Element *tempon_element_precedent = liste.suivant;
struct Element tempon_element_suivant1;
struct Element *P_tempon_element_suivant1 = &tempon_element_precedent1; //struct Element *tempon_element_suivant = liste.suivant;*/
};
#endif // CLASSES_CHAINEES_H
/**si il est deja existant alors on change sa valeur pour le mettre en dernier
if ((index1==(tempon1->index)) )
{
cout<<"cas d'une valeur identique "<< endl;
cout<<"Liste_EC->suivant->index= " <<Liste_EC->suivant->index<<endl;
tempon1=Liste_EC->suivant ;//on recupere le dernier element de la liste
nouveau->index=((tempon1->index)+1);//on incremente d'un l'index du dernier element de la liste puisque l'index etait erroné
tempon_element_precedent=tempon1->precedent;//on recupere l'element precedent du dernier element
tempon_element_suivant=tempon1->suivant;//on recupere l'element suivant du dernier element
nouveau->suivant = tempon_element_suivant;//on affecte l'element suivant dans le nouveau
nouveau->precedent = tempon_element_precedent;//on affecte l'element precedent dans le nouveau
tempon_element_suivant->precedent=nouveau;//on modifie l'element precedent dans l element precedent
tempon_element_precedent->suivant=nouveau;//on modifie l'element suivant dans l element suivant
Liste_EC->suivant=nouveau;//on modifie le dernier element de la liste
// on n'oublie pas d'incrementer le nombre d'element de la liste
Liste_EC->index = Liste_EC->index + 1;
cout <<"************************Creation d'un element avec modification de son index ************************ \n";
cout <<"Nouveau->index="<<nouveau->index<<endl;
cout <<"Nouveau->precedent="<<nouveau->precedent<<endl;
cout <<" Nouveau="<<nouveau<<endl;
cout <<"Nouveau->suivant="<<nouveau->suivant<<endl;
cout <<"************************Fin creation d'un element avec modification de son index**************************** \n";
break;
}**/
//Sorties_series.hpp
#ifndef SORTIES_SERIES
#define SORTIES_SERIES
#include "Arduino.h"
#include "Listes_chainees.hpp"
/******
compiler (Ctrl + R)
de téléverser (Ctrl + U)
de créer un nouveau programme (Ctrl + N)
d'ouvrir un programme (Ctrl + O)
de sauvegarder le programme en cours (Ctrl + S)
ainsi qu'un moniteur série (Ctrl + Maj + M).
******/
//!!!!!!!!!ne pas creer la liste ici mais directement dans la classe sinon message:multiple definition of!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!//
class Sorties_series
{
public:
Listes_chainees Liste_chainee;
Liste *MaPremierListe = Liste_chainee.Creation_Liste();
Sorties_series();
~Sorties_series();
void configure_sortie_serie(int, int, int, int, int); //permet d'initialiser les sorties
void configure_sortie_serie(int, int, int, int, int, int);
void configure_sortie_serie(int, int, int, int, int, int, int);
void configure_sortie_serie(int, int, int, int, int, int, int, int);
//int trouver_le_bon_element(int );
void val_a_ecrire_sur_sorties (int, bool); //a la fin il relance le tableau qu'il doit récupérer et après y avoir changé la valeur au niveau de la sortie souhaité
void pilotage_bascule(int); //gère le relancement du tableau en utilisant les 2 foctions qui suivent incremente_registre() et valide_sorties()
// int select_num_ref_de_la_sortie(int);
void incremente_registre();
void valide_sorties();
private:
int conserve_num_ref = 1;
int tempon1 = 0;
int _clean;
int sortie = 0;
//_Bool led[8] = {0};
int validation_des_sorties;
int _nb_de_sorties_rajoutes;
// int num_ref_de_la_sortie;
int _validation_des_sorties;
int _registre_bit_suivant;
int _etat_bit_a_intergrer;
int _num_ref_de_la_sortie;
};
/***************************
pour un arduino uno sorties integrées en digital jusqu'à la 13eme sortie
num_ref_de_la_sortie:
on a donc par paquet de huit
1er element 14 et 14 + 8 = 22
2eme element 22 et 22 + 8 = 30
3eme element 30 et 30 + 8 = 38
4eme element 38 et 38 + 8 = 46
5eme element 46 et 46 + 8 = 54
**************************/
#endif
//Sorties_series.cpp
#include "Sorties_series.h"
/* Trouver une solution pour que la premiere sortie de chaque "sortie serie" change en fonction du type de carte*/
/******
compiler (Ctrl + R)
de téléverser (Ctrl + U)
de créer un nouveau programme (Ctrl + N)
d'ouvrir un programme (Ctrl + O)
de sauvegarder le programme en cours (Ctrl + S)
ainsi qu'un moniteur série (Ctrl + Maj + M).
******/
Sorties_series::Sorties_series()
{
}
void Sorties_series::configure_sortie_serie( int registre_bit_suivant,int clean, int etat_bit_a_intergrer, int num_ref_de_la_sortie, int validation_des_sorties1)
{
Element *tempon = NULL;
_clean = clean;
_registre_bit_suivant = registre_bit_suivant;
_etat_bit_a_intergrer = etat_bit_a_intergrer;
_num_ref_de_la_sortie = num_ref_de_la_sortie;
/* pinMode(_clean , OUTPUT );
pinMode(_num_ref_de_la_sortie , OUTPUT);
pinMode(_registre_bit_suivant , OUTPUT);
pinMode(_etat_bit_a_intergrer , OUTPUT);*/
Liste_chainee.insertion(0, MaPremierListe);
tempon = Liste_chainee.recuperation_d_un_element(0 , MaPremierListe);
tempon->validation_des_sorties_ds_element = validation_des_sorties1;
_nb_de_sorties_rajoutes = 1;
}
void Sorties_series::configure_sortie_serie( int registre_bit_suivant,int clean , int etat_bit_a_intergrer, int num_ref_de_la_sortie, int validation_des_sorties1, int validation_des_sorties2)
{
Element *tempon = NULL;
configure_sortie_serie( registre_bit_suivant,clean, etat_bit_a_intergrer, num_ref_de_la_sortie, validation_des_sorties1);
Liste_chainee.insertion(1, MaPremierListe);
tempon = Liste_chainee.recuperation_d_un_element(1 , MaPremierListe);
tempon->validation_des_sorties_ds_element = validation_des_sorties2;
_nb_de_sorties_rajoutes = 2;
}
void Sorties_series::configure_sortie_serie( int registre_bit_suivant,int clean, int etat_bit_a_intergrer, int num_ref_de_la_sortie, int validation_des_sorties1, int validation_des_sorties2, int validation_des_sorties3)
{
Element *tempon = NULL;
configure_sortie_serie( registre_bit_suivant,clean, etat_bit_a_intergrer, num_ref_de_la_sortie, validation_des_sorties1, validation_des_sorties2);
Liste_chainee.insertion(2, MaPremierListe);
tempon = Liste_chainee.recuperation_d_un_element(2 , MaPremierListe);
tempon->validation_des_sorties_ds_element = validation_des_sorties3;
_nb_de_sorties_rajoutes = 3;
}
void Sorties_series::configure_sortie_serie(int registre_bit_suivant, int clean, int etat_bit_a_intergrer, int num_ref_de_la_sortie, int validation_des_sorties1, int validation_des_sorties2, int validation_des_sorties3, int validation_des_sorties4)
{
Element *tempon = NULL;
configure_sortie_serie( registre_bit_suivant,clean, etat_bit_a_intergrer, num_ref_de_la_sortie, validation_des_sorties1, validation_des_sorties2, validation_des_sorties3);
Liste_chainee.insertion(3, MaPremierListe);
tempon = Liste_chainee.recuperation_d_un_element(3 , MaPremierListe);
tempon->validation_des_sorties_ds_element = validation_des_sorties4;
_nb_de_sorties_rajoutes = 4;
}
Sorties_series::~Sorties_series()
{
}
/*int Sorties_series::trouver_le_bon_element(int place)
{
}*/
void Sorties_series::val_a_ecrire_sur_sorties(int num_de_la_sortie, bool etat)
{
Element *tempon = NULL;
digitalWrite(_clean, HIGH);
int tempon_num_ref_de_la_sortie = _num_ref_de_la_sortie;
int tempon_place_dans_tableau = num_de_la_sortie - _num_ref_de_la_sortie + 1;
int numero_de_l_element = 0;
int place = 0;
//numero_de_l_element = trouver_le_bon_element(num_de_la_sortie); //666666 je recupere par la fonction la valeur que doit avoir mon index
place = place - tempon_num_ref_de_la_sortie;
Serial.print(" _num_ref_de_la_sortie = ");
Serial.print(tempon_num_ref_de_la_sortie);
Serial.print(" num_de_la_sortie = ");
Serial.print(num_de_la_sortie);
Serial.print(" numero_de_l_element = ");
Serial.print(numero_de_l_element);
Serial.print("\n");
while ( tempon_num_ref_de_la_sortie <= num_de_la_sortie)
{
tempon_num_ref_de_la_sortie = tempon_num_ref_de_la_sortie + 8;
numero_de_l_element = numero_de_l_element + 1;
};
numero_de_l_element = numero_de_l_element - 1;
//numero_de_l_element est le numero de l'octuple verrou et numero_de_l_element va devoir
//correspondre au numero de l'index d'unelement donc je dois soustraire un car avec
//les elements je commence a partir de 0 et avec le numero de l'octuple verrou a partir de 1
Serial.print(" numero_de_l_element = ");
Serial.print(numero_de_l_element);
Serial.print("\n");
tempon = Liste_chainee.recuperation_d_un_element(numero_de_l_element , MaPremierListe);
//777777 je recupere l'addresse de l'element pour pouvoir y amnipuler un tableau
do //999999je cherche la place de ma sortie dans mon tableau
{
tempon_place_dans_tableau = tempon_place_dans_tableau - 8;
} while (tempon_place_dans_tableau > 0);
tempon_place_dans_tableau = tempon_place_dans_tableau + 8;
//Serial.print(" tempon_place_dans_tableau = ");
//Serial.print(tempon_place_dans_tableau);
//Serial.print("\n");
tempon->les_8_sorties[tempon_place_dans_tableau - 1] = etat; //10 10 10 10 je change l'état de la variable dans mon tableau
Serial.print(" _nb_de_sorties_rajoutes = ");
Serial.print(_nb_de_sorties_rajoutes);
Serial.print("\n");
Serial.print(" _validation_des_sorties = ");
Serial.print(_validation_des_sorties);
Serial.print("\n");
Serial.print(" _registre_bit_suivant = ");
Serial.print(_registre_bit_suivant);
Serial.print("\n");
Serial.print(" _etat_bit_a_intergrer = ");
Serial.print(_etat_bit_a_intergrer);
Serial.print("\n");
pilotage_bascule(numero_de_l_element);
//validation_des_sorties = 9 ; //tempon->validation_des_sorties_ds_element
Serial.print("tempon->validation_des_sorties = ");
Serial.print(validation_des_sorties);
digitalWrite(_clean, LOW);
digitalWrite(_clean, HIGH);
Serial.print("\n");
Serial.print("fin de l'action");
Serial.print("\n");
}
void Sorties_series::pilotage_bascule(int tempon1 )
{
Element *tempon = NULL;
int arret = 0;
//Serial.print(" tempon_insertion 0= ");
int numero = 0;
/*int tempon = 0;
tempon = Liste_chainee.recuperation_d_un_element(tempon1 , MaPremierListe);
digitalWrite(_clean, HIGH);
do
{
digitalWrite(_etat_bit_a_intergrer,tempon->les_8_sorties[tempon]);
digitalWrite(bascule_suivant, HIGH);
digitalWrite(bascule_suivant, LOW);
Serial.print("led 0 = ");
//Serial.print(tempon->les_8_sorties[0]);
Serial.print("\n");
digitalWrite(validation_des_sorties, HIGH);
digitalWrite(validation_des_sorties, LOW);
tempon++;
}while(tempon < 8);
digitalWrite(_clean, LOW);
digitalWrite(_clean, HIGH);
*/
if (arret == 0)
{
while (tempon1 < _nb_de_sorties_rajoutes)
{
tempon = Liste_chainee.recuperation_d_un_element(tempon1 , MaPremierListe);
while (numero < 8)
{
digitalWrite(_etat_bit_a_intergrer , tempon->les_8_sorties[numero]);
incremente_registre();
digitalWrite(11, HIGH);
digitalWrite(11, LOW);
Serial.print("led 0 = ");
Serial.print( tempon->les_8_sorties[numero]);
Serial.print("\n");
valide_sorties();
digitalWrite(9, HIGH);
digitalWrite(9, LOW);
numero++;
};
// digitalWrite( 9 , HIGH); //tempon->validation_des_sorties_ds_element
// delay(1000);
// digitalWrite(9, LOW); //tempon->validation_des_sorties_ds_element
//Serial.print(" tempon_insertion 0= ");
tempon1++;
};
}
if (arret == 0)
{
arret = 1;
}
// digitalWrite(_validation_des_sorties, HIGH);
}
void Sorties_series::incremente_registre()
{
digitalWrite(_registre_bit_suivant, HIGH);
digitalWrite(_registre_bit_suivant, LOW);
}
void Sorties_series::valide_sorties()
{
digitalWrite(_validation_des_sorties, HIGH);
digitalWrite(_validation_des_sorties, LOW);
}
Merci beaucoup de votre aide et dites le moi si je dois corriger des éléments qui vous on perturbé.
le tableau est celui créé dans le fichier "Listes_chainees.hpp", dans la structure "Element" ,ligne 17.
dans le fichier "Sorties_series.cpp" ,ligne 191 à 206, lorsque je demande à l'arduino de m'afficher les valeurs sur le moniteur série(lignes 199,200,201).
merci d'avoir regardé et encore désolé pour la structure du code.
Si tu conviens que la structure du code n'est pas bonne, c'est que tu as une idée de comment ça pourrait être mieux.
Reste plus qu'a l'arranger.
PS le choix des structures de données. Un _Bool est représenté sur un entier d'au moins 8 bits. Donc un tableau de 8 booléens occupe 64 bits dont 56 ne servent à rien.
La tradition (Et le bon goût) est plutôt d'utiliser un seul char pour 8 bits, et d'agir dessus avec des masques binaires.
Pour déclarer et initialiser un tableau de 8 bits à faux : unsigned char tableau = 0;
Pour mettre le bit 3 à vrai : tableau |= (1 << 3);
Pour mettre le bit 4 à faux : tableau &= ~(1 << 4);
Pour tester si le bit 2 est a vrai : if (tableau & (1 << 2)) { ....}
PS2 POURQUOI s'embêter avec une liste chaînée là où un vector ou un array ferait le boulot, avec du code à la fois beaucoup plus simple et plus rapide ? Le nombre de circuits varie pendant l'exécution ?
Je ne sais pas tout à fait le but du montage, mais il me semble qu'il existe un circuit qui prend 3 bits en input et qu'il active une ligne parmi 8 lignes en sortie.
On a la même chose pour un 4 bits sur 16 lignes.
Chercher: 3 bits to 8 lines multiplexer.
- Edité par PierrotLeFou 15 mars 2024 à 19:49:34
Le Tout est souvent plus grand que la somme de ses parties.
Je ne sais pas tout à fait le but du montage, mais il me semble qu'il existe un circuit qui prend 3 bits en input et qu'il active une ligne parmi 8 lignes en sortie.
Avec deux, on peut faire un 4 vers 16 en jouant avec les 3 entrées "enable". Le 4ieme bit d'adresse va vers une sélection sur un circuit, et une sélection inversée sur l'autre
Ps Un multiplexeur , ça prendrait 3 bits d'adresse, 8 de données et ça recopierait un bit de donnée sur la sortie.
c'est difficile de faire du reverse engineering sur du code source qui a été pas mal mutilé pendant la copie sur le forum (il manque des lignes, il y a deux main...), et qui fait quand même dans les 600 lignes...
Reprenons par le début. Que veut-on faire ? J'ai l'impression qu'il s'agit de créer un montage avec 54 sorties, sur lesquelles on peut agir par un truc comme
Les sorties 1 à 13 correspondant directement à celles de l'arduino, les autres (à partir de 14) aux sorties de 5 bascules D octales.
Hypothèses sur le montage (si je devais faire un truc comme ça)
Pour mettre des données dans une bascule octale, on commence par charger un octet dans un registre à décalage 8 bits, puis on active l'entrée d'horloge de la bascule.
Les sorties du registre à décalage vont sur un bus de données auquel sont raccordées les bascules D.
Avec ça, il nous faut
2 sorties de l'arduino pour clock et data_in du registre à décalage
1 sortie arduino pour le clock de chaque bascule (ce qui nous en fait 5)
Pour le code de la classe Montage
un tableau de 5 octets pour mémoriser les données de chaque bascule octale
les numéros des 2 sorties pour le pilotage du registre à décalage
un tableau de numéros des sorties qui activent chaque bascule (broche_horloge)
et en quelques lignes de code ça devrait le faire.
void Montage::set(unsigned int numero_sortie, int etat)
{
if (numero_sortie < 14) {
digitalWrite(numero_sortie, etat);
return;
}
auto numero_bit = numero_sortie - 14:
auto numero_bascule = numero_bit / 8;
auto index_bit = numero_bit % 8;
// 1. forcer le bit index_bit de tableau[numero_bascule]
// à 0 ou 1 selon etat
// 2 charger tableau[numero_bascule]
// dans le registre à décalage
// 3 envoyer un bip sur broche_horloge[numéro_bascule]
thats_all();
}
Ça fait un circuit en moins et ça réduit à 3 le nombre de sorties arduino nécessaires
2 pour l'entrée des données (SER premier circuit, SRK communs)
1 pour le transfert en sortie (RCK commun)
à qui on peut ajouter une remise à 0 et activation des sorties.
Avantage : y a moins de circuits (juste les 5 74HC595) qui ont moins de pattes (16 au lieu de 20 pour les bascules D) Peut être un inconvénient si il y a une problématique de rapidité : pour changer une sortie, il faut transférer les 5 x 8 = 40 bits en série.
merci pour les réponses mais j'ai fait ces listes chainées pour pouvoir les réutilisées pus tard dans d'autre programmes.Je les utilisent juste là pour m'entrainer.
De plus, j’essaye de "consommer" les composants qui ne me servent à rien et que j'ai en stock et, sur la carte, le nombre de sorties (donc de composants) peut varier (en fonction des besoins). cette carte étant utilisé pour augmenter le nombre de sorties sur l’Arduino (uno). Et je ne peux pas avoir de confusion en utilisant un char (dont la structure que vous avez présenté semble assez compliquée) ?
Maintenant que les listes chaînées ont été écrites, c'est une bonne idée de les (ré)utiliser dans des programmes qui en ont besoin.
Donc de les enlever de celui ci, où ça n'amène que des complications (et un gaspillage monstrueux de ressources) dont on peut facilement se dispenser.
Comme disait quelqu'un, un gentleman c'est quelqu'un qui sait jouer de l'accordéon, et s'en abstient. Pareil pour les programmeurs et les listes chaînées.
> je ne peut pas avoir de confusion ?
Quelle confusion par exemple ?
PS: ce n'est pas difficile de construire une structure de données qui représente un tableau de booléens en les casant dans des entiers considérés comme tableaux de bits.
Exemple, sous forme d'une classe paramétrée, utilisation d'un tableau de 33 bits
void test_get_set()
{
BoolArray<33> a;
a.set(0);
a.set(1);
a.set(5);
a.set(6);
a.set(32);
a.reset(0);
a.reset(5);
std::cout << "Bits à 1 : ";
for (int i = 0; i < 33; i++) {
if (a.get(i)) std::cout << i << " ";
}
std::cout << std::endl;
}
le type char n'est-il pas spécifique aux caractères ?
Et ce que je ne comprend pas c'est le fait que un tableau, dont les valeurs à l'interieur ne peuvent être que 0 ou 1 grâce au type "_Bool", me renvoi des entiers supérieur à 1.
le type char n'est-il pas spécifique aux caractères ?
Et ce que je ne comprend pas c'est le fait que un tableau, dont les valeurs à l'interieur ne peuvent être que 0 ou 1 grâce au type "_Bool", me renvoi des entiers supérieur à 1.
merci d'avoir répondu aussi vite
Le type char est mal nommé en C/C++, ça date d'une époque où les informaticiens voyaient les caractères en codage ASCII 7 bits ou EBCDIC 8 bits. Et pour ça des petits entiers suffisaient (8 bits en général, parfois 9 sur les machines à mot de 18 ou 36 bits)). Ils auraient mieux fait de distinguer "byte" et "char". Mais en C, ils voulaient pas s'emmerder, alors, allons-y Alonzo, on dit que les entiers sur un octet c'est des caractères.
Sans d'ailleurs décider si les char c'était des entiers signés ou pas. Ce qui change pas mal de choses.
Les _Bool, c'est un rajout tardif à la norme C pour pallier le manque de booléens. Ils ne sont pas représentés sur 1 bit. La norme C https://open-std.org/JTC1/SC22/WG14/www/docs/n3220.pdfnote en bas de la page 105 dit que le nombre de bits d'un bool est AU MOINS égal à celui d'un char (CHAR_BITS)
Et il peut traîner n'importe quoi dans les 8 bits si ça n'a pas été initialisé : comportement indéfini. C'est probablement ce qui vous arrive, mais votre code est trop touffu pour que je me lance à chercher où précisément. Faites-le compiler avec la détection de tous les warnings, ça sera déjà ça.
PS: suis arrivé à bricoler les surcharges pour utiliser la notation "crochets"
void test_brackets()
{
BoolArray<33> a;
std::cout << "test_brackets" << std::endl;
a[0] = true;
a[1] = true;
a[5] = true;
a[6] = true;
a[0] = false;
a[32] = true;
a[5] = false;
std::cout << "Bits à 1 : ";
for (int i = 0; i < 33; i++) {
if (a[i]) std::cout << i << " ";
}
std::cout << std::endl;
Idées :
une expression avec crochets comme a[i] retourne un objet qui indique la position d'un bit dans un BoolArray. C'est le type BoolArrayPosition
l'affectation d'un booléen à un BoolArrayPosition modifie le BoolArray
La conversion d'un BoolArrayPosition en bool retourne le bit correspondant
C'est un peu galère parce que les deux classes templates se font des références mutuelles, donc il faut faire des prédéclarations, etc. Je déteste C++.
emplate<int size> class BoolArrayPosition;
template<int size> class BoolArray
{
uint8_t m_array[(size + 7) / 8] = {0};
public:
// get, set, reset comme avant
BoolArrayPosition<size> operator[](unsigned int i);
};
template<int size> class BoolArrayPosition
{
BoolArray<size> &m_array;
unsigned m_i;
public:
BoolArrayPosition(BoolArray<size> &array, unsigned int i)
: m_array{array}
, m_i{i} {}
bool operator=(bool value)
{
m_array.set(m_i, value);
return value;
}
operator bool() const {
return m_array.get(m_i);
}
};
template<int size> BoolArrayPosition<size> BoolArray<size>::operator[](unsigned int i)
{
return BoolArrayPosition<size>{*this, i};
}
> Arduino, toute autre valeur est équivalente à true.
Arduino, c'est du C++ sans une partie de la bibliothèque standard.
L'affectation à une variable booléenne provoque une normalisation, exemple en C
include <stdio.h>
int main() {
_Bool b;
b = 33;
printf("%d\n", b);
return 0;
}
qui affiche 1.
Ou encore
#include <stdbool.h>
bool b(int i) {
return i;
}
que le compilateur convertit en
testl %edi, %edi
setne %al
ret
Doc: testl : "et" du registre edi avec lui même pour positionner les indicateurs
SETNE/SETNZ - Set if Not Equal / Set if Not Zero (386+)
Usage: SETNE dest
SETNZ dest
Modifies flags: none
Sets the byte in the operand to 1 if the Zero Flag is clear,
otherwise sets the operand to 0.
Ce qui permet d'induire que si il y a n'importe quoi dans un bool, c'est qu'il n'a probablement pas été initialisé (ou alors il y a eu un accès mémoire illégal avec un pointeur tourné zinzin). Mais pas par une affectation.
Comme j'aime bien pisser dans les violons( comme le regretté Kevin Ayers https://www.youtube.com/watch?v=8xgx0CmHw_k ), développement sur le même thème "tableau de bits" : selon l'architecture, il peut être avantageux de représenter par un tableau d'octets, ou de mots de 16 bits, ou de 32, ou de 64 etc.
test 33 bits brackets avec éléments de type uint8_t, taille objet = 5 octets
Bits à 1 : 1 6 32
test 33 bits brackets avec éléments de type uint16_t, taille objet = 6 octets
Bits à 1 : 1 6 32
test 33 bits brackets avec éléments de type uint32_t, taille objet = 8 octets
Bits à 1 : 1 6 32
test 33 bits brackets avec éléments de type uint64_t, taille objet = 8 octets
Bits à 1 : 1 6 32
expl: pour représenter 33 bits sur des entiers 16 bits, il en faut au minimum 3, donc 3*2 = 6 octets.
Le code du test (la même séquence, avec différents types)
template<int size, typename Element_Type>
class BoolArrayPosition;
template<int size, typename Element_Type = uint8_t>
class BoolArray
{
constexpr static int BITS_BY_ELEMENT = 8 * sizeof(Element_Type);
constexpr static Element_Type ONE = 1;
Element_Type m_array[(size + BITS_BY_ELEMENT - 1)
/ BITS_BY_ELEMENT] = {0};
public:
void set(unsigned int i)
{
m_array[i / BITS_BY_ELEMENT] |= ONE << (i % BITS_BY_ELEMENT);
}
void reset(unsigned int i)
{
m_array[i / BITS_BY_ELEMENT] &= ~(ONE << (i % BITS_BY_ELEMENT));
}
void set(unsigned i, bool value)
{
if (value) {
set(i);
} else {
reset(i);
}
}
bool get(unsigned int i)
{
return m_array[i / BITS_BY_ELEMENT] & (ONE << (i % BITS_BY_ELEMENT)); // conversion en bool
}
BoolArrayPosition<size, Element_Type> operator[](unsigned int i);
};
template<int size, typename Element_Type> class BoolArrayPosition
{
BoolArray<size, Element_Type> &m_array;
unsigned m_i;
public:
BoolArrayPosition(BoolArray<size, Element_Type> &array, unsigned int i)
: m_array{array}
, m_i{i} {}
bool operator=(bool value)
{
m_array.set(m_i, value);
return value;
}
operator bool() const
{
return m_array.get(m_i);
}
};
template<int size, typename Element_Type>
BoolArrayPosition<size, Element_Type> BoolArray<size, Element_Type>::operator[](unsigned int i)
{
return BoolArrayPosition<size, Element_Type> {*this, i};
}
template <typename Element_Type = uint8_t>
void test_brackets(const std::string & name)
{
std::cout << "test 33 bits brackets avec éléments de type " << name;
BoolArray<33, Element_Type> a;
std::cout << ", taille objet = " << sizeof(a) << " octets" << std::endl;
a[0] = true;
a[1] = true;
a[5] = true;
a[6] = true;
a[0] = false;
a[32] = true;
a[5] = false;
std::cout << "Bits à 1 : ";
for (int i = 0; i < 33; i++) {
if (a[i]) std::cout << i << " ";
}
std::cout << std::endl;
}
Exercice amusant : Quand on programme on fait des erreurs, c'est pour ça qu'il faut tester. Au départ j'avais écrit
void reset(unsigned int i)
{
m_array[i / BITS_BY_ELEMENT] &= ~(1 << (i % BITS_BY_ELEMENT));
}
et pareil pour set, et ça marchait pas pour uint64_t.
Saurez-vous expliquer pourquoi ?
---
Bref moralité, si on veut mémoriser 55 bits au maximum, on les met dans un entier 64 bits si y en a, et c'est réglé en 10 lignes.
- Edité par michelbillaud 3 avril 2024 à 22:32:51
tableau _Bool renvoit des entiers
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Discord NaN. Mon site.
Le Tout est souvent plus grand que la somme de ses parties.