Disparition eeprom_read_word(adr) !

Salut à tous,

Bon, voilà mon pb : dans la version 3 de l'environement de dev. eeprom_read_word(adr) fonctionnait. Dans la version 4 non :cry: !

J'ai regardé dans le code de la lib 3 et je n'ai trouvé que le fichier de déclaration (.h), pas le code d'accès à l'eeprom. C'est ennuyeux de ne pas pouvoir conserver des paramètres dans l'eeprom intégrée. Une astuce ou faut que je me tape de l'assembleur :-/ ?

Try adding:

#include <avr/eeprom.h>

to the top of your sketch.

The full path is: <ARDUINO>/tools/avr/avr/include/avr/eeprom.h

I tried this before but there is this error. Everything is ok with 003 version... Is a cast will work ?

In function 'void init_deplacement()':
error: invalid conversion from 'int' to 'const uint16_t*' In function 'void loop()':

J'avais essayé mais non l'erreur précédente apparaît ! Alors qu'auparavant sur la 003 ca fonctionnait... Est-ce qu'un transtypage pourrait fonctionner ?

Re-salut à tous,

Bon, j'ai trouvé une solution sur http://www.avrfreaks.com/index.php?name=PNphpBB2&file=viewtopic&t=21371.

Je vous donne le code brut vous adapterez pour les "word" :

byte eeprom_rd_byte ( byte const * ptr )
{ 
  register byte sreg, tmp; 
  
  sreg = SREG; 
  cli(); 
  while ( EECR & (1 << EEWE )) { 
    SREG = sreg; 
    cli (); 
  } 
  EEAR = (unsigned int)ptr; 
  EECR |= (1 << EERE); 
  tmp = EEDR; 
  SREG = sreg; 
  return tmp; 
} 

void eeprom_wr_byte ( byte const * ptr, byte val )
{ 
  register byte sreg; 

  sreg = SREG; 
  cli(); 
  while ( EECR & (1 << EEWE )) { 
    SREG = sreg; 
    cli (); 
  } 
  EEAR = (unsigned int)ptr; 
  EEDR = val; 
  EECR |= ( 1 << EEMWE ); 
  EECR |= ( 1 << EEWE ); 
  SREG = sreg; 
}

Attention au noms des fonctions qui ne sont pas ceux des libs standards pour éviter la confusion. Si vous souhaitez changer les noms, vous pouvez ou changez les dans votre code.

Le #include proposé précédement devrait fonctionner, il suffit peut être d'un cast ou qque chose de trés simple, mais voilà une solution.

Salut Benoit....

bouhhhh comme c'est compliqué. :-?
je voudrais utiliser ce code pour mettre une table contenant des mots (p.ex : "bonjour")
je suis à cours de ram dans un petit projet et peut-être que les 512 bytes de l'eeprom feront la blague pour le script

genre je voudrais placer cette table dans l'eeprom :

char *sJour[33] = {"", " premier", " deux", " trois", " quatre", " cinq", " six", " sept", " huit", " neuf", " dix", " onze", " douze", " treize", " quatorze", " quinze", " seize", " dix-sept", " dix-huit", " dix-neuf", " vingt", " vingt-et-un", " vingt-deux", " vingt-trois", " vingt-quatre", " vingt-cinq", " vingt-six", " vingt-sept", " vingt-huit", " vingt-neuf", " trente", " trente-et-un", " mille"};

tu veux bien m'aider un peu sur ce coups là... je suis un peu dépassé par le script....
je suis que graphiste :slight_smile:

merci
eric

Bonjour Eric,

Combien te manque t'il d'octets pour que ça passe ? Si tu as la version 4 c'est donné au chargement du prog. même si le chargement n'a pas eut lieu.

Genre :
Binary sketch size: 5586 bytes (of a 7168 byte maximum)
Programmer is not responding.

Tu fais "sketch size" ici 5586 moins le maximum : 5588 - 7168 = -1580 octets (négatif ici, donc octets de libre).

c'est en RAM que je manque de place (la place pour les variables), le programme se charge normalement mais quand il tourne, une des table du programme contient du "n'importe quoi".
suivant la version d'arduino, je n'ai pas le même résultat dans mon serial monitor mais il semble bien qu'une des table prenne l'eau.
d'où l'idée de stocker dans l'eeprom.
ecrire mes constants dans la flash ça marche pas avec arduino.enfin j'ai pas réussit en suivant l'exemple là
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array

j'ai trouvé un thread chez avrfreak mais je pipe rien
http://www.avrfreaks.com/index.php?name=PNphpBB2&file=viewtopic&t=36339&highlight=enough+ram+var&sid=ac0aaea81038b29246ff1a3bb17834a7

sinon dans ce thread http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1147121045/0 le gars dit que l'eproom write read fonctionne....

que faire ?

eric

PS: la taille de mon prog

Binary sketch size: 6554 bytes (of a 7168 byte maximum)

Re,

J'avais déjà regardé des threads où ils parlaient de la localisation d'espaces mémoire. Je n'ai pas approfondi, j'ai réussi avec l'eeprom à m'en sortir. Je vais te faire une autre proposition avant de regarder la localisation du stockage. Je prépare ça, ca arrive, si ca fonctionne, ca laissera le temps de voir la localisation des variables.

:frowning: èh ben, j'en ch... Mais ca va passer. Sûrement une petite bêtise de rien qui me coince...

:smiley: ah oui j'avais écrit << en place de < ! Il me reste une chose à régler, le pb du stockage des chaînes vides et c'est bon. Tu pourras, Eric, Stocker tes chaînes en eeprom.

re bonjour Eric,

Je dois partir et je n'ai pas le temps de t'expliquer maintenant mais peut-être comprendras-tu vant mon retour, tard cette nuit. dans le cas ou cela pourrait de débloquer voici le code :

#define nbChaines 5
#define maxCaracteres 15

char *sJour[nbChaines] = {"", "*premier", "*deux", "*trois", "*quatre"};
char strRet[maxCaracteres];

byte eeprom_rd_byte (unsigned int const * ptr)
{ 
  register byte sreg, tmp; 
  
  sreg = SREG; 
  cli(); 
  while ( EECR & (1 << EEWE )) { 
    SREG = sreg; 
    cli (); 
  } 
  EEAR = (unsigned int)ptr; 
  EECR |= (1 << EERE); 
  tmp = EEDR; 
  SREG = sreg; 
  return tmp; 
} 

void eeprom_wr_byte (unsigned int const * ptr, byte val)
{ 
  register byte sreg; 

  sreg = SREG; 
  cli(); 
  while ( EECR & (1 << EEWE )) { 
    SREG = sreg; 
    cli (); 
  } 
  EEAR = (unsigned int)ptr; 
  EEDR = val; 
  EECR |= ( 1 << EEMWE ); 
  EECR |= ( 1 << EEWE ); 
  SREG = sreg; 
}

void eeprom_wr_word (unsigned int const * ptr, unsigned int val)
{
  byte bH = (val > 8) & 0xFF;
  byte bL = val & 0xFF;
  eeprom_wr_byte (ptr++, bL);
  eeprom_wr_byte (ptr, bH);
}

unsigned int eeprom_rd_word (unsigned int const * ptr)
{
  unsigned int iRet = 0;
  byte bH = 0;
  byte bL = 0;
  bL = eeprom_rd_byte (ptr++);
  bH = eeprom_rd_byte (ptr);
  iRet = bH;
  iRet = iRet < 8;
  iRet |= bL;
  return iRet;
}

void EEpromInscritJours()
{
  char* strEltPt;
  unsigned int strIndex = 0;
  unsigned int indexSAT = 0;
  int iTmp = 0;
 
  strIndex = (nbChaines * 2)+1;
  
  for (int i=0; i<nbChaines; i++)
  {
    printString ("no ");
    printInteger (i);
    printString (" d ");
    printInteger (strIndex);
    printString (" >");

    strEltPt = sJour[i];
    eeprom_wr_word ((unsigned int *)indexSAT, strIndex);
   
    while (*strEltPt)
    {
      printByte (*strEltPt);
      eeprom_wr_byte ((unsigned int *)strIndex, *strEltPt++); // on recopie la chaîne octet par octet
      strIndex++;
    }; 
    
    printByte (*strEltPt);
    eeprom_wr_byte ((unsigned int *)strIndex, 0); // 0 délimiteur
    strIndex++;

    printString ("< ");
    printString (" f ");
    printInteger (strIndex);
    
    indexSAT += 2;

    printByte(13);
  }
}

char* Jour(byte indexJour)
{
  char* strRetPt = strRet;
  char caractere;
  unsigned int strIndex;
  unsigned int indexSAT = indexJour * 2; // 2 octets par index
 
  strIndex = eeprom_rd_word((unsigned int *)indexSAT);
  
  printByte (13);
  printString ("indexSTR ")  ;
  printInteger (strIndex);
  printByte(32);
  
  do {
    caractere = eeprom_rd_byte ((unsigned int *)strIndex);
    *strRetPt = caractere;
    strIndex++;
    strRetPt++;
  } while (caractere);

  return strRet;
}

void setup()
{
  beginSerial(9600);
  EEpromInscritJours();
 
  int no=0;
  for (; no<nbChaines; no++)
  {
    printString(Jour(no));
    printByte(13);
  }
};

unsigned int eei = 0;
void loop ()
{
  while (eei < 25)
  {
    if (eeprom_rd_byte((unsigned int *)eei) < 32)
      printByte(254);
    else
      printByte(eeprom_rd_byte((unsigned int *)eei));
    eei++;
  }

};

L'eeprom est non volatile et, dans ton cas, pour stocker toutes tes phrases il faut je pense faire une première programmation de l'eeprom avec un prog. sans code superflu avec toutes tes phrases. Puis, ton code utile qui est chargé ensuite dans la carte et qui ne fait que la lecture de l'eeprom qui a été programmée auparavant.

En clair, il te faut programmer la carte deux fois. La première fois avec le plus petit code possible pour écrire dans l'eeprom et la seconde avec ton code enchichi de la fonction char* Jour(byte indexJour) et la déclaration de strRet et des fonctions eeprom. Ca bouffera de l'espace Flash (code), mais pas RAM.

Si t'es bloqué on voit cela plus-tard ou demain matin. Pose tes questions pendant mon absence ou mieux, dis moi que ca fonctionne pour toi.

ou non de diou... :o de crédiou...

si t'avais pas mis les doigts dedans j'aurais jamais trouvé ça. :-*
wahouuuuu.
je suis pas à la maison... je teste en rentrant.... quand je rentre :-?

merci, merci, MERCI

eric

Bonjour Eric,

Bon je suis rentré? Je t'explique un peu la démarche.

D'abord j'ai regardé si la capacité de l'eeprom était suffisante pour contenir le nombre de caractères que tu as a stocker pour tes 33 chaînes de caractères.
"" 0 caractères
" premier" 8 caractères
" deux" 5 caractères
" trois" 6 caractères
" quatre" 7 caractères
" cinq" 5 caractères
" six" 4 caractères
" sept" 5 caractères
" huit" 5 caractères
" neuf" 5 caractères
" dix" 4 caractères
" onze" 5 caractères
" douze" 6 caractères
" treize" 7 caractères
" quatorze" 9 caractères
" quinze" 7 caractères
" seize" 6 caractères
" dix-sept" 9 caractères
" dix-huit" 9 caractères
" dix-neuf" 9 caractères
" vingt" 6 caractères
" vingt-et-un" 12 caractères
" vingt-deux" 11 caractères
" vingt-trois" 12 caractères
" vingt-quatre" 13 caractères
" vingt-cinq" 11 caractères
" vingt-six" 10 caractères
" vingt-sept" 11 caractères
" vingt-huit" 11 caractères
" vingt-neuf" 11 caractères
" trente" 7 caractères
" trente et un" (il n'y a pas de tirets) 13 caractères
" mille" 6 caractères

En C, les chaînes de caractères sont terminées par un 0 qui sert de délimiteur. Donc, le total d'octets est au minimum de 255 (amusant) + 33 soit 288 octets.

Bon, si on écrit les chaînes à la suite en eeprom c'est bien, mais il faudrait avoir un tableau en RAM pour conserver l'index de début des chaînes de caractères, sinon comment retrouver une chaîne en particulier. Un tableau en RAM ? Zut, nous voulions libérer de la RAM ! Alors pourquoi ne pas utiliser un index en début d'eeprom ? Une SAT (String Allocation Table :D).

Mais comment savoir combien il y a d'entrées dans la SAT ? On pourrait mettre un octet en début d'eeprom et? STOP ! Il y en a 33 et c'est déclaré en constante « #define nbChaines 33 ».

L'eeprom comporte 512 cellules d'un octet. Ca laisse une marge de 224 octets. Pour la SAT, il nous faut pouvoir gérer des indices jusqu'à 512 donc des valeurs sur deux octets. La SAT occupera donc 33*2=66 octets.

La suite dans un prochain message?

Bonjour Eric,
Houla ! En faits ce n 'est pas simple ton truc ! J'en suis a compresser les données et ca ne loge toujours pas en ram ! J'arrive à 26 mais pas plus. Je regarde encore mon code ligne par ligne pour voir si je n'ai pas commit d'erreurs. Ensuite, si je ne trouve pas, je te fait un programme en C# pour charger les phrases en eeprom, avec les compléments arduino qui vont bien.

a+

trop sympa Benoit. :sunglasses:

merci une masse.

eric

Re, c'est FAIT !

Ca fonctionne !

J'avais divers pbs dans mon code, c'est résolu. Du coup j'ai revu mes fonctions de lecture/écriture dans l'eeprom et j'ai trouvé pourquoi auparavant mes fonctions refusaient de fonctionner avaec une adresse en int*. J'écrirai là-dessus ensuite...

Bon, le système est scindé en deux programmes : prog_jours2 et test_jours2.

Le premier, prog_jours2, inscrit les jours dans l'EEprom.
Le second, test_jours2, affiche sur la liason série (j'utilise HyperTerminal) le contenu de l'EEprom pour vérifier.

Le format de stockage dans l'EEprom est le suivant :

  • premier octet, le nombre de chaînes stockées ;
  • les n (nombre de chaînes stockées) mots suivants, les index de début des chaînes (ce que j'appelle la SAT, String Allocation Table) ;
  • les octets suivants sont les caratères des chaînes de caractères avec un 0 délimiteur en fin de chacune.

Suite à différents essais, ... j'ai changé le système de description des chaînes. Il n'y a plus de tableau pour les "nombres", mais une chaîne de caratères. Plus simple à modifier vérifier, coder, ... Et cette chaîne de caractères est "compressée" pour éviter les redites. Le système est le suivant '/' pour une fin de chaîne, '1' pour 'un', 2 pour 'deux', ... 'D' pour 'dix', ... regardez le code, c'est compréhensible, je pense.

Le programme met un certain temps à programmer l'EEprom. Installez si vous le pouvez une LED sur la broche 13, elle s'allumera à la fin de la programmation de l'eeprom. Sans LED, attendre 30s.

Pas de place pour les programmes en direct dans le message donc :

Dites-moi si ca fonctionne chez vous.

a+.

Bonjour Benoît... ça fait longtemps hein :stuck_out_tongue:

gros, gros projet sur le feu... pas eu de temps libre... mais là j'en ai du coups je reviens à mes amours.
j'ai installé un atmega168 sur une de mes cartes, mais le problème de manque de ram est le même que sur l'atmega8... donc j'ai besoin d'écrire mes trucs dans la rom...
donc je suis allé rechercher ton prog et j'ai testé....avec arduino06
et j'a une erreur ;D (3 versions d'arduino plustard...)

 In function 'void eeprom_wr_byte(const unsigned int*, byte)':
error: 'EEWE' was not declared in this scope

qu'est c' y veut le monsieur ? :o
y a pas d'init de la var ?

merci d'avance

eric

salut :slight_smile:

non, c'est un problème du aux changements du nom des registres dans l'ATMEGA168 j'ai résolu le pb mais je ne te répondrai que demain... patience...

C'est quand demain Benoit ? ::slight_smile:

Salut,

Désolé, je t'avais oublié, j'ai enchaîné deux missions et je pensais avoir le temps... Je te réponds ce soir de l'hôtel... :slight_smile: la je suis en cours et comme je suis le formateur, "ca la fout mal".