[ARDUINO] Simulation proteus

Bonjour les amis,

je viens vers vous car je n'arrive pas a faire une simulation sur proteus et j'ai un doute que le code qui ne fonctionne pas.

je souhaite utiliser un 4 Boutons (en realité ce sont des switch magnetique mais pour le test j'opte pour les boutons) pour chaque bouton j'ai 4 fonctionnements d'un moteur soit 5, 10, 20 ou 30seconds.

int LED5 = 3;
int LED10 = 4;
int LED20 = 5;
int LED30 = 6;

int REED5 = 7;
int REED10 = 10;
int REED20 = 11;
int REED30 = 12;

int RelaisM1 = 13;
int RelaisM2 = 9;

unsigned long StartTime;

void setup() {
  // put your setup code here, to run once:
pinMode(LED5, OUTPUT);
  pinMode(LED10, OUTPUT);
  pinMode(LED20, OUTPUT);
  pinMode(LED30, OUTPUT);
  pinMode(RelaisM1, OUTPUT);
  pinMode(RelaisM2, OUTPUT);

  analogWrite(LED5, HIGH);
  analogWrite(LED10, HIGH);
  analogWrite(LED20, HIGH);
  analogWrite(LED30, HIGH);

  delay(500);

  analogWrite(LED5, LOW);
  analogWrite(LED10, LOW);
  analogWrite(LED20, LOW);
  analogWrite(LED30, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(REED5) == HIGH){
  analogWrite(LED5, HIGH);
  analogWrite(LED10, LOW);
  analogWrite(LED20, LOW);
  analogWrite(LED30, LOW);
  minutes5();      
  }
  if (digitalRead(REED10) == HIGH){
  analogWrite(LED5, LOW);
  analogWrite(LED10, HIGH);
  analogWrite(LED20, LOW);
  analogWrite(LED30, LOW);
  minutes10();    
}
  if (digitalRead(REED20) == HIGH){
  analogWrite(LED5, LOW);
  analogWrite(LED10, LOW);
  analogWrite(LED20, HIGH);
  analogWrite(LED30, LOW);
  minutes20();    
}
  if (digitalRead(REED30) == HIGH){
  analogWrite(LED5, LOW);
  analogWrite(LED10, LOW);
  analogWrite(LED20, LOW);
  analogWrite(LED30, HIGH);
  minutes30();    
}
}

void minutes5(){
  digitalWrite(RelaisM1, HIGH);
  StartTime = millis();
  if (millis() - StartTime >= 5000){
    digitalWrite(RelaisM1, LOW);
  }
}

void minutes10(){
  digitalWrite(RelaisM1, HIGH);
  StartTime = millis();
  if (millis() - StartTime >= 10000){
    digitalWrite(RelaisM1, LOW);
  }
}

void minutes20(){
  digitalWrite(RelaisM1, HIGH);
  StartTime = millis();
  if (millis() - StartTime >= 20000){
    digitalWrite(RelaisM1, LOW);
  }
}

void minutes30(){
  digitalWrite(RelaisM1, HIGH);
  StartTime = millis();
  if (millis() - StartTime >= 30000){
    digitalWrite(RelaisM1, LOW);
  }
}

Schéma du circuits proteus:

Salut,
Alors déjà tes REED5-30 ne sont pas défini comme entrées, cela peux te poser problème.
Ensuite tes différentes fonctions minutes5() et autres, tu les appelles en boucle et à chaque fois tu met "StartTime = millis();"... du coup ton écart ne se fera jamais

unsigned long StartTime = 0;
bool flag = 1;

void loop()
{
  if (flag == 1)
  {
    StartTime = millis();
    flag = 0;
  }

  if ((millis() - StartTime) >= 5000)
  {
    ....
    flag = 1;
  }
}

Bonjour mskna17,
Merci pour votre réponse.

  • C'est corrigé.
  • Je vous cache pas que je n'ai pas compris comment faire:
    est ce que vous pouvez me donner plus de éclaircissement ?

Par avance merci

Salut,
Pour résumé, tant que REED5 est à 1, tu appelles la fonction minutes5(). Dans la fonction minutes5(), tu met un pointeur nommé StartTime sur millis() pour ensuite faire une comparaison de temps.
Mais dans ton cas à chaque cycle tu vas repointer sur millis(), donc l'écart entre StartTime et millis() ne se fera jamais...
C'est pour cela que je t'ai proposé de mettre une variable mémoire ("flag" dans mon exemple) afin de pointer StartTime sur millis() une seule fois et laisser l'écart se faire

Salut,

Je ne suis pas sur est ce que j'ai bien compris, le code deviendra t il comme suite?:

void loop() {

  digitalWrite(RelaisM1, HIGH);
  if (flag == 1)
  {
  StartTime = millis();
  flag = 0;
  if (millis() - StartTime >= 5000){
    digitalWrite(RelaisM1, LOW);
    flag = 1;
  }
}
}

Merci

Bonjour,
j'ai passé beaucoup de temps pour trouver une solution mais sans réussite.
pouvez vous m'aider svp?

Par avance merci

hello
sur protéus, tu as des erreurs( bobine relais et busser bouclent sur le GND)
tes raccordements ne correspondent pas au code.

ton code ne va pas non plus
je t'ai fais celui ci. je ne le teste pas, à toi de le faire

saisir //on suppose que les BP actionnés ammenent 5 V sur leur entrée
// les LEDS sont sur 3, 4, 5, 6
int LED5   =  3;
int LED10  =  4;
int LED20  =  5;
int LED30  =  6;
// les BP sont sur 13, 10, 11, 7
int REED5  =  7;
int REED10 =  8;
int REED20 =  9;
int REED30 = 10;
// les Relais sont sur 13, 9
int RelaisM1 = 13;
int RelaisM2 =  9;//non utilisé

int tempo[] {5000, 10000, 20000, 30000};//tableau des temps désirés

void MINUTES(int tempo)
{
  digitalWrite(RelaisM1, HIGH);
  delay(tempo);
  digitalWrite(RelaisM1, LOW);
}

void setup() {
  pinMode(REED5,   INPUT);//_PULLUP);
  pinMode(REED10,  INPUT);//_PULLUP);
  pinMode(REED20,  INPUT);//_PULLUP);
  pinMode(REED30,  INPUT);//_PULLUP);
  pinMode(LED5,  OUTPUT); digitalWrite(LED5, LOW);
  pinMode(LED10, OUTPUT); digitalWrite(LED10, LOW);
  pinMode(LED20, OUTPUT); digitalWrite(LED20, LOW);
  pinMode(LED30, OUTPUT); digitalWrite(LED30, LOW);
  pinMode(RelaisM1, OUTPUT); digitalWrite(RelaisM1, LOW);
  pinMode(RelaisM2, OUTPUT); digitalWrite(RelaisM2, LOW);
  
//test des leds
  for ( byte f = 3; f <= 6;f++) 
  {
    digitalWrite(f + 4, HIGH);//allumes les 4 leds
  }
  delay(500);
  for ( byte f = 3; f <= 6;f++) 
  {
    digitalWrite(f + 4, LOW);//eteinds les 4 leds
  }
}

void loop()
{
  for ( byte f = 3; f <= 6;f++) 
  {
    digitalWrite(f + 4, LOW);                      //eteinds les leds
  }
  for ( byte f = 7; f <= 10;f++)
  {
    if (digitalRead(f) == HIGH)                    //lecture des BP chacun à son tour
    {
      digitalWrite(f + 4, HIGH); MINUTES(tempo[(f-7)]);//et si BP actionné, appel de la tempo correspondante
    }
  }
}
ou coller le code ici

Salut dfgh,

Merci beaucoup pour la réponse.

Par contre je ne voie pas comment les moteurs vont arreter en plus dés que j'ai mis le code sur proteus les 2 moteurs fonctionnent sans que j'appuie sur les boutons:

Si tu met un delay, il ne pourra utiliser qu'une tempo moteur à la fois, ce qui n'est pas le but recherché si il a utilisé millis() dans son code de base ...

@dich as tu déjà utilisé millis ou c'est la première fois ?

Salut,
@mskna17 c'est la premiere fois que j'utilise millis.
le probleme c'est que j'arrive maintenant a faire fonctionner le moteur mais ne s'arrete pas aprés la temporisation car je n'arrive pas a deployer correctement ton code avec le flag.
j'ai cherché sur google c'est ce qu'on appele memoire. Sauf seulement que je n'ai pas la logique :slight_smile:
et c'est vrai le code de dfgh ne me parviens pas.

hello
tu avais raison, je n'adressais pas les bonnes cases das les tableaux
voici le code qui fonctionne comme je l'ai compris ( compilé et testé sur maquette)
ouvres le moniteur à 115200 bauds et appuies sur tes touches.
attention à l'affecttion des pins

//on suppose que les BP actionnés ammenent GND sur leur entrée
// les LEDS sont sur 3, 4, 5, 6
int LED5   =  3;
int LED10  =  4;
int LED20  =  5;
int LED30  =  6;
// les BP sont sur 7, 8, 9, 10
int REED5  =  7;
int REED10 =  8;
int REED20 =  9;
int REED30 = 10;
// les Relais sont sur 11,12
int Relais[] = {0,11, 12};//case 0 non utilisée

int tempo[] {5000, 10000, 20000, 30000};//tableau des temps désirés

void MINUTES(byte relais, int tempo)
{
  digitalWrite(Relais[relais], HIGH);
  Serial.print("appel relais ");Serial.print(relais); Serial.print(" pendant "); Serial.println(tempo);
  delay(tempo);
  Serial.print("relachement relais "); Serial.println(Relais[relais]);
  digitalWrite(Relais[relais], LOW);
}

void setup() {
  Serial.begin(115200);
  pinMode(REED5,   INPUT_PULLUP);
  pinMode(REED10,  INPUT_PULLUP);
  pinMode(REED20,  INPUT_PULLUP);
  pinMode(REED30,  INPUT_PULLUP);
  pinMode(LED5,  OUTPUT); digitalWrite(LED5, LOW);
  pinMode(LED10, OUTPUT); digitalWrite(LED10, LOW);
  pinMode(LED20, OUTPUT); digitalWrite(LED20, LOW);
  pinMode(LED30, OUTPUT); digitalWrite(LED30, LOW);
  pinMode(Relais[1], OUTPUT); digitalWrite(Relais[1], LOW);//RelaisM1 sur 13
  pinMode(Relais[2], OUTPUT); digitalWrite(Relais[2], LOW);//Relaism2 sur 9

  //test des leds
  for ( byte f = 3; f <= 6; f++)
  { Serial.print("allumage led "); Serial.println(f);
    digitalWrite(f , HIGH);//allumes les 4 leds
  }
  delay(500);
  for ( byte f = 3; f <= 6; f++)
  { Serial.print("extintion led "); Serial.println(f);
    digitalWrite(f , LOW);//eteinds les 4 leds
  }
}

void loop()
{
  for ( byte f = 3; f <= 6; f++)
  { Serial.print("extintion led "); Serial.println(f);
    digitalWrite(f, LOW);                      //eteinds les leds
  }
  for ( byte f = 7; f <= 10; f++)
  { Serial.print("lecture BP "); Serial.println(f);
    if (digitalRead(f) == LOW)                    //lecture des BP chacun à son tour
    {
      Serial.print("touche "); Serial.print(f); Serial.println(" pressee");
      Serial.print("allumage led  "); Serial.println(f - 4);
      Serial.print("appel tempo de  "); Serial.println(tempo[(f - 7)]);
      digitalWrite(f , HIGH); MINUTES(1,tempo[(f - 7)]); //et si BP actionné, appel de la tempo correspondante
    }
  }
}

nota: tu n'as pas précisé si tu avais besoin de coller deux relais en meme temps 
si c'est avec des tempos differentes
et das ton code, tu ne commandes pas le relais 2
1 Like

Merci infiniment pour ta réponse dfgh,
je vais tester et te dire la suite.
le 2eme relais c'est pour autre chose.
au fait c'est un grand projet et c'est sur cette partie que j'ai coincé.
Merci en tout cas

attention une erreur,il faut:  -4
 digitalWrite(f-4 , HIGH); MINUTES(1,tempo[(f 

tu ne dis pas s'il te faut la possibilité d'appeler une autre tempo ( d'ou l'emploi de millis();
mais je ne crois pas, car ce serait pour appeler le 2ème relais

1 Like

Salut dfgh,
chappeau.

Quand je lis le code je le comprends pas et j'avais un doute mais vraiment chappeau. sa fonctionne comme je le souhaite.

par contre je vais faire des recherches sur le tableau que tu as mis pour les relais et tempo et aussi f sert a quoi?

en tout cas 1000 merci.
je reviens vers vous dés que je termine ce projet.
je joint le fichier proteus si ca peut interesser quelqu'un.

Oooops le fichier ne se telecharge pas

voir les extensions acceptées, au besoin transformer en .zip
ça pourra peut être servir à quelques uns ayant accès à Proteus

Ce logiciel est peu utilisé içi , les participants actifs de ce forum en général n'ont pas à accès à Proteus, ne l'achètent pas ....... et ne le volent pas non plus !
Ils sont plutôt portés vers les logiciels multiplateforme, Open Source .....et de préférence gratuits.
L'absence de simulation ne les gêne pas.
S'ils voulaient simuler ils seraient bien en peine car il utilisent de plus en plus des microcontrolleurs que Proteus ne sait pas simuler.

1 Like

hello
comme tu as dis que ce prg n'est qu'une petite partie d'un autre projet,
voici le meme prg mais avec millis() qui ne bloque pas le prg. il est donc possible de faire autre chose pendant les tempos

nota, en fin de loop j'ai placé un delai pour te permettre de voir ce qui se passe sur le moniteur.
il faudra supprimer ce delai en utilisation normale
et si tu le veux, tu pourras supprimer tous les Serial.print . le prg y gagnera en vitesse d'execution

//on suppose que les BP actionnés ammenent GND sur leur entrée
byte LED[] = {0, 3, 4, 5,  6}; // les LEDS sont sur 3, 4, 5, 6
byte REED[] = {0, 7, 8, 9, 10}; // les BP sont sur 7, 8, 9, 10
int Relais[] = {0, 11, 12};// les Relais sont sur 11,12 case 0 non utilisée
unsigned long deb_tempo[]={0,0,0,0,0};
unsigned long tempo [] = {0000, 5000, 10000, 20000, 30000};//tableau des temps désirés
boolean  flag_tempo[] = {false, false, false, false, false, false};

void setup() 
{
  Serial.begin(9600);
  for ( byte f = 1; f <= 4; f++)
  {
    pinMode(REED[f],     INPUT_PULLUP);
    pinMode(LED[f],      OUTPUT); digitalWrite(LED[f], LOW);
  }
  pinMode(Relais[1], OUTPUT); digitalWrite(Relais[1], LOW);//RelaisM1 sur 13
  pinMode(Relais[2], OUTPUT); digitalWrite(Relais[2], LOW);//Relaism2 sur 9
  test_leds();
}

void loop()
{
  extinction_leds();
  for ( byte f = 1; f <= 4; f++)
  { //Serial.print("lecture BP "); Serial.print(f);Serial.print(" "); Serial.print(REED[f]);
  //Serial.print(" "); Serial.print(digitalRead(REED[f])); 
  //Serial.print(" et flag tempo ");Serial.println(flag_tempo[f]);
    if ((digitalRead(REED[f]) == LOW) && ( flag_tempo[f] == false))                //lecture des BP chacun à son tour
    {
      flag_tempo[f] = true;
      deb_tempo[f] = millis();
      Serial.print("touche "); Serial.print(REED[f]); Serial.println(" pressee");
      Serial.print("allumage led  ");Serial.print(f); Serial.print(" sur pin ");Serial.println(LED[f]);
      Serial.print("deb_tempo  "); Serial.println(deb_tempo[f]);
    }
    MINUTES(1);//1 pour relais 1
   // delay(500);//ligne pour debug, a supprimer ensuite
  }
}

void MINUTES(byte relais)
{//Serial.print(" relais"); Serial.print(relais);
  for (byte m = 1; m <= 4; m++)
  {//Serial.print("controle minuterie ");Serial.print(m);
    if (flag_tempo[m] == true)
    {
      if ((millis() - deb_tempo[m]) < tempo[m])
      {
        digitalWrite(Relais[relais], HIGH);
        digitalWrite(LED[m] , HIGH); //allume la led correspondant à la tempo
        Serial.print("appel relais sur pin µµµµµµµµµµµµµµµµµµµµµ"); Serial.print(Relais[relais]); Serial.print(" pendant "); Serial.print(tempo[m]);
        Serial.print("  tempo ecoulee  ");Serial.print((millis() - deb_tempo[m]));
        Serial.print("  sur ");Serial.println(tempo[m]);
      }
      else
      { flag_tempo[m] = false;
        digitalWrite(Relais[relais], LOW);
        digitalWrite(LED[m] , LOW); //allume la led correspondante
        Serial.print("relachement relais sur pin *******************"); Serial.println(Relais[relais]);
      }
    }
  }
}
void extinction_leds()
{
  Serial.print(" extinction led ");
  for ( byte f = 1; f <= 4; f++)
  {
    if (flag_tempo[f] == false)
    {
      Serial.print(f);Serial.print(" sur pin ");Serial.println(LED[f]);Serial.print("                ");
      digitalWrite(LED[f], LOW);                      //eteinds les leds
    }
  }
  Serial.println(" ");
}

void test_leds()
{
  Serial.print("  allumage led  ");
  for ( byte f = 1; f <= 4; f++)
  {  Serial.print(f);Serial.print(" sur pin ");Serial.println(LED[f]);Serial.print("                ");
    digitalWrite(LED[f] , HIGH);//allume les 4 leds
  }
  Serial.println(" ");
  delay(500);
  Serial.print(" extinction led ");
  for ( byte f = 1; f <= 4; f++)
  {  Serial.print(f);Serial.print(" sur pin ");Serial.println(LED[f]);Serial.print("                ");
    digitalWrite(LED[f] , LOW);//eteinds les 4 leds
  }
  Serial.println(" ");
}

Merci dfgh, c'est top.
Merci

Bonsoir les amis,

A nouveau je reviens vers vous!
@dfgh le dernier code fonctionne bien, seuelement j'ai 2 problemes:
1- le servo ne communique pas comme je le souhaite avec la HMC5883L. La communication est lente (la reaction du moteur est lente vise a vis le module HMC).
Et plus je veux que le moteur part de 1degré comme la boussole HMC (si la HMC devie de 1degré le servo doit faire la meme chose).
Comme vous pouvez le remarquer sur le code j'ai mis ca pour cette raison:

myservo.write(servoPos - offset);

2- Je veux ajouté un 2eme servo qui doit fonctionner a la fin de chaque temporisation (il part de 90 degré a 180 par exemple).

Voici le code:

#include <Servo.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_HMC5883_U.h>

/* Assign a unique ID to this sensor at the same time */
Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345);
Servo myservo;
Servo myservo2;
int servoPos = 90; //
int compassCorrection = 0; // set to 0 (not used)

//on suppose que les BP actionnés ammenent GND sur leur entrée
byte LED[] = {0, 3, 4, 5,  6}; // les LEDS sont sur 3, 4, 5, 6
byte REED[] = {0, 7, 8, 9, 10}; // les BP sont sur 7, 8, 9, 10
int Relais[] = {0, 11, 12};// les Relais sont sur 11,12 case 0 non utilisée
unsigned long deb_tempo[]={0,0,0,0,0};
unsigned long tempo [] = {0000, 5000, 10000, 20000, 30000};//tableau des temps désirés
boolean  flag_tempo[] = {false, false, false, false, false, false};

void setup() 
{
  Serial.begin(9600);
  for ( byte f = 1; f <= 4; f++)
  {
    pinMode(REED[f],     INPUT_PULLUP);
    pinMode(LED[f],      OUTPUT); digitalWrite(LED[f], LOW);
  }
  pinMode(Relais[1], OUTPUT); digitalWrite(Relais[1], LOW);
  pinMode(Relais[2], OUTPUT); digitalWrite(Relais[2], LOW);
  test_leds();

    if(!mag.begin())
  {
    /* There was a problem detecting the HMC5883 ... check your connections */
    Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
    while(1);
  }
    /* Display some basic information on this sensor */
  displaySensorDetails();
  myservo.write(90);
  myservo2.write(90);
  delay(2000);
}

void displaySensorDetails(void)
{
  sensor_t sensor;
  mag.getSensor(&sensor);
  myservo.attach(13);
  myservo2.attach(12);
  delay(500);
}

static int headingDegreesInteger;

void loop()
{
  extinction_leds();

  /*Section du HMC5883l*/
sensors_event_t event; 
  mag.getEvent(&event);

  float heading = atan2(event.magnetic.y, event.magnetic.x);  
  
  int headingDegrees = (heading * 180/M_PI); 

if (headingDegreesInteger==0)
{
headingDegreesInteger =headingDegrees;
}
  
  Serial.print("Heading (Initial): "); Serial.println(headingDegreesInteger);
  Serial.print("headingDegrees: "); Serial.println(headingDegrees);
  

int offset =   headingDegreesInteger - headingDegrees;
myservo.write(servoPos - offset);
/*Fin Section du HMC5883l*/

  for ( byte f = 1; f <= 4; f++)
  { 
    if ((digitalRead(REED[f]) == LOW) && ( flag_tempo[f] == false))                //lecture des BP chacun à son tour
    {
      flag_tempo[f] = true;
      deb_tempo[f] = millis();

    }
    MINUTES(1);//1 pour relais 1
    MINUTES(2);
    
  }
}

void MINUTES(byte relais)
{
  for (byte m = 1; m <= 4; m++)
  {
    if (flag_tempo[m] == true)
    {
      if ((millis() - deb_tempo[m]) < tempo[m])
      {
        digitalWrite(Relais[relais], HIGH);
        digitalWrite(LED[m] , HIGH); //allume la led correspondant à la tempo

      }
      else
      { flag_tempo[m] = false;
        digitalWrite(Relais[relais], LOW);
        digitalWrite(LED[m] , LOW); //allume la led correspondante
      }
    }
  }
}
void extinction_leds()
{
  Serial.print(" extinction led ");
  for ( byte f = 1; f <= 4; f++)
  {
    if (flag_tempo[f] == false)
    {
      digitalWrite(LED[f], LOW);                      //eteinds les leds
    }
  }
}

void test_leds()
{
  for ( byte f = 1; f <= 4; f++)
  {   digitalWrite(LED[f] , HIGH);//allume les 4 leds
  }
  delay(500);
  for ( byte f = 1; f <= 4; f++)
  {    digitalWrite(LED[f] , LOW);//eteinds les 4 leds
  }
}

par avance merci

hello
je suis surpris de ton code, je ne vois pas très bien ce que tu veux faire.
tu calcules un cap et tu veux qu'un servo s'aligne dessus.
et tu as aussi des tempos qui allument des leds ( que tu éteins à chaque tour de loop ?)

si on ne s'occupe que du compas pour le cap
tu calcules le cap, tu ne vérifies pas s'il est dans le cohérent. ( >360° ou <0°)
puis tu le compares avec le cap calculé au tour de loop pécédent et que tu as mémorisé.
si > ou <, le delta devient l'offset que tu soustrais à la position actuelle du servo1.
offset=ancien cap -nouveau cap ==> 120°-121°=-1°
servo=valeur-offset==> 120--1°=121

tu "attach" les servo en D12 et D13 mais D12 est déjà alloué au relais 2
de plus es tu sur que D12 et D13 soient le bonnes pins pour des servos ?

edit:

remplaces les lignes d'origine par ces lignes
et modifie ton cabalge en conséquence

//on suppose que les BP actionnés ammenent GND sur leur entrée
byte LED[] = {0, 2, 3, 4, 5}; // les LEDS sont sur 2, 3, 4, 5
//les servos sont sur 6 et 9
byte REED[] = {0, 7, 8, 10, 11}; // les BP sont sur 7, 8, 10, 11
int Relais[] = {0, 12, 13};// les Relais sont sur 12,13 case 0 non utilisée

re edit:
sans oublier ces lignes

myservo1.attach(6);
  myservo2.attach(9);