Comment incrémenter ceci 0x0100

Super merci et aussi a super_cinci.

J'ai lu rapidement vos idées. Je prendrai le temps de bien relire, ce soir et voir comment adapter mon code pour le rendre plus optimal en fonction de vos comentaire.

Je vous remercie

Je suis en train de reproduire la porposition de supercinci.
Et j'ai une question:
Dans ce code

#define EPROM_LON EPROM_LAT+SIZE_LAT // 15 octets plus loin (taille de cou[15] enregistré précédemment)

On additionne EPROM_LAT qui est en hexa avec SIZE_ALT qui ne l'est pas. Ca ne rsique pas de causer un proble dans le résultat, vu qu'on est en hexa??

Comprendre un compilateur, c'est pas toujours facile.

x = 0x42; le "0x" devant le nombre indique que c'est de l'hexa. donc le compilateur va le transformer en binaire (des 1 et des 0) à partir de sa valeur hexa. Pour le µP qui exécutera le code, x=01000010.
y = 75; rien devant le nombre, c'est du décimal. le compilateur va le traduire par y=01001011.
z = 0117; le 0 en premier indique que c'est de l'octal (base 8 ). traduit par z=01001111.
t = b00001101; le b indique binaire, il rest donc en binaire.

x + y + z + t = ? Le processeur va faire le calcul en binaire, soit

processeur // programmeur
01000010 // 0x42
+01001011 // + 75
+01001111 // + 0117
+00001101 // + b00101101

11001001 // =DOKA (en bibi-binaire)

as-tu vu un problème quelque part? Le processeur, lui, n'a eu aucun souci pour calculer... mais je crois qu'on t'en avait déjà parlé dans les premières pages de ce topic, non?

Bon , j'espère ne pas avoir loupé une partie de ton explication, mais il y a un peti binz.

Par exemple

// SI
#define EPROM_COU 0x0000
#define EPROM_INC 84
// D'AILLEUR, POURQUOI word ET PAS int?
word index_EPROM = 0;

Serial.println((EPROM_INC*index_EPROM)+EPROM_COU);
// CECI DEVRAIT AFFICHER ZERO, MAIS IL M'AFFICHE 82

Si EPROM_INC est egal à 84 et qu'on multiplie par 0, ca doit faire 0. Et si après on fait 0 + 0x0000. Il doit s'afficher 0 ou 0x0000.

Pourquoi ca afiiche 82, et même pas 84?

  1. le type de variable

Je fais toujours attention à mes types de variables. un word ou un int occupent la même place en mémoire (2 octets), mais la diff entre les deux, c'est les valeurs qu'ils peuvent prendre.

word = entier positif. 0 <= word <= 65535
int = entier signé -32763 <= int <= 32763

quand je sais qu'une variable ne prendra jamais de valeur négative, je la déclare en non signé, c'est comme ça, ma façon de faire. de même, si j'ai :

int table[64];

pour indexer table, j'utiliserai une variable byte, car 0 <= byte <= 255, et pourquoi travailler avec un 16bits quand 8 suffisent?

j'appelle ça de l'optimisation. n'oublions pas que l'arduino est une plateforme 8 bits, et que bosser avec 16 bits lui demande pas loin de 10 x plus de temps qu'avec un simple octet. alors je travaille toujours avec des variables 8bits non signées, et seulement si j'ai besoin, j'attaque les word, int, long...

c'est la grosse erreur de la team arduino qui parle toujours d'int, déformation du PC où l'int est maintenant la base des procs de PC (une plateforme 64 bits n'aura pas peur de bosser avec des variables 32bits, car sur PC, un int fait 4 octets).

  1. Serial.println((EPROM_INC*index_EPROM)+EPROM_COU)

si ça donne 82, ça m'inquiète, car dans (84 x 0) + 0, il est impossible de trouver "82".

Serial.write(48); // affiche "0"
Serial.println("0"); // affiche "0"

je sais que le "préprocesseur", au niveau du compilateur, va traduire ton code en Serial.println(0*index_EPROM); mais de là à faire 82...

tu as essayé avec Serial.println((index_EPROM*EPROM_INC)+EPROM_COU) ? c'est tout con, mais qui sait?

j'appelle ça de l'optimisation. n'oublions pas que l'arduino est une plateforme 8 bits, et que bosser avec 16 bits lui demande pas loin de 10 x plus de temps qu'avec un simple octet. alors je travaille toujours avec des variables 8bits non signées, et seulement si j'ai besoin, j'attaque les word, int, long...

Ok mais alors pourquoi utiliser un word alors qu unsigned int, serait plus optimal alors?

Mais ce qui me rpéoccupe le plus c'est le "82".
A savoir que

#define SIZE_COU 7
#define SIZE_LON 15
#define SIZE_LAT 15
#define SIZE_LON 15
#define SIZE_ALT 15
#define SIZE_TIM 15
#define SIZE_VEL 15
#define SIZE_STA 2

char stat;
char lon[SIZE_LON];
char lat[SIZE_LAT];
char alt[SIZE_ALT];
char time[SIZE_TIM];
char vel[SIZE_VEL];
char msg1[5];
char msg2[5];
char coords[99];
byte courseid;

#define EPROM_COU 0x0000
#define EPROM_LON EPROM_COU+SIZE_COU //7
#define EPROM_LAT EPROM_LON+SIZE_LON //22
#define EPROM_ALT EPROM_LAT+SIZE_LAT //37
#define EPROM_TIM EPROM_ALT+SIZE_ALT //52
#define EPROM_VEL EPROM_TIM+SIZE_TIM //67
#define EPROM_STA EPROM_VEL+SIZE_VEL //82
#define EPROM_INC EPROM_STA+SIZE_STA //84 // Incrementation de façon à ce que le prochain enregistrement se fasse directement à la suite

word index_EPROM = 0;

Par contre j'ai essayé de remplacé ceci

        Serial.print(F("INDEX : ")); Serial.println(index_EPROM); // Affiche 0
        Serial.print(F("EPROM_INC : ")); Serial.println(EPROM_INC); // Affche 84
        Serial.print(F("EPROM_INC*INDEX : ")); Serial.println(EPROM_INC*index_EPROM); // Affiche 82
        Serial.print(F("INDEX : ")); Serial.println(index_EPROM); // Affiche 0
        Serial.print(F("EPROM_INC : ")); Serial.println(EPROM_INC); // Affche 84
        Serial.print(F("EPROM_INC*INDEX : ")); Serial.println(EPROM_INC*0); // Affiche 82
        Serial.print(F("INDEX : ")); Serial.println(index_EPROM); // Affiche 0
        Serial.print(F("EPROM_INC : ")); Serial.println(EPROM_INC); // Affche 84
        Serial.print(F("EPROM_INC*INDEX : ")); Serial.println(84*0); // Affiche 0
        Serial.print(F("INDEX : ")); Serial.println(index_EPROM); // Affiche 0
        Serial.print(F("EPROM_INC : ")); Serial.println(EPROM_INC); // Affche 84
        Serial.print(F("EPROM_INC*INDEX : ")); Serial.println(index_EPROM*EPROM_INC); // Affiche 84 mais devrait affihcer 0

Bon , hier soir, avec une petite bière dans la main :), j'ai pensé à un truc.

  1. Es-ce que je dois absolument utiliser des hexa comme
#define EPROM_COU 0x0000;

D'après cr que j'ai pu lire, dans mes précédents post, je pourrai faire ceci

#define EPROM_COU 0;

Aussi, j'ai remplacer mes #define par des const, mais uniquement pour la difition des positions dans l'eeprom:

// 24LC236
const unsigned int EPROM_COU = 0x0000;
const unsigned int EPROM_LON = EPROM_COU+SIZE_COU; //7
const unsigned int EPROM_LAT = EPROM_LON+SIZE_LON; //22
const unsigned int EPROM_ALT = EPROM_LAT+SIZE_LAT; //37
const unsigned int EPROM_TIM = EPROM_ALT+SIZE_ALT; //52
const unsigned int EPROM_VEL = EPROM_TIM+SIZE_TIM; //67
const unsigned int EPROM_STA = EPROM_VEL+SIZE_VEL; //82
const unsigned int EPROM_INC = EPROM_STA+SIZE_STA; //84 // Incrementation de façon à ce que le prochain enregistrement se fasse directement à la suite

et là! ceci

Serial.print(F("EPROM_INC*INDEX : ")); Serial.println(index_EPROM*EPROM_INC); // Affiche 0 et plus 84 :o)

m'affiche bien 0 quand EPROM_INC est egal à 84 et index_EPROM est egal à 0. Aussi, que j'utilise 0x0000 ou 0, ca ne change rien, mais bon ca ne m'étonne pas.

S'il y a une remarque concernant ce changement, je vais laisser ceci, mais je me pose la question, pourquoi le #define cause se problème. Mais d'un cote, je prefere garder ceci, comme ceci, car ce me semble plus claire quand on defini distinctement, le type de EPROM_INC ou EPROM_XXX.

N'es-ce pas?

J'ai aussi unsigned, vu que me s nombres ne seront pas en dessous de zero, et en 8bit...

:slight_smile:

Si tu avais su, tu te serais mis à boire plus tôt. XD

Alors oui, pourquoi pour qui et comment? peut-être que #define (qui n'a comme fonction que de remplacer l'identifiant par la valeur dans tout ton programme avant compilation) fait se mélanger des byte et des words, et je sais que par moments si on n'y pense pas assez, un word multiplié par un byte sera retenu comme byte, et qu'à la lecture du word, l'otcet de poids faible sera le byte calculé, et l'otcet de poids fort la case mémoire suivante qui sera peut-être occupée par autre chose, mais là, le µP s'en contre-fout, il lit quand même. ou l'inverse, enfin je me comprends...

Ce qui compte, c'est que tu as trouvé une parade, alors restons dessus et félicitations!

Sinon, pourquoi word au lieu de unsigned int? parce que que l'on écrive "word", "unsigned int", "uint16_t" ou "uint16", c'est exactement la même chose. Le core arduino comprend des milliers de #define qui se redéfinissent entre eux... Puis il y a 20 ans, à l'école on ne m'a parlé que de byte (octet) et word (un mot de deux octets) quand on jouait à programmer des 68HC11. Du coup, j'ai gardé ces définitions qui sont bien plus claires pour moi-même...

oK alors je vais rester sur

const unsigned int eprom_cou = 0x0000;

meme s'il y aun peu plus d'écriture, si c'est la même chose?

Par contre derniere question, on est d'acord que de faire

const unsigned int EPROM_COU = 0x0000;

ou

const unsigned int EPROM_COU = 0;

c'est exactement la même chose pour le microtrolleur? (juste pour avoir une confirmation.

En tout cas, milles mercis (et a fdufnews aussi) pour toutes ces explications et le temps passé.

Je passerai bien en bretagne te payer une biere, mais c'est fait un peu loin, suis de l'autre côté :slight_smile:

pierrot10:
Par contre derniere question, on est d'acord que de faire

const unsigned int EPROM_COU = 0x0000;

ou

const unsigned int EPROM_COU = 0;

c'est exactement la même chose pour le microtrolleur? (juste pour avoir une confirmation.

dans ce cas, oui, car le format de la variable est défini, c'est un entier non signé sur 2 octets (16 bits). donc lui affecter 0 ou 0x0000, c'est tout pareil, le compilateur va transformer ta valeur numérique en un nombre binaire de 16 bits, soit 0000000000000000.

Pour la bière, t'inquiète, je n'oublie pas, méfiance si un jour tu viens en vacances dans le coin!

Super. Milles mercis pour tout ces explications. C'est super cool.

Pour la bière, t'inquiète, je n'oublie pas, méfiance si un jour tu viens en vacances dans le coin!

J'y étais, y a ....deux ans. Et comme ca été vraiment bien, ca sera en grand plaisir de revenir.

Hello,

Je constate qu'il y a un probleme au niveau de l'incrémentation (index)

Ceci est mon index

unsigned long int index_EPROM = 0L;

Je l'incrlmente simplement comme ceci

index_EPROM++;

Le truc c'es qu'il ne depasse pas 10. Ensuite il recommence à 0.
C'est pas bisard alors qu'on est en long int?

heu... tu parles de 10 ou de 0x10? c'est étonnant que tu ne puisses pas incrémenter un long. tu as essayé :

index_EPROM = index_EPROM + 1;

?

c'est tout con, mais si on n'essaie pas, on ne sait pas...

Ce serait bien de mettre le code incriminé. Par ce que bon un ++ ça incrémente mais tu peux faire autre chose à coté qui modifie la valeur.

Hello!

Oui j'avais essayéc eci sans succès

index_EPROM+=1L;

J'ai reproduit cette exrcice afin d'exclure une partie de mon code.
Ceci me permets de tester aJSON (qui ne marche pas, ca n'affiche le format JSON, mais doit encore chercher :slight_smile: aJson/README.md at master · interactive-matter/aJson · GitHub ),

Mais avant, je souhaiterai comprendre et résoudre l'incrémentation qui ne dépasse pas 10L. J'ai mis les commentaire, dans le code.
Ha, ne le lisez pas le tout. Le probleme se situe dans setup() et dans loop(). Mais si c'est reglé dans setup(), ben ca regler dans loop() :slight_smile:

Par contre je dois mettre le code me dehor du post, a cause de la limitation du nombre de caratctere:
http://www.hello-web.net/temp/forum2.html

Salut.

unsigned long int intMax = 9L; // L Parce qu'il interfera avec index_EPROM

 (...)

for(index_EPROM=0L; index_EPROM <=intMax; index_EPROM++ ){
}

si ça peut t'aider...

et pourquoi utiliser un long??? tu vas perdre énormément de temps à le traiter, alors que c'est une valeur qui ne devrait pas dépasser les 3000. utilises un unsigned int, et :

#define SIZE_IND 2 // Debug, pour suivre l incrementation
(...)
word ind;  // au lieu d'un char[]

//writeEEPROM(rom,(eprom_inc*index_EPROM)+eprom_ind,char_index_EPROM); // ICI JE VOIS L EVOLUTION DE L INCREMENTATION
writeEEPROM(rom,(eprom_inc*index_EPROM)+eprom_ind,index_EPROM); // normalement, ça passe comme ça, mais le but du jeu est d'enregistrer une valeur numérique sur deux octets.

te prends pas la tête à convertir en chaîne de caractère, tu perds du temps et c'est un risque de foirer les données. en même temps, tu n'as plus besoin de l'enregistrer, ça ne sert absolument à rien car j'ai trouvé ton erreur...

Alors, oui j'ai essayé d'utiliser de int au lieu des long int.
et avec des int ca fonctionne.

Le truc c'est que je suis limitl à 32763 aors que le long int va au moins jusqu'a la valeur max de l'EEPROM soit de 262144.
Je suis conscient qu'il sera extrement rare d'aller jusquà ce grand nombre

Mais bon c'est vrai que j exagere puisque 32763min fait 546 heure. :slight_smile:

surtout que l'index, c'est le numéro d'un bloc de 90 octets, donc l'index max = 262144/90 = 3000 environ... donc soit un int soit un word. le jour où tu mettras une eprom de 2,5Mo, oui, l'int ne suivra plus. pour saturer un word, il faudra dépasser les 5Mo... pour un long, la limite sera dans les... 175Go, je crois pas qu'on ait encore inventé une telle eprom sur un DIP8 XD.

pierrot10:
Alors, oui j'ai essayé d'utiliser de int au lieu des long int.
et avec des int ca fonctionne.

Le truc c'est que je suis limitl à 32763 aors que le long int va au moins jusqu'a la valeur max de l'EEPROM soit de 262144.
Je suis conscient qu'il sera extrement rare d'aller jusquà ce grand nombre

Mais bon c'est vrai que j exagere puisque 32763min fait 546 heure. :slight_smile:

Je crois que tu t'es un peu mélangé entre taille mémoire et adressage de la mémoire (et nous on a suivi sans réfléchir). Je viens seulement de faire le rapprochement entre les deux fils de discussion que tu as ouvert, l'un sur l'incrémentation et l'autre sur le calcul avec des long int.
La mémoire à une capacité de 256k bits mais en fait l'accès à son contenu se fait par octet et donc on a une mémoire de 32k octets.
Dans la fonction write l'adresse est un entier entre 0 et 32767.