Multi Wii et SoftwareSerial pour un drone arduino

Portrait de Azerty2289

Bonjour a tous

J'aurais besoin d'un avis externe car certains comportement de ma carte arduino me laisse perplexe...

Je construit actuellement un drone avec multiwi sur une carte nano qui tourne et gère les 4 moteurs. Les commandes sont envoyée par une autre carte nano par un signal PPM sur la broche 2. Cette carte reçois les informations (Throttle, Yaw,Pitch,Roll,Aux1 et Aux2) par un module H-12 depuis la télécommande.

Joystick => Arduino UNO => HC 12 (par les ondes) HC 12 =>  Arduino nano =>(via PPM) arduino nano (avec multiwii)

La chaîne d'information fonctionne bien sauf que il y a un petit problème : les signaux générer par la carte nano sont reconnu par multiWii ( je vois varier les valeurs sur le logiciel ) mais il y a des instabilité. Les valeur font des "sauts" et varie entre 1600 et 1400 aléatoirement  au lieu de reste a 1500 par exemple ce qui rendra le drone instable.

Après beaucoup de recherche jai trouve la source du problème : la bibliothèque SoftwareSerial (qui sert a communiquer avec le HC 12) utilise des interruptions pour fonctionner et les signaux PPM générer par le code que je vous fourni en dessous sont alors instable. En augmentant le baudrate de communication a 115200 bauds ( le maximum avec le HC 12 ) , les valeurs sont plus stable mais cela ne fixe pas totalement le problème. Auriez ne serait ce qu'une piste ou une idée de comment fixer cela car je bloque depuis maintenant 2 semaines.

Voici le code :

#include <SoftwareSerial.h>
SoftwareSerial HC12(10, 11);
#define channel_number 6  //set the number of channels
#define sigPin 2  //set PPM signal output pin on the arduino
#define PPM_FrLen 27000 
#define PPM_PulseLen 400  //set the pulse length
//////////////////////////////////////////////////////////////////

int ppm[channel_number];

struct MyData {
  byte throttle;
  byte yaw;
  byte pitch;
  byte roll;
  byte AUX1;
  byte AUX2;
};

MyData data;

void resetData()
{
  // 'safe' values to use when no radio input is detected
  data.throttle = 0;
  data.yaw = 127;
  data.pitch = 127;
  data.roll = 127;
  data.AUX1 = 0;
  data.AUX2= 0;
 
  setPPMValuesFromData();
}

void setPPMValuesFromData()
{
  ppm[0] = map(data.throttle, 0, 255, 1000, 2000);
  ppm[1] = map(data.yaw,      0, 255, 1000, 2000);
  ppm[2] = map(data.pitch,    0, 255, 1000, 2000);
  ppm[3] = map(data.roll,     0, 255, 1000, 2000);
  ppm[4] = map(data.AUX1,    1, 0, 1000, 2000);
  ppm[5] = map(data.AUX2,     1, 0, 1000, 2000);  
  }

/**************************************************/

void setupPPM() {
  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, 0); 

  cli();
  TCCR1A = 0;
  TCCR1B = 0;

  OCR1A = 100; 
  TCCR1B |= (1 << WGM12);  // turn on CTC mode
  TCCR1B |= (1 << CS11);  // 8 prescaler: 0,5 microseconds at 16mhz
  TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
  sei();
}

void setup()
{  
  resetData();
  setupPPM();
  HC12.begin(115200);
  Serial.begin(115200);
}
void loop()
{
  if (HC12.available()) {
    data.AUX1 = HC12.read(); while (!HC12.available()) {}
    data.throttle = HC12.read(); while (!HC12.available()) {}
    data.roll = HC12.read(); while (!HC12.available()) {}
    data.pitch = HC12.read(); while (!HC12.available()) {}
    data.yaw = HC12.read(); while (!HC12.available()) {}
    data.AUX2 = HC12.read(); while (!HC12.available()) {}
 

    Serial.println("eee");
    Serial.println(data.throttle);
    Serial.println(data.yaw);
    Serial.println(data.pitch);
    Serial.println(data.roll);
    Serial.println(data.AUX1);
    Serial.println(data.AUX2);
  }
  setPPMValuesFromData();
}

/**************************************************/

#define clockMultiplier 2

ISR(TIMER1_COMPA_vect){
  static boolean state = true;

  TCNT1 = 0;

  if ( state ) {
    //end pulse
    PORTD = PORTD & ~B00000100;
    OCR1A = PPM_PulseLen * clockMultiplier;
    state = false;
  }
  else {
    //start pulse
    static byte cur_chan_numb;
    static unsigned int calc_rest;

    PORTD = PORTD | B00000100; // turn pin 2 on. Could also use: digitalWrite(sigPin,1)
    state = true;

    if(cur_chan_numb >= channel_number) {
      cur_chan_numb = 0;
      calc_rest += PPM_PulseLen;
      OCR1A = (PPM_FrLen - calc_rest) * clockMultiplier;
      calc_rest = 0;
    }
    else {
      OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * clockMultiplier;
      calc_rest += ppm[cur_chan_numb];
      cur_chan_numb++;
    }     
  }
}

Portrait de Azerty2289

Me probleme est que le module HC12 ( qui menvoit les informations depuis la telecommande ) est limité a 115200 bauds et c'est lui qui fait beugé les signaux PPM. Jai testé en augmentant a 2000000 et ca ressous les problème mai c'est impossible avec ce module... La communication serie avec le port serie arduino me sert juste a voir les valeurs a l'écran et elle n'influence en rien les signaux.

Portrait de Azerty2289

Tu na pas compris : cest le module HC12 quo fait beuge mes signaux, lorsque je genere des signaux sans avoir déclaré le Hc12 et sa biblioteque ( jenvoie des valeur fixe ) les valeur sont stable . Le serial moniteur na rien a voir la dedans, il le sert juste a avoir un oeil  sur mon programme. Tu t'énerve vite quand même.... 

Portrait de Azerty2289

Jai déjà essayé et même de supprimer la communication avec le port serie car je pensé quelle prouvait influencer aussi les signaux mais ca ne change rien cest uniquement la liason avec le HC 12 qui faut beugé 

Portrait de Azerty2289

Merci pour tes conseil je vais pour linstant me contenter dun autre module rado le nrf24l01 qui a une porte plus faible mais l'influence pas le signal. Je ferais des modifs avec le HC12 plus tard.