Interruption ou boucle pour attendre une intruction materielle

Bonjour à tous
je réalise pour mes petits enfants un canon qui lance des balle de tennis, il fonctionne actuellement avec des relais programmables ce qui n'est pas très satisfaisant. j'ai essayé de me lancer dans la programmation d'une carte UNO pour rassembler l'ensemble des fonctions des phases de chargement et de tir. Pour armer le canon il faut ouvrir la culasse de chargement de la balle, cela met en contact un ILS (boutonAir)
qui envois du 5v sur le pin 5 (evAir) par le changement d'état de la variable (etatair)
.... un anneau de leds donne l’état de chargement du canon et le feu vert pour la le tir
Il y a tout les détails dans les commentaire du programme.
J'ai essayé de fixé des états précis dans l'attente d'un contact extérieur (ILS ou bouton)
dans le programme c'est les moments signalés par des points d'interrogation.
j'ai essayé avec des boucles et des interruptions sans aucun succès. je ne dois pas avoir le niveau suffisant pour résoudre ce genre de PB. j'aimerai avoir un avis pour m'indiquer ce qu'il faut faire ou du moins dans quel sens je dois travailler.
cela fait 1 mois que je suis sur le coup, avec un max de recherche, en vain.
ce n'est peut être possible avec un Arduino et peut être plus simple Raspberry???
je vous joint le programme, auquel j'ai enlevé mes solutions inutiles de boucle et d'interruption. un grand merci pour vos retours.

canon9.ino (4.4 KB)

Bonjour Alcar

Joli projet :wink:
Petite question pour "m'éclairer",

	etatair = digitalRead(boutonAir);  // lecture du contact de vanne air, quand l'on ouvre la culasse pour introduire la balle de tennis un aimant actionne un ILS
	// ce qui permet, via un relais d'ouvrir une electrovanne.

	if (etatair == HIGH) {

Si l'ILS est fermé et que l'on est en PULL_UP (pinMode(boutonAir, INPUT_PULLUP);), on devrai lire LOW ou l'ILS est NF?

A+
Cordialement
jpbbricole

bonjour,
les ILS sont NO, seul le bouton de tir est NF
cette partie la marche correctement jusqu'au premier point d'interrogation
merci

Il y a un truc bizarre, le bouton de tir est lu

etattir = digitalRead(boutonTir);
if (etattir == LOW)

donc avec une initialisation pinMode(boutonTir, INPUT_PULLUP); j'en déduis que ton bouton est NO.

Est ce que tout ces 3 contacts sont bien d'un côté à GND et l'autre sur une entrée de l'Arduino?

Etrange :wink:
J'ai repris ton programme en lisant les contacts actifs à LOW pour qu'il fonctionne à peu près bien.

Ensuite j'ai ajouté 2 variables d'état:

boolean electrovanneOuverte = false;
boolean etatArmeOk = false;

et les 3 conditions

if (etatair == LOW) {
if (etatarm == LOW) {

et
if (etattir == LOW) {
sont maintenant indépendantes.

Essaies ça:

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel leds(12, 7, NEO_GRB + NEO_KHZ800);
const int boutonAir = 5;
const int evAir = 9;
const int armTir = 2;
const int evTir = 10;

const int boutonTir = 3;
const int pinSon = 12;
int etatair = LOW;
int etatarm = LOW;
int etattir = HIGH;

boolean electrovanneOuverte = false;
boolean etatArmeOk = false;

void setup() {
	Serial.begin(115200);
	leds.begin();
	leds.setBrightness(50);
	leds.show();

	//initialisation des modes
	pinMode(boutonAir, INPUT_PULLUP);
	pinMode(evAir, OUTPUT);

	pinMode(armTir, INPUT_PULLUP);
	pinMode(evTir, OUTPUT);

	pinMode(boutonTir, INPUT_PULLUP);

	pinMode(pinSon, OUTPUT);

}

void loop() {
	if (!electrovanneOuverte)     // Si pas ouverte
	{
		leds.fill(leds.Color(255, 0, 0), 0, 12);  // allume toutes les leds en rouge (anneau de 12 leds)
		leds.show();
	}

	etatair = digitalRead(boutonAir);  // lecture du contact de vanne air, quand l'on ouvre la culasse pour introduire la balle de tennis un aimant actionne un ILS
	// ce qui permet, via un relais d'ouvrir une electrovanne.

	if (etatair == LOW) {
		digitalWrite(evAir, HIGH);  // ILS  est en contact, la vanne est s'ouvre et l'air entre dans le reservoir de tir, elle doit rester ouverte entre 4 et 6''
		Serial.println("etatair");

		leds.setPixelColor(0, leds.Color(0, 255, 0));  // allume une leds sur 2 les autres sont rouges (Anneau de 12 leds)
		leds.show();
		delay(300);

		leds.setPixelColor(2, leds.Color(0, 255, 0));
		leds.show();
		delay(300);


		leds.setPixelColor(4, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(6, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(8, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(10, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(12, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		electrovanneOuverte = true;
		// Ici il faudrait que les leds restent allumées en fixe (une rouge, une verte...)???????
		// alors que etatair est peut etre  encore sur HIGH, ou sur LOW ???????
	}

	etatarm = digitalRead(armTir);  // Quand l'on a mis la balle et que l'on referme la culasse,  lecture du contact ILS d'armement

	if (etatarm == LOW) {
		digitalWrite(evTir, LOW);  //envoi la tension sur la borne du contact de tir par l'intermediare d'un relais
		Serial.println("etatarm");

		leds.setPixelColor(0, leds.Color(0, 255, 0));  // maintient les leds vertes allumée
		leds.show();
		leds.setPixelColor(2, leds.Color(0, 255, 0));
		leds.show();
		leds.setPixelColor(4, leds.Color(0, 255, 0));
		leds.show();
		leds.setPixelColor(6, leds.Color(0, 255, 0));
		leds.show();
		leds.setPixelColor(8, leds.Color(0, 255, 0));
		leds.show();
		leds.setPixelColor(10, leds.Color(0, 255, 0));
		leds.show();
		leds.setPixelColor(12, leds.Color(0, 255, 0));
		leds.show();

		leds.setPixelColor(1, leds.Color(0, 255, 0));  //passe en vertes les leds qui sont encore en rouges
		leds.show();
		delay(300);

		leds.setPixelColor(3, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(5, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		leds.setPixelColor(7, leds.Color(0, 255, 0));
		leds.show();

		delay(300);
		leds.setPixelColor(9, leds.Color(0, 255, 0));
		leds.show();

		leds.setPixelColor(11, leds.Color(0, 255, 0));
		leds.show();
		delay(300);

		digitalWrite(evAir, LOW); // ferme l'electrovanne de remplissage du reservoir de tir

		leds.fill(leds.Color(0, 255, 0), 0, 11);  // maintient allumé  toutes  les leds en vert
		leds.show();

		etatArmeOk = true;
		// Ici il faudrait que evTir reste sur HIGH et que toutes les leds soient allumées en vertes fixes, en attente de l'appui sur le bouton
		// de tir (bouton double NF et NO) qui va ouvrir l'electrovanne de Tir (fontion NO de 1 à 0)?????????
	}
	etattir = digitalRead(boutonTir);  // lecture du bouton de tir. quand il y a un appui sur le bouton de tir l'electrovanne de tir s'ouvre
	// directement par le bouton, sans effet sur le programme par contre la fonction NF du bouton de tir passe de 1 à 0
	// ce qui doit renvoyer au debut du programme et couper le relais allimenté par evtir???????
	if (etattir == LOW) {
		if (electrovanneOuverte && etatArmeOk)
		{
			Serial.println("Tir !!!");
			digitalWrite(evTir, LOW);
			electrovanneOuverte = false;
			etatArmeOk = false;
		}
	}
}

Je n'ai pas essayé de presser les divers contacts dans tout les sens, mais, fait dans l'ordre, pas de problème. A toi d'assurer la sécurité d'emploi.
Pour l'allumage de tes LED tu pourrais simplifier le code en utilisant une boucle, mais ça pourrait une prochaine étape.

Il y a des indications quand au déroulement du programme dans la console à 115200, c'est très pratique pour chercher des disfonctionnements, tu peur supprimer ces print quand ton programme tournera à satisfaction.

A+
Cordialement
jpbbricole

je viens de rentrer, je vais essayer
Le bouton de tir est a double fonction
la fonction NO est sert à amener la tension 24volt
Au bouton de tir via le relais declanché par armtir.

La fonction NF sert à constater que l'on a appuyé sur le bouton , quand il s'ouvre le 5volt n'arrive plus sur le pin 3... sinon les 2 autres entrées pin 2 et 5, reçoivent du 5 volt quand les ILS se collent....

C'est peut-être ça le hic???

En tout cas un grand merci

Bonsoir Alcar

Sans aucun doute :wink:

Pour résumer, autour du programme "corrigé" du post #4, tout les contacts et boutons:

	const int armTir = 2;
	const int boutonAir = 5;
	const int boutonTir = 3;

sont initialisés:

	pinMode(armTir, INPUT_PULLUP);
	pinMode(boutonAir, INPUT_PULLUP);
	pinMode(boutonTir, INPUT_PULLUP);

INPUT_PULLUP signifie que, "en l'air", c'est à dire bouton non pressé ou contact ILS ouvert (donc les 2 NO), un lit un état HIGH, cet état du fait de la résistance interne de l'Arduino, résistance "connectée" par l'instruction pinMode(boutonAir, INPUT_PULLUP);
De ce fait, ces 3 contacts doivent, quand ils sont pressés ou tiré, mettre un GND sur leur pin respective.
Ainsi on lit quand pressé ou tiré:
if (etatair == LOW) {
if (etatarm == LOW) {
if (etattir == LOW) {

Encore une petite info sur les PULL_UP:

A+
Cordialement
jpbbricole

bonjour, voici le lien pour la simulation du programme avec le circuit.

je pensais pouvoir envoyer une photo des canons, mais j'ai trouver comment joindre une photo
encore merci

Bonjour Alcar

Super la simulation!

J'ai trouvé une retouche à faire dans le programme, il faut modifier cette condition ainsi:
if (etatarm == LOW && electrovanneOuverte) {
sans l'ajout de && electrovanneOuverte on peut démarrer directement depuis armTir sans passer par boutonAir

Il faut simplement copier le fichier image dans le presse-papier et faire un coller dans le post.

A titre de comparaison, je te mets une version de ton programme "simplifié" par des boucles, Boucles qui suppriment les répétitions avec uniquement le numéro de la LED qui change.
Avec ça, pour modifier le nombre de LED, il suffit de changer la valeur de la variable ledNombre; Je te laisses regarder la différence :wink:

#include <Adafruit_NeoPixel.h>
const int ledNombre = 12;     // Ni
Adafruit_NeoPixel leds(ledNombre, 7, NEO_GRB + NEO_KHZ800);
const int boutonAir = 5;
const int evAir = 9;
const int armTir = 2;
const int evTir = 10;

const int boutonTir = 3;
const int pinSon = 12;
int etatair = LOW;
int etatarm = LOW;
int etattir = HIGH;

boolean electrovanneOuverte = false;
boolean etatArmeOk = false;

void setup() {
	Serial.begin(115200);
	leds.begin();
	leds.setBrightness(50);
	leds.show();

	//initialisation des modes
	pinMode(boutonAir, INPUT_PULLUP);
	pinMode(evAir, OUTPUT);

	pinMode(armTir, INPUT_PULLUP);
	pinMode(evTir, OUTPUT);

	pinMode(boutonTir, INPUT_PULLUP);

	pinMode(pinSon, OUTPUT);

}

void loop() {
	if (!electrovanneOuverte)     // Si pas ouverte
	{
		leds.fill(leds.Color(255, 0, 0), 0, ledNombre);  // allume toutes les leds en rouge (anneau de 12 leds)
		leds.show();
	}

	etatair = digitalRead(boutonAir);  // lecture du contact de vanne air, quand l'on ouvre la culasse pour introduire la balle de tennis un aimant actionne un ILS
	// ce qui permet, via un relais d'ouvrir une electrovanne.

	if (etatair == LOW) {
		digitalWrite(evAir, HIGH);  // ILS  est en contact, la vanne est s'ouvre et l'air entre dans le reservoir de tir, elle doit rester ouverte entre 4 et 6''
		Serial.println("etatair");

		for (int l = 0; l <= ledNombre; l += 2)     // Step 2
		{
			leds.setPixelColor(l, leds.Color(0, 255, 0));  // allume une leds sur 2 les autres sont rouges (Anneau de 12 leds)
			leds.show();
			delay(300);
		}

		electrovanneOuverte = true;
	}

	etatarm = digitalRead(armTir);  // Quand l'on a mis la balle et que l'on referme la culasse,  lecture du contact ILS d'armement

	if (etatarm == LOW && electrovanneOuverte) {
		digitalWrite(evTir, LOW);  //envoi la tension sur la borne du contact de tir par l'intermediare d'un relais
		Serial.println("etatarm");

		for (int l = 1; l <= ledNombre; l += 2)     // Step 2
		{
			leds.setPixelColor(l, leds.Color(0, 255, 0));  // allume une leds sur 2 les autres sont rouges (Anneau de 12 leds)
			leds.show();
			delay(300);
		}

		digitalWrite(evAir, LOW); // ferme l'electrovanne de remplissage du reservoir de tir

		leds.fill(leds.Color(0, 255, 0), 0, 11);  // maintient allumé  toutes  les leds en vert
		leds.show();

		etatArmeOk = true;
	}
	etattir = digitalRead(boutonTir);  // lecture du bouton de tir. quand il y a un appui sur le bouton de tir l'electrovanne de tir s'ouvre
	// directement par le bouton, sans effet sur le programme par contre la fonction NF du bouton de tir passe de 1 à 0
	// ce qui doit renvoyer au debut du programme et couper le relais allimenté par evtir???????
	if (etattir == LOW) {
		if (electrovanneOuverte && etatArmeOk)
		{
			Serial.println("Tir !!!");
			digitalWrite(evTir, LOW);
			electrovanneOuverte = false;
			etatArmeOk = false;

			for (int f = 0; f < 3; f ++)     // Flasher les LED tir
			{
				leds.fill(leds.Color(255, 0, 0), 0, ledNombre);
				leds.show();
				delay(250);
				leds.fill(leds.Color(0, 0, 0), 0, ledNombre);
				leds.show();
				delay(250);
			}
		}
	}
}

Cordialement
jpbbricole

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.