Stránka 1 z 2

Arduino- delay

Napsal: 20 čer 2016, 13:47
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.

Napsal: 20 čer 2016, 13:54
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.

Napsal: 20 čer 2016, 13:57
od dj_rizek
Děkuju,

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

Napsal: 20 čer 2016, 14:02
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();
  }
}

Napsal: 20 čer 2016, 14:04
od ross4435897

Napsal: 20 čer 2016, 18:10
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)
{
//...
}

Napsal: 20 čer 2016, 19:26
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...

Napsal: 20 čer 2016, 23:04
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;
     }
  }
}

Napsal: 21 čer 2016, 09:42
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.

Napsal: 21 čer 2016, 09:44
od ross4435897

Napsal: 21 čer 2016, 09:47
od FHonza
a nejlíp "nepoužívejte millis, ale timer" :)

Napsal: 21 čer 2016, 11:30
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:

Napsal: 21 čer 2016, 11:34
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.

Napsal: 21 čer 2016, 12:44
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);} 
}
}


Napsal: 21 čer 2016, 19:07
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...