Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

garder 1 chiffre apres la virgule
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#1 Message par dyli » jeu. 23 févr. 2017 08:52

Bonjour tout le monde,

J'apprends la programmation de pics, voici mes 2 question2: est ce qu'il y a une fonction specifique dans c pour arrondir les chiffres? je utilise
un capteur de temperature LM35 et pic16f877. Le but est de mesurer la température negative aussi et ne garder qu'un chiffre après la virgule. J'ai vu en faisant des recherches la fonction math roud que j'ai pas trouvé dans Mikro c.
La 2 eme question est: que fait ce 39 dans cette ligne Lcd_Chr(2,9,39);

Code : Tout sélectionner

// 21.02.2017  thermometre a PIC16F877A
// LCD module connections

sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB2_bit;
sbit LCD_D5 at RB3_bit;
sbit LCD_D6 at RB4_bit;
sbit LCD_D7 at RB5_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections


unsigned int adc_rd;   //   Declare variables
char temp[15];           //    Declare variables
long tension1;          //     Declare variables
long tension2;          //     Declare variables
long difference;
long  valeur_final;

void main() {
 
INTCON 0;      // All interrupts disabled
 
ADCON1  0X82// Configure AN0 et AN1 as input adc
 
CMCON 0X7;   // Disable comparators
TRISA 0xFF;     //   PORTA configuré en entrée

 
Lcd_Init(); // LCD display initialization
 
Lcd_Cmd(_LCD_CURSOR_OFF); // LCD command (cursor off)
 
Lcd_Cmd(_LCD_CLEAR); // LCD command (clear LCD)



 
Delay_ms(500);


 while (
1) {
   
adc_rd ADC_Read(0); //lire entrée RA0

   
tension1 =  ADC_Read(0);
   
adc_rd ADC_Read(1);   //lire entrée RA1
   
tension2  =  ADC_Read(1);
   
difference = (tension1-tension2);
   
valeur_final =(difference.488);
   
floattostr (valeur_final,temp);
     
Lcd_Chr(2,9,39);
 
Lcd_out(2,5,temp);
 
Delay_ms(200);
 }

garder 1 chiffre apres la virgule
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#2 Message par Jérémy » jeu. 23 févr. 2017 13:25

Bonjour dyli,

 ! Message de modération :
merci de lire cette page : Utilisation du Forum, et plus partoculierment ce post sur comment bien poster son code .


est ce qu'il y a une fonction specifique dans c pour arrondir les chiffres?

pas à ma connaissance ! mais je suis pas un expert !

Pourquoi vouloir arrondir ? pour l'affiché sur un LCD ?

J'ai vu en faisant des recherches la fonction math roud que j'ai pas trouvé dans Mikro c.

peux-tu montrer le lien ?

que fait ce 39 dans cette ligne Lcd_Chr(2,9,39);


Tu utilises la librairie LCD , et la fonction Lcd_Chr, qui affiche, comme son nom l'indique un caractère , et justement ce caractère c'est le N°39 de la table ASCII qui correspond ou l'apostrophe '. Il l’affiche à la position ligne 2 colonne 9 .

A+
C'est en faisant des erreurs, que l'on apprend le mieux !!!

garder 1 chiffre apres la virgule
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#3 Message par dyli » jeu. 23 févr. 2017 16:04

salut Jérémy,

Désolé pour le désagrément, la fois prochaine je vais mettre mon code entre les balises.

Oui, c'est pour afficher la temperature sur un lcd ( aussi bien la température négative que positive) dans ce style : 25.5 ou - 3.5 mais pas 25.457372.

Le langage qui utilise le fontion math round est le php, mais tu as raison en C, ca n'existe pas, alors comment faire?

merci encore

garder 1 chiffre apres la virgule
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#4 Message par Jérémy » jeu. 23 févr. 2017 17:12

la fois prochaine je vais mettre mon code entre les balises.

Je viens de le faire , mais normalement tu pouvais éditer ton post ! :langue:

Il y a plusieurs solutions suivant ton applciation finale, et ton niveau !

La plus simple à mon avis reste le sprintf sous mikroC ! Cette fonction va tout simplement formaté ton texte.

Code : Tout sélectionner

sprintf(buffer,"%.1f C",valeur_lue) ; // Avec sprintf on convertit notre nombre décimal en string.
  
Lcd_Out (1,1buffer ) ;              // Affichage sur la deuxième ligne du LCD
  
delay_ms(100);            // pause entre deux lectures 


Un autre méthode consisterais a tout mettre en entier et à rajouter un point en guise de virgule au bon endroit .

Tu aurais donc 256 par exemple, et tu viens rajouter un point au milieu genre 25.6 !

Ton programme est assez bizarre, je trouve !

Code : Tout sélectionner


   adc_rd 
ADC_Read(1);   //lire entrée RA1
   
tension2  =  ADC_Read(1); 


Pourquoi ne pas écrire tout simplement

Code : Tout sélectionner

   tension2  =  ADC_Read(1); 


Tu travaille avec des float, dur dur pour un PIC.

est ce le programme complet ? as tu un schéma !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

garder 1 chiffre apres la virgule
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » jeu. 23 févr. 2017 17:52

bonsoir Dily,


effectivement floatToStr de mikroC ne ger epas le nb de decimales affichées
tu peux utiliser à la place la procedure suivante, dans laquelle, le 3em parametre defini le nb de decimales sur le resultat string (texte)

Code : Tout sélectionner





float f1
;
char TEXTE[21] ;   // si LCD de 20 caract ou    17 si LCD de 16 cars
char *txt;

void fltToa (double xunsigned char *str,char precision)
{
 
/* converts a floating point number to an ascii string */
 /* x is stored into str, which should be at least 30 chars long */
 
int ieikndig;
 
double y;
 
ndig = ( precision<=0) ? : (precision 22 23 precision+1);
 
ie 0;
 
/* if x negative, write minus and reverse */
 
if ( 0)
 {
  *
str++ = '-';
  
= -x;
 }
 
/* put x in range 1 <= x < 10 */
 
if (0.0) while (1.0)
 {
  
*= 10.0;                // a la place de =*
  
ie--;
 }
 while (
>= 10.0)
 {
   
x/10.0;
   
ie++;
 }
 
ndig += ie;                                // a la place de =+
 //round. x is between 1 and 10 and ndig will be printed to
 // right of decimal point so rounding is ...
 
for (1ndigi++)  y/10.;
 
+= y/2.;
 if (
>= 10.0) {1.0ie++;}
 if (
ie<0)
 {
   *
str++ = '0'; *str++ = '.';
   if (
ndig 0ie ie-ndig;
   for (
= -1iei--)  *str++ = '0';
 }
 for (
i=0ndigi++)
 {
   
x;
   *
str++ = '0';
   if (
==  ie ) *str++ = '.';
   
-= (y=k);
   
*= 10.0;
 }
*
str '\0';
}


// exemple d'usage


  
UART1_Init(9600);
  
UART1_Write(CLS);
  
Delay_ms(500);
  
CRLF1();
 
  
txt=&TEXTE[0];   // init du pointeur txt sur deburt table TEXTE
  
f1=-2.3758;
  
fltToa (f1,txt,1);   //   conversion flotant en texte avec precision 1 decimale
  
UART1_Write_Text(txt); CRLF1();
   
   
f1=-0.768;
    
fltToa (f1,txt,1);
    
UART1_Write_Text(txt); CRLF1();
   
  
f1=1.2987666;
  
fltToa (f1,txt,1);
  
UART1_Write_Text(txt); CRLF1();
   
  
f1=125.987652;
  
fltToa (f1,txt,1);
  
UART1_Write_Text(txt);   CRLF1();
  
 for (
i=1;i<6;i++)
  {
   
f1=1.297654321;
  
fltToa (f1,txt,i);  // nb de decimale variable
  
UART1_Write_Text(txt); CRLF1();
  }
    
    while(
1);
 }
  


ce qui donne sur l'ecran

-2.4 avec 1 seule decimale
-0.8
1.3
126.0

1.3 avec 1 à 5 decimales
1.30
1.298
1.2977
1.29765


l'exemple est pour un ecran
pour un LCD
en supposant que tu veuilles le resultat en ligne 1 , position 8 sur le LCD

Code : Tout sélectionner

 f1=1.2987666;   // f1 represente le resultat de ta mise à l'echelle de la mesure analogique
  fltToa (f1,txt,1);
  // pour faire propre
 LCD_Out(1,8,"        "); // pour effacer les residus de texte precedent , 8 blancs si LCD de 16 cars
 LCD_Out(1,8,txt):
 


apres on peut compliquer un peu , en cadrant le resultat à droite... mais ce sera pour une procahaine etape
Aide toi, le ciel ou FantasPic t'aidera

garder 1 chiffre apres la virgule
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#6 Message par dyli » jeu. 23 févr. 2017 22:34

[img]Bonsoir Jérémy et paulfjujo,
Merci de vos réponses, ca m'aide beaucoup... pour répondre a la question de Jérémy, cela fait un mois que j'apprend a la maison le langage C adapté au pics.
Je me renseigne sur internet et forum, le but est d'apprendre, j'aime bricoler. Je suis technicien en électronique.Autre fois je utilisais l'assembleur pour programmer.

Jérémy tu me demande si le code est complet, oui, c'est ce que j'ai trouvé en cherchant sur le net et ca marche un peu bizarrement, c'est dire la temperature qui s'affiche correspnd a la temperature sur le lm35, mais quand la temperature est négative est quand j'augmente la temperature pour passer en dessus du zero, soudain , lcd affiche 11 ou 12 ou 15 et plus je monte plus ca redevient précis. ci-joint le schema.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.

garder 1 chiffre apres la virgule
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#7 Message par paulfjujo » ven. 24 févr. 2017 16:00

bonjour Dyli,


Questions :
ton LM35 , c'est bien un capteur 0 à 100°C => 0mv à 1000mV ?
et le role des 2 diodes ? pour permettre une mesure de temperature negative ?

nota : le LM335 va de -40 à +100 et donne 2730mV à 0°C

Tu peux peut etre afficher les 3 valeurs
EA0 , EA1 et ecart sur le LCD
pour mieux voir ce qui se passe ..

nota :
le "sprintf" est bien sur le moyen le plus élégant et facile pour formater un resultat flottant,
mais neamoin, avec un 16F , il faudra faire attention à la taille memoire ROM occupée
avec un programme plus conséquent
car "sprintf" necessite beaucouo de ressources MCU.

remarque
valeur_finale doit etre un flottant.
pourquoi utiliser des long pour tension1 et tension 2
un int est largement suffisament dimensionné


Code : Tout sélectionner


   tension1 
=  ADC_Read(0);    //lire entrée RA0
    
tension2  =  ADC_Read(1);    //lire entrée RA1
   
difference tension1 tension2 ;
   
valeur_final =(float) difference  *  0.488;   //pour etre un peu plus puriste
   
fltToa (valeur_final,temp,1);   // 1 si une seule decimale
 


===========================
2em cas

Code : Tout sélectionner

  
/*
on pourrait eviter l'usage de flottant en utilisant 
une valeur approximative de la valeur flottante 0.488
multipliée par 10 pour avoir des 1/10em de degres
 39/8=4.875    tres proche 4.88 pour exprimer en 1/10 de degres
*/
 
difference = (difference 39)>>3       ;   3 decalage à droite pour diviser par 8  
 
// il faut ensuite positionner le point (ou la virgule separatrice)
  
IntToStr(difference,temp);  // convertion de l'entier signé en ascii
  
k=strlen(temp);
  *(
temp+k+1)=0;   // on met la fin du string , un caractere plus loin  , car il faut TOUJOURS un zero en fin de string
  
*(temp)+k=*(temp);// on met le dernier caratere utile à sa place
   
*(temp)=','  ;  // on a ainsi crée un espace libre pour y mettre le separateur virgule ou point .
   
Lcd_out(2,5,temp);  // et on affiche le tout au 1/10em de degr

 


nota: voir la difference de ROM utilisée SANS floattant ..

nota2 : il y a quand meme une limitation dans le 2em cas ..
à toi de le decouvrir exit
Aide toi, le ciel ou FantasPic t'aidera

garder 1 chiffre apres la virgule
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1644
Âge : 65
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#8 Message par Gérard » ven. 24 févr. 2017 18:21

Bonjour,
Je suis de l'avis de Paul, le LM335 sait mesurer des températures sous 0°C et vu la précision, ce n'est pas la peine d'afficher quelque chose derrière la virgule.
Si tu connais le bus I2C, il existe le LM75, en utilisant uniquement l'octet de poids fort, tu auras la mesure au degré (sans virgule).
Le 18/04/19 je suis devenu papy de jumeaux, le 01/09/23 une petite cousine des jumeaux est née.

garder 1 chiffre apres la virgule
dyli
Débutant
Débutant
Messages : 33
Enregistré en : février 2017

#9 Message par dyli » ven. 24 févr. 2017 18:48

Bonsoir paulfjujo et Gérard

Pour repondre aux questions de paulfjujo,

1- le capteur C'est Lm 35 NATDCA , ca va de -55 a 150c. C'est le modele de simulation sous Proteus.
2- A -55C , on aura -550mV et a + 150 C on aura 1500mV la la sortie du capteur.
3- Effectivement les 2 diodes sont mises pour pouvoir mesurer les températures négatives.

Juste encore cette instruction de fltToa , je ne l'ai pas trouvé dans l'aide de Mikro C et un message indique que c'est undeclared idetifier.

paulfjujo, je vais utiliser le 2eme cas de ton programme et sprintf 8-)

un Grand merci

garder 1 chiffre apres la virgule
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2597
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#10 Message par paulfjujo » ven. 24 févr. 2017 20:19

je vais utiliser le 2eme cas de ton programme et sprintf


le 2em cas n'utilise pas sprintf , ni de flottant.
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 26 invités