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.
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 ?
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.
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:
#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°.
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.
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.
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) ?
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.
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...
Sur le D1 les coordonnées ne passent bizarrement jamais en négatif
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.
al1fch:
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.