Un peu de contexte pour vous aider à expliquer votre approche:
Votre accéléromètre est un MMA7660FC qui mesure des accélérations jusqu'à ±1.5g sur chacun des 3 axes X,Y et Z. Il offre aussi d'ailleurs un mode de "Shake Detection" (on secoue et on peut préciser les axes d'intérêt) et de "Tap Detection" on tapote dessus.
il n'est pas super précis et offre 6-bit seulement par axe, donc 64 valeurs pour représenter jusqu'à ±1.5G (donc une amplitude de 3G)
Un G est une accélération de 9,80665 ms−2 donc chaque bit va représenter (3*9,80665)/64= 0,46ms−2 ou une autre façon de le voir c'est 64/3 = ~21 LSB par G que vous allez retrouver dans la spec.
Pour votre simulation, vous auriez 3 potentiomètres qui devront générer ces valeurs entre 0 et 63 (le 64 valeurs possibles) - mais si vous faites la lecture de vos potentiomètres avec analogRead() vous avez une valeur entre 0 et 1023. Vous appeleriez alors la fonction map() pour convertir cette valeur vers une autre valeur qui serait plus en lien avec ce que l' accéléromètre retournerait (pour être cohérent) donc entre 0 et 63.
const byte xAxisPotPin = A0;
const byte yAxisPotPin = A1;
const byte zAxisPotPin = A2;
... plus loin dans le code
int8_t xReg = map(analogRead(xAxisPotPin), 0, 1024, 0, 64); // on aura une valeur entre 0 et 63 soit 6 bits
int8_t yReg = map(analogRead(yAxisPotPin), 0, 1024, 0, 64); // on aura une valeur entre 0 et 63 soit 6 bits
int8_t zReg = map(analogRead(zAxisPotPin), 0, 1024, 0, 64); // on aura une valeur entre 0 et 63 soit 6 bits
Voilà vous avez votre MPU simulé...
Si on veut aller un peu plus loin pour avoir un code qui pourrait ensuite utiliser la bibliothèque associée à votre composant, on pourrait faire une fausse bibliothèque qui ressemblerait à la vraie.
Le code source de la vraie bibliothèque est disponible -> Accelerometer_MMA7660 et vous avez deux fichiers importants, MMA7660.cpp
et MMA7660.h
Dans le .h on voit que la bibliothèque offre les fonctions suivantes:
void init();
void init(uint8_t interrupts);
void setMode(uint8_t mode);
void setSampleRate(uint8_t rate);
// get the signed value of x,y,z register
bool getXYZ(int8_t* x, int8_t* y, int8_t* z);
// calculate the acceleration from the signed value of x,y,z register
bool getAcceleration(float* ax, float* ay, float* az);
// lookup the acceleration from the lookup table from this chip's datasheet
bool getAcceleration(MMA7660_ACC_DATA* data);
// get all the register value
bool getAllData(MMA7660_DATA* data);
On va essayer de refaire une bibliothèque qui offre un peu la même interface de façon à simuler le MPU mais on va conserver que celles que vous utiliseriez dans le vrai monde pour votre projet, soit l'appel de l'initialisation de la bibliothèque
void init();
et ensuite la lecture des accélérations
bool getAcceleration(float* ax, float* ay, float* az);
Il nous faut donc une classe qui a ces deux fonctions uniquement (et en prime on peut intégrer à la fonction init des valeurs par défaut qui seraient les pins de vos potentiomètres A0,A1 et A2).
Si on simule avec les potentiomètres l'obtention d'un nombre entre -32 et +31 on aurait le fonctionnement à l'identique de leur fonction getXYZ() donc il nous suffit d'écrire
bool getXYZ(int8_t* x, int8_t* y, int8_t* z) {
*x = map(analogRead(xAxisPotPin), 0, 1024, -32, 32); // résultat entre -32 pour 0 et +32 pour 1024 qui n'est pas possible donc +31 sur la plage linéaire juste avant 1023
*y = map(analogRead(yAxisPotPin), 0, 1024, -32, 32);
*z = map(analogRead(zAxisPotPin), 0, 1024, -32, 32);
return true;
}
et ensuite on peut conserver le code d'origine de la librairie pour getAcceleration()
bool getAcceleration(float* ax, float* ay, float* az) {
int8_t x, y, z;
if (!getXYZ(&x, &y, &z)) return false;
*ax = x / 21.00;
*ay = y / 21.00;
*az = z / 21.00;
return true;
}
mais comme on a vu que le 21 venait de 64/3 on peut mettre cette valeur à la place de 21.00 pour être un peu plus précis.
voilà en mettant tout cela ensemble, vous pouvez créer un fichier .hpp de définition de notre nouvelle bibliothèque (pour simplifier et en avoir qu'un)
FakeMMA7660.hpp
/*
MMA7760.hpp
FAKE Library for accelerometer_MMA7760 simulated with 3 potentiometers
Copyright (c) 2020 J-M-L
Author : J-M-L
Create Time : April 2020
Change Log :
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef __FAKEMMC7660_H__
#define __FAKEMMC7660_H__
#include <Arduino.h>
class FAKEMMA7660 {
private:
byte xAxisPotPin;
byte yAxisPotPin;
byte zAxisPotPin;
public:
void init(byte xPotPin = A0, byte yPotPin = A1, byte zPotPin = A2 ); // valeurs par défaut
// get the signed value of x,y,z register
bool getXYZ(int8_t* x, int8_t* y, int8_t* z);
// calculate the acceleration from the signed value of x,y,z register
bool getAcceleration(float* ax, float* ay, float* az);
};
void FAKEMMA7660::init(byte xPotPin, byte yPotPin, byte zPotPin) {
xAxisPotPin = xPotPin;
yAxisPotPin = yPotPin;
zAxisPotPin = zPotPin;
pinMode(xAxisPotPin, INPUT);
pinMode(yAxisPotPin, INPUT);
pinMode(zAxisPotPin, INPUT);
}
/*Function: Get the contents of the registers in the MMA7660*/
/* so as to calculate the acceleration. */
bool FAKEMMA7660::getXYZ(int8_t* x, int8_t* y, int8_t* z) {
*x = map(analogRead(xAxisPotPin), 0, 1024, -32, 32); // résultat entre -32 pour 0 et +32 pour 1024 qui n'est pas possible donc +31 sur la plage linéaire juste avant 1023
*y = map(analogRead(yAxisPotPin), 0, 1024, -32, 32);
*z = map(analogRead(zAxisPotPin), 0, 1024, -32, 32);
return true;
}
bool FAKEMMA7660::getAcceleration(float* ax, float* ay, float* az) {
int8_t x, y, z;
if (!getXYZ(&x, &y, &z)) return false;
*ax = x * 3.0 / 64.0; // (on divise par ~21 --> 64/3 pour être précis ce qui revient à multiplier par 3/64)
*ay = y * 3.0 / 64.0; // idem
*az = z * 3.0 / 64.0; // idem
return true;
}
#endif
ensuite votre code pour l'utiliser va ressembler vraiment à ce que vous auriez fait en vrai, mais au lieu d'instancier un MMA7660
on va instancier un FAKEMMA7660
Voici un petit .ino de test
#include "FakeMMA7660.hpp"
FAKEMMA7660 mpu;
void setup() {
Serial.begin(115200);
mpu.init(); // pins par défaut A0, A1, A2
}
void loop()
{
float accX, accY, accZ;
if (mpu.getAcceleration(&accX, &accY, &accZ)) {
Serial.print(F("Accélération:"));
Serial.print(accX);
Serial.write('\t'); // tabulation à l'affichage
Serial.print(accY);
Serial.write('\t'); // tabulation à l'affichage
Serial.println(accZ);
}
}
il faut mettre le fichier FakeMMA7660.hpp
dans le répertoire du sketch pour qu'il soit pris en compte. ou intégrer son code au début du .ino
Voilà avec ce petit code vous pouvez utiliser tinkerCad et en bougeant les potentiomètres votre sketch recevra des accélérations sur les axes.
Quand vous voudrez passer au vrai code, au lieu de
#include "FakeMMA7660.hpp"
FAKEMMA7660 mpu;
il suffira de faire
#include <MMA7660.h>
MMA7660 mpu;
et le tour sera joué
En espérant que cela vous aide à démarrer, bonne journée