Sa me renvoie bien ma variable sous forme d'un string.
Voici ce que je fais pour utilisé cette fonction et l'envoyer dans mon afficheur. (Afficheur I2C de ma boite)
Variables
String L2; // contenue de la ligne 2
Float Temp; Variable de température
String st;
Serial.print("Valeur de Mesure Temperature = ");
Serial.println(Temp); //Temp étant ma variable float.
Ligne = "temp = ";
st = ConvertionFloatToString(Temp);
L2 = Ligne + st; //J'ai retiré le + "C" pour voir mais c'est pareil
Serial.print("Valeur de L2 = ");//Voila, parfois cela bloque ici, je n'arrive pas a voir le serial print.
Serial.println(L2);
LCD.Write_Line(L2,2);
Serial.println("debug affichage 3");
Cela ne plante pas tout le temps, Seule la 1ere fois cela passe bien, mais la seconde fois cela plante. à la ligne L2. Plantage complet arrêt de l'arduino car du coup mon afficheur ne reçois rien et s'il n'a rien pendant quelque milliseconde il plante lui aussi.
J'utilise ceci pour envoyer des float à mon afficheur.
char inputbuffer[6] = { '\0' }; // variable temperature
char outputbuffer[20] = { '\0' }; // variable string (de taille suffisante pour acceuillir la phrase + 1 pour le caractère de fin de ligne.)
dtostrf(temperature1,5,2,inputbuffer); // conversion float en string.
snprintf(outputbuffer,20, "Temperature= %s C", inputbuffer); // on formate le texte dans le buffer de sortie
glcd.writeBitmapText(outputbuffer, 10, 100, LUCIDA_FONT); // on affiche.
J'ai rencontré les mêmes difficultés que toi j'ai tourné en rond pendant des jours : plantages intempestifs lorsque je concaténais des chaines de caractères.
J'ai trouvé ceci qui semble résoudre pour le moment mon problème :
Dans mon cas j'initialise ma chaine avec qq chose par exemple String str=" "; avant de concaténer c'est bizare mais depuis plus de plantages et cela fait au moins trois jours.... avant je faisais String str="";
Pour convertir un float en string j'utilise cette fonction trouvé sur le forum cela fonctionne parfaitement dans mon cas :
String ftoa(float number, uint8_t precision, uint8_t size) {
// Based on mem, 16.07.2008
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num = 1207226548/6#6
// prints val with number of decimal places determine by precision
// precision is a number from 0 to 6 indicating the desired decimial places
// example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)
// Added rounding, size and overflow #
// ftoa(343.1453, 2, 10) -> " 343.15"
// ftoa(343.1453, 4, 7) -> "# "
// avenue33, April 10th, 2010
String s = "";
// Negative
if (number < 0.0) {
s = "-";
number = -number;
}
double rounding = 0.5;
for (uint8_t i = 0; i < precision; ++i) rounding /= 10.0;
number += rounding;
s += String(uint16_t(number)); // prints the integer part
if(precision > 0) {
s += "."; // prints the decimal point
uint32_t frac;
uint32_t mult = 1;
uint8_t padding = precision -1;
while(precision--) mult *= 10;
frac = (number - uint16_t(number)) * mult;
uint32_t frac1 = frac;
while(frac1 /= 10) padding--;
while(padding--) s += "0";
s += String(frac,DEC) ; // prints the fractional part
}
if (size>0) // checks size
if (s.length()>size) return("#");
else while(s.length()<size) s = " "+s;
return s;
}
Je pense qu'il va falloir que je m'habitue à utiliser les Char*. Je l'ai fait pendant m'a formation BTS IRIS, mais depuis que je suis au boulot, ils utilisent encore VB6, j'ai réussi a imposé VB.net au moi j'ai aussi le C#, mais j'ai perdu l'habitude.
Le code complet commence à être imposant, pour l’éclaircir, ce qui marchais bien j'ai crée une autre classe qui gère l'affichage.
merci pour l'info pour l'initialisation, moi aussi j'ai essayé avec "" et non " ". Je vais essayer demain, mais la avec 40 de fièvre c'est pas top pour réfléchir.
merci pour le code. je n'est pas besoin de chercher les negatif car la c'est pour un aquarium récifal donc je doit être toujours a 25 et avec des borne mini maxi de 22 a 28°C .
D'ailleurs pour le moment j'utilise un LM35 que j'envoie directement sur l'entrée analogique. La tension mesurer du LM est bonne mais l'ardinio oscille un peut trop à mon gout. Surtout que je vais me servir de la mesure pour commander des ventilateurs, alarme, et Calibrage de la sonde PH
Merci
PS: J'ai essayé de mettre mon code complet mais cela fait trop de caractère donc je vais voir sa demain pour le découper
Voici en attendant la méthode Loop ou il y a mon souci. je vais le sortir du loop après:
void loop()
{
int top;
unsigned char dt[16];
unsigned char Button;
boolean ScanOsci = true;
String Ligne;
String st;
if (millis() >= ancien_millis) { // Vérifie que le temps millis() est bien supérieur à l'ancienne valeur mémorisée
// >> risque à l'init et au retour à zéro de l'horloge interne.
if (millis() - ancien_millis >= 100){ top = 1; // création d'un top toutes les 100ms
ancien_millis = millis(); // réinitialisation ancien_millis
compteur_top = compteur_top + 1; // Incrémente le compteur de tops
compteur_Heure = compteur_Heure +1;
compteur_I2C = compteur_I2C + 1;
compteur_InCom = compteur_InCom + 1;
compteur_Temperature = compteur_Temperature + 1;
compteur_DigitEntree += 1;
compteur_Nourissage += 1;
compteur_PH1 += 1;
for (int i = 0 ; i<= 3 ; i ++)
{
compteur_Osci[i] += 1;
compteur_PauseOsci[i] += 1;
}
}
}
//Recherche de l'heure DS1307
if (compteur_Heure * 10 >= 1000){ //en milliseconde
DateHeure();
compteur_Heure = 0;
}
//Oscilateur
GestionOscilateur();
//Verification des entrées;
if(compteur_DigitEntree >= 5){
DetectEntree();
compteur_DigitEntree = 0;
}
//Temperature
if (compteur_Temperature >= 10)
{
Temperature();
compteur_Temperature = 0;
}
//Gestion de l'I2C Vitesse
if (compteur_I2C >= 3){
//Affichage de la 1ere ligne
LCD.Write_Line("Aquarius 37",1);
//Affichage de la 2eme lignes
LCD.Write_Line(L2,2);
// Serial.println("debug affichage 1");
switch (affichageBas){
case 0:
L2 = " ";
L2 = AffichageHeure();
affichageBas ++;
LCD.Write_Line(L2,2);
Serial.println("debug affichage 2");
break;
case 10:
L2 = " ";
Serial.print("Valeur de Mesure Temperature = ");
Serial.println(Temp);
Ligne = "temp = ";
st = ConvertionFloatToString(Temp);
L2 = Ligne + st;
Serial.print("Valeur de L2 = ");
Serial.println(L2);
LCD.Write_Line(L2,2);
Serial.println("debug affichage 3");
affichageBas ++;
break;
case 20:
L2 = " ";
Serial.print("Valeur de Mesure PH1 = ");
Serial.println(MesurePH1);
st = ConvertionFloatToString(MesurePH1);
Serial.print("Valeur de ST = ");
Serial.println(st);
Ligne = "PH Rac = ";
L2 = Ligne + st;
Serial.print("Valeur de L2 = ");
Serial.println(L2);
LCD.Write_Line(L2,2);
Serial.println("debug affichage 5");
Serial.println(MesurePH1);
affichageBas ++;
break;
case 30:
affichageBas = 0;
Serial.println("debug affichage 5");
break;
default:
affichageBas ++;
}
/*Serial.print("Nonbre de tour = ");
Serial.println(affichageBas);*/
if(affichageBas >= 30)affichageBas = 0;
//LCD.Write_Line(L2,2);
//String L = AffichageHeure();
//LCD.Write_Line(L,2);
Button = LCD.I2CXD_ReadCommand(LCD_SLAVE_ADRR, I2C_CMD_BUTTON_STATUS_REGISTER ,1);
compteur_I2C = 0;
}
//Compteur Input COM
if (compteur_InCom >= 3){
InputCOM();
compteur_InCom = 0;
}
if (compteur_PH1 >= 10){
MyPH1Mesure();
compteur_PH1 = 0;
}
Il y a une autre méthode, qui fait un peu enfler le binaire je crois, mais qui marche:
// Niveau global
char buffer[50]; // Doit être en mesure de contenir toute la chaine
// Dans le loop
sprintf(buffer, // Là ou va travailler sprintf
"Ma temperature est: %.2f", // en prenant ce template (avec %.2f comme "placeholder" avec 2 digit de précision)
Temp);
Serial.println(buffer);
Ce code n'est probablement pas exempt d'erreur mais dans l'idée, il doit être bon
Zut, j'ai souvent utilise sprintf avec des ints, c'est pratique pour formater rapidement pendant le debugage, mais jamais avec des floats.
Après quelques recherches, il s'avère que le sprintf de l'arduino ne gère pas les floats (problème de place [déjà ajouter sprintf fait salement enfler le binaire :)]).
Source: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1164927646
C'est pour cela que l'on passe par dtostrf pour la conversion, le resultat est un buffer qui sera réutiliser par snprintf. A savoir que snprintf est plus sur que sprintf et attend un caractère de fin d'instruction (0).
char inputbuffer[6] = { '\0' }; // variable temperature (12.55 = 5 char)
char outputbuffer[20] = { '\0' }; // variable string (de taille suffisante pour acceuillir la phrase + 1 pour le caractère de fin de ligne.)
dtostrf(temperature1,5,2,inputbuffer); // conversion float en string.
snprintf(outputbuffer,20, "Temperature= %s C", inputbuffer); // on formate le texte dans le buffer de sortie
glcd.writeBitmapText(outputbuffer, 10, 100, LUCIDA_FONT); // on affiche.
C'est pour cela que l'on passe par dtostrf pour la conversion, le resultat est un buffer qui sera réutiliser par snprintf. A savoir que snprintf est plus sur que sprintf et attend un caractère de fin d'instruction (0).
char outputbuffer[20] = { '\0' }; // variable string (de taille suffisante pour acceuillir la phrase + 1 pour le caractère de fin de ligne.)
dtostrf(temperature1,5,2,inputbuffer); // conversion float en string.
snprintf(outputbuffer,20, "Temperature= %s C", inputbuffer); // on formate le texte dans le buffer de sortie
glcd.writeBitmapText(outputbuffer, 10, 100, LUCIDA_FONT); // on affiche.
@+
Zoroastre.
J'allais l'essayer ce matin, comme je l'ai annoncé je suis pas trop en forme en ce moment, la fièvre est tombée donc cela va aller un peut mieux ce matin, j'essaie sa, merci.
"C" est à considerer comme une seconde variable string à inclure dans ta phrase.
Le buffer doit être augmenter à 22 pour passer.
--> "temperature = 00.00 C" = 21 caractères (espaces compris).
Pour que le string soit valide, il faut considérer le caractère de fin de ligne attendu par snprintf, le buffer doit faire 21+1 = 22
Tu peux mettre le buffer à 25 pour voir large, il occupera l'espace jusqu'au '\0'.