Go Down

Topic: Faire bouger des servomoteurs identifiés  (Read 721 times) previous topic - next topic

Oeildelys

Bonjour,

J'ai écrit un code qui est censé mettre en mouvement trois servomoteurs respectivement identifiés 1, 2 et 3.

Dans le moniteur série, j'envoie une instruction qui doit permettre de mettre un servomoteur dans une certaine position.
Par exemple, j'envoie dans le moniteur série "1180" --> alors le servo 1 doit bouger jusqu'à l'angle de 180°. Le premier caractère correspond donc à l'ID du servo.

Pour l'instant, le moniteur série affiche bien la chaîne envoyée, mais mes servos ne bougent pas.

Pouvez-vous m'aider ?

Ci-dessous mon code :

Code: [Select]


#include <Servo.h>
 #include <SPI.h>
#include <ServoCds55.h>
ServoCds55 myservo;

String inputString = "";         // a string to hold incoming data
boolean stringComplete = false;  // whether the string is complete
int ID = 0;
int pos = 0;

void setup() {
  Serial.begin(115200);
  inputString.reserve(200);
 
}

void loop() {
  serialEvent();
  if (stringComplete) {
 
  ID=int((inputString[0]-48)*1000);
    pos=int((inputString[1]-48)*100)+int((inputString[2]-48)*10)+int(inputString[3]-48);
   Serial.println(ID+pos);
  myservo.write(ID, pos);
    inputString = "";
    stringComplete = false;
       
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    inputString += inChar;
    if (inChar == '\n') {
      stringComplete = true;
    }
  }
}



void controlServo(int val) {
  switch (val) {
    case '1':
      inputString[0]=val;
      case '2':
      inputString[0]=val;
      case '3':
      inputString[0]=val;
      break;
  }
}


infobarquee

il ne te manque pas des interrupt?
regarde les exemples de servo moteur pour un et adapte pour trois
AUCUNE AIDE PAR MP

Oeildelys

il ne te manque pas des interrupt?
regarde les exemples de servo moteur pour un et adapte pour trois
Merci pour la réponse.

Des interrupteurs ? C'est-à-dire ?
J'arrive à les faire bouger avec un autre code, mais sans pouvoir choisir la valeur de l'angle de position.
Le problème vient je pense de l'instruction que j'envoie sur le moniteur série.
Je ne pense pas qu'il reconnaît l'ID du servo.

Ci-dessous le code qui les fait bouger correctement :

Code: [Select]

#include <SPI.h>
#include <ServoCds55.h>
ServoCds55 myservo;

//int servoNum = 1;
char inputCommand ;         // a string to hold incoming data
boolean inputComplete = false;

void setup () {
  Serial.begin (115200);
  digitalWrite(SS, HIGH); 
  SPI.begin ();
  //myservo.begin ();
}

void loop () {
  serialEvent();
  if (inputComplete) {
    Serial.print("Your command is: "); Serial.println(inputCommand); Serial.println("");
    controlServo(inputCommand);
    // clear the command:
    inputCommand = 0;
    inputComplete = false;
  }
}

void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    if (inChar == '\n') {
      inputComplete = true;
      break;
     
    }
    inputCommand += inChar;
  }
}

void controlServo(char val) {
  switch (val) {
    case 'a':
      myservo.write(1, 100);
      delay(3000);
      myservo.write(1, 200);
      break;
 case 'b':
      myservo.write(2, 100);
      delay(3000);
      myservo.write(2, 200);
      break;
      case 'c':
      myservo.write(3, 100);
      delay(3000);
      myservo.write(3, 200);
      break;
      //case 'd':
      //delay(2000);
      //Serial.println("");   Serial.println("Please close the monitor and re-open it to play your servo! ");
      //break;
    default:
      Serial.println("Please give me an available instruction:");
      Serial.println("  Servo mode: p_Set position; v_Set velocity.");
      Serial.println("  Motor mode: m_Rotate; v_Set velocity.");
      Serial.println("  Others: r_Reset servo to factory settings; i_Change servo ID."); Serial.println("");
      // case 'x':
        // myservo.Reset(1);
        case 'y':
        myservo.Reset(2);
        // case 'z':
        // myservo.Reset(3);
        // break;
  }
}



Alain46

Code: [Select]
ID=int((inputString[0]-48)*1000);

Si inputString[0]correspond à '1'
Ton calcul pour ID = ((49-48)*1000) soit ((1)*1000) soit 1000

Si inputString[0]correspond à '2'
Ton calcul pour ID = ((50-48)*1000) soit ((2)*1000) soit 2000

Tu es sur que tes servos ont bien cet ID ?
De plus ton  transtypage en int n'est pas bon

Essaye avec
Code: [Select]
ID=(int) (inputString[0]-'0');
Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

Oeildelys


Alors les ID de mes servos sont 1,2 et 3.

Vous avez parfaitement raison quand vous dites 1000 et 2000.
Mais en fait l'idée c'est d'utiliser le premier caractère soit 1 pour 1000 et 2 pour 2000 pour appeler le bon servo.
Le reste de la chaîne sert à donner la position (180 pour 180°, 090 pour 90°.... etc)

Donc en envoyant par exemple 2090 sur le moniteur série, je devrais voir le servo 2 bouger jusqu'à l'angle de 90°.

Merci pour le transtypage, je corrige ça

Alain46

C'est bien ce que javais compris
Le 1er caractère est l'ID du servo
Donc, pas besoin de multiplier par 1000
Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

Oeildelys

C'est bien ce que javais compris
Le 1er caractère est l'ID du servo
Donc, pas besoin de multiplier par 1000
Oui je comprends ce que vous voulez dire, mais le souci c'est que quand j'écris tout à la suite dans le moniteur série (1180, ou 2090....), il me renvoie un nombre absurde, comme s'il calculait quelque chose.

J'ai obtenu des -18800 et quelques....

Alain46

Puisque ID est faux la ligne suivante est fausse aussi
Code: [Select]
Serial.println(ID+pos);

Je suppose que ton "println()" te sers à debugger.
Comment veux tu debugger avec le résultats dun calcul
Tu ne peu pas vérifier la valeur de ID et de pos

Code: [Select]
Serial.print("ID=");
Serial.print(ID);
Serial.print(" pos=");
Serial.println(pos);
Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

Oeildelys

Oui ça me sert à débugger.
D'accord, je pensais qu'en mettant Serial.println(ID+pos); il n'y avait pas de calcul.
En fait je pensais que cela "collait" uniquement les caractères entre eux.
C'est d'ailleurs ce qu'il se produit : le moniteur série me renvoie une valeur correcte avec le code que j'ai écrit (j'envoie 1180, je récupère bien 1180).

Simplement, ce que je ne comprends pas, c'est pourquoi je n'ai aucun mouvement.

Alain46

#11
Dec 04, 2017, 06:43 pm Last Edit: Dec 04, 2017, 06:45 pm by Alain46
Pour "1180", tu récupère bien 1180

Mais avec ton calcul le servo a pour id : ID+pos  soit ID=1000 et pos=180, je suis d'accord ça fait 1180
Mais ton ID de servo est 1000

Pour "2180", ton ID de servo est 2000
Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

Oeildelys

Pour "1180", tu récupère bien 1180

Mais avec ton calcul le servo a pour id : ID+pos  soit ID=1000 et pos=180, je suis d'accord ça fait 1180
Mais ton ID de servo est 1000

Pour "2180", ton ID de servo est 2000
Oui je vois. Merci.
Il faut que je trouve un moyen d'écrire les caractères côte à côte tel que 1180 ou 2180 sans qu'il y ait d'addition (seulement des caractères mis bout à bout) sinon je vais obtenir 181 ou lieu de 1180.

Alain46

Je t'ai donné la solution, maintenant si tu veu pas essayer, je t'y oblige pas
Quote
Essaye avec


ID=(int) (inputString[0]-'0');

...

Serial.print("ID=");
Serial.print(ID);
Serial.print(" pos=");
Serial.println(pos);
Un programme qui se compile sans erreur n'est pas forcément un programme qui fonctionne.

Oeildelys

Je t'ai donné la solution, maintenant si tu veu pas essayer, je t'y oblige pas
Si si je vais essayer !
Autant pour moi je croyais que cétait seulement la méthode de débuggage.

Merci beaucoup, je ne suis plus à l'école je n'ai plus le matériel avec moi, mais demain j'essaie bien entendu.

Go Up