Bonsoir à tous,
Je me faisais une joie d'utiliser les classes afin de programmer proprement, mais je tombe dans une impasse.
Sachant que :
Le code contenu dans une classe ne voit que les propriétés et méthodes de cette classe.
Il n'est pas possible d'attacher une interruption dans une méthode d'une classe (message = multiple definition of 'PCintPort::PCint()').
La seule possibilité de transmettre des données aux méthodes d'une classe est via les paramètres de ces méthodes.
Comment faire lorsqu'on doit récupérer plusieurs fois (boucle jusqu'à ce que cela soit bon) des données qui ne peuvent être lues que par interruption
Cas concret :
Un récepteur (modèle réduit) donne les positions de 4 voies.
Pour que le programme connaisse la fonction de chaque voie, une méthode demande à l'utilisateur de poisitionner les manches de la radio dans des configurations particulières (tout au neutre, puis pas au max, puis pas au mini, puis....)
Le programme détermine que l'utilisateur a positionner les manches dans la position demandée lorsque les données seront dites 'stables'
J'ai donc développer une méthode 'calibrer' qui me renvoit dans l'intance 'récepteur' les valeurs demandées.
class recepteur {
public:
unsigned long voie1;
unsigned long voie2;
unsigned long voie3;
unsigned long voie4;
recepteur();
int calibrer(char);
};
int recepteur::calibrer(char type) {
// Attendre que le Rx lu soit stable
// Test : OK
// --------------------------------------------------
recepteur currentRx[NBRE_IND_TAB]; // Données issues du récepteur
int nbreIter = 0; // Nbre d'itération pour avoir une valeur stable
int indTab = 0;
boolean stable = false;
boolean minData = false; // Il faut avoir rempli le tableau
do{ // Attendre que les données soient stable
currentRx[indTab++].lire(type); // Lecture Rx...
nbreIter++;
if (indTab >= NBRE_IND_TAB) {
indTab = 0; //
minData = true; // Le tableau est complet
}
if (minData) { // Le tableau est complet alors calcul de l'écart
//recepteur minRx = recepteur(-1);
recepteur minRx(-1);
recepteur maxRx = recepteur(-1);
// Détermine le min et le max pour chaque voie
for (int i = 0; i < NBRE_IND_TAB; i++){
minRx.minimum(currentRx[i]);
maxRx.maximum(currentRx[i]);
}
stable = maxRx.stable(minRx); // Ecart sur chaque voie < ERR
// minRx.debug();
// maxRx.debug();
}
}
while (!stable || !minData);
recepteur stableRx = recepteur(0);
for (int i = 0; i < NBRE_IND_TAB; i++) stableRx += currentRx[i];
stableRx /= NBRE_IND_TAB;
voie1 = stableRx.voie1;
voie2 = stableRx.voie2;
voie3 = stableRx.voie3;
voie4 = stableRx.voie4;
return nbreIter;
}
void recepteur::lire(char type){
// <TODO> A remplacer par la lecture du récepteur...
// voie1 = random(900, 2100);
// voie2 = random(900, 2100);
// voie3 = random(900, 2100);
// voie4 = random(900, 2100);
voie1 = Donnée issue du traitement d'une interruption pin n (temps écoulé entre le front montant et le front descendant)
voie2 = Donnée issue du traitement d'une it...
voie3 = Donnée issue du traitement d'une it...
voie4 = Donnée issue du traitement d'une it...
}
La lecture des voies RC se fait par du code du style :
#include <PinChangeInt.h> // http://playground.arduino.cc/Main/PinChangeInt
#include <PinChangeIntConfig.h>
#include <TimerOne.h> // http://playground.arduino.cc/Code/Timer1
#define NO_PORTB_PINCHANGES //PinChangeInt setup
#define NO_PORTC_PINCHANGES //only port D pinchanges (see: http://playground.arduino.cc/Learning/Pins)
#define PIN_COUNT 3 //number of channels attached to the reciver
#define MAX_PIN_CHANGE_PINS PIN_COUNT
#define RC_TURN 3 //arduino pins attached to the reciver
#define RC_FWD 2
#define RC_FIRE 4
byte pin[] = {RC_FWD, RC_TURN, RC_FIRE}; //for maximum efficency thise pins should be attached
unsigned int time[] = {0,0,0}; // to the reciver's channels in the order listed here
byte state=0;
byte burp=0; // a counter to see how many times the int has executed
byte cmd=0; // a place to put our serial data
byte i=0; // global counter for tracking what pin we are on
void setup() {
Serial.begin(115200);
Serial.print("PinChangeInt ReciverReading test");
Serial.println(); //warm up the serial port
Timer1.initialize(2200); //longest pulse in PPM is usally 2.1 milliseconds,
//pick a period that gives you a little headroom.
Timer1.stop(); //stop the counter
Timer1.restart(); //set the clock to zero
for (byte i=0; i<3; i++)
{
pinMode(pin[i], INPUT); //set the pin to input
digitalWrite(pin[i], HIGH); //use the internal pullup resistor
}
PCintPort::attachInterrupt(pin[i], rise,RISING); // attach a PinChange Interrupt to our first pin
}
void loop() {
cmd=Serial.read(); //while you got some time gimme a systems report
if (cmd=='p')
{
Serial.print("time:\t");
for (byte i=0; i<PIN_COUNT;i++)
{
Serial.print(i,DEC);
Serial.print(":");
Serial.print(time[i],DEC);
Serial.print("\t");
}
Serial.print(burp, DEC);
Serial.println();
}
cmd=0;
switch (state)
{
case RISING: //we have just seen a rising edge
PCintPort::detachInterrupt(pin[i]);
PCintPort::attachInterrupt(pin[i], fall, FALLING); //attach the falling end
state=255;
break;
case FALLING: //we just saw a falling edge
PCintPort::detachInterrupt(pin[i]);
i++; //move to the next pin
i = i % PIN_COUNT; //i ranges from 0 to PIN_COUNT
PCintPort::attachInterrupt(pin[i], rise,RISING);
state=255;
break;
/*default:
//do nothing
break;*/
}
}
void rise() //on the rising edge of the currently intresting pin
{
Timer1.restart(); //set our stopwatch to 0
Timer1.start(); //and start it up
state=RISING;
// Serial.print('r');
burp++;
}
void fall() //on the falling edge of the signal
{
state=FALLING;
time[i]=readTimer1(); // read the time since timer1 was restarted
// time[i]=Timer1.read(); // The function below has been ported into the
// the latest TimerOne class, if you have the
// new Timer1 lib you can use this line instead
Timer1.stop();
// Serial.print('f');
}
unsigned long readTimer1() //returns the value of the timer in microseconds
{ //rember! phase and freq correct mode counts
//up to ICR1 then down again
unsigned int tmp=TCNT1;
char scale=0;
switch (Timer1.clockSelectBits)
{
case 1:// no prescalse
scale=0;
break;
case 2:// x8 prescale
scale=3;
break;
case 3:// x64
scale=6;
break;
case 4:// x256
scale=8;
break;
case 5:// x1024
scale=10;
break;
}
while (TCNT1==tmp) //if the timer has not ticked yet
{
//do nothing -- max delay here is ~1023 cycles
}
tmp = ( (TCNT1>tmp) ? (tmp) : (ICR1-TCNT1)+ICR1 );//if we are counting down add the top value
//to how far we have counted down
return ((tmp*1000L)/(F_CPU /1000L))<<scale;
}
En bref, comment mixer les 2 programmes...
Merci pour vos lumières