Bonjour, j'aimerai avoir votre aide à propos d'un problème de programmation.
Je suis en terminal STI2D et je dois donc réaliser un projet. Dans celui-ci je connecte deux arduino UNO ensemble et grâce à la carte dîtes esclave je cherche à contrôler un moteur. Dans le fonctionnement de mon système j'ai besoin de marquer des delay () dans le void receiveEvent (), or quand je test mon programme, le système ignore mes delais.
J'aimerais donc savoir si il y a une programmation spéciale à faire dans le void receiveEvent () pour pouvoir le faire lire les delais.
voici mon code :
//Arduino esclave:
#include <Wire.h> // Librairie pour la communication I2C
// Moteur
const int ouverture = 9; // Pin pour l'ouverture
const int fermeture = 12; // Pin pour la fermeture
//
void setup()
{
// Setup moteur
pinMode( ouverture, OUTPUT); // pin en sortie
pinMode( fermeture, OUTPUT); // pin en sortie
// établit le portail à l'arret:
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
Wire.begin(4); // Rejoindre le bus à l'adresse #4
Wire.onReceive(receiveEvent); // Preparer une fonction spécifique a la reception de donnee
Serial.begin(9600); // Demarrer la liaison serie avec le PC
}
void loop ()
{
}
// Fonction qui s'execute si quelque chose est present sur l interface
void receiveEvent(int howMany)
{
int x = Wire.read(); // recevoir un chiffre
Serial.println(x); // afficher ce chiffre sur l'interface serie
if(x == 1)// si on veut ouvrir le portail
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
delay(3000);
// Moteur en marche arrière
digitalWrite( ouverture, LOW); // Ouverture activée
digitalWrite( fermeture, HIGH); // Fermeture désactivée
//
// On allume les signaux
digitalWrite(Flashlight, LOW);// on allume le flash
digitalWrite(Spotlight, LOW); // on allume l'halogène
//
}
if(x == 0)// si on veut Fermer le portail
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
delay(3000);
// Moteur en marche avant
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, LOW); // Fermeture activée
//
// On allume les signaux
digitalWrite(Flashlight, LOW);// on allume le flash
digitalWrite(Spotlight, LOW); // on allume l'halogène
//
}
if (x == 2 )// si on veut arreter le portail
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
}
}
Ben je croyais que les projets STI2D étaient finis
T'es en avance pour l'année prochaine ?
Bon allez, par rapport à tes collègues tu as l'air de savoir un peu mieux de quoi tu parles.
Et en plus ton sujet est bien présenté, donc...
Tu veux faire beaucoup trop de choses dans receiveEvent()
Cette fonction est appelée dans le cadre d'une interruption.
Elle doit être la plus courte possible.
Elle doit donc :
Lire la valeur reçue par un Wire.read(), et se contenter de stocker le résultat dans une variable globale sans le traiter tout de suite.
Valoriser une seconde variable globale qui sert d'indicateur pour signaler qu'il y a quelque chose à traiter.
Et rien d'autre, même pas un Serial.print et encore moins un delay()
Et dans le loop(), lorsqu'il y a quelque chose à traiter (c'est là que la valeur de la variable indicateur est utile), faire tout ce que tu as mis initialement dans receiveEvent().
Merci pour ta réponse
Non en fait il me reste quelques jours, du coup j'en profite pour finaliser les problèmes de fonctionnement qu'il me reste
D'accord donc en fait si je comprend bien, le void receiveEvent () ne sert vraiment qu'a stocker et envoyer l'information dans le void loop () par exemple pour que celui-ci la traite.
Un programme de ce type pourrait donc faire l'affaire ? :
//Arduino esclave:
#include <Wire.h> // Librairie pour la communication I2C
// Moteur
const int ouverture = 9; // Pin pour l'ouverture
const int fermeture = 12; // Pin pour la fermeture
int Ouvrir = 0;
int Fermer = 0;
int Arret = 0;
//
void setup()
{
// Setup moteur
pinMode( ouverture, OUTPUT); // pin en sortie
pinMode( fermeture, OUTPUT); // pin en sortie
// établit le portail à l'arret:
digitalWrite( ouverture HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
Wire.begin(4); // Rejoindre le bus à l'adresse #4
Wire.onReceive(receiveEvent); // Preparer une fonction spécifique a la reception de donnee
Serial.begin(9600); // Demarrer la liaison serie avec le PC
}
void loop ()
{
if (Ouvrir == 1)
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
delay(3000);
// Moteur en marche arrière
digitalWrite( ouverture, LOW); // Ouverture activée
digitalWrite( fermeture, HIGH); // Fermeture désactivée
//
// On allume les signaux
digitalWrite(Flashlight, LOW);// on allume le flash
digitalWrite(Spotlight, LOW); // on allume l'halogène
//
}
if (Fermer == 1)
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
delay(3000);
// Moteur en marche avant
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, LOW); // Fermeture activée
//
// On allume les signaux
digitalWrite(Flashlight, LOW);// on allume le flash
digitalWrite(Spotlight, LOW); // on allume l'halogène
//
}
if (Arret == 1)
{
// Moteur à l'arret
digitalWrite( ouverture, HIGH); // Ouverture désactivé
digitalWrite( fermeture, HIGH); // Fermeture désactivé
//
}
}
// Fonction qui s'execute si quelque chose est present sur l interface
void receiveEvent(int howMany)
{
int x = Wire.read(); // recevoir un chiffre
Serial.println(x); // afficher ce chiffre sur l'interface serie
if(x == 1)// si on veut ouvrir le portail
{
Ouvrir = 1;
}
if(x == 0)// si on veut Fermer le portail
{
Fermer = 1;
}
if (x == 2 )// si on veut arreter le portail
{
Arret = 1;
}
}
Oui quelque chose comme ça
N'oublie pas de remettre "ouvrir" à zéro dans ton loop, juste après "if (ouvrir==1)"
Parce que sinon tu vas boucler sur la commande reçue
j'ai réalisé le programme final de ma carte esclave. Serait-il possible de savoir ce que vous en pensez ?
Mais avant tout je pense qu'il serait judicieux de ma part d'expliquer réellement mon projet :
Mon objectif est de créer un système pour commander un portail de différentes manières tout en le sécurisant. J'utilise 2 arduino Uno, sur la carte Maître ce trouve le programme pour le commandement par carte à puce et par application ANDROID, et sur la carte esclave ce trouve le programme pour la commande par badge RFID ainsi que tout le système moteur et sécurité.
Sur ce code Maître il n'y a pas de problèmes, c'est sur le programme de la carte esclave que le fonctionnement n'est pas tout à fait celui que j'attendais.
Avec l'aide de bricoleau je pense avoir réglé ce problème. Mais j'aimerais avoir si possible une confirmation sur le code complet de la carte esclave.
Au niveau du câblage de mon système, j'utilise deux contacts fin de course ( un pour l'ouverture et un pour la fermeture ) qui sont câblés en série et je n'ai pas la possibilité de les câbler indépendamment.
Par soucis de sécurité, j'aimerais empêcher la commande d'ouverture lorsque le contact d'ouverture est activé et de même pour la fermeture. J'ai donc essayer de reproduire ce comportement via la programmation mais je ne suis pas sure du résultât.