En cours conversion 7 bits en variable bytes

M

Mcar

Compagnon
Bonjour à tous,

je voudrais sauvegarder dans une variable de type bytes(etat2_led) l'état HIGH ou LOW de 7 pins.
1718564764373.png

mon idée est de considérer digitalRead (pin) comme une valeur Boolean ( 0/1) que je multiplie par le rang (64 = 2|6 (2 puissance 6), 32= 2|5 etc..) pour obtenir ainsi dans une valeur bytes 7 bits (0 ou 1) (donc inferieur à 255).
mais ça ne marche pas :smt017
en d'autres termes, comment sauvegarder dans une variables bytes l'état de 7 pins ?
je me sert de cette variable pour la sauvegarder dans l'EEPROM
merci pour vos réponses
 
P

petit_lulu

Compagnon
salut,
je ne suis pas spécialiste arduino mais...

une function:

int bit_to_byte(int valeur, int num_bit, bool bit_memo){
int memo=valeur;
int val=pow(2,num_bit);

if (bit_memo){
memo=memo | val;
}
return memo;
}

et tu fais les appels:
etat2_led=0;
etat2_led=bit_to_byte(etat2_led, 6, digitalRead(led_O[1]));
etat2_led=bit_to_byte(etat2_led, 5, digitalRead(led_A[1]));
etat2_led=bit_to_byte(etat2_led, 4, digitalRead(led_S[1]));
etat2_led=bit_to_byte(etat2_led, 3, digitalRead(led_VL[1]));
etat2_led=bit_to_byte(etat2_led, 2, digitalRead(led_M[1]));
etat2_led=bit_to_byte(etat2_led, 1, digitalRead(led_C[1]));
etat2_led=bit_to_byte(etat2_led, 0, digitalRead(led_R[1]));
 
D

Dudulle

Compagnon
tu peux le faire comme ceci :

byte etat2_led = 0;

etat2_led |= digitalRead(led_O[1]) << 6;
etat2_led |= digitalRead(led_A[1]) << 5;
etat2_led |= digitalRead(led_S[1]) << 4;
etat2_led |= digitalRead(led_VL[1]) << 3;
etat2_led |= digitalRead(led_M[1]) << 2;
etat2_led |= digitalRead(led_C[1]) << 1;
etat2_led |= digitalRead(led_R[1]) << 0;
 
M

Mcar

Compagnon
Merci pour vos réponses
la dernière solution me plait bien et fonctionne, pas essayer les autres,
ça fait 1 jour que je cherche, merci à vous tous :smt038
 
S

speedjf37

Compagnon
Bonjour,

C'est surprenant de relire les états.
Il serait plus logique de mémoriser à la commande des led et encore mieux de conserver l'état du signal.

Mais on ne sait rien du fonctionnement de ton système .

Cordialement Jf
 
M

Mcar

Compagnon
Bonjour,
je construis un décodeur de signal pour représenter la signalisation SNCF de mon réseau train en HO,
pour cela j'utilise un Arduino nano en utilisant toute les sorties de 0 à 21 exception de la pin 2 que j'utilise en interruption pour capter le signal DCC qui vient de ma centrale Lenz DCC.
1718603939210.png

le décodeur ainsi définit pourra représenter 3 cibles (poteaux) SNCF sur 7 états possibles. (3*7+1=22 sorties)
voilà pour le préambule. mon code fonctionne bien.
toutes ces sorties sont affectées à alimenter des leds pour la représentation des signaux SNCF.
Je veux sauvegarder les états avant l'arrêt (coupure du courant) du décodeur, pour à la remise sous tension réinitialiser toutes les leds allumées avant la coupure. pour rappel, j'utilise un logiciel RRTC qui va commander ce décodeur.
la mémoire de sauvegarde du nano est de 255 bytes,
comme la mémoire a une durée de vie de 100.000 cycles, j'utilise toute la mémoire en rolling list
une case mémoire est un octet soit un chiffre décimal de 0 à 255.
mes états signaux par cibles sont de 7 soit la représentation d'un chiffre binaire de 7 bits.
d'où ma question
esperant avoir été clair ,
Bonne journée à tous,
 
M

midodiy

Compagnon
comme la mémoire a une durée de vie de 100.000 cycles, j'utilise toute la mémoire en rolling list
Tu peux m'en dire un peu plus? Tu veux dire qu'un coup tu utilises une case eeprom, le coup suivant une autre case?
Ça m'intéresse pour ma dro de tour...
Merci
 
M

Mcar

Compagnon
Dans le principe oui, c'est ça.
j'utilise un nano every le moins cher,

1718611781454.png


il possède 256 byte de mémoire, pour rappel cette mémoire est sauvegardée même sans alimentation.
mais le problème est qu'elle a une durée de vie limitée à 100.000 cycles.
c'est beaucoup et peu en même temps, tout dépend du type et du nombre de cycle d'enregistrement.
donc pour augmenter cette durée de vie j'utilise cet artifice de sauvegarder à chaque sauvegarde 3 byte ,car j'ai besoin de 3 case mémoire, une case mémoire = un octet de 8 bits = un décimal de 0 à 255.
ce qui augmente la durée de vie de ma mémoire eeprom = 256/3 = 85 * 100.000 = 8.500.000 enregistrements.
ce qui est suffisant pour mon application et la durée de vie de mon décodeur. :mrgreen:
la routine que j'utilise est toujours la même (les pros vont surement dire qu'il y a mieux :siffle:)
c'est le principe du pile FIFO qui va de 0 à 255, que l'on efface (réinitialise ) qu'une fois pleine. la réinitialisation se fait à 0, le premier bit sur les 8 étant toujours à 1 , comme j'ai besoin de 7 bits , l'enregistrement sera jamais à 0.
l'enregistrement se fera toujours sur le dernier enregistrement +1, la lecture pour connaitre le dernier index de la pile se fera donc toujours sur le dernier enregistrement, testée par une simple boucle = 0;
voilà , je ne suis un pro du C++, j'essaye juste de finaliser mes projets avec mes maigres connaissances. et si elle ne sont pas suffisantes, alors je frappe ici , :wavey:
 
Dernière édition:
S

speedjf37

Compagnon
Re.

Les décodeurs que je connais ne mémorisent pas les états.

Par contre les aiguillages peuvent être stables.
C'est le logiciel qui rafraîchit toutes les sorties au redémarrage que ce soit les aiguillages , les signaux , les éclairages etc.

Jf
 
M

mvt

Compagnon
Bonjour Marc,

Une question en passant. Tu veux mémoriser 3 états en un bit si j'ai bien compris. A ma connaissance, seuls 2 peuvent l'être, O ou 1. Comment gères tu le 3ème état. Ou je n'ai rien compris ! Un poteau comprend 7 leds, chaque led peut être allumée ou éteinte. C'est la combinaison des 7 qui donne le statut final. Dans ce cas, c'est Ok. Merci pour ton éclairage. Je suis une bille en trains ! (aussi !)
 
5

59JAG

Ouvrier
dans ton cas plutot un bitRead
un ptit prog que j ai fait sur wokwi il y a un momment qui utilise bitSet BitClear BitRead BitWrite Prog Wokwi
 
M

Mcar

Compagnon
Bonjour Marc,

Une question en passant. Tu veux mémoriser 3 états en un bit si j'ai bien compris. A ma connaissance, seuls 2 peuvent l'être, O ou 1. Comment gères tu le 3ème état. Ou je n'ai rien compris ! Un poteau comprend 7 leds, chaque led peut être allumée ou éteinte. C'est la combinaison des 7 qui donne le statut final. Dans ce cas, c'est Ok. Merci pour ton éclairage. Je suis une bille en trains ! (aussi !)
oui, un bit = 0 ou 1 , soit 0 = LOW = led allumée avec l'anode de la led au commun +5v
et 1 = HIGH, la sortie de arduino (pin) au moins cathode de la led. donc par led 2 états possibles. (LOW/HIGH)
1718622213129.png

un poteaux = une cible = 7 leds maxi = 7 bits , le décodeur est capable de gérer 3 cibles/poteaux, donc 3x7bits = 3 octets de 7bit, le 8eme sert pour l'index de la pille.
avec une case mémoire = un octet de l'eeprom.
 
M

Mcar

Compagnon
Re.

Les décodeurs que je connais ne mémorisent pas les états.

Par contre les aiguillages peuvent être stables.
C'est le logiciel qui rafraîchit toutes les sorties au redémarrage que ce soit les aiguillages , les signaux , les éclairages etc.

Jf
oui, je viens de m'en rendre compte ce matin, :smt021
mais c'est pas grave, cette routine servira pour un autre projet. merci pour l'info,
une fois le décodeur au point, j'irai chez Leb Modelisme pour les cibles ou poteaux :wink: , ils sont beaux.
 
G

greg_elec

Compagnon
Autre astuce pour augmenter la durée de ve de la mémoire il ne faut écrire dedans qu'en cas de disparition de l'alim principale. Pour que cela fonctionne il faut conserver l'alim de l'arduino quelques secondes après la disparition de l'alim (une diode et une capa suffisent). il faut detecter la coupure de l'alim par une entrée qui va activer une interuption qui va déclancher la routine d'écriture dans la mémoire.
A la remise sous tension on lit la mémoire sauvegardée .
Je l'ai fait pour un thermostat dans une maison ou je ne suis pas en permanence 14° en mode absent et 19° en mode présent .
Par -5° il me faut 2 heures pour passer le 14 à 19 si cela interesse du monde je peux ouvrir un sujet avec description du montage
 
F

furynick

Compagnon
tu peux le faire comme ceci :

byte etat2_led = 0;

etat2_led |= digitalRead(led_O[1]) << 6;
etat2_led |= digitalRead(led_A[1]) << 5;
etat2_led |= digitalRead(led_S[1]) << 4;
etat2_led |= digitalRead(led_VL[1]) << 3;
etat2_led |= digitalRead(led_M[1]) << 2;
etat2_led |= digitalRead(led_C[1]) << 1;
etat2_led |= digitalRead(led_R[1]) << 0;
Je suis à la bourre mais y'a encore plus simple à écrire :

Syntax​

bitWrite(x, n, b)

Parameters​

x: the numeric variable to which to write.
n: which bit of the number to write, starting at 0 for the least-significant (rightmost) bit.
b: the value to write to the bit (0 or 1).

 
M

MegaHertz

Compagnon
Bonjour,

Tu peux aussi utiliser les champs de bit

typedef struct {
unsigned byte led_O : 1;
unsigned byte led_A : 1;
unsigned byte led_S : 1;
unsigned byte led_VL : 1;
unsigned byte led_M : 1;
unsigned byte led_C : 1;
unsigned byte led_R : 1;
} EtatFeux;
Ensuite avec une variable ou un tableau de type EtatFeux il suffit d'écrire dans le bit qui t'intéresse

EtatFeux ef;
ef.led_C = digitalRead...
ef.led_O = digitalRead...

ou :

EtatFeux ef[100] = {};
int idx = 0;

...
ef[idx].led_C = digitalread...
ef[idx].led_O = digitalread...
idx++;
 

Sujets similaires

V
Réponses
3
Affichages
1 600
vibram
V
G
Réponses
123
Affichages
20 013
gaston83
G
V
Réponses
62
Affichages
6 069
vibram
V
zygo4619
Réponses
34
Affichages
35 728
zygo4619
zygo4619
totoche974
Réponses
6
Affichages
12 305
totoche974
totoche974
M
Réponses
30
Affichages
26 299
wika58
W
U
Réponses
85
Affichages
7 942
Hubert86
H
01power
Réponses
3
Affichages
14 337
01power
01power
F
Réponses
14
Affichages
3 346
franckapik
F
J
Réponses
1
Affichages
1 690
pro-ms
P
M
Réponses
185
Affichages
26 025
wika58
W
D
Réponses
9
Affichages
3 282
David80
D
V
Réponses
7
Affichages
2 178
vibram
V
Haut