mercredi 12 octobre 2016

[ARDUINO] Rotor site azimuth

Bonjour,

Aujourd'hui je vais vous montrer comment fabriquer un rotor de suivi satellite à moindre coût.

Vous aurez besoin de 2 servomoteurs de modelisme ( j'utilise des servos standard car mon rotor est prévu pour une petite antenne patch très légère), un arduino (uno, nano, mini ou juste un atmega 328 et ses 3 composants vitaux...).
Et c'est tout !

Ceux qui connaissent les servos 'classique' dirons : "Ca marchera pas, ces servos ont une course de 180°..."
C'est vrai! On trouve des servos 360° mais beaucoup plus chère, et voulant réduire les coûts, il fallait trouver une solution.

Voici la solution qui fonctionne en vidéo :
 Concrètement, et pour faire simple,
-du Nord au Sud en passant par l'Est, tout est bon avec les 180° du servo.
-lorsque qu'on passe le Sud, le servo Az fait un 180° alors que le servo de Site inverse sa position. Ce qui permet le suivi de 181° à 360°.


Coté hard, rien de compliqué : Une alim pour les servos et un arduino où l'on branchera les 2 servos (PWM 9 et 10).
Ces 2 derniers sont montés l'un sur l'autre avec quelques petites équerres. Il est possible de vous équiper d'un kit 'tilt-pan' qu'on trouve sur les drones pour bouger la caméra. Ou alors quelques pièces imprimés en 3D !

Coté software, l'arduino interprète les commandes d'un rotor au protocole Easycomm2. Il suffira donc de configurer un rotor 'easycomm2' dans votre logiciel de suivi sat préferé.
Voici la procédure sous Linux avec Gepredict :
-installer 'hamlib'
-dans un terminal : rotctld -m 901 -r /dev/ttyACM0 -s 19200
  ou -m 901 correspond au protocole Easycomm2
       -r le port série de l'Arduino (à adapter en fonction..)
       -s la vitesse du port.
-dans Gpredict:
  Edition/Préférences/Interfaces/Rotor
et ajouter un rotor comme suit :
Pour avoir accès au contrôleur de rotor, cliquer sur la flèche en haut à droite de la fenêtre de Gepredict puis "contrôle d'antenne".
Et voilà !
Le sketch de l'arduino à la fin de cet article.
Bonne bidouille !

Jérôme, F4GMU

#include <Servo.h>
Servo azServo;
Servo elServo;

char az[4];
char el[4]; 
int azInt;  
int elInt;
char inBuffer[13];
int inCount = 0;  

char command;  
bool inBufferFull = false; 

void setup() {
 
  command = 0x00; 
 
  for (int i=0; i<4; i++){
  az[i]=0x0;
  el[i]=0x0;
  }
 

  Serial.begin(19200, SERIAL_8N1);
  azServo.attach(9);
  elServo.attach(10);
  azServo.write(0);
  elServo.write(0);
   
}

void loop() {
  
   
   
    if (command!=0x1f && command!=0x2f) return;
  
    if (command == 0x2f){
      for (int i=0;i<4;i++){   
      az[i] = inBuffer[i+1]-'0'; 
      el[i] = inBuffer[i+6]-'0';
      }
      updateAZEL();   
     
      command=0x0;   
     
      if (azInt > 180){   
        azInt=azInt-180;
        elInt=180-elInt;
      }
      azInt=azInt*(.972);
      elInt=elInt*(1);

      moveServos();
      return;                   
    }
   
    Serial.write(0x57);         
       for (int i=0; i<4; i++){
       Serial.write (az[i]);
       }
      
       Serial.write(0x01); 
      
       for (int i=0; i<4; i++){
       Serial.write(el[i]); 
        }
       
       Serial.write(0x01);     
       Serial.write(0x20);      /
       command=0x0;
}




//--------------------------------------------------------------

void updateAZEL() {
 
  elInt=0;
  azInt=0;
 
  azInt = az[1]*100;         
  azInt = azInt + az[2]*10;
  azInt = azInt + az[3];
 
  elInt = el[1]*100;
  elInt = elInt + el[2]*10;
  elInt = elInt + el[3];
 
  if (azInt >= 360) azInt=azInt-360; 

  char buf[3];
 
  sprintf (buf, "%03i", azInt);
  for (int i = 0; i<3;i++){
    az[i] = buf[i]- '0';
  }
 
  sprintf (buf, "%03i", elInt);
  for (int i = 0; i<3;i++){
    el[i] = buf[i]- '0';
  }
 
  az[3]=0;
  el[3]=0;
 
  if (elInt >= 360) elInt=elInt-360;  //
}

//--------------------------------------------------------------

void serialEvent(){

  while (Serial.available()){
 
    char inChar= (char) Serial.read();
      inBuffer[inCount]=inChar;
      inCount++;
     
  }
 
  if (inCount==13){
    command=inBuffer[11];

    inCount=0;
  }
}



//--------------------------------------------------------------

void moveServos(){

  azServo.write(azInt);
  elServo.write(elInt);
}

13 commentaires:

  1. Super, bravo et merci pour ton article Jérôme

    RépondreSupprimer
  2. Hello D'jé , comme d'habitude une superbe bidouille !!!! A très bientôt et merci pour le partage !!! F1OLG

    RépondreSupprimer
    Réponses
    1. Merci Thierry, à bientôt pour d'autres bidouilles ;)

      Supprimer
  3. Bonjour Jérôme,
    je suis très intéressé par ce projet et j'aimerai marcher sur vos pas et realisé ce projet à mon tour ... Pourriez vous m'indiquer comment faut il s'y prendre pour calibrer les servos s'il vous plait ? Quelles positions initiales faut il leur donner (c'est à dire comment fixer physiquement le "zero" ) ? Merci beaucoup pour ce site, vos idées et votre patience ;-) ... Excellente journée

    RépondreSupprimer
    Réponses
    1. Bonjour et merci pour ton commentaire.
      La position initiale de se rotor est le Nord, 0° d'élévation (0° site, 0°azimunth).
      Dans cette position, les servos (180°) sont en butée CCW si mes souvenirs sont bon (je n'utilise plus ce montage). Mais une chose est sûr, il sont en buté d'un coté.
      Tu auras vite fais de trouver le sens une fois l'arduino branché ;)
      Bonne bidouille,
      Jérôme.

      Supprimer
  4. Bonjour Jérome,
    je suis intéressé par votre montage mais je suis sous Windows et non Linux.
    avez vous la procédure pour son fonctionnement sous Windows.
    cordialement
    Ed

    RépondreSupprimer
    Réponses
    1. Bonjour Ed,
      N'utilisant pas Windows pour mes loisirs, je ne peux pas vous aider.
      Néamoins, si vous avez compris que l'Arduino émule un protocole série de type "easycomm2", vous ne devriez pas avoir de soucis pour l'utiliser avec un logiciel qui reprends ce protocole.
      Bonne bidouille à vous et bonnes fêtes,
      Jérôme.

      Supprimer
  5. Très belle réalisation, je souhaiterais faire la même chose avec une antenne un petit peu plus lourde à savoir une antenne plate satellitaire de 3 kg, que me conseillez-vous ?

    RépondreSupprimer
    Réponses
    1. Bonjour et merci pour votre message.
      Je sais qu'il existe des gros servomoteur en modelisime, dans ce cas, ils auraient sûrement besoin d'une alimentation propre à eux.
      Sinon, il existe un rotor open-source à fabriquer soi-même (du moment qu'on a accès à une imprimante 3D) : faites une recherche sur le projet SATNOGS.
      Bonne journée,
      Jérôme, F4GMU

      Supprimer
  6. Bonjour et merci pour la rapidité de votre réponse. Je possède une petite imprimante Ender 3 de chez creality. Je vais bien regarder le projet, merci beaucoup pour le sinformations.

    RépondreSupprimer
  7. Bonjour, lorsque j'essaie de charger le code, j'obtiens cette erreur :
    int inCount = 0; d ('d' does not name a type)

    RépondreSupprimer
    Réponses
    1. Ah oui, un 'd' s'est invité dans mon code...
      Supprimez ce 'd' et ça devrait compiler.
      Je corrigerai mon article à l'occasion.
      (PS : Je vous suggère de vous intéresser à la programmation de base pour éviter de poser ce genre de questions. Vous auriez pu trouver de vous même 😉 )

      Supprimer