Go Down

Topic: Utiliser valeur du potentiomètre pour décaler une action (Read 9919 times) previous topic - next topic

B@tto

Déjà il faut modérer le terme de tâche sur Arduino : il ne peut pas executer plusieurs tâche à la fois comme sur un PC par exemple. En revanche il tourne à 16 mhz, et bien souvent on utilise moins de 1% de la capacité de calcul, ce qui fait qu'on peut très bien executer une tache, puis uen autre et que celà soit completement transparent pour l'utilisateur.

Le delay() consiste à faire tourner l'atmega dans le vide, ce qui bloque le code un certain temps à cette ligne la donc pendant ce temps on ne peut rien faire. L'astuce consite plutot à vérifier à chaque boucle avec la fonction millis() si le temps voulu s'est écouler, comme si tu étais dans un bureau à surveiller l'horloge pour executer une autre tache. Tu scrute l'heure en permanence mais tu peux taper à l'ordianteur par exemple, et quand l'heure vient tu vas te chercher un café ;)
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

gunsman76

Le problème est un peu plus compliqué qu'il n'y parait.

En fait je ne veux pas utiliser la commande delay tout simplement parce que le nombre de tâche à effectuer et d'environ 50 par minutes...


chaque fois que l'IR est déclenché (donc environ 50 fois par minutes, chiffre qui peut évoluer à la baisse mais au minimum 26), chaque déclenchement doit entrainer la mise au niveau haut de 3 sortie de l'arduino décalé dans le temps de 0,5 à 5 secondes. Mais ce qui complique encore c'est que les 3 sorties ne sont pas déclenché ensemble mais décalé.

Déclenchement = décalage
Déclenchement = décalage


Etc...


et ceci multiplié par au maximum 50 fois par minutes


Voilà pourquoi j'hésite à utiliser delay sur le potentiomètre, car j'ai peur qu'un déclenchement suivant soit bloqué ou pas vu car la fonction delay a été utilisé

Jean-François

C'est justement ce que B@tto t'explique, au lieu d'utiliser delay() tu utilises millis() qui bien que plus laborieux à utiliser dans ce contexte, ne bloque pas le déroulement de la boucle.
MacBook intel core 2 duo  os X snow Leopard 10.6<br/> eMac PPc G4  os X Leopard 10.5<br/>powerbook G4 os X Leopard 10.5
imac PPC G3 os X Pa

B@tto

Et puis 50 fois par minute, ton Atmega est en train de rigoler ... Une mesure IR tu peux la faire très très largement en 1 ms, x 50 il te reste environ 59,995 secondes de libre pour faire ce que tu veux ... Soit une exploitation de ton Atmega de 0.01% ... 
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

gunsman76

A merci pour le renseignement, je m'inquiétais justement, j'avais peur de dépasser la capacité.


Et le relais va resister pour 50 ouverture fermeture par minute 365 jours par an ?

Christian_R

Oui delay() est une fonction blocante, utiliser millis() si on veut éviter ça.
Christian

B@tto

Pour des relais mécaniques c'est pas terrible ... Pas terrible du tout même : 50x60x365= + de 1 000 000 de commutations !! On est loin des specs des fabriquants !!

Quelle est la charge à commander ? Continu ? alternatif ? Il existe d'autres solutions : transistor, triac, relais statique ...
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

gunsman76

Oui effectivement j'abandonne l'idée du relais... Il y a une faible tension, ça déclenche une électrovanne. J'ai le choix pour l'électrovanne (pas encore acheté) 12v, 24v et 220v le mieux étant du 24 volts.

Un mosfet ???


En fait depuis cet après midi je fais des montages et j'ai trouvé l'idée pour mon problème (peut-être pas la solution)

J'ai un potentiomètre qui me donne une valeur de 0 à 1023 en fonction de la position du bouton. Ce qu'il faut c'est tout simplement transformé cette valeur en dixième de seconde et ensuite d'utiliser le resultat pour déclencher l'action B.


J'avance dans ma tête

skywodd

Si j'ai bien compris il y aura (au maximum) 50 attentes en parallèle dans le pire des cas ?


Un mosfet ???

Si la charge n'est pas trop grosse un mosfet remplacerait avantageusement un relai.


J'ai un potentiomètre qui me donne une valeur de 0 à 1023 en fonction de la position du bouton. Ce qu'il faut c'est tout simplement transformé cette valeur en dixième de seconde et ensuite d'utiliser le resultat pour déclencher l'action B.

Voir mon post précédent sur map ;)
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

gunsman76

Oui le mosfet est je pense la solution, je vais profiter d'une commande pour en prendre plusieurs (70 centimes).


Et oui tu as raison la fonction map correspond à ce que je veux faire.


Bientôt le programme dans ce fil de discussion, laissé moi digéré tout ça  ;)



gunsman76

Voilà mon petit programme avance,

J'ai un barrière laser rouge qui lorsqu'elle est coupé déclenche l'allumage d'une led. J'ai installé un potentiomètre qui me permet d'afficher sur le LCD un nombre qui va de 0 à 100. J'aimerais récupérer le résultat de cet affichage pour allumé une autre led avec un décalage dans le temps de 0 à 100 secondes.

Comment procédé ?


Code: [Select]
#include <LiquidCrystal.h>

// initialisation librairie LCD
const int RS=2;
const int E=3;
const int D4=4;
const int D5=5;
const int D6=6;
const int D7=7;

const int RVar=0; //potentiomètre 1 "col"
const int RVar1=1; //potentiomètre 2 "fond"
const int RVar2=2; // potentiomètre 3 "Travers"

const int photoIR=3; //cellule mesure de lumière ARCHE

const int Led=8;

int mesureIR=0; //Infrarouge initialisation
int mesureBrute=0; // Potard initialisation

int seuil=100; //Infrarouge seuil sensiblité passage pièce

float mesure;
float potard;

LiquidCrystal lcd(RS,E,D4,D5,D6,D7);

void setup() {
  // set up LCD indication nb colonne et case:
  lcd.begin(16, 2);
  lcd.clear();
  delay(10);
  // Print a message to the LCD.
  lcd.print("Piochel 2013");
  delay(1000);
  lcd.clear();
  delay (10);
   lcd.print("Initialisation...");
  delay(2000);
  lcd.clear();
  delay (10);
 
  pinMode (Led, OUTPUT);
 
  Serial.begin(115200);
 
}

void loop() {

  mesureBrute=analogRead(RVar);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);
 
  //lcd.clear();
  //delay(5);
 
  lcd.home();
  lcd.print("Col");
  lcd.setCursor(6,0);
  lcd.print("Fond");
  lcd.setCursor(13,0);
  lcd.print("Tra");
 
  //1er potard
 
  potard=mesure/10.0;
  lcd.setCursor(0,1);
  lcd.print(potard,0);
  //delay(200);
 
  //2e potard
 
  mesureBrute=analogRead(RVar1);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);
 
  potard=mesure/10.0;
  lcd.setCursor(7,1);
  lcd.print(potard,0);
  if (mesure < 1000) lcd.print(" ");
  if (mesure < 100) lcd.print(" ");
  if (mesure < 10) lcd.print(" ");
  //delay(100);
 
  //3e potard

 
  mesureBrute=analogRead(RVar2);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);
 
  potard=mesure/10.0;
  lcd.setCursor(13,1);
  lcd.print(potard,0);
  if (mesure < 1000) lcd.print(" ");
  if (mesure < 100) lcd.print(" ");
  if (mesure < 10) lcd.print(" ");
  //delay(100);
 
  mesureIR=analogRead(photoIR);
  if (mesureIR<seuil) {//Serial.println("Piece detecte");
  digitalWrite (Led, HIGH);
  }
  else {
    digitalWrite(Led,LOW);
  }
  //delay(10);
 
}



j'ajouterais donc une LED sur le pin 8

Impératif, il ne faut pas bloquer le déclenchement d'un second passage avec une fonction delay.


Est-ce possible ?

gunsman76

J'ai édité le premier post comme c'est un peu plus clair...

infobarquee

bonjour,
Quote
J'ai installé un potentiomètre qui me permet d'afficher sur le LCD un nombre qui va de 0 à 100. J'aimerais récupérer le résultat de cet affichage pour allumé une autre led avec un décalage dans le temps de 0 à 100 secondes.


je dirais que tu écris un code sans en comprendre son fonctionnement.
tu crois pas que tu peux récupérer quelque chose la dedans?
Quote
mesureBrute=analogRead(RVar);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);

gunsman76

Non justement j'essaie d'éviter de récuperer des bouts de code à droite à gauche, tout ce que j'ai mis dans mon code, je l'ai compris.


mesureBrute=analogRead(RVar);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);

je récupère une mesure de 0 à 1000 que je redivise par 10 si tu regardes bien mon programme.


Maintenant que j'ai mesure et c'est là que je bloque.

Comment récupérer cette mesure pour décaler l'allumage d'une seconde led.


Led A sur pin 8 s'allume
Led B sur pin 9 s"allume avec décalage de la valeur récupérer sur le potentiomètre (donc de 0 à 100 secondes)

Sans bloquer le programme, car un autre déclenchement doit pouvoir être enregistré et décalé

infobarquee


Non justement j'essaie d'éviter de récuperer des bouts de code à droite à gauche, tout ce que j'ai mis dans mon code, je l'ai compris.


mesureBrute=analogRead(RVar);
  mesure=map(mesureBrute,0,1023,0.0,1000.0);

je récupère une mesure de 0 à 1000 que je redivise par 10 si tu regardes bien mon programme.


Maintenant que j'ai mesure et c'est là que je bloque.

Comment récupérer cette mesure pour décaler l'allumage d'une seconde led.


Led A sur pin 8 s'allume
Led B sur pin 9 s"allume avec décalage de la valeur récupérer sur le potentiomètre (donc de 0 à 100 secondes)

Sans bloquer le programme, car un autre déclenchement doit pouvoir être enregistré et décalé


tu récupère dans une variable les millis() de la première led et tu ajoute ton décalage.
Quote

unsigned long time1;
unsigned long time2;
unsigned long time3;


si led allumée
time1 = millis();
alors
time2 = time1 + valeur_a_ajouter;
si time2 == millis();
allumer led2
etc.....

Go Up