Pages: 1 [2] 3   Go Down
Author Topic: Comment incrémenter ceci 0x0100  (Read 2662 times)
0 Members and 1 Guest are viewing this topic.
France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3414
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Par contre, je suis surpis d'un truc

Code:
#define EPROM_INC 0x0100
byte mask = 0x1100;

mask = mask+EPROM_INC;


mask devrait être egal à
Quote
0x1200
non?
Non, la variable mask est de type byte donc limitée à 0xFF si tu veux voir le bon résultat déclare ta variable comme int ou unsigned int.
Logged

Orleans
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Macbidouilleur
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Euh, du reste tout est déclaré en byte en fait. Forcement que ca marche pas bien :/

Le mieux pour faire joujou avec des mask c'est des unsigned int pour des paquets de 16 bits, voir des unsigned long pour des pack de 32
Logged


France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3414
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Euh, du reste tout est déclaré en byte en fait. Forcement que ca marche pas bien :/

Le mieux pour faire joujou avec des mask c'est des unsigned int pour des paquets de 16 bits, voir des unsigned long pour des pack de 32
Faut pas se fier au nom, de ce que j'ai compris c'est plutôt l'adresse de base dans la mémoire
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,¨

Je suis toujours bloqué avec ceci. Du moins j'ai une solution, mais j'en suis pas convaicnu.
Si vous pour m'en convaincre ou me dire comment vous le feriez mieux.

En résumé et pour rappel
Je defini la position des enregustrement longitude, latitude, altitude etc
Code:
// 24LC236
#define EPROM_COU 0x0001
#define EPROM_LON 0x0008 // 8 en dec
#define EPROM_LAT 0x0018 // 24 en dec
#define EPROM_ALT 0x0028 // 40 en dec
#define EPROM_TIM 0x0038 // 56 en dec
#define EPROM_VEL 0x0048 // 72 en dec
#define EPROM_STA 0x0058  // 88 en dec
#define EPROM_INC 0x0100  // Incrementation
unsigned int mask=0x0000;
const byte rom = 0x50;    // Address of 24LC256 eeprom chip
char data[15];

Puis en suite , je dois trouver un truc pour que lorsque la fonction GetGPS() est appelée la deuxieme fois, il enregistre ces positions aux positions incrémentée de 0x0100, par exemple
Quote
course à l'adresse 0x0101
lontitude à la position 0x0108
latitude à la position 0x0118
altitude à la position 0x0128
etc
Puis quand elle sera appelée la troisème fois, ca serait ca
Quote
course à l'adresse 0x0201
lontitude à la position 0x0208
latitude à la position 0x0218
altitude à la position 0x0228
etc
et aindi de suite

J'ai donc trouvé cette solution. Comme pourriez-vous faire mieux, comment feriez-vous
Code:
char cou[15];
char lon[15];
char lat[15];
char alt[15];
char time[14];
char vel[6];
char sta[2];

// 24LC236
#define EPROM_COU 0x0001
#define EPROM_LON 0x0008 // 8 en dec
#define EPROM_LAT 0x0018 // 24 en dec
#define EPROM_ALT 0x0028 // 40 en dec
#define EPROM_TIM 0x0038 // 56 en dec
#define EPROM_VEL 0x0048 // 72 en dec
#define EPROM_STA 0x0058  // 88 en dec

#define EPROM_INC 0x0100  // Incrementation
unsigned int mask=0x0000;
const byte rom = 0x50;    // Address of 24LC256 eeprom chip

setup(){
 Serial.begin(9600);
  Wire.begin ();
}

loop(){
GetGPS();
delay(60000);
}

GetGPS(){
         
          gps.getPar(lon,lat,alt,time,vel);

        // first time mask is egual to 0x0000 then it will be recorded at position 0x0001
        // next time , mask is equla to 0x0100, then it will be recorded at position 0x0101
        // next time, mask is equal t0 0x0200, then it will be recorded at position 0x0201
        writeEEPROM(rom,mask+EPROM_COU,cou); // No worries about the value of cou, it's work
       // EPROM_LON will inrement as for EPROM_COU, etc
        writeEEPROM(rom,mask+EPROM_LON,lon);
        writeEEPROM(rom,mask+EPROM_LAT,lat);
        writeEEPROM(rom,mask+EPROM_ALT,alt);
        writeEEPROM(rom,mask+EPROM_TIM,tim);
        writeEEPROM(rom,mask+EPROM_VEL,vel);
        writeEEPROM(rom,mask+EPROM_STA,sta); // No worries about the value of sta, it's work, it not my worries

       mask = mask+EPROM_INC;
       // Incrment mask as the folowing 0x0100, 0x0200, 0x0300, 0x0400 .... 0x1100, 0x1200.. etc

}
How would you to bette, to increment the 2 digit of the hexa.

Was I clear to undertand, my wories?
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3414
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Le principe de l'incrément fonctionne mais la mémoire est très mal utilisée.
Tu écris dans les 90 octets et tu utilises un pas de 256 donc environ 1/3 de la mémoire ne sera pas utilisé.
En plus ta mémoire fait 32k octets avec un pas de 256 pour chaque enregistrement tu ne pourras pas stocker plus de 32768/256 = 128. Avec un enregistrement toutes les minute comme tu l'as programmé cela de donne 2h d'enregistrement.
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oui tu as raison, mais je ne suis pas expert en EEPROM. En fait c'est la premiere fois que j'utilise un EEPROM et je suis passé par la décourte pour en arrivé.

Je suis arrivé aussi à cette déduction. 2h c'est suffisant pour l'useage que je veux en faire. même si j'exploite mal la mémoire.

L'aventage que je vois dans cette manière de faire, c'est que je sais exactement ou son mes informations, par minutes.

Pour le moment je ne vois pas comment faire mieux, avec mes connaissances, mais je n'exclu pas une maélioration en deuxième temps, quand j'aurais acquis plus de connaissances...

Mais merci pour cette remarque qui est juste.
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

France
Offline Offline
Faraday Member
**
Karma: 36
Posts: 3414
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
L'aventage que je vois dans cette manière de faire, c'est que je sais exactement ou son mes informations, par minutes
Quelque soit la valeur de l'incrément tu retrouveras toujours tes données. Il suffit de multiplier le temps (en minutes) par la valeur de l'incrément.
Logged

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1392
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Une façon d'optimiser ta mémoire, ça ne change en rien le reste du code...

Code:
#define SIZE_COU 15  // taille de cou[]
#define SIZE_LON 15  // taille de lon[]
#define SIZE_LAT 15  // taille de lat[]
#define SIZE_ALT 15  // taille de alt[]
#define SIZE_TIM 14  // taille de time[]
#define SIZE_VEL 6  // taille de vel[]
#define SIZE_STA 2  // taille de sta[]

char cou[SIZE_COU];
char lon[SIZE_LON];
char lat[SIZE_LAT];
char alt[SIZE_ALT];
char time[SIZE_TIM];
char vel[SIZE_VEL];
char sta[SIZE_STA];

// 24LC236
#define EPROM_COU 0x0000  // autant commencer au début de la mémoire...
#define EPROM_LON EPROM_COU+SIZE_COU // 15 octets plus loin (taille de cou[15] enregistré précédemment)
#define EPROM_LAT EPROM_LON+SIZE_LON // même raisonnement pour les adresses suivantes
#define EPROM_ALT  EPROM_LAT+SIZE_LAT // ...
#define EPROM_TIM EPROM_ALT+SIZE_ALT //
#define EPROM_VEL EPROM_TIM+SIZE_TIM //
#define EPROM_STA EPROM_VEL+SIZE_VEL  //

#define EPROM_INC EPROM_STA+SIZE_STA  // Incrementation de façon à ce que le prochain enregistrement se fasse directement à la suite
unsigned int mask=0x0000;
const byte rom = 0x50;    // Address of 24LC256 eeprom chip


Maintenant, un enregistrement n'occupera plus que 80 octets au lieu des 256 avant (soit 409 enregistrements possibles au lieu de 128, soit 6h50' environ). L'avantage de ce genre de déclaration, c'est que si à un moment tu changes la taille d'un enregistrement (par exemple cou[15] devient cou[6], il te suffit de ne changer que la première ligne par

Code:
#define SIZE_COU 6  // taille de cou[]
et tout ton code suivra (par contre, ce genre de modif rend tout ce qu'il y avait avant dans l'EPROM inutilisable, mais il te suffira de refaire un enregistrement pour réécraser le tout...). ça réorganisera totalement l'adressage en ROM de façon à toujours utiliser au mieux ta mémoire (dans cet exemple de passer cou à 6, tu passerais à 461 enregistrements...)

Autre idée, pour l'indexation dans get_gps(), tu devrais déclarer une variable genre word index_EPROM = 0; et réécrire ces codes :

Code:
       writeEEPROM(rom,(EPROM_INC*index_EPROM)+EPROM_STA,sta); // No worries about the value of sta, it's work, it not my worries

       index_EPROM++;  // incrément de l'index
Ton premier enregistrement se fera pour index_EPROM = 0, le suivant pour index_EPROM = 1 etc etc...

Niveau lecture, pareil, pour récupérer par exemple time sur le 9ième enregistrement, il suffira de faire

Code:
  // le premier enregistrement étant à 0, le 9ième se trouve à 8, logique...
  readEPROM(rom, (EPROM_INC*8)+EPROM_TIM, time);   // enfin selon comment tu gères ta lecture de l'EPROM...

si ça peut t'aider...

PS : encore un bonus :
Après la ligne #define EPROM_INC, mets ça :
Code:
#define EPROM_SIZE 32768  // taille de l'EPROM en octets
const word EPROM_MAX = (EPROM_SIZE/EPROM_INC)-1;  // limite du nombre d'enregistrements
EPROM_MAX contient précisément le dernier index possible pour les enregistrements (et toujours en phase avec la taille de tes variables, donc si index_EPROM > EPROM_MAX, c'est que la mémoire est pleine.
« Last Edit: September 25, 2013, 05:23:14 am by Super_Cinci » Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Je suis en train de reproduire la porposition de supercinci.
Et j'ai une question:
Dans ce code
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??
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1392
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
« Last Edit: September 25, 2013, 10:23:38 am by Super_Cinci » Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Par exemple
Code:
// 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?
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

Bretagne
Offline Offline
Edison Member
*
Karma: 16
Posts: 1392
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 :
Code:
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).

2) 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?
Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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
Code:
#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
Code:
        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

Code:
        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

Code:
        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
Code:
        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
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

Offline Offline
Sr. Member
****
Karma: 0
Posts: 368
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

D'après cr que j'ai pu lire, dans mes précédents post, je pourrai faire ceci
Code:
#define EPROM_COU 0;

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

Code:
// 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
Code:
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...

 smiley
Logged

Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!

Pages: 1 [2] 3   Go Up
Jump to: