Besoin d'aide Projet Table élévatrice automatisée !

Bonjour à tous !

Alors voila étant actuellement en Terminale S SI , je présente à la fin de l'année mon projet de SI
qui consiste à automatiser une table élévatrice que l'on peut trouver dans les labos de Physiques Chimie .

Je m'occupe de la partie programmation en Arduino.
Pour cela nous avons donc décidé d'utiliser un module bluetooth HC-06 afin de recevoir la Hauteur auprès de l'utilisateur + 2 boutons poussoirs (un pour le démarrage et un pour l'arret d'urgence ), un moteur pas à pas afin d'élever la table et un écran lcd afin d'afficher les différentes informations.

Mon code est presque fini mais je fais aujourd'hui appel à vous afin de m'aider à améliorer mon code et afin de le perfectionner .

Voici mon code :

#include <SoftwareSerial.h>
#include <Wire.h>
#include <Adafruit_RGBLCDShield.h>
#include <utility/Adafruit_MCP23017.h>
#include <Stepper.h>

SoftwareSerial HC06(51,53);
String hauteurRecu = String();
int NbHauteurRecu = -1;
int HauteurActuelle = 80;
int Hauteur = 0;

const int  BP1 = 24; /*Boutton demarrage/ 

const int  BPU = 28; /*Boutton d'arret d'urgence*/

int hauteur = 0;
double x = 0;
float o = 0;
const float y = 1/0.35;
const float v = 80.4871198924;
const float b = 23.23;
const float p = 69.5;
int m =0;

Stepper monMoteur(200,31,33,35,37);


Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();


#define RED 0x1

void setup() {
  
  pinMode(BP1, INPUT);
  
  pinMode(BPU, INPUT);

 
  
   Serial.begin(9600);

  lcd.begin(16, 2);
  HC06.begin(9600);

  lcd.print("Entrer la valeur");
  lcd.setCursor(4,1);
  lcd.print("de hauteur");
  lcd.setBacklight(RED);
  
  monMoteur.setSpeed(9);

}

void loop() {

  int Urgence = digitalRead(BPU);
  
do{
  
  int Demarrage = digitalRead(BP1);
  int Urgence = digitalRead(BPU);



if (Demarrage == LOW) { // Bouton demarrage
  Demarrage = LOW;
  lcd.clear();
  lcd.print("Bouton demarrage");
  lcd.setCursor(4,1);
  lcd.print("enclenche");
  delay(2000);

  
  hauteurRecu = String(); // Module bluetooth ici
  while(HC06.available())
  {
    delay(3);
    char c = HC06.read();
    hauteurRecu += c;
    NbHauteurRecu = hauteurRecu.toInt();
    m = 1; 
   }
   
 if (m == 1 && NbHauteurRecu != -1) {   

 if (NbHauteurRecu >= 80 && NbHauteurRecu <= 270 ){ 
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print("Votre hauteur" );
    lcd.setCursor(4,1);
    lcd.print("est de ");
    lcd.print(NbHauteurRecu);
    delay(2000);
    lcd.clear();
    lcd.setCursor(4,0);
    lcd.print("Elevation");
    lcd.setCursor(4,1);
    lcd.print("en cours");
    delay(3000);

   


  
  
  //x = (exp(y)*log((NbHauteurRecu-HauteurActuelle)/v))*200;
  x = exp(y)*log(float(NbHauteurRecu-HauteurActuelle)/v);  // formule qui convertit Hauteur en nombre pas  pour moteur moteur
   
  
  
  x = o*200;  // on multiplie par 200 car moteur 200 pas
  monMoteur.step(x);
  lcd.clear();
  lcd.print("Hauteur : " );
  lcd.print(NbHauteurRecu);
  lcd.print(" mm");

    
   }
 HauteurActuelle=NbHauteurRecu;
   }

 if (NbHauteurRecu > 270 ){
  lcd.clear();
  lcd.print("Erreur Hauteur ");
  lcd.setCursor(0,1);
  lcd.print("trop importante");
  delay(3000);
  lcd.clear();
  lcd.print("Entrer nombre");
  lcd.setCursor(0,1);
  lcd.print("inferieur 270mm");
  }
  
if (NbHauteurRecu < 80){
  lcd.clear();
  lcd.print("Erreur Hauteur");
  lcd.setCursor(0,1);
  lcd.print("insuffisante");
  delay(3000);
  lcd.clear();
  lcd.print("Entrer nombre");
  lcd.setCursor(0,1);
  lcd.print("superieur 80mm");

  }
  
   
   
   
  
    
    
                  
     m = 0;                  
               }
              
 else {
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Appuyer sur le");
  lcd.setCursor(0,1);
  lcd.print("bouton demarrage");
  delay(3000);
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Afin de lancer");
  lcd.setCursor(2,1);
  lcd.print("le programme");
  delay(3000);}
  
}while (Urgence == HIGH);

Urgence = LOW;



               
               

}

Merci beaucoup pour votre aide !
Bonne journée / soirée

sketch_jan14a.ino (3.57 KB)

Bonjour,

tu crées au début de la fonction void loop () la variable Urgence pour la créer juste après dans la boucle do...while().

J'ai du mal à comprendre pourquoi tu met :

if (Demarrage == LOW) { // Bouton demarrage
** Demarrage = LOW;**

car si "démarrage" a pour valeur 0, inutile de lui donner la valeur 0 car il l'a déjà.

Lorsque tu crées les variables "Urgence" et "Démarrage", tu peux leur donner le type "Boolean" au lieu de "int" car elles ne peuvent prendre que deux valeurs, 0 ou 1.

Bon je vais m'arrêter de corriger le code car j'ai du mal à croire qu'il fonctionne, notamment le bouton poussoir d'urgence qui se trouve être la condition de la boucle mais pourtant il y a plein de fonction "delay()" dans cette boucle donc si l'utilisateur appuie sur le bouton poussoir en urgence, et qu'on se trouve au milieu de la boucle "do...while();", le bouton poussoir va revenir dans sa position d'origine et son changement d'état ne sera même pas enregistré donc le programme continuera à fonctionner.

Et bon comme son nom l'indique, un bouton 'arrêt d'urgence" doit arrêter la machine en urgence, donc il faudrait le relier électroniquement, sans rapport avec la carte électronique, pour que lors de l'appuie, l'Arduino s'éteigne et tout le système électrique en fasse de même.

zTont:
Bonjour,

tu crées au début de la fonction void loop () la variable Urgence pour la créer juste après dans la boucle do...while().

J'ai du mal à comprendre pourquoi tu met :

if (Demarrage == LOW) { // Bouton demarrage
Demarrage = LOW;

car si "démarrage" a pour valeur 0, inutile de lui donner la valeur 0 car il l'a déjà.

Lorsque tu crées les variables "Urgence" et "Démarrage", tu peux leur donner le type "Boolean" au lieu de "int" car elles ne peuvent prendre que deux valeurs, 0 ou 1.

Bon je vais m'arrêter de corriger le code car j'ai du mal à croire qu'il fonctionne, notamment le bouton poussoir d'urgence qui se trouve être la condition de la boucle mais pourtant il y a plein de fonction "delay()" dans cette boucle donc si l'utilisateur appuie sur le bouton poussoir en urgence, et qu'on se trouve au milieu de la boucle "do...while();", le bouton poussoir va revenir dans sa position d'origine et son changement d'état ne sera même pas enregistré donc le programme continuera à fonctionner.

Et bon comme son nom l'indique, un bouton 'arrêt d'urgence" doit arrêter la machine en urgence, donc il faudrait le relier électroniquement, sans rapport avec la carte électronique, pour que lors de l'appuie, l'Arduino s'éteigne et tout le système électrique en fasse de même.

Bonjour,

Tout d'abord Merci beaucoup pour votre aide et pour votre réponse .

J'ai corrigé les erreurs que vous avez constaté notamment avec le démarrage.
Puis j'ai donné aux variables Urgence et démarrage le type boolean comme vous me l'aviez recommandé.

Je rencontre en effet le problème que vous avez cité au niveau de ma commande d'urgence : je ne sais pas comment faire pour que celle ci fonctionne a n'importe quel moment et qu'on puisse intervenir sur celle ci a n'importe quel moment . De la manière dont je l'ai programmé on ne peut en effet pas intervenir dessus à n'importe quel moment puisqu'il y a des instructions qui se réalisent .

La solution serait donc de le relier électriquement ? Comment faire et quel serait mon code ?

Merci beaucoup pour votre précieuse aide

zTont:
Et bon comme son nom l'indique, un bouton 'arrêt d'urgence" doit arrêter la machine en urgence, donc il faudrait le relier électroniquement, sans rapport avec la carte électronique, pour que lors de l'appuie, l'Arduino s'éteigne et tout le système électrique en fasse de même.

Je suis pas tout à fait d'accord sur ce point. Un arrêt d'urgence doit bien effectivement stopper la machine mais pas nécessairement couper l'alimentation électrique.
Imagine un système de frein qui fonctionne que sous tension, suivant ton principe, les freins ne fonctionnerai plus alors que justement on en aurai besoin lors de l'arrêt d'urgence.
En pratique les systèmes bien conçues doivent se retrouver en sécurité même en cas de coupure d'alimentation.

kankan775:
Je rencontre en effet le problème que vous avez cité au niveau de ma commande d'urgence : je ne sais pas comment faire pour que celle ci fonctionne a n'importe quel moment et qu'on puisse intervenir sur celle ci a n'importe quel moment . De la manière dont je l'ai programmé on ne peut en effet pas intervenir dessus à n'importe quel moment puisqu'il y a des instructions qui se réalisent .

La solution serait donc de le relier électriquement ? Comment faire et quel serait mon code ?

A minima, je partirai sur une interruption matérielle (attachInterrupt()) avec une fonction qui gère correctement l'arrêt de la table (blocage des moteurs et verrouillage des commandes + un reset lors de l'acquittement de l'arrêt d'urgence)

(Tu pourrais utiliser un bouton d'arrêt d'urgence)

Ou oui pourquoi pas les interruptions, c'est vrai !

Mais bon, de toute façon, il ne risque pas d'arriver grand chose puisque tu fais fonctionner le tout en 5V, avec probablement un petit moteur pas à pas, il n'y pas vraiment de grand risque, il y en a encore moins si ton circuit électrique est bien conçu, un simple interrupteur à bascule "On/Off" suffirait.

Je suis d'accord avec toi Jambe mais bon pour le coup, ce n'est pas vraiment le cas ici ^^

Jambe:
A minima, je partirai sur une interruption matérielle (attachInterrupt()) avec une fonction qui gère correctement l'arrêt de la table (blocage des moteurs et verrouillage des commandes + un reset lors de l'acquittement de l'arrêt d'urgence)

Merci pour ton aide !!

Je connais pas du tout interruption matérielle attachInterrupt()
De ce que j'en ai compris les interruptions permettraient à certaines tâches importantes de survenir à tout moment, et donc de contrer ce problème ?

Dans mon cas comment devrais-je réaliser cette interruption ?

Tu as un tutoriel qui est bien fait, ici : LOCODUINO - Les interruptions (1)

Il faut savoir que les interruptions ne peuvent être utilisées que sur les broches 3 et 3 de l'Arduino.

Il faut savoir que les interruptions ne peuvent être utilisées que sur les broches 3 et 3 de l'Arduino.

C'est Dupont et Dupond ? :grin:

Et ce n'est pas vrai.

Ce n'est pas parce que Wiring/Arduino n'a pas géré tous les cas que la possibilité d'avoir une interruption sur n'importe quelle pin n'existe pas. Wiring/arduino c'est pratique mais c'est réducteur, le micro peut faire beaucoup mieux.

Extrait de la datasheet :

The External Interrupts are triggered by the INT0 and INT1 pins or any of the PCINT23...0 pins.

Voir pour quelques explications
http://forum.arduino.cc/index.php?topic=100906.0

Pour les interruptions autres que les pins PD2 (arduino 2) et PD3 (arduino 3) c'est juste un peu plus compliqué.
Cela fonctionne bien et c'est bien utile quand on a besoin de plus de 2 pins devant générer une interruption.

Je suis pas tout à fait d'accord sur ce point. Un arrêt d'urgence doit bien effectivement stopper la machine mais pas nécessairement couper l'alimentation électrique.

Cela dépend des situations, en électricité générale l’arrêt d'urgence coupe totalement l'alimentation, en automatise il coupe juste les actionneurs et envoie un signal a la centrale.

L'utilisation d'une interruption ne confère pas une plus grande sécurité de fonctionnement. Si l'interruption est masquée la sécurité ne sera jamais activée.
La sécurité doit interrompre le fonctionnement de l'actionneur au plus près afin de limiter les risques liés à des composants intermédiaires défectueux (aussi bien logiciels que matériels).
L'exemple du frein est à mon sens "tordu" le frein sûr étant justement inactif lorsqu'il est excité afin d'être certain qu'il soit opérationnel si l'énergie était coupée.

@zTont bien sur qu'il n'y a pas de danger en soit dans cette application (encore qu'un doigt pris dans ce genre de montage...) . Mais quitte mettre une sécurité autant le faire bien.