tableau dynamique : mon code fonctionne ... mais pourquoi ?

salut

en faisant des tests sur les tableaux dynamiques, j'ai pondu ce code qui fonctionne ... mais qui ne devrait pas, selon moi

en effet, je dimensionneun tableau à 10 éléments puis je le parcours sur 100

mon choix d'utiliser Malloc entrainerais t'il une allocation dynamique de mémoire en fonction de l'usage ?

merci

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11,5, 4, 3, 2);
const int sensorpin = A0;
int sensorval;
float temp,tempmoy;
float tmin = 1000.0;
float tmax = 0.0;
int echantillon = 100; // nb d'élément pour le calcul de la moyenne des T°
float liste = (float)malloc(10 * sizeof(float));

void setup()
{
Serial.begin(9600);
lcd.begin(16, 2);
lcd.clear();
}

void loop()
{
sensorval = analogRead(sensorpin);
temp = (((sensorval/1024.0)*5.0)-0.5)*100;
//le capteur est sensible et varie beaucoup
//il faut donc en calculer la moyenne permanente
fn_nouvelle_temp(temp, echantillon);
// Serial.println(sizeof(liste)/sizeof(liste[0]));
tempmoy = fn_moyenne_temp(echantillon);
if (millis() > 5000)
{
if (tempmoy > tmax) {tmax = tempmoy;}
if (tempmoy < tmin) {tmin = tempmoy;}
}
lcd.setCursor(0, 0);
lcd.print("Mx:");
lcd.print(tmax);
lcd.print(" Mn:");
lcd.print(tmin);
lcd.setCursor(0, 1);
lcd.print(" Temp : ");
lcd.print(tempmoy);
}

//fonction d'insertion de la nouvelle valeur en place 0
//par décallage des autres vers le haut
void fn_nouvelle_temp(float temperature, int nb_val)
{
for (int i = nb_val-1; i >=1; i--)
{
liste = liste[i-1];

  • }*
  • liste[0] = temperature;*
    }
    //fonction de calcul de la moyenne des valeurs du tableau
    float fn_moyenne_temp(int nb_val)
    {
  • float result = 0.00;*
  • for (int i=0; i<=nb_val-1; i++)*
  • {*
    _ result = result + liste*;_
    _
    }_
    return result/nb_val;
    _
    }*_

Salut,

Pense à utiliser les balises code, plus lisible et évite les bugs dus aux autres balises.

Ma première question est : que vient faire le malloc() ici ?

balises code ?

je vouais un dimensionnement dynamique du tableau, histoire de régler l'échantillon non plus statiquement par lavariable "echantillon" mais par un potentiometre

Felix83:
salut

en faisant des tests sur les tableaux dynamiques, j'ai pondu ce code qui fonctionne ... mais qui ne devrait pas, selon moi

en effet, je dimensionneun tableau à 10 éléments puis je le parcours sur 100

mon choix d'utiliser Malloc entrainerais t'il une allocation dynamique de mémoire en fonction de l'usage ?

Le malloc ne fait qu'une réservation dans l'espace mémoire. Il retourne un pointeur sur la zone mémoire s'il a pu faire l'allocation sinon il retourne null.
Si tu demandes 10 octets, malloc t'alloue de la mémoire à un endroit où il sait qu'il y a 10 octets de libre. Maintenant si tu débordes de l'espace mémoire que tu as demandé c'est ton problème. Si de la mémoire a été allouée après ton malloc, lorsque tu débordes de la zone qui t'est allouée tu écrases des données d'une autre partie de ton code.

mouais ... pas glop ..

comment puis je gérer proprement un tableau dynamique ?

Pour modifier la taille d'un tableau en dynamique on utilise realloc mais sur un petit processeur c'est pas très indiqué.

Autrement ta manière de gérer les échantillons dans le tableau n'est pas très efficace. Au lieu de décaler tout les éléments pour insérer la nouvelle mesure à la position 0, il est beaucoup plus rapide d'avoir un pointeur sur la plus ancienne valeur et de placer directement la mesure à cet emplacement. Puis d'avancer le pointeur sur l'élément suivant qui devient le plus ancien.
De même pour le calcul de la moyenne au lieu de refaire la somme de tous les éléments à chaque fois. Il est plus rapide de soustraire de la somme le plus ancien élément (juste avant de le remplacer par la nouvelle mesure) et d'ajouter la nouvelle mesure.

Si tu veux pouvoir ajuster la réponse de ton filtre avec un potentiomètre, plutôt que faire une moyenne sur un tableau dynamique tu peux aussi utiliser un filtre du type:
ancienne_mesure = ancienne_mesure * k + nouvelle_mesure * (1-k) avec 0 < k <1.
Plus k est proche de 1 plus l'historique est prépondérant sur la mesure courante mais plus le temps de réponse est long évidemment.

merci
la nuit pourtant consel i, je mets ça en application demain

a+

comme ça c'est mieux ...

merci de vos conseils

a+

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11,5, 4, 3, 2);
const int sensorpin = A0;
int sensorval;
int compteur = 0;
float temp,tempmoy;
float tmin = 1000.0;
float tmax = 0.0;
int echantillon = 100; // nb d'élément pour le calcul de la moyenne des T°
float liste[100];
float *ptr_liste = &liste[0];

void setup() 
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() 
{
  sensorval = analogRead(sensorpin);
  temp = (((sensorval/1024.0)*5.0)-0.5)*100;
  //le capteur est sensible et varie beaucoup
  //il faut donc en calculer la moyenne permanente
  fn_nouvelle_temp(temp, echantillon);
//  Serial.println(sizeof(liste)/sizeof(liste[0]));
  tempmoy = fn_moyenne_temp(echantillon);
  if (millis() > 5000)
  {
    if (tempmoy > tmax) {tmax = tempmoy;}
    if (tempmoy < tmin) {tmin = tempmoy;}
  }
  lcd.setCursor(0, 0);
  lcd.print("Mx:");
  lcd.print(tmax);
  lcd.print(" Mn:");
  lcd.print(tmin);
  lcd.setCursor(0, 1);
  lcd.print(" Temp : ");
  lcd.print(tempmoy);
}


//fonction d'insertion de la nouvelle valeur
//par remplacement de la plus ancienne valeur
void fn_nouvelle_temp(float temperature, int nb_val)
{
  *ptr_liste = temperature;
  if (++compteur > nb_val) {compteur = 0;}
  ptr_liste = &liste[compteur];
}

//fonction de calcul de la moyenne des valeurs du tableau
float fn_moyenne_temp(int nb_val)
{
  float result = 0.00;
  for (int i=0; i<=nb_val-1; i++)
  {
    result = result + liste[i];
  }
  return result/nb_val;
}

Bonjour,

Felix83:
comme ça c'est mieux ...

merci de vos conseils

a+

Cela serait encore mieux :wink: si tu présentais ton code entre les balises #

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11,5, 4, 3, 2);
const int sensorpin = A0;
int sensorval;
int compteur = 0;
float temp,tempmoy;
float tmin = 1000.0;
float tmax = 0.0;
int echantillon = 100; // nb d'élément pour le calcul de la moyenne des T°
float liste[100];
float *ptr_liste = &liste[0];

void setup() 
{
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() 
{
  sensorval = analogRead(sensorpin);
  temp = (((sensorval/1024.0)*5.0)-0.5)*100;
  //le capteur est sensible et varie beaucoup
  //il faut donc en calculer la moyenne permanente
  fn_nouvelle_temp(temp, echantillon);
//  Serial.println(sizeof(liste)/sizeof(liste[0]));
  tempmoy = fn_moyenne_temp(echantillon);
  if (millis() > 5000)
  {
    if (tempmoy > tmax) {tmax = tempmoy;}
    if (tempmoy < tmin) {tmin = tempmoy;}
  }
  lcd.setCursor(0, 0);
  lcd.print("Mx:");
  lcd.print(tmax);
  lcd.print(" Mn:");
  lcd.print(tmin);
  lcd.setCursor(0, 1);
  lcd.print(" Temp : ");
  lcd.print(tempmoy);
}


//fonction d'insertion de la nouvelle valeur
//par remplacement de la plus ancienne valeur
void fn_nouvelle_temp(float temperature, int nb_val)
{
  *ptr_liste = temperature;
  if (++compteur > nb_val) {compteur = 0;}
  ptr_liste = &liste[compteur];
}

//fonction de calcul de la moyenne des valeurs du tableau
float fn_moyenne_temp(int nb_val)
{
  float result = 0.00;
  for (int i=0; i<=nb_val-1; i++)
  {
    result = result + liste[i];
  }
  return result/nb_val;
}

balises ?

Dans la fenêtre de rédaction il y a un bouton avec une icone #. Tu cliques dessus et ensuite il faut placer le code entre les 2 balises

avais pas vu...

effectivement c'est plus clair

merci