Distributeur croquettes automatique - Problème Blynk

Bonjour à tous,

Je souhaite réaliser un distributeur de croquettes composé de :

  • Un NodeMCU 1.0
  • Un expender MCP23017
  • Un écran LCD 16x2 I2C
  • Un stepper avec contrôler ULN2003A
  • Un potentiomètre de réglage du temps de distribution
  • 4 boutons poussoirs
  • 3 LED

Par ailleurs, les fonctions à réaliser sont les suivantes :

  • Un mode de distribution automatique à heure fixe. Pour cela, j'utilise un serveur NTP.
  • Un mode de distribution forcée, en appuyant sur le BP.
  • Un mode de distribution Wifi : Je souhaite utiliser Blynk pour ensuite rattacher Blynk à GoogleHome via IFTTT.
  • Afficher l'heure en continu sur l'écran, avoir la possibilité de voir le nombre de distributions restantes avant que le réservoir soit vide (avec un compteur), pouvoir indiquer que le remplissage du réservoir...

Voilà pour la description du projet. Viennent ensuite les problèmes ::slight_smile:

Les 3 modes de distributions fonctionnent indépendamment les uns des autres, de même que l'affichage de l'heure sur le LCD.

Néanmoins, lorsque j'assemble ces différentes fonctions (en essayant de les structurer en sous programme) c'est la catastrophe ! Au téléversement du programme, l'heure s'affiche correctement dans le Serial. Cependant lorsque je lance un front montant sur l'application Blynk, le programme ne cesse de reboucler sur Blynk.run(), et se reconnecte sans cesse au wifi.

Je vous place le programme ci dessous : il n'est pas complet mais regroupe les fonctions principales.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Wire.h>
#include "Adafruit_MCP23017.h"
#include <LiquidCrystal_I2C.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Stepper.h>

char auth[] = "6Uh***********W8kg1jj8vZDI6"; //Authentification Blynk
char ssid[] = "********";
char pass[] = "******";

const int led_rouge = 0;
const int led_orange = 2;
const int led_verte = 16;

const int stepsPerRevolution = 32*64;  
int motorSpeed ;
int val_potar;
int nb_distribution; 
long temps_distrib_manuel;
long temps_distrib_wifi;
long temps_distrib_auto;
long temps;
String heure ;

// Initialisation LCD
LiquidCrystal_I2C lcd(0x3F, 16, 2);
Adafruit_MCP23017 mcp;

//Initialisation stepper (step,1N1,1N4,1N3,1N1) ou (step,1N1,1N3,1N2,1N4)
Stepper myStepper(stepsPerRevolution, 14,13,12,15);

//Initialisation serveur NTP
WiFiClient espClient;
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "fr.pool.ntp.org", 3600, 60000);

void setup()
{

  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass); //Connexion au réseau wifi
  mcp.begin();
  
  lcd.begin(16,2);
  lcd.init();
  timeClient.begin();
  
  pinMode(led_rouge, OUTPUT);
  pinMode(led_orange, OUTPUT);
  pinMode(led_verte, OUTPUT);
  mcp.pinMode(7, INPUT_PULLUP);
  mcp.pinMode(6, INPUT_PULLUP);
  mcp.pinMode(5, INPUT_PULLUP);
  mcp.pinMode(4, INPUT_PULLUP);

  mcp.digitalWrite(7, LOW);
  
}

void loop()
{
  Blynk.run();
  serveur_NTP ();
  stepper();
  val_potar=1;
  
  if (digitalRead(led_orange)==HIGH){               //Si LED allumée
    distribution_wifi ();
  }

  boolean etat_BP1=mcp.digitalRead(7);
  if (etat_BP1==LOW){                    //Si BP enclenché 
    distribution_manuelle ();
  }

  distribution_automatique ();
  
  affichage_lcd ();
 
  if (nb_distribution<5){                 //Allumer LED si nb_disrtibution restante inférieur à 5 
    digitalWrite(led_rouge,HIGH);
   } 
   
 /* boolean etat_BP2=mcp.digitalRead(6);   
  while (etat_BP2=HIGH){                 //Affichage du nombre de distribution restante si appui sur BP2
    lcd.clear();
    lcd.home();
    lcd.print("Il reste");
    lcd.setCursor(0,1);
    lcd.write(nb_distribution);
    lcd.write("portion(s) à distribuer");
      }
      
  boolean etat_BP3=mcp.digitalRead(5);
  if (etat_BP2=HIGH){    
    lcd.clear();
    lcd.home();
    lcd.print("Voulez-vous remplir le réservoir ?");
    lcd.setCursor(0,1);
    lcd.write();
    lcd.write("");    
    
   } */
    
  }


void distribution_wifi ()
{
  temps_distrib_wifi = millis();
  while (millis()-temps_distrib_wifi<10000){
    Serial.println("Lancement moteur wifi");
    myStepper.setSpeed(motorSpeed);
    myStepper.step(2048);
    digitalWrite(led_rouge, LOW);
    digitalWrite(led_verte,LOW);
    digitalWrite(led_orange, HIGH);
    
  }
  nb_distribution=nb_distribution-1;
}

void distribution_manuelle ()
{
  temps_distrib_manuel = millis();
  while (millis()-temps_distrib_manuel<10000){
    Serial.println("Lancement moteur manuel");
    myStepper.setSpeed(motorSpeed);
    myStepper.step(2048);
    digitalWrite(led_rouge, LOW);
    digitalWrite(led_verte,LOW);
    digitalWrite(led_orange,HIGH);
  }
  nb_distribution=nb_distribution-1;
}

void distribution_automatique ()
{
  temps_distrib_auto = millis();
  if(heure=="12:00:00" or heure=="16:00:00" or heure=="20:00:00" or heure=="12:00:01" or heure=="16:00:01" or heure=="20:00:01") {
    while (millis()-temps_distrib_auto<10000){
      Serial.println("Lancement moteur automatique");
      myStepper.setSpeed(motorSpeed);
      myStepper.step(2048);
      lcd.clear();
      lcd.home();
      lcd.print("Distribution en cours...");
      digitalWrite(led_rouge, LOW);
      digitalWrite(led_verte,LOW);
      digitalWrite(led_orange,HIGH);
    }
  }  
nb_distribution=nb_distribution-1;
}

void affichage_lcd ()
{
  
}

void serveur_NTP ()
{
  lcd.clear();
  timeClient.update();
  timeClient.getFormattedTime();
  heure=timeClient.getFormattedTime();
  if (millis()- temps>950){
    Serial.println(timeClient.getFormattedTime());
    lcd.print(heure); 
    temps=millis();
 } 
} 

void stepper (){
  int sensorReading = analogRead(A0);
  int motorSpeed = map(sensorReading, 0, 1023, 0, 10);  
  if (val_potar !=motorSpeed){                              //Si modification de la valeur du potentiomètgre
   // Serial.print(motorSpeed);
    lcd.clear();
    lcd.home();
    lcd.print("Vitesse moteur :");
    lcd.print(motorSpeed);
    val_potar=motorSpeed;
}

  
}

Etant relativement débutant, je suis ouvert à toutes les suggestions d'amélioration de mon programme !

Merci à vous

enlevez vos secrets du code posté...

char auth[] = "xxx"; //Authentification Blynk
char ssid[] = "xxx";
char pass[] = "xxx";

tous vos temps devraient être des unsigned long, pas des long.

avez vous assez de puissance pour tout alimenter ? précisez le câblage

Bien vu merci !

Quelle est la différence entre ces deux types ?

Si je n'ai rien oublié, le câblage en pj.

votre image

je ne vois pas le contrôleur ULN2003A

Quelle est la différence entre ces deux types ?

[url=https://www.arduino.cc/reference/en/language/variables/data-types/long/]long[/url] est signé, il représente des valeurs entre 2 147 483 648 et 2 147 483 647.

[url=https://www.arduino.cc/reference/en/language/variables/data-types/unsignedlong/]unsigned long[/url] n'est pas signé et représente donc des valeurs entre 0 et 4 294 967 295 (232 - 1).

un temps retourné par millis() est un unsigned long, le nombre de millisecondes depuis le démarrage de votre arduino. si vous utilisez un long pour stocker ce nombre, au bout de 25 jours il va passer négatif :slight_smile:

C'est noté, je viens de faire la modification merci.

Des idées pour le problème de connexion qui tourne en boucle ?