Go Down

Topic: conversion avec dtostrf () (Read 5400 times) previous topic - next topic

turw

Bonjour,

Je veux savoir pourquoi dans un programme on converti un nombre Float en String ???
j'ai un capteur de gaz Mq-3 que je veux calibrer pour les concentration 1%, 2%, 3% 4% et 5%.

je veux avoir une réponse qui reste stable pour chaque concertation dois-je augmenter la sensibilité ( résistance ) ???

Merci

fdufnews

Eh eh !! on est pas devins.
Si tu ne donnes pas le code en question ni le schéma ça va pas être facile de t'aider.

turw

voici le code:

Code: [Select]

#include "arduino.h"
#include <LiquidCrystal.h>
#include <sstream>
#include <string>
#include <iostream>

using namespace std;

float concentration(float x) {
  const float A[] = {
    2.71494E+02, -3.10999E+02, 6.85051E+02, -3.47587E+02, 7.47499E+01            };
  float result;
  float B[4];
  B[0] = x*x;
  B[1] = B[0]*x; 
  B[2] = B[1]*x;
  B[3] = B[2]*x;

  result = A[0]*x+A[1]*B[0]+A[2]*B[1]+A[3]*B[2]+A[4]*B[3];
  return result;
}

char messages[5][16] = {
  "Heating sensor", "64 seconds", "Autozero", "Ready!", "ppm"};

int L;
float x;
float x0[5];
float x_initial;

LiquidCrystal lcd(12, 11,5, 4, 3, 2); // Wiring microcontroller - LCD:

const int pushbutton = 8; // Pushbutton (normally open). Stops initial heating time when it is pressed. .
const int analogPin = A0; // Reads sensor voltage as a float int the interval (0-1) corresponding to (0 - 3.3V).
float sensor_value_AnalogIn = 7; // Analog output to a multimeter or datalogger (1V = 1000 ppm).

void text_screen( char messages[],  int colum, int row) {
  lcd.setCursor( colum, row);
  lcd.print(messages);
}



void setup() {
  lcd.begin(16,2);
  Serial.begin(9600);
  lcd.clear();
  text_screen(messages[0], 0, 0);
  text_screen(messages[1], 0, 1);
  delay(2000);

  for (int j = 0; j<4; j++)
  {
    lcd.clear();  // Heating sensor 4x16 = 64 seconds
    text_screen(messages[0], 0, 0);


    for (int i = 0; i<16; i++){ 
      if (pushbutton == 1){   // Pressing pushbutton stops initial heating and enters in measuring mode.
        break;
      }

      lcd.setCursor(i, 1);
      lcd.write(62);
      delay(1000);
    }
  }


  lcd.clear();
  text_screen(messages[2], 0, 0);
  delay(1000);


  float sensor_value_AnalogIn = 7; // Analog output to a multimeter or datalogger (1V = 1000 ppm).

  for (int i=0; i<5; i++)
  {
   x0[i]= analogRead(analogPin);
   
    delay(2000);

  }
  x_initial = (x0[0]+x0[1]+x0[2]+x0[3]+x0[4])/5.0; // Autozero. Average of 5 initial measures.

  lcd.clear();
  text_screen(messages[3], 0, 0);
  delay(2000);

 
}

void loop()  {
  x = analogRead(analogPin);
  Serial.println(x);
  x = (x-x_initial)*3.3; // Calculate real voltage.
  float sensor_value_AnalogIn = x/1000; 

  if(x<0)
    x = 0;

  x = concentration(x);
 

  delayMicroseconds(100);

  //Float to string conversion.

char buffer[10];     

  dtostrf(x, 10, 3, buffer);

lcd.clear();

  for (int i=0; i<strlen(buffer); i+=1)
  {
    lcd.setCursor(i,0);
    lcd.write(buffer[i]);

  }
   
text_screen(messages[4], 10, 0);

}
 
  delay(2000);
 
}


B@tto

Bin un LCD affiche des caractères et cela permet de limiter les chiffres après la virgule
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

turw

Merci pour l'information, dans ce cas le chiffre ( le caractère ) affiché est de l'ordre de 10^6 voir plus ce qui n'a aucune signification.
Faut-il augment la résistance du capteur ou divisé le chiffre par 1000 par exemple ?????
Merci

B@tto

Oula que c'est flou ... Va falloir être plus exhaustif parce que c'est dur de comprendre, toi tu es dans ton projet, nous on a aucune idée de quoi il s'agit ;)
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

turw

Ok,

donc je reçoi une réponse du capteur mq3 mais c'est un nombre à 6 chiffre et des fois plus. je veut limiter la réponse du capteur à par exemple 4 chiffres.

B@tto

4 chiffres en tout ou après la virgule ?
Blog électronique : battomicro.wordpress.com
Photographie : www.interactive-celebration.fr
Fablab de Montpellier : www.labsud.org

turw

salut,

je voudrais avoir 5 chiffres en tout dont deux après la virgule : XXX,XX
Et comment stabiliser les chiffres qui s'affichent : en connectant un multimètre je reçois une tension stable exemple 1,5 v mais sur l'afficheur LCD le chiffre n'est jamais stable ???

Merci

XavierMiller

Hello,

Essaie de formater avec une variante de printf (snprintf par exemple).

Et pour avoir une valeur stable, n'affiche pas en permanence la valeur, mais une valeur de temps en temps, voire une moyenne des dernières valeurs.

turw


skywodd

Bonjour,

dtostrf()
Quote
char* dtostrf (double __val,  signed char  __width,  unsigned char __prec, char * __s)

http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga060c998e77fb5fc0d3168b3ce8771d42

__val : la valeur en flottant à convertir
__width : taille totale de ton buffer en comptant le signe - et le point décimal, ici 1 (signe) + 3 + 1 (point) + 2 + 1 (\0 de fin de chaine) = 8
__prec : nombre de chiffre après la virgule, ici 2
__s : le buffer à utiliser

Code: [Select]
char buffer[8];
float val = 13.37;

dtostrf(val, 8, 2, buffer);

// buffer = { '1', '3', '.', '3', '7', '\0', ' ' }


Pour ton problème de stabilité c'est tout simplement l'erreur de bit de poids faible du convertisseur analogique/numérique.
Mesure ton écart si la valeur en sortie de analogRead() varie de +/- 1, tu verras que tes calculs amplifient cette erreur et donnent cette "instabilité".
Solution : faire une moyenne glissante sur N échantillons.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

turw

Ok,

Merci pour le coup de main.

La moyenne glissante me parait une excellente idée, pourrais-je avoir un code de cette moyenne on dire sur 10 mesures ?


skywodd


La moyenne glissante me parait une excellente idée, pourrais-je avoir un code de cette moyenne on dire sur 10 mesures ?

Avec deux croissants ?

Sérieusement ... une moyenne glissante ...
Allez je suis sympa voila l'algorithme :
Code: [Select]
val = 0
Pour i = 0, tant que i < 10, faire i++
    val += lireValeur()
    delay(10)
val /= 10
afficher(val)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

turw

Merci Skywodd.

Tu me dois deux croissants bien chauds.

Merci.

Go Up