[CONSEILS] Gestion d'éclairage leds pour un Photobooth

Bonjour,
Etant plus familier avec les Wemos D1 ou autres ESP pour la gestion de mes périphériques de domotique, je suis un vrai débutant côté programmation arduino. Pour mon projet je pense qu'il est judicieux de me tourner vers cet univers mais je préfère d'abord demander vos précieux conseils plutôt que de foncer dans des échecs cuisants...

Je suis en train de réaliser un photobooth (cabine de photos automatisée qu'on voit dans les mariages, anniversaires ou autres soirées évènementielles). Pour ce projet j'ai incorporé au système 2 rangées de 5 leds 12v (sur 2 mosfets IRLZ44N) qui ont deux fonctions :

  • un côté décoratif lorsque l'appareil n'est pas utilisé : pour cette fonction j'ai réussi à bidouiller un début de programme qui joue sur la modulation de largeur d'implusions (PWM) afin de donner un effet de clignotement lent "fader" et ça fonctionne très bien (j'utilise 2 lignes de leds, c'est pourquoi dans mon programme il y a ledPin1 et ledPin2).

  • un côté éclairage intense lorsqu'une photo s'apprête à être prise.
    Montée des leds à pleine puissance pendant 5 secondes puis retour au "mode décoratif"

Voici le code que j'ai mis rapidement en place pour un premier essai :

int ledPin1 = 3;    
int ledPin2 = 9;   
int startPin = 7;
int startState = 0;

void setup() {

pinMode(startPin, INPUT);

}


void loop() {

startState = digitalRead(startPin);

if (startState == 1) {

  analogWrite(ledPin1, 255);
  analogWrite(ledPin2, 255);
  delay(5000);

}

  for (int fadeValue = 20 ; fadeValue <= 128; fadeValue ++) {

    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue-20);
    delay(60);

  }

   for (int fadeValue = 128 ; fadeValue >= 20; fadeValue --) {

    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue-20);
    delay(60);

  }

}

Je suis satisfait de cette première ébauche, mais je souhaiterais améliorer les points suivants :

  • Pour passer en "mode photo" j'ai utilisé comme déclencheur le passage à "1" de la pin7. Mais lorsque je passe la pin7 à 1 je dois attendre que mes boucles "for" aient terminé leur fonction. Y a-t-il un moyen pour que le passage à 1 de la pin7 soit prioritaire et qu'il ne faille pas attendre pour que le déclenchement de mes leds soit instantané ?
  • Aussi pour ce premier essai le déclenchement est "manuel" (en utilisant la pin7). Le déclenchement final se fera via une url ou un trigger via usb ou port série. Le logiciel spécifié dans le manuel utilisateur est SerialSend. Est-ce complexe de faire dialoguer une carte Arduino avec ce genre de système ?
    J'ai peur de me lancer dans une épreuve trop complexe...
    Merci pour vos suggestions et votre aide !

Ce genre de besoin se prête assez bien à l'utilisation d'une machine à états
Il y a un tuto sur ce sujet
Programmation Automate fini / Machine à état

Si besoin (je ne sais pas quel appareil photo vous pilotez) j’ai aussi un tuto qui pourrait vous intéresser

La méthode la plus simple des de faire un test de sortie de ta boucle sur l'état de la pin7
par exemple

if (digitalRead(startPin) == HIGH) break;

Bonjour à tous et merci pour vos précieux conseils !
J'ai avancé dans mon programme et je suis maintenant satisfait du comportement obtenu.
J'ai deux séries de leds qui scintillent par alternance en faisant varier leur intensité par PWM, l'effet obtenu est exactement ce que je cherchais à avoir.
Lorsque je simule le déclenchement d'une photo en passant la PIN7 à HIGH, j'ai bien mes leds qui augmentent leur puissance pour 5 secondes et ensuite ma boucle de scintillement reprend.

int ledPin1 = 3;    
int ledPin2 = 9;   
int startPin = 7;
int startState = 0;
int fadeValue2 = 30;
int side = 1;

void setup() {
  pinMode(startPin, INPUT);
}

void loop() {
  startState = digitalRead(startPin);
  for (int fadeValue = 2 ; fadeValue <= 30; fadeValue ++) {
    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue2);
    delay(60);
    fadeValue2 = fadeValue2 - side;
    if (digitalRead(startPin) == HIGH) break;
  }

   for (int fadeValue = 30 ; fadeValue >= 2; fadeValue --) {
    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue2);
    delay(60);
    fadeValue2 = fadeValue2 + side;
    if (digitalRead(startPin) == HIGH) break;
  }

if (startState == 1) {
  analogWrite(ledPin1, 2);
  analogWrite(ledPin2, 2);
  for(int flash = 2 ; flash <= 254; flash ++) {
     analogWrite(ledPin1, flash);
     analogWrite(ledPin2, flash);
     delay(5);
  }
  delay(5000);
  startState = 0;
  fadeValue2 = 30;
}
}

Prochaine étape : parvenir à récupérer le signal envoyé par mon logiciel lors du déclenchement d'une prise de photo.
Pour cela mon logiciel permet d'utiliser des déclencheurs : https://support.lumasoft.co/hc/en-us/articles/360000637854-Triggers-Webhooks-and-API#h_01FT6Q0RGTCMJZ8ASVH5Q7EW9B

Et il semblerait nécessaire d'utiliser un petit programme appelé SerialSend qui permettrait d'envoyer ces instructions via un port série vers un microcontrolleur.

Je suis preneur de toutes pistes ou suggestions, merci beaucoup par avance !!

On dirait que c’est une interface HTTP, le serial tool semble être autre chose qui permettrait à leur application de notifier à votre arduino un événement mais apparemment pas à l’arduino d’envoyer une commande

Leur soft tourne sur un PC ou c’est une machine dédiée ?

Il faudra un arduino avec ethernet ou wifi pour envoyer les commandes HTTP

Le soft tourne sur un mini PC sous Windows 10 dedié à ça. Lorsqu'une personne appuie sur l'écran tactile cela déclenche la séquence qui prend 3 photos puis elles sont imprimées par une imprimante photos et sortent du photobooth. Du coup lorsqu'une personne appuie sur l'écran un trigger envoie une information. Je dois parvenir à récupérer cette information via le port série et cela doit permettre de sortir de ma loop pour déclencher l'éclairage plus intense pendant 5 secondes et ensuite retour dans la boucle loop.
D'après ce que je comprends il est également possible de déclencher l'exécution d'un fichier .bat sur le PC. Est-ce que je pourrais via un tel fichier déclencher l'événement sur mon Arduino ?

dans ce cas oui, c'est l'application sur le mini PC qui a un "Triggers to Application" comme dans la doc qui va déclencher SerialSend qui sera configurée pour parler à votre arduino

faudrait jouer avec pour voir comment on s'assure de trouver le bon port pour votre Arduino et voir ensuite le message à faire passer - je n'utilise pas de PC donc je ne peux pas aider sur ce point.

(Un point important à se souvenir : ouvrir le port série par défaut va rebooter l'arduino.... Peut-être vous voudrez désactiver cela)

J'ai facilement réussi à trouver la solution.
Lorsqu'on exécute le programme avec la ligne de commande : ' SerialSend.exe "start" ', il commence par rechercher les ports série disponibles et envoie le message dès qu'il trouve un port en écoute.
Voici mon code finalisé, je suis preneur de toutes observations, peut-être n'est-il pas optimisé pour fonctionner au plus simple... Merci à tous pour votre aide précieuse !

int ledPin1 = 3;    
int ledPin2 = 9;   
int fadeValue2 = 30;
int side = 1;
int incomingByte = 0;

void setup() {
   Serial.begin(9600);
}

void loop() {
  
if (Serial.available() > 0) {
    // read the incoming byte:
    incomingByte = Serial.read();
}
  for (int fadeValue = 2 ; fadeValue <= 30; fadeValue ++) {
    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue2);
    delay(60);
    fadeValue2 = fadeValue2 - side;
    if (incomingByte != 0) break;
  }

   for (int fadeValue = 30 ; fadeValue >= 2; fadeValue --) {
    analogWrite(ledPin1, fadeValue);
    analogWrite(ledPin2, fadeValue2);
    delay(60);
    fadeValue2 = fadeValue2 + side;
    if (incomingByte != 0) break;
  }

if (incomingByte != 0) {
  analogWrite(ledPin1, 2);
  analogWrite(ledPin2, 2);
  for(int flash = 2 ; flash <= 254; flash ++) {
     analogWrite(ledPin1, flash);
     analogWrite(ledPin2, flash);
     delay(5);
  }
  delay(5000);

for(int flash = 254 ; flash >= 2; flash --) {
     analogWrite(ledPin1, flash);
     analogWrite(ledPin2, flash);
     delay(5);
  }



  fadeValue2 = 30;
  incomingByte = 0;
}
}

dans votre loop vous allez lire le port série s'il y a quelque chose de dispo et vous vous en servez pour sortir des boucles for. mais s'il n'y a rien à lire au moment de rentrer dans la loop() vous êtes coincé dans les 2 boucles for() pour environ 3.5 secondes d'animation

il faudrait tester le port série directement dans les boucles for en permanence si vous ne voulez pas attendre.

bien entendu une meilleure façon de faire serait de ne pas avoir de delay() et utiliser millis et une machine à états

Merci pour ton retour ! Je viens d'intégrer les IF dans mes boucles FOR et effectivement je bascule tout de suite en mode "flash" lorsqu'une photo va être déclenchée sans délais. C'est beaucoup mieux !!
Encore merci à toi !

Très bien !