[Aide] Déclaration de variable

Bonjour a tous,

Quelqu'un peut il me dire pourquoi le code suivant, fonctionne si la variable patchin[200] est déclarée en global en début de programme et donne des résultats aberrants si elle est déclarée en local dans la fonction patchread()

Merci de votre aide
Philippe

#include <LiquidCrystal.h>

LiquidCrystal lcd(A4,A5,A0,A1,A2,A3);

const uint8_t patchreq[11] = {0xF0, 0x0, 0x21, 0x02, 0x00, 0x02, 0x11, 0x00, 0x00, 0x00, 0xF7};
uint8_t patchin[200];
uint8_t i = 0;
uint8_t a = 0;
uint8_t index = 0;
uint8_t checksumlu = 0;
uint8_t checksum = 0;
uint8_t b=0;

void setup()
{
  Serial.begin(31250);

  lcd.begin(16,2);
  lcd.clear();
  lcd.print("o0o FACTORY");
  lcd.setCursor(0,1);
  lcd.print("Serial SysEx ");
  delay(100);
  lcd.clear(); 
}

void loop()
{
  patchread();
    
  lcd.print(a);
  lcd.print(" ");
  lcd.print(checksumlu, HEX);
  lcd.print(" ");
  lcd.print(checksum, HEX);
    
  loop:
  goto loop;
}

//-----------------------------------------------------------------------------------------------------------------
void patchread() 
{
  //uint8_t patchin[200];
  Serial.flush();                             //Vide le buffer serie
  Serial.write(patchreq,11);            //Envoi la commande "Patch Request" au synthé

  while(Serial.available() < 205)      //Attente de la réception des 205 bytes du patch du synthé
  {
  } 
 
  do {                                         //Vidage de l'écho "Patch Request" dans le buffer série (F0,......, F7)                
    i = Serial.read();
  } 
  while(i != 0xf7); 

  index = 0;
  do                                            //Lecture des 195 octets du patch de F0,....... à .....F7
  {
    patchin[index] = Serial.read();
    index++;
  } 
  while(patchin[index] != 0xf7);

  checksumlu = patchin[192];            //Formatage du checksum tranmit dans le path sous forme de 2 nibble
  checksumlu *= 16;
  checksumlu += patchin[193];
  
  checksum = 0;
  for (index = 0; index < 92; index++)  //Calcul du checksum des données reçues
  {
    i = (index * 2) + 8;  
    b = (patchin[i] * 16) + patchin[(i+1)];
    checksum += b;
  }  
  a=patchin[10];
  a *= 16;
  a += patchin[11]; 
  
}

Les variables locales sont allouées dynamiquement dans la pile (zone mémoire qui sert aussi a mémoriser les adresses de retour des fonctions, les paramètres des fonctions, le contexte des interruptions.
Généralement cette zone est de petite taille sur un micro comme l'ATmega qui ne dispose que de 2KO de RAM.
Déclarer des tableaux dans la pile pourrait provoquer des débordements de pile et donc un fonctionnement erratique.
Je n'ai pas encore regardé en détail le fonctionnement de l'Arduino coté gestion mémoire mais pour l'avoir rencontré sur d'autres micro, ca pourrait etre une piste.

A l'opposé, la memoire pour les variables globales est réservée a la compilation (en fait a l'édition de liens) et donc si ca compile, c'est que ca passe.

je crois qu'il à tout dit ^^ les variables global et local on des caractéristiques différente or mis le faite qu'une variable local utilisé en dehors de sa fonction n’existe plus, je pense que ça ne peut être que ça ton problème.

je crois qu'il à tout dit

Non il a oublié de dire qu'il faut mettre le code entre balise. Le bouton # dans l'écran de saisie du post.

je me disais bien aussi ^^'

Pour avoir une vue d'ensemble de l'état de la RAM (partie statique) et de la ROM aprés compilation :

avr-size -C --mcu=atmega328p monfichier.hex

Cela donnera quelque chose dans ce style :

$ make size
avr-size -C --mcu=atmega328p dcpu.elf
AVR Memory Usage

Device: atmega328p

Program: 4532 bytes (13.8% Full)
(.text + .data + .bootloader)

Data: 1831 bytes (89.4% Full)
(.data + .bss + .noinit)

Program:
.text -> code (instructions en langage machine)
.data -> variable statique (chaine de caractére, const, ...)
.bootloader -> zone mémoire réservé au bootloader (si utilisé et disponible)

Data:
.data (cf program)
.bss -> variables global ou static non initialisé (zone mémoire initialisé à 0 lors du démarage)
.noinit -> pareil que .bss mais cette zone n'est pas initialisé à 0 lors du démarage

cf: Memory Sections

(Le fichier .hex se trouve dans un dossier buildxxxxxxx dans le dossier temporaire (/tmp sous linux, %appdata%..\local\temp sous windows)

Merci pour vos réponses, mais je crois que je vais abandonner Arduino et retourner vers d'autre Micro contrôleurs.
L'outil de développement est vraiment nul, aucune possibilité de debug, je ne parle même pas de la documentation. (même avec un Stamp un SX ou un Pic Basic le debug est possible)
Du coup, personne ne comprend rien à la gestion des variables et de la mémoire.
A part faire clignoter une LED et lire un Switch pas de salut. Bon ceci dit, pour 20€ la carte il n'y à pas possibilité de se plaindre.
Merci à tous pour vos tentatives d'aide.

phm78:
Merci pour vos réponses, mais je crois que je vais abandonner Arduino et retourner vers d'autre Micro contrôleurs.
L'outil de développement est vraiment nul, aucune possibilité de debug, je ne parle même pas de la documentation. (même avec un Stamp un SX ou un Pic Basic le debug est possible)
Du coup, personne ne comprend rien à la gestion des variables et de la mémoire.
A part faire clignoter une LED et lire un Switch pas de salut. Bon ceci dit, pour 20€ la carte il n'y à pas possibilité de se plaindre.

Le principe d'arduino :

  • simple pour que n'importe qui sans aucune connaisances en prog puisse faire des choses de lui même
  • le plus basique possible pour continuer dans l'optique de la simplicité.

Si tu veut du debug et un ide complet :
AVR studio de atmel + toolchain winAVR + debuggeur AVR dragon.

Pour ceux qui est de la gestion de la mémoire tu peut te reporter à la documentation officiel de lib-avrc (on ne le dira jamais assez mais ARDUINO != AVR !)
http://www.nongnu.org/avr-libc/user-manual/index.html

Ps: comparer un basic stamp ou un pic basic qui se programme en basic et qui n'est rien d'autre que du code interprété, et un microcontroleur programmé en C/C++ et/ou assembleur n'est pas du tout logique :wink:

PPs: le potentielle d'une carte arduino, ou plus précisément d'un ATmega ne se résume pas à faire clignoter une led ou lire un bouton :wink:
Va donc faire un tour sur mon blog tu auras de nombreux exemples de ce qu'il est possible de faire.

Pour te donner une idée, j'ai codé hier et avant-hier un émulateur de DCPU-16 avec un ATmega328 comme base, comme quoi on peut faire pas mal de choses avec :
http://twitpic.com/aa7ras

phm78:
A part faire clignoter une LED et lire un Switch pas de salut.

tien regarde ce qu'en dit le créateur de la carte Mais puisqu’on vous dit que nous sommes en train de changer le monde ! – Framablog