Probleme avec appel d'une fonction

Bonsoir tout le monde!

Je suis un étudiant en Master Mécatronique.
J’ai un mini-projet a faire avec Arduino: une tourelle contrôlée par joystick (2 servos). Avec 2 modes de fonctionnement:

  • Maintien de position même quand on relâche le joystick (avec zone morte ou dead bande).
  • suivi continue de la position du joystick.

Pour ceci j’ai utilise un bouton poussoir, tourne en switch par software, pour sélectionner entre les deux.
j’ai ajouté aussi un LCD pour afficher lequel des modes est actif. Jusqu’ici tout va bien

Le problème est quand je fait l’appel des fonctions, selon l’état du bouton, les fonctions des deux modes ne fonctionnent pas, même si l LCD affiche correctement quel mode est actif.

je vous laisse ici un ample du code, juste avec l’appel d’un des deux modes. sans lcd et sans bouton:

#include <Servo.h>;

const int servoHPin = 9;
const int servoVPin = 10;

int horzPin = A0;
int vertPin = A1;

Servo horzServo;
Servo vertServo;

int horzInitPos;
int vertInitPos;

int horzPotMAX = 2350;
int horzPotMIN = 594;
int vertPotMAX = 2350;
int vertPotMIN = 594;

int horzDeadBandLOW = 400;
int horzDeadBandHIGH = 600;
int vertDeadBandLOW = 400;
int vertDeadBandHIGH = 600;

int horzSpeed = 4 ;
int vertSpeed = 4 ;

int jyHorzVal;
int jyVertVal;
int jyHorzMapped;
int jyVertMapped;




void setup() {
  // put your setup code here, to run once:

  horzServo.attach(servoHPin);
  vertServo.attach(servoVPin);
  horzInitPos = 1472;
  vertInitPos = 1472;
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);


}


void loop() {
  // put your main code here, to run repeatedly:

holdPositionMODE();

}



void holdPositionMODE() {
  
  int horzInitPos;
  int vertInitPos;

  jyHorzVal=analogRead(horzPin);
  jyVertVal=analogRead(vertPin);
  
  horzInitPos = constrain(horzInitPos, horzPotMIN, horzPotMAX) ;
  vertInitPos = constrain(vertInitPos, vertPotMIN, vertPotMAX) ;
  
  if(jyHorzVal<horzDeadBandLOW || jyHorzVal>horzDeadBandHIGH)
    {
      jyHorzMapped=map(jyHorzVal,0,1023,horzSpeed,-horzSpeed);
      horzInitPos=horzInitPos+jyHorzMapped;
    }
  
  if(jyVertVal<vertDeadBandLOW || jyVertVal>vertDeadBandHIGH)
    {
      jyVertMapped=map(jyVertVal,0,1023,vertSpeed,-vertSpeed);
      vertInitPos=vertInitPos+jyVertMapped;
    }
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);

  delay(20);
}

Et aussi le fichier avec tout mon code.

J’espère que quelqu’un pourrait m’aider parce que la je suis bloque.

Merci beaucoup!!

two_modes_servos.ino (5.02 KB)

Je n'ai pas tout lu, mais il y a un truc qui pourrait être en cause: dans la fonction holdPositionMode(), il y a deux variables horzInitPos qui sont initialisées, alors que deux variables portent le même nom au niveau global (déclarées en début de sketch). Puisqu'elles sont initialisées dans la fonction, ce sont les variables locales dans l'espace de la fonction qui sont appelées prioritairement, et donc une fois la fonction terminée elles disparaissent. Il est donc très possible que ce soit la cause du dysfonctionnement constaté...

troisiemetype:
Je n’ai pas tout lu, mais il y a un truc qui pourrait être en cause: dans la fonction holdPositionMode(), il y a deux variables horzInitPos qui sont initialisées, alors que deux variables portent le même nom au niveau global (déclarées en début de sketch). Puisqu’elles sont initialisées dans la fonction, ce sont les variables locales dans l’espace de la fonction qui sont appelées prioritairement, et donc une fois la fonction terminée elles disparaissent. Il est donc très possible que ce soit la cause du dysfonctionnement constaté…

mon erreur, j’ai mal copie le code. la déclaration à l’intérieur de la fonction ne devrait pas être la. voila mon code.

#include <Servo.h>;

const int servoHPin = 9;
const int servoVPin = 10;

int horzPin = A0;
int vertPin = A1;

Servo horzServo;
Servo vertServo;

int horzInitPos;
int vertInitPos;

int horzPotMAX = 2350;
int horzPotMIN = 594;
int vertPotMAX = 2350;
int vertPotMIN = 594;

int horzDeadBandLOW = 400;
int horzDeadBandHIGH = 600;
int vertDeadBandLOW = 400;
int vertDeadBandHIGH = 600;

int horzSpeed = 4 ;
int vertSpeed = 4 ;

int jyHorzVal;
int jyVertVal;
int jyHorzMapped;
int jyVertMapped;




void setup() {
  // put your setup code here, to run once:

  horzServo.attach(servoHPin);
  vertServo.attach(servoVPin);
  horzInitPos = 1472;
  vertInitPos = 1472;
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);


}


void loop() {
  // put your main code here, to run repeatedly:

holdPositionMODE();

}



void holdPositionMODE() {
  

  jyHorzVal=analogRead(horzPin);
  jyVertVal=analogRead(vertPin);
  
  horzInitPos = constrain(horzInitPos, horzPotMIN, horzPotMAX) ;
  vertInitPos = constrain(vertInitPos, vertPotMIN, vertPotMAX) ;
  
  if(jyHorzVal<horzDeadBandLOW || jyHorzVal>horzDeadBandHIGH)
    {
      jyHorzMapped=map(jyHorzVal,0,1023,horzSpeed,-horzSpeed);
      horzInitPos=horzInitPos+jyHorzMapped;
    }
  
  if(jyVertVal<vertDeadBandLOW || jyVertVal>vertDeadBandHIGH)
    {
      jyVertMapped=map(jyVertVal,0,1023,vertSpeed,-vertSpeed);
      vertInitPos=vertInitPos+jyVertMapped;
    }
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);

  delay(20);
}

ce que j’ai fait est declares les variables comme globales. horzInitPos et vertInitPos sot initialisées dans void setup()

donc, que ce que tu me proposes de faire? jai pas bien compris.

Merci!

Ooh merde !!! Quelle erreur stupide j’ai fait! J’avais connecté les servos aux broches 5 et 6. Parce que j’ai utilisé un registre à décalage avec l’écran LCD donc je n’ai pas à utiliser 9 broches juste pour elle, maintenant l’écran LCD utilise 3 broches: 13, 12 et 9.

Okey donc l’appel de fonction est résolu, buut maintenant j’ai de nouveaux problèmes.

PROBLÈMES:

  • d’abord l’affichage à cristaux liquides ne montre aucun mode (juste le msg de réparation de “ARDUINO TURRET”);

  • quand je clique sur le bouton une fois il montre “Hold position ON”

  • si je clique de nouveau rien ne change

  • Je dois faire un clic prolongé de sorte qu’il change et montre “Sweep mode ON”

  • Même si j’appuie sur le bouton le mode ne change pas, l’écran LCD change le message (cela signifie qu’il appelle l’autre fonction lcd) mais pas la fonction du mode. Son toujours le mode de position de maintien

  • à chaque fois que je clique sur le bouton de la tourelle tente d’aller à 90º (en microsecondes pour mes servos est 1472)

voila mon code complet:

#include <Servo.h>;
#include <ShiftedLCD.h>

const int servoHPin = 5;      //  arduino pin affected to SERVO 1 (horizontal motion)
const int servoVPin = 6;     //  arduino pin affected to SERVO 2 (vertical motion)

const int laserPin = 4;       //  arduino pin affected to the laser
const int lsrButtonPin = 2;   //  arduino pin affected to the laser button

const int modeButtonPin = 8;  //  arduino pin affected to the "Mode" activated

int lsrButtonState = LOW;    //  tracks the state of the button, low if not pressed, high if pressed
int laserState = -1;         //  tracks the state of the LED, negative if off, positive if on
long lastDebounceTime1 = 0;  // the last time the output pin was toggled
long debounceDelay1 = 200;   // the debounce time; increase if the output flickers


int lastModeButtonState = LOW;    //  tracks the last state of the button
int currentModeButtonState = HIGH;  //  tracks the current state of the button
long lastDebounceTime2 = 0;       // the last time the output pin was toggled
long debounceDelay2 = 200;        // the debounce time; increase if the output flickers


int horzPin = A0;
int vertPin = A1;

Servo horzServo;
Servo vertServo;

LiquidCrystal lcd(9);

int horzInitPos;
int vertInitPos;

int horzPotMAX = 2350;
int horzPotMIN = 594;
int vertPotMAX = 2350;
int vertPotMIN = 594;

int horzDeadBandLOW = 400;
int horzDeadBandHIGH = 600;
int vertDeadBandLOW = 400;
int vertDeadBandHIGH = 600;

int horzSpeed = 2 ;
int vertSpeed = 2 ;

int jyHorzVal;
int jyVertVal;
int jyHorzMapped;
int jyVertMapped;

void setup() {
  // put your setup code here, to run once:

  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("ARDUINO TURRET");
    
  horzServo.attach(servoHPin);
  vertServo.attach(servoVPin);
  
  pinMode (laserPin, OUTPUT);
  pinMode (lsrButtonPin, INPUT);
  pinMode (modeButtonPin, INPUT);
  
  horzInitPos = 1472;
  vertInitPos = 1472;
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);

}


void loop() {
  // put your main code here, to run repeatedly:
holdPositionMODE();
  lsrButtonState = digitalRead(lsrButtonPin);
 
  //filter out any noise by setting a time buffer
  if ((millis() - lastDebounceTime1) > debounceDelay1) {
 
    //if the button has been pressed, toggle the Laser from "off to on" or "on to off"
    if ((lsrButtonState == HIGH) && (laserState < 0)) {
 
      digitalWrite(laserPin, HIGH); //turn Laser on
      laserState = -laserState; //now the Laser is on, we need to change the state
      lastDebounceTime1 = millis(); //set the current time
    }
    else if ((lsrButtonState == HIGH) && (laserState > 0)) {
 
      digitalWrite(laserPin, LOW); //turn Laser off
      laserState = -laserState; //now the Laser is off, we need to change the state
      lastDebounceTime1 = millis(); //set the current time
    }
 
  }

  
  currentModeButtonState=digitalRead(modeButtonPin);

    //filter out any noise by setting a time buffer
  if ((millis() - lastDebounceTime2) > debounceDelay2) {

    //if the button has been pressed, change the motion mode of the turret, call the  functions
    if ((currentModeButtonState == HIGH) && (lastModeButtonState == LOW)){
      sweepMODE();
      lcdMODE1();
      lastDebounceTime2 = millis();
    }
    else if ((currentModeButtonState == LOW) && (lastModeButtonState == HIGH)){
      holdPositionMODE();
      lcdMODE2();
      lastDebounceTime2 = millis();

    }
    
 }
  lastModeButtonState = currentModeButtonState;
}




void holdPositionMODE() {

  jyHorzVal=analogRead(horzPin);
  jyVertVal=analogRead(vertPin);
  
  horzInitPos = constrain(horzInitPos, horzPotMIN, horzPotMAX) ;
  vertInitPos = constrain(vertInitPos, vertPotMIN, vertPotMAX) ;
  
  if(jyHorzVal<horzDeadBandLOW || jyHorzVal>horzDeadBandHIGH)
    {
      jyHorzMapped=map(jyHorzVal,0,1023,horzSpeed,-horzSpeed);
      horzInitPos=horzInitPos+jyHorzMapped;
    }
  
  if(jyVertVal<vertDeadBandLOW || jyVertVal>vertDeadBandHIGH)
    {
      jyVertMapped=map(jyVertVal,0,1023,vertSpeed,-vertSpeed);
      vertInitPos=vertInitPos+jyVertMapped;
    }
  
  horzServo.writeMicroseconds(horzInitPos);
  vertServo.writeMicroseconds(vertInitPos);

  delay(2);

}


void lcdMODE1() {

  lcd.setCursor(0,1);
  lcd.print("Hold position ON");
  
}


void sweepMODE () {
  
  jyHorzVal=analogRead(horzPin);
  jyVertVal=analogRead(vertPin);
  
  
  horzInitPos = constrain(horzInitPos, horzPotMIN, horzPotMAX) ;
  vertInitPos = constrain(vertInitPos, vertPotMIN, vertPotMAX) ;
  
  jyHorzMapped=map(jyHorzVal,0,1023,horzPotMIN,horzPotMAX);
  //horzInitPos=horzInitPos+jyHorzMapped;
  
  jyVertMapped=map(jyVertVal,0,1023,vertPotMIN,vertPotMAX);
  //vertInitPos=vertInitPos+jyVertMapped;
  
  if(jyHorzMapped<horzInitPos){
    horzInitPos=horzInitPos+horzSpeed;
  }
  
  if(jyVertMapped<vertInitPos){ 
    vertInitPos=vertInitPos+vertSpeed;
  }
  
  horzServo.writeMicroseconds(jyHorzMapped);
  vertServo.writeMicroseconds(jyVertMapped);
  delay(100);
 
}


void lcdMODE2() {
  
  lcd.setCursor(0,1);
  lcd.print("Sweep mode ON   ");
  
}