Go Down

Topic: Atan2 sur D1Mini [RESOLU] (Read 574 times) previous topic - next topic

enzweb

May 23, 2020, 11:43 pm Last Edit: May 25, 2020, 09:42 pm by enzweb
Bonjour,

Je lutte pour intégrer atan2 et autres fonctions trigonométriques dans un D1mini, en effet je suis conscient que quelques une des fonctions de math.h ont été volontairement laissées de cotè afin de préserver de la mémoire, mais aujourd'hui j'en ai besoin pour faire fonctionner une girouette avec un GY271.
Mon code est parfait sur UNO mais pas fonctionnel sur le D1.
Je ne parviens pas a trouver la parade, quelqu'un peut il m'aiguiller.

Merci.

lesept

Si tu as arctan (atan en C), il te suffit de calculer comme ceci (wikipedia)

A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

MicroQuettas

Bonjour,

Chez moi la lutte a été de courte durée... car cela fonctionne parfaitement !

Vous parlez bien d'un Wemos D1 mini, carte à ESP8266 comme il en existe beaucoup ?
Qu'est ce qui vous fait dire que la bibliothèque "math" ne serait  pas complète ?
Qu'est ce que vous utilisez comme IDE et comme gestionnaire de carte ?

A plus et bonne bidouille,

MicroQuettas

enzweb

Bonjour,

oui c'est bien cela, un générique mais cela reviens a peu prés au même.
J'utilise l'IDE 1.8.12 Arduino, et Wemos D1 R1 comme gestionnaire.

Ce qui me fait dire qu'il me manque des fonctions trigo, c'est que je n'arrive pas a faire fonctionner des sketchs simplistes faisant appel a atan2. Puis après avoir pas mal chercher je suis parfois tomber sur des forums indiquant que certaines fonctions de la librairie "math.h" n'étaient pas activée.

Voila.

68tjs

#4
May 24, 2020, 01:52 pm Last Edit: May 24, 2020, 01:55 pm by 68tjs
Et si tu mettais ton code (entre balises code) tu ne crois pas que ce serait plus facile de répondre plutôt que de faire des suppositions ?



Voir "Règles du forum francophone " épinglé en tête de forum.

enzweb

Oui,

tu as raison.
Par exemple ce code sur Uno, me renvoi les bons éléments, et sur D1mini des références erronées, j'utilise ce code sans me préoccuper des prérogatives du wifi pour le moment...

Voici:

Code: [Select]

#include <Wire.h>                       //I2C Arduino Librarie

#define addr 0x0D                       //I2C Adresse pour HMC5883

void setup()
{
  Serial.begin(9600);
  Wire.begin();
  Wire.beginTransmission(addr);         // Début
  Wire.write(0x0B);                     // Apelle HMC5883 en Mesure continue
  Wire.write(0x01);                     // Reset des registres
  Wire.endTransmission();
  Wire.beginTransmission(addr);         // Début de Lecture
  Wire.write(0x09);                     // Apelle configuration Reg HMC5883
  Wire.write(0b00010001);               // 7,6 OSR, 5,4 RNG, 3,2 ODR, 1,0 MODE
  Wire.endTransmission();               //   512       8G      10Hz   Continue
}

void loop()

{
  int x, y, z;                          // Trois axes
  Wire.beginTransmission(addr);
  Wire.write(0x00);                     // Début
  Wire.endTransmission();
  Wire.requestFrom(addr, 6);            // Lire 6 octects, deux par axe
  if (Wire.available() <=6)
  {
    x =  Wire.read() | Wire.read() << 8; // Lecture des valeurs X, Y, Z
    z =  Wire.read() | Wire.read() << 8;
    y =  Wire.read() | Wire.read() << 8;
  }

  // Test encore
  float heading=atan2(z, x)/0.0174532925;
  if(heading < 0) heading+=360;
  heading=360-heading; // N=0/360, E=90, S=180, W=270
  Serial.print(", Direction: ");
  Serial.print(heading);
  delay(500);

  {
   
  int Dir;

  Dir = int(heading);

  if ((Dir >=348)or (Dir <= 12))   Serial.print ("  Nord  ");
  if ((Dir >=11) and (Dir <= 34))  Serial.print ("  Nord-Nord-Est  "); 
  if ((Dir >=33) and (Dir <= 57))  Serial.print ("  Nord-Est  ");
  if ((Dir >=56) and (Dir <= 79))  Serial.print ("  Est-Nord-Est  "); 
  if ((Dir >=78) and (Dir <= 102)) Serial.print ("  Est  ");
  if ((Dir >=101)and (Dir <= 124)) Serial.print ("  Est-Sud-Est  "); 
  if ((Dir >=123)and (Dir <= 147)) Serial.print ("  Sud-Est  ");
  if ((Dir >=146)and (Dir <= 169)) Serial.print ("  Sud-Sud-Est  "); 
  if ((Dir >=168)and (Dir <= 192)) Serial.print ("  Sud  ");
  if ((Dir >=191)and (Dir <= 214)) Serial.print ("  Sud-Sud-Ouest  ");
  if ((Dir >=213)and (Dir <= 237)) Serial.print ("  Sud-Ouest  ");
  if ((Dir >=236)and (Dir <= 259)) Serial.print ("  Ouest-Sud-Ouest  "); 
  if ((Dir >=258)and (Dir <= 282)) Serial.print ("  Ouest  ");
  if ((Dir >=281)and (Dir <= 304)) Serial.print ("  Ouest-Nord-Ouest  ");
  if ((Dir >=303)and (Dir <= 327)) Serial.print ("  Nord-Ouest  ");
  if ((Dir >=326)and (Dir <= 349)) Serial.print ("  Nord-Nord-Ouest  ");

  }
 
  Serial.println();
 
  delay(3000);                            // Mesure possible 10 par seconds
}



Ce sketch me donne bien une direction de 0 a 360° ainsi que le littéral, or le même sur le d1 mini est très aléatoire et me donne un angle variant entre 270 et 360°.

voila.

68tjs

Quote
or le même sur le d1 mini est très aléatoire
Les fonctions Wiring/Arduino ne sont pas universelles ad vitam æternam, elles sont datées de l'époque où il n'existait qu'une seule interface I2C sur le microcontroleur disponible à l'époque où elles ont été écrites.

Maintenant il y a plusieurs interfaces UART, SPI, I2C  dans les micros, où autre possibilité il est possible de les rediriger sur différents groupes de pins. Conséquence avec les circuits Espressif il faut indiquer quelles pins sont  utilisées.

La meilleur source d'information est de rechercher des exemples pour les circuit ESP.
Sur D1 mini Scl doit être en D1 et SDA en D2
Par exemple ici : https://projetsdiy.fr/reperage-broches-bus-i2c-spi-esp8266/
On peut lire ceci :

Quote
Bus I2C
Par défaut, chaque fabriquant réserve 2 broches du MCU (micro-contrôleur) pour le bus I2C. Si vous avez besoin de déplacer le bus I2C sur d'autres broches, voici comment faire.
Au début du programme, ajoutez la librairie Wire.h
#include <Wire.h>

puis dans la fonction setup(), utilisez la fonction begin en indiquant la broche SDA et la broche SCL.
Wire.begin(broche SDA, broche SCL);

enzweb

C'est effectivement une première étape, mais cela ne change pas le résultat pour le moment.

Je suis toujours campé a des valeurs oscillants entre 270 et 360°.

al1fch

#8
May 24, 2020, 05:21 pm Last Edit: May 24, 2020, 05:24 pm by al1fch
Essayer de localiser l'anomalie : apparait elle au niveau des valeurs de x et z,  des valeurs de heading ou  dir ?

Dans les deux  cas le test est-il fait avec le même exemplaire  du module à HMC5883 ou avec deux modules 'équivalents' (l'un avec un HMC5883 l'autre avec un QMC5883) ?

enzweb

#9
May 24, 2020, 08:26 pm Last Edit: May 24, 2020, 10:18 pm by enzweb
Donc, donc, donc,

Pas forcément simple d'analyser cela, mais de ce que j'ai pu constater, l'erreur doit se faire sur heading car d'après les valeurs sorties en x et z et le calcul selon la formule du sketchs les resulats ne matchent pas.

Dir est quant a lui est conforme au résultat donné par heading.

Je fais mes tests avec un seul est unique module GY271.

enzweb

Donc, donc, donc,

Pas forcément simple d'analyser cela, mais de ce que j'ai pu constater, l'erreur doit se faire sur heading car d'après les valeurs sorties en x et z et le calcul selon la formule du sketchs les resultats ne matchent pas.

Dir est quant a lui est conforme au résultat donné par heading.

Je fais mes tests avec un seul est unique module GY271.
Bonjour,

Finalement, l'erreur ne se situe pas sur heading, lui fait son travail. J'ai comparé les coordonnées de x, y et z entre le Uno et le D1mini, et la ça ne correspond plus du tout. Sur le D1 les coordonnées ne passent bizarrement jamais en négatif, or pour faire un 360° avec atan2 il y a forcément du négatif a un moment.

Ce qui signifie également, que atan2 est bien fonctionnel sur le D1, en somme sur ce point vous aviez complètement raison.

Bon je vais encore chercher un peu mais je ne sais pas trop ou désormais...

al1fch

#11
May 25, 2020, 07:10 pm Last Edit: May 25, 2020, 09:41 pm by al1fch
Bonsoir
Quote
Sur le D1 les coordonnées ne passent bizarrement jamais en négatif
Code: [Select]
int x, y, z;                          // Trois axes

int : 32 bits sur ESP8266 contre 16bits sur AVR, ça peut jouer des tours quand on transpose le code sans précautions 
(y compris sur le signe en complément à 2 )   

 int n'a pas la même taille selon les architectures.

essayer en déclarant x,y et z comme  int16_t

enzweb

#12
May 25, 2020, 07:18 pm Last Edit: May 25, 2020, 07:21 pm by enzweb
32 bits sur ESP8266 contre 16bits sur AVR, ça peut jouer des tours quand on transpose le code sans précautions , y compris sur le signe.... (int n'a pas la même taille selon les architecures)

essayer en déclarant x,y et z comme int16_t

C'est effectivement ça, j'avais pris la mauvaise direction depuis le début et je n'ai pas ces automatismes et l'expérience.

Merci a tous pour l'aide apportée !

al1fch

On mémorise mieux quand on se fait prendre une ou deux fois dans ce genre de chose....

peux-tu éditer le titre du message initial poour y ajouter [RESOLU] en début de ligne ?

Go Up