Pages: [1]   Go Down
Author Topic: Calcul de puissance et problème de compréhension .  (Read 1722 times)
0 Members and 1 Guest are viewing this topic.
France - Pays de la Loire
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Bidouilleur du dimanche ... et des autres jours de la semaine ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir à toutes et à tous,

Je démarre avec l'Arduino et aussi avec le C donc, excusez moi par avance pour ces questions sans doute banales.

J'ai quelques petits problèmes avec ce programme:

int Adresse = 64;
int Valeur = 0;
int BrocheLed = 10;

void setup()
{
  Serial.begin(9600);
  pinMode (BrocheLed, OUTPUT); // configure BrocheLed en sortie
  delay(1000); // attente de 1 secondes
  digitalWrite(BrocheLed, LOW);  // Led pour info
}

void loop()
{  // DEBUT DE LA ROUTINE
   for (int i=7; i>-1; i--) // Envoie Adresse du bit 7 au Bit 0
  {
    int Za = pow(2,i);
    Valeur = Adresse & Za;
    Serial.print("Boucle");
    Serial.println(i);
    Serial.print("Adresse ");
    Serial.println(Adresse);    
    Serial.print("2^i ");
    Serial.println(Za);          
    Serial.print("Valeure ");
    Serial.println(Valeur);
    
    if ( Valeur == 0 )
    {
      Serial.println("Sortie=0");
      digitalWrite(BrocheLed, LOW); // Mets sortie à 0
    }
    else
    {
      Serial.println("Sortie=1");
      digitalWrite(BrocheLed, HIGH);// Mets sortie à 1
    } // Endif
    
    delay(3000); // attente de 3 secondes
  Serial.println("");  
  } //Fin de boucle For
Serial.println("--------------");
  
} // Fin de void

Premier problème : Pourquoi l'instruction "pow(2,i);" me donne 127 pour i=7 ? Je ne devrai pas avoir 128 ? ( le problème est le même avec les autres puissances ...)

Autre problème : Quand je déclare les variables en "byte", l'instruction "Serial.println(Variable)" m'envoie le code Ascii et quand je déclare les variables en "int" , l'instruction "Serial.println(Variable)" me renvoie bien la valeur en chiffre.
Qui peux m'expliquer la raison ?
Puis je utiliser malgré tout la variable byte pour faire des calculs ?

Merci d'avance pour votre aide. smiley
A+
Logged

France - Pays de la Loire
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Bidouilleur du dimanche ... et des autres jours de la semaine ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour à tous,

Bon, pour l'histoire de la fonction POW(), a priori, elle n'est pas capable de faire des calculs simples avec des entiers ( byte ) : y a des arrondis qui sont fait et la partie entière est amputé" d'un chouilla ce qui fait que c'est pas bon.
Si quelqu'un à une solution pour éviter de faire une boucle pour élever à la puissance, je suis preneur ...

Pour le problème de l'affichage du code ascii, j'ai trouvé aussi : il suffit de préciser dans serial.print(variable,DEC);
... j'vous l'avais dit, je débutte  smiley-wink mais j'avance .

A+
Logged

France - Morbihan
Offline Offline
Newbie
*
Karma: 0
Posts: 42
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

un lien utile pour la fonction print():
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Serialprint

Sinon, pour élever 2 à la puissance voulue, tu dois pouvoir utiliser l'instruction bit() qui bien que prévue pour çà le fait bel et bien :
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.Bit

A+

Logged

France - Pays de la Loire
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Bidouilleur du dimanche ... et des autres jours de la semaine ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Rebonjour,

Super ta réponse : ca fonctionne !!!
J'ai passé plus de 3 heures ce matin à trouver une solution et le coté positif, c'est que j'ai découvert beaucoup de chose dont cette page : http://www.arduino.cc/playground/Code/BitMath
J'ai pas encore tout compris mais ça semble prometteur pour mes applications ...

A partir de tes indications, maintenant, au lieu de faire un AND , je teste directement la valeur du bit de la variable  avec bitread().

Pour en revenir à la fonction pow() elle semble vraiment pourrie avec des entiers ...

Encore merci et bon week end à tous , à moins que je ne sèche sur autre chose ... smiley-wink
Logged

France - Morbihan
Offline Offline
Newbie
*
Karma: 0
Posts: 42
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

suite à ton mail, j'ai fait un petit test de la fonction pow qui rappelons-le doit être utilisée avec des float ! Donc, avant de l'utilisée, tu dois être sûr que tes variables sont des float.

La conversion d'un entier en float se fait avec la fonction float() :
http://www.mon-club-elec.fr/pmwiki_reference_arduino/pmwiki.php?n=Main.ConversionFloat

Voici le code que j'ai testé :

// --- Déclaration des variables globales ---
float xf=2.0, yf=7.0;

//**************** FONCTION SETUP = Code d'initialisation *****
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { // debut de la fonction setup()


Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission



} // fin de la fonction setup()
// ********************************************************************************


//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

xf=pow(xf,yf); // 2.0 élevé à la puissance 7.0
Serial.print(xf);

delay(1000); // entre 2 affichages


} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// ********************************************************************************

Le résultat = 128.0... donc la fonction pow() fonctionne très bien !!

Il ne faut pas oublier qu'Arduino repose pour les maths sur la librairie avr-libc math.h qui est à priori fiable... donc si çà foire, il vaut mieux se remettre en cause avant de crier au loup...  smiley-wink

A+
Logged

France - Morbihan
Offline Offline
Newbie
*
Karma: 0
Posts: 42
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

pour compléter mon post précédent, la façon la plus élégante de résoudre le problème de l'utilisation des valeurs entières avec la fonction pow(x,y) est de faire la conversion float() directement dans la fonction pow selon :

void setup()   { // debut de la fonction setup()

// --- ici instructions à exécuter au démarrage ---

Serial.begin(115200); // initialise connexion série à 115200 bauds
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission

} // fin de la fonction setup()
// ********************************************************************************


//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()


float xf=2.0, yf=7.0;
int x=2.0, y=7;

xf=pow(xf,yf); // 2 élevé à la puissance 7
Serial.print(xf);

xf=pow(float(x),float(y)); // 2 élevé à la puissance 7
Serial.println(xf);

delay(1000); // entre 2 affichages


} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin

Dans les 2 cas, on obtient 128.00, donc çà fonctionne parfaitement bien.

A+


Logged

France - Pays de la Loire
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Bidouilleur du dimanche ... et des autres jours de la semaine ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

Merci pour cette solution.
Elle requière l'utilisation de variable float ce qui est quand même luxueux pour faire un calcul de puissance... qui ne dépasse pas 255  ;D

J'ai trouvé un site ou ils parlent de ce problème et utilisent des doubles mais ça ne marche pas : http://www.pervasive-network.org/post/2009/11/27/%5Barduino%5D-Hands-on-Arduino-duemilanove-Ethernet-shield.

Je note quand même ta solution au cas où j'aurai besoin de calcul de puissance.
Dans mon cas présent, comme il s'agissait de tester les 8 bit d'un octet, la solution du bit.read est vraiment très simple :

void loop()
{  // DEBUT DE LA ROUTINE
   for (int i=7; i>-1; i--) // Envoie Adresse du bit 7 au Bit 0
  {
    Valeur = bitRead(Adresse,i);
 
    if ( Valeur == 0 )
    {
      digitalWrite(BrocheLed, LOW); // Mets sortie à 0
    }
    else
    {
      digitalWrite(BrocheLed, HIGH);// Mets sortie à 1
    } // Endif
    
    delay(3000); // attente de 3 secondes
  Serial.println("");  
  } //Fin de boucle For
} // Fin de void

Merci encore et Bonne soirée
Logged

France - Morbihan
Offline Offline
Newbie
*
Karma: 0
Posts: 42
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Salut,

pour une puissance de 2, ton code est effectivement le plus simple.

Concernant la place en mémoire de la fonction pow(x,y) on arrive 3700 octets... et il en reste donc encore près de 27 000 de libres sur une Duemilanove...

Ce qui est bien avec Arduino, c'est la souplesse du langage qui permet de s'adapter au mieux aux différentes situations, du plus simple au plus complexe. Le cas présent en est une belle illustration...

A+

Logged

France
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3636
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Il ne faut pas oublier les opérations sur les bits qui font partie du langage.
Pour rappel en C il y a les opérateurs << et >> qui font respectivement des décalages à gauche et à droite et qui travaillent sur des entiers (char int ...).

1<<0 = 1
1<<1 = 2
1<<2 = 4
1<<3 = 8
 ......

8>>1 = 4
8>>2 = 2
8>>3 = 1

Avec des décalages on peut facilement déplacer des bits pour faire des masques ou positionner des états (en combinaison avec des | et des &.

Et en plus cette opération est codé très efficacement. Elle est donc c'est rapide. A utiliser à chaque fois que l'on doit multiplier ou diviser un nombre entier par une puissance de deux.
« Last Edit: March 01, 2010, 08:02:42 am by fdufnews » Logged

France - Pays de la Loire
Offline Offline
Full Member
***
Karma: 0
Posts: 176
Bidouilleur du dimanche ... et des autres jours de la semaine ...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour,

En tant que débutant "patenté", je ne connais pas encore ces notations avec les >> et <<.

En ce moment, j' éssais d'acquérir les bases ( pas simple de se mettre dans le bain vu mon grand age ).

L'exercice du moment : faire fonctionner un PCF 8574 sans utiliser de librairie ( je sais pas encore comment faut faire mais j'vais trouver  smiley-wink ).
J'arrive à éteindre et allumer des LEDS !!! ( balaise, non ? )
2ème étape : lire l'état des interrupteurs toujours sur le  PCF 8574.

Par contre, je rencontre un problème que j'avais déjà avec mes précédents bricolages sur le bus I2C : pas de Ack de l'esclave !!!
Comme j'ai pas envie de me casser la tête, dans l'immédiat, je ne le lit pas : un coup de SCL=1 et le tour est joué, je passe à la suite.
J'espère seulement que la librairie du I2C le gère mais ça,se sera pour plus tard.

A+ et encore merci pour votre aide.
Logged

France
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3636
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
pas de Ack de l'esclave !!!
Ce ne serait pas un problème de conflit sur la ligne data. Tu la repasses en entrée assez rapidement?
Logged

Pages: [1]   Go Up
Jump to: