Go Down

Topic: Problème de lecture de l'état d'un interrupteur sous Linux (Read 660 times) previous topic - next topic

Anaelle

Bonjour à tous,

Je suis novice en électronique (mais je m'accroche!), j'ai longtemps cherché la solution à mon problème sans succès... Voilà pourquoi je me tourne vers vous en espérant que vous pourrez l'aider !

J'ai un problème de lecture de l'état d'un interrupteur sous Linux (Ubuntu). Sous Windows mon PC lit très bien l'état de mes deux interrupteurs.
Je dois intégrer mon programme au reste du système d'exploitation du robot et donc interfacer mon programme Arduino avec ROS (donc forcément utiliser Linux).

Voici mon problème en détails :

Je réalise un petit système qui permet de sortir ou de rentrer deux petites plaques à l'aide d'un moteur DC 12V et de deux interrupteurs (l'un indique à mon programme quand les plaques ont atteint leur extension maximale et l'autre indique quand les plaques sont rentrées).
J'ai donc besoin de récupérer l'état des interrupteurs.

De façon simple mon programme fait les choses suivantes :

1) ROS donne l'ordre d'étendre les plaques --> le moteur démarre
2) Tant que (interrupteur 1 ouvert) --> le moteur tourne dans le sens des aiguilles d'une montre
3) Le moteur s'arrête quand on sort de la boucle i.e. quand l'interrupteur 1 se ferme
...
4) ROS donne l'ordre de rentrer les plaques -->
5) Tant que (interrupteur 2 ouvert) --> le moteur tourne dans le sens inverse des aiguilles d'une montre

J'ai défini l'état de mes interrupteurs pas des booléens (1=ouvert, 0=fermé), par exemple pour l'interrupteur 1 :

boolean stateSwitch1 = digitalRead(switch1Pin);  // switch1Pin est le Pin de Arduino auquel est relié mon interrupteur
Je récupère l'état des interrupteurs par la commande :
stateSwitch1 = digitalRead(switch1Pin);
et je l'affiche pour vérifier ce que fait mon programme :
Serial.println(stateSwitch1, DEC);

Sur mon PC (Windows) cela marche très bien (les 0 ou les 1 que j'obtiens correspondent bien à l'état de mes interrupteurs).

Sur le système d'exploitation du robot (ROS sur Ubuntu), quand je fais tourner le même programme j'obtiens de façon aléatoire des 0 ou des 1, ces valeurs changent tout le temps même quand je ne touche pas aux interrupteurs. Par exemple en lançant une boucle qui lit l'état de l'interrupteur j'obtient :

1
1
1
0
0
1
1
0
1

Alors que je n'ai pas touché à l'interrupteur, il est resté en position ouverte, je n'aurais dû obtenir que des 1.

J'ai déjà vérifié que la communication entre ROS et arduino se faisait bien.

Auriez vous une solution pour lire sans erreur l'état des interrupteurs sous Linux?

Voici le code de mon programme :

#include <ros.h>
#include <std_msgs/Bool.h>

void messageCb( const std_msgs::Bool& msg);

ros::NodeHandle nh;
ros::Subscriber<std_msgs::Bool> sub("lift", &messageCb );

// Declaration of variables
int  enablePin = 11;
int  in1Pin = 10;
int  in2Pin = 9;
int  switch1Pin = 7;
int  switch2Pin = 2;
int speed = 200;


void setup()
{
pinMode(in1Pin, OUTPUT);
pinMode(in2Pin, OUTPUT);
pinMode(enablePin, OUTPUT);
pinMode(switch1Pin, INPUT );
pinMode(switch2Pin, INPUT );

  //Switch M12V DC motor on
  analogWrite(enablePin, speed);
  digitalWrite(in1Pin, LOW);
  digitalWrite(in2Pin, HIGH);
 
}

void messageCb( const std_msgs::Bool& msg){
 
  if (msg.data==true){
    boolean stateSwitch1 = digitalRead(switch1Pin);
    boolean stateSwitch2 = digitalRead(switch2Pin);
 
    //Open arms while there are not in opened position (= switch 1 on)
    while(!(stateSwitch1 && ! stateSwitch2))
    {
      stateSwitch1 = digitalRead(switch1Pin);
      stateSwitch2 = digitalRead(switch2Pin);
      analogWrite(enablePin, speed);
      digitalWrite(in1Pin, LOW);
      digitalWrite(in2Pin, HIGH);
    }
  }
  else{
    boolean stateSwitch1 = digitalRead(switch1Pin);
    boolean stateSwitch2 = digitalRead(switch2Pin);
 
    //Latch arms while there are not in closed position (= switch 2 on)
    while(! (!stateSwitch1 && stateSwitch2))
    {
      stateSwitch1 = digitalRead(switch1Pin);
      stateSwitch2 = digitalRead(switch2Pin);
      analogWrite(enablePin, speed);
      digitalWrite(in1Pin, HIGH);
      digitalWrite(in2Pin, LOW);
    } } }

// Main Loop
void loop(){
  nh.subscribe(sub);
  nh.spinOnce();
  delay(1);}

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy