Arduino- delay

Raspberry, Arduino, Mini-PC a další

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
dj_rizek
Příspěvky: 711
Registrován: 07 dub 2005, 02:00
Bydliště: blízko Třeboně

Arduino- delay

#1 Příspěvek od dj_rizek »

Ahoj,

potřebuju synovi do domečku vyrobit ovládání světla.

Chci tuto funkci:
Ovládání tlačítky zap/vyp
po zapnutí aktivní časovač 60minut (znáte děti pořád něco nechával zaplý jako manželky)
výstup PWM pro LED pásek ovládané potenciometrem
zapínací tlačítko podsvícené pulzující LED

Funkce naprogramovaný (kromě 60m časovače tam bych ještě dodal odpočet pomocí LED po 10minutách)mám ale problém Delay (),ten mi zabrzdí všechno ostatní.

Prosím o nakopnutí jak to vyřešit aby to nečekalo,teda pokud to Arduino umí,zatím jsem s ním dělal vymyšlené věci nebo jednoduché aplikace.

Uživatelský avatar
pocitujlasku
Příspěvky: 1757
Registrován: 12 pro 2005, 01:00

#2 Příspěvek od pocitujlasku »

nedavat delay, ale upravit to cez interrupt - prerusenie, kde sa bude v pravidelnych casovych intervaloch inkrementovat premenna. A v hlavnom programe len doplnit porovnavanie.
No vidis, a tak si sa bal

Uživatelský avatar
dj_rizek
Příspěvky: 711
Registrován: 07 dub 2005, 02:00
Bydliště: blízko Třeboně

#3 Příspěvek od dj_rizek »

Děkuju,

mohl bys hodit část nějakýho programu nebo odkaz abych to správně pochopil.

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#4 Příspěvek od FHonza »

Nahraď funkci Delay() testem zda uběhl již požadovaný čas. Nástřel:

Kód: Vybrat vše

#define DELAY_TIME = 500 // v milisekundach
long lastTime = 0;
...

void loop()
{
   if ((millis() - lastTime)) >= DELAY_TIME)
  {
    // neco, co se ma vykonat jednou za DELAY_TIME
   ...
   lastTime = millis();
  }
}

Uživatelský avatar
ross4435897
Příspěvky: 426
Registrován: 10 lis 2009, 01:00
Bydliště: Brno

#5 Příspěvek od ross4435897 »


Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 01:00

#6 Příspěvek od frpr666 »

2FHonza
to mě vždycky zajímalo co se stane při přetečení proměnné lastTime a millis() ?

Kód: Vybrat vše

// millis() is an unsigned long
long lastTime = 0;

if ((millis() - lastTime)) >= DELAY_TIME)
{
//...
}

Uživatelský avatar
monterjirka
Příspěvky: 2761
Registrován: 14 čer 2003, 02:00
Bydliště: Blížejov

#7 Příspěvek od monterjirka »

S tím "přetečením" je problém, ono se to vynuluje a jede to od začátku...
Ale potřeboval jsem to do jedné aplikace a nezjistil jsem jestli to jde nějak "programově" vynulovat...

Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 01:00

#8 Příspěvek od frpr666 »

Vypadá to, že pokud je "millis" unsigned typ a "lastTime" signed typ stejné velikosti, přetékání nedělá žádný problém.
Zkoušel jsem to na uint16_t a int16_t s DELAY_TIME=500.
Ať přeteče millis nebo přeteče lastTime furt je rozdíl stejný (millis - lastTime = 500).
Nejsem matematik, připadá mě to, že souvisí s operací odečítání a interpretací kladného a záporného čísla.

Kód: Vybrat vše

void test_function( void)
{
uint16_t millis = 0;
int16_t lastTime = 0;
int16_t diff;
uint16_t terminate_me = 1000;

  for(;;)
  {
     millis++;
     if (diff = millis - lastTime, diff >= DELAY_TIME)
     {
         printf("%08i\t%08i\t%08i\t%08i\n", millis, lastTime, diff, terminate_me);
         lastTime = millis;
         terminate_me--;
         if (0==terminate_me) break;
     }
  }
}
Přílohy
2016-06-20-graph.png
(6.69 KiB) Staženo 190 x

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#9 Příspěvek od FHonza »

Správně by mělo být

Kód: Vybrat vše

unsigned long lastTime = 0; 
už jenom protože fce milis() vrací také bezznaménkový long.
Otázkou je, jaký typ "použije" překladač pro výsledek ulong - long.

Uživatelský avatar
ross4435897
Příspěvky: 426
Registrován: 10 lis 2009, 01:00
Bydliště: Brno

#10 Příspěvek od ross4435897 »


Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#11 Příspěvek od FHonza »

a nejlíp "nepoužívejte millis, ale timer" :)

Uživatelský avatar
dj_rizek
Příspěvky: 711
Registrován: 07 dub 2005, 02:00
Bydliště: blízko Třeboně

#12 Příspěvek od dj_rizek »

Tak jsem se na to vyprdnul,pokud použiju něco jinýho,tak mi to neběží, zredukoval jsem delay časy a použiju externí 60 minutovej časovač,nějaký časovací moduly mám.

Program zveřejňovat nebudu protože byste se mi vysmáli,je to upravená slátanina několika programů ale dělá co potřebuju.

Už na škole moje programy v Pascalu učitele vždy pobavily. :cry:

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#13 Příspěvek od FHonza »

Nikdo by se ti nesmál, fakt. Nahraj sem původní program s Delay, rád ti pomůžu. Když už jednou v projektu máš mcu, tak je škoda dávat navíc HW jenom kvůli chybě v SW.

Uživatelský avatar
dj_rizek
Příspěvky: 711
Registrován: 07 dub 2005, 02:00
Bydliště: blízko Třeboně

#14 Příspěvek od dj_rizek »

Je to paskvil ale to jsou začátky,
PWM mám aktivní pořád protože napájení LED bude přes relátko ovládaný taky arduinem (nechci mít vypnutý LED pásky pod žádným napětím) takže proto se neaktivuje až po stisknutí tlačítka.
Vstupy/výstupy taky zvolený nahodile.

Kód: Vybrat vše

int led = 11;           // Led ovladaci tlacitko
int brightness = 0;    
int fadeAmount = 6;    
int Ledpin=9;           //vystup na Mosfet PWM
int analogpin= A2;      //vstup potenciometru
int value=0;            //promenna pro hodnotu potenciometru
int x;                  //prevedena hodnota z 0..1023 na 0..255 
int LEDka =2;           // rele pro 12V led + ovladaci napeti ext casovace
int TLAC = 3;           // ovladaci tlacitko
int timer= 7;           // vstup z ext casovace
boolean svetlo = false; // Pomocná hodnota světlooid setup() 

void setup() {
 
  pinMode(led, OUTPUT);
  pinMode(Ledpin, OUTPUT);      
  pinMode(LEDka, OUTPUT);    
  pinMode(TLAC, INPUT);    
  pinMode(timer, INPUT);  
}

void loop() {
  //mzouratko
  analogWrite(led, brightness);
  
  brightness = brightness + fadeAmount;
   
  if (brightness == 50 || brightness == 255) {
    fadeAmount = -fadeAmount ; }
    {
   //PWM   
 value=analogRead(analogpin);  //precist potenciometr
 x=map(value,0,1023,0,255);    //prevod hodnot z potenciometru na PWM rozsah
 analogWrite(Ledpin,x); 
     }   
 delay(20);
   
   {
  //tlac zap/vyp
  if (digitalRead(TLAC))
  {
   
   if (svetlo) svetlo = false; else svetlo = true;
      
    
   
   digitalWrite(LEDka, svetlo);
   
   while (digitalRead(TLAC)) 
         
      delay(50);
    
       
  }
    // vypnuti ext casovacem
  if (digitalRead(timer)) {
    svetlo=false;
    digitalWrite(LEDka,svetlo); delay(50);} 
}
}


Uživatelský avatar
frpr666
Příspěvky: 1051
Registrován: 28 pro 2009, 01:00

#15 Příspěvek od frpr666 »

@FHonza
Co je to millis() ? Pokud dáte do programu millis(), tak arduino automaticky na "pozadí" spustí časovač, uživatel o tom mnohdy ani neví.

To jsem tak jednou přemýšlel proč mi nejede PWM. Až jsem udělal výpis pomocí:
build.path=f:\arduino_out\
build.verbose=true
Tak jsem zjistil, že arduino si už použilo časovač ke svým účelům...

Odpovědět

Zpět na „Miniaturní počítače (Arduino, Raspberry a další)“