Vítejte na Elektro Bastlírn?
Nuke - Elektro Bastlirna
  Vytvořit účet Hlavní · Fórum · DDump · Profil · Zprávy · Hledat na fóru · Příspěvky na provoz EB

Vlákno na téma KORONAVIRUS - nutná registrace


Nuke - Elektro Bastlirna: Diskuzní fórum

 FAQFAQ   HledatHledat   Uživatelské skupinyUživatelské skupiny   ProfilProfil   Soukromé zprávySoukromé zprávy   PřihlášeníPřihlášení 

Arduino menu -k čemu flagy a jak zkrátit čekání pro přepnutí
Jdi na stránku 1, 2  Další
 
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další)
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: pá leden 15 2016, 13:01    Předmět: Arduino menu -k čemu flagy a jak zkrátit čekání pro přepnutí Citovat

Ahoj,jsem začátečník... mám tu program na menu s LCD , trochu sem ho přibarvil tlačítky a teploměrem.... nechápu : 1, k čemu je tady ten flag t_tlUp (to je flag pro tlačítko nahoru )
tl_up je pak samotné tlačítko-???myslím si dobře že to brání ke startu if hned od začátku co je tlačítko zmáčknuto...
kód:

void changeMenu() {
  if (!digitalRead(tlUp)) t_tlUp = 1;
  if (!digitalRead(tlDown)) t_tlDown = 1;
  if (digitalRead(tlUp) && t_tlUp) {
    t_tlUp = 0;
    lcd.clear();
    menu++;
    if (menu > pocetmenumax) menu = 1;
  }
  if (digitalRead(tlDown) && t_tlDown) {
    t_tlDown = 0;
    lcd.clear();
    menu--;
    if (menu < pocetmenumin)menu = 4;
  }
}


a další věc za 2,
čekám na zmáčknutí tlačítka pro přepnutí menu ,ale když ho trefím v nésprávný čas ,než se mi zmeří teplota tak se nic neděje....
kód:


void menu3() {
  lcd.setCursor(0, 0);
  lcd.print("Teplota :");
 
  int rawvolts = analogRead(analog0);
  float volts = rawvolts/205.0;
  float tempCelsius = 100.0 * volts -52;
  lcd.setCursor(0,1);
  lcd.print(tempCelsius);
  lcd.setCursor(6,1);
  lcd.print("C");
  delay(250);
  lcd.clear();
}

jednoduše mi přepíná menu zase funkce jiná a tady čekám na dokončení čtení teplota a prodlevu při velké prodlevě to nejde přepnout...nějaký nápad jak to přepnout v průběhu čtení teploty.kdykoliv?
kód:

void loop() {
  changeMenu();
  dispMenu();
}
//fce meni menu,flagy asi brani o5tovnemu spustenivcyklu
void changeMenu() {
  if (!digitalRead(tlUp)) t_tlUp = 1;
  if (!digitalRead(tlDown)) t_tlDown = 1;
  if (digitalRead(tlUp) && t_tlUp) {
    t_tlUp = 0;
    lcd.clear();
    menu++;
    if (menu > pocetmenumax) menu = 1;
  }
  if (digitalRead(tlDown) && t_tlDown) {
    t_tlDown = 0;
    lcd.clear();
    menu--;
    if (menu < pocetmenumin)menu = 4;
  }
}
//tady probiha prepinani
void dispMenu() {
  switch (menu) {
    case 1:
      menu1();
      break;
    case 2:
      menu2();
      break;
    case 3:
      menu3();
      break;
    case 4:
      menu4();
      break;
  }
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zmije



Založen: Jun 30, 2005
Příspěvky: 1576
Bydliště: Pardubický kraj

PříspěvekZaslal: pá leden 15 2016, 17:17    Předmět: Citovat

1) Hodnota menu se mění jen při náběžné hraně, pokud by se měnila při jedné úrovní, tak by se menu při držení tlačítka měnilo rychlostí odpovídající rychlosti volání changeMenu().

2) Tady jsou vpodstatě tři možnosti, buď zrychlit měření, tak aby reakční doba byla v pořádku, nebo použít odložené zpracování, nebo multitasking (nějaký rtos) což je v tomto případě zbytečně složité.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: pá leden 15 2016, 17:38    Předmět: Citovat

Díky Zmije.
1,Myslel jsem ,že je to k tomuhle aby se to nevykonávalo dokola.
2,proboha říkám sem začátečník jak se dělají ty dvě poslední možnosti nevím,
ale měření sem zpomalil kvůli LCD ,nešlo to ani číst ,jak to bylo rychlé.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pavoucisit



Založen: Nov 02, 2008
Příspěvky: 176
Bydliště: Havířov

PříspěvekZaslal: pá leden 15 2016, 20:56    Předmět: Citovat

Ahoj, viz bod 2 , celé to kazí delay(); čeká to zbytečně ¼ sekundy a po tuto dobu nic neuděláš. Návod jak vynechat delay pomocí millis http://www.pistek.eu/blog/2013/08/15/arduino-7-casovani-millis/

Já bych to třeba řešil inkrementací z a podmínkou if při dosažení hodnoty 250 bych hodnotu zobrazil a na konci zobrazení z=0
citace:
void menu3() {
z=z++;
int rawvolts = analogRead(analog0);

if (z==250){
lcd.setCursor(0, 0);
lcd.print("Teplota :");
float volts = rawvolts/205.0;
float tempCelsius = 100.0 * volts -52;
lcd.setCursor(0,1);
lcd.print(tempCelsius);
lcd.setCursor(6,1);
lcd.print("C");
delay(250);
lcd.clear();
z=0; }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 9:03    Předmět: Citovat

Z vámi uvedeného odkazu nechápu to použití millis.
Podle mě se vždy spustí první if .
kód:

void loop(){
  aktualniMillis = millis(); //podivam se na hodinky
  if(led_svetlo){ //potrebuju LED zhasnout nebo rosvitit?
    if(aktualniMillis - predchoziMillis > 500) { //pokud zhasnout ubehlu uz 500ms od posledni akce?
            predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
            led_svetlo=LOW; //zhasni led
    }
  }else if(aktualniMillis - predchoziMillis > 1000) { //pokud zhasnout ubehlu uz 1000ms od posledni akce?
            predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
            led_svetlo=HIGH; //rozsvit led
  }
  digitalWrite(led, led_svetlo); //aktualizace stavu LED
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial.write(inByte);
  }
}

začne to - (aktualniMillis - predchoziMillis) = 501 pak predchoziMillis = 501
pak třeba - ( 1002 - 501)=501 pak predchoziMillis 1002
pak -(1503 - 1002) = 501 zase první if ......predchoziMillis =1503
---vždy bude asi splněna první podmínka if
Nechápu kdy by mělo dojít k else if...vždy se spustí první if-což určuje pdomínka v závorce,nebo se pletu?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Cowley



Založen: Feb 04, 2005
Příspěvky: 3405

PříspěvekZaslal: so leden 16 2016, 9:25    Předmět: Citovat

Koukas spatne.
Else if se vztahuje k prvni podmince (svetlo jiz sviti), pokud ta nebude splnena, provede se podminka za else if.
Pokud bude splnena, udela se vnorena podminka IF pokud bude svetlo svitit dele jak 500.

Efektem je tedy blikani 501/1001.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 10:49    Předmět: Citovat

Chápu ,že else if se provede když není splněna podmínka if a je splněna podmínka else if ,ale proměná poslednimillis bude třeba v jednom za splnění if cyklu rovna 501 v prvním případě ,pak časovač millis doteče na 1002 a máme tady proměnou poslednimillis která se rovná aktuální millis tzn. že v cyklu kdy bude millis časovač na 1002 je podmínka prvního if splněna tj větší než 500,např 1002 -501 je 501 a zase mi nabíhá první if tohle nemohu z tohohle pohledu pochopit musím se přece dívat na hodnotu poslednimillis do které se mi ukládá aktuální millis.

ještě jednou

1 cyklus
poslednimillis 0
aktuální millis 501
---tzn. if je větší než 500

X cyklus

poslednimillis 501
aktualnimillis 1002
1002-501 je 500-první if zase ukládám hodnotu posledni millis na 1002.

z cyklus
poslednimillis 1002
aktualnimillis 1503
1503-1002 je 501 zase jede první if
....atd.prosím o vyluštění Smile záhady vždy to nejdřív dojde k hodnotě větší než 500 a ne hodnotě větší než 1000 protože ukládám do globální proměnné poslední hodnotu času.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 11:19    Předmět: Citovat

Tak přátelé myslim že sem sem dal špatný kus písma ,Zapoměl jsem na první if které konrtoluje zhasnutí světla v IDE jsem dal autoformat a bylo to jasné .
celé to je takle.
kód:

unsigned long aktualniMillis; //aktualni cas
unsigned long predchoziMillis; //cas poseldni akce
boolean led_svetlo; // promenna pro stav LED
int led = 13; //port pro LED

void setup() {
  pinMode(led, OUTPUT);
}
  void loop() {
    aktualniMillis = millis(); //podivam se na hodinky
    if (led_svetlo) { //potrebuju LED zhasnout nebo rosvitit?
      if (aktualniMillis - predchoziMillis > 500) { //pokud zhasnout ubehlu uz 500ms od posledni akce?
        predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
        led_svetlo = LOW; //zhasni led
      }
    } else if (aktualniMillis - predchoziMillis > 1000) { //pokud zhasnout ubehlu uz 1000ms od posledni akce?
      predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
      led_svetlo = HIGH; //rozsvit led
    }
    digitalWrite(led, led_svetlo); //aktualizace stavu LED

  }

Nezkopíroval jsem tady If led světlo které je jinak uzavřené k tomu patří ten else if a né k if co je nad else if. Tady to slouží jako taková výhybka pomocí světlo svítí a nebo ne....


Naposledy upravil saitt dne so leden 16 2016, 11:20, celkově upraveno 1 krát.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Cowley



Založen: Feb 04, 2005
Příspěvky: 3405

PříspěvekZaslal: so leden 16 2016, 11:19    Předmět: Citovat

Doplnim poznamkami do kodu:
kód:

void loop(){
  aktualniMillis = millis(); //nakopiruju aktualni cas
  if(led_svetlo){ //dotaz: sviti svetlo?
// ted se bude delat to, pokud sviti a budeme se prubezne ptat...
    if(aktualniMillis - predchoziMillis > 500) { //dotaz: sviti jiz dele jak 500 od posledniho nakopirovani?
            predchoziMillis = aktualniMillis; //pokud ANO: nastav si cas posledni zmeny
            led_svetlo=LOW; //zhasni led
    }
  }else if(aktualniMillis - predchoziMillis > 1000) { //a pokud nesviti svetlo a od posledni akce Ubehlo vice jak 1000
            predchoziMillis = aktualniMillis; //pokud ANO: nastav si cas posledni zmeny
            led_svetlo=HIGH; //rozsvit led
  }
  digitalWrite(led, led_svetlo); //aktualizace stavu LED
  if (Serial.available()) {
    int inByte = Serial.read();
    Serial.write(inByte);
  }
}
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 11:22    Předmět: Citovat

Tohle je rozhodující if (led_svetlo) ,přehlédl jsem to.... omlouvám se
pro vysvětlení uvažoval jsem jenom
kód:

 if (aktualniMillis - predchoziMillis > 500) { //pokud zhasnout ubehlu uz 500ms od posledni akce?
        predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
        led_svetlo = LOW; //zhasni led
      }
else if (aktualniMillis - predchoziMillis > 1000) { //pokud zhasnout ubehlu uz 1000ms od posledni akce?
      predchoziMillis = aktualniMillis; //v tento cas jsem provedl posledni akci
      led_svetlo = HIGH; //rozsvit led
    }
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Cowley



Založen: Feb 04, 2005
Příspěvky: 3405

PříspěvekZaslal: so leden 16 2016, 11:25    Předmět: Citovat

saitt napsal(a):
Tohle je rozhodující if (led_svetlo) ,přehlédl jsem to.... omlouvám se


Spis pocty, umisteni a vyznam zavorek, ktere ukazuji co k cemu patri... a pred else if jsou 2.
A i v prvnim prispevku jsou a byly dve, zadne kopirovani na to nemelo vliv...
Uz v 9:25 jsem na to upozornoval...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 11:30    Předmět: Citovat

jj dal jsem Autoformat a pěkně se to zobrazilo tj.odsazeni.
....Tak jsem to zkoušel a hodnota na displeji LCD s použitím funkce millis je nečitelná.



arduino1.jpg
 Komentář:

Stáhnout
 Soubor:  arduino1.jpg
 Velikost:  168.18 kB
 Staženo:  172 krát

Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 13:35    Předmět: Citovat

Tak už jsem něco zkoušel...problém je ,že v menu 3 pokud odkomentuju lcd.clear() tak mi displey začne blikat chtěl bych dosáhnout vymazání LCD pokud by se tam objevila např hodnota 100 stupnu a pak třeba 99 zustalo by tam 990 stupňů což je trošku hodně...

kód:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define tlUp 14
#define tlDown 15
#define tlLeft 16
#define tlRight 17
#define tlacitko5 18
#define led1 19
#define led2 20
#define analog0 A0
boolean t_tlUp, t_tlDown, t_tlLeft, t_tlRight;
int pocetmenumax = 4;
int pocetmenumin = 1;
char menu = 1;
char set1 = 0, set2 = 0;
boolean merim=1;
  long cas ;
  long aktualnicas;
 
////MAIN c0dE
//tady  je tlacitko5 vyrazeno
void setup() {
  for (int i = 14; i < 18; i++) {
    pinMode(i, INPUT);
    Serial.println(i);
  }
  pinMode(led1, OUTPUT);

  pinMode(led2, OUTPUT);
  lcd.begin(16, 2);
  Serial.begin(9600);
  Serial.println("RESTART");
  //flags
  t_tlUp = 0;
  t_tlDown = 0;
  t_tlLeft = 0;
  t_tlRight = 0;


}
void loop() {
  changeMenu();
  dispMenu();
}
//fce meni menu,flagy asi brani o5tovnemu spustenivcyklu
void changeMenu() {
  if (!digitalRead(tlUp)) t_tlUp = 1;
  if (!digitalRead(tlDown)) t_tlDown = 1;
  if (digitalRead(tlUp) && t_tlUp) {
    t_tlUp = 0;
    lcd.clear();
    menu++;
    if (menu > pocetmenumax) menu = 1;
  }
  if (digitalRead(tlDown) && t_tlDown) {
    t_tlDown = 0;
    lcd.clear();
    menu--;
    if (menu < pocetmenumin)menu = 4;
  }
}
//tady probiha prepinani
void dispMenu() {
  switch (menu) {
    case 1:
      menu1();
      break;
    case 2:
      menu2();
      break;
    case 3:
      menu3();
      break;
    case 4:
      menu4();
      break;
  }
}
//menu
void menu1() {
  lcd.setCursor(0, 0);
  lcd.print("LCD 1");
}
//meneni setu dvou led
void menu2() {
  lcd.setCursor(0, 0);
  lcd.print("LCD 2/LED");
  if (!digitalRead(tlLeft)) t_tlLeft = 1;
  if (!digitalRead(tlRight)) t_tlRight = 1;
  if (digitalRead(tlLeft) && t_tlLeft) {
    t_tlLeft = 0;
    set1++;
    if (set1 > 2) set1 = 1;

  }
  if (digitalRead(tlRight) && t_tlRight) {
    t_tlRight = 0;
    set2++;
    if (set2 > 2) set2 = 1;

  }
  switch (set1) {
    case 0:
      lcd.setCursor(0, 1);
      lcd.print("L1 off");
      digitalWrite(led1, LOW);
      break;
    case 1:
      lcd.setCursor(0, 1);
      lcd.print("L1 on ");
      digitalWrite(led1, HIGH);
      break;
    case 2:
      lcd.setCursor(0, 1);
      lcd.print("L1 off");
      digitalWrite(led1, LOW);
      break;
  }
  switch (set2) {
    case 0:
      lcd.setCursor(8, 1);
      lcd.print("L2 off");
      digitalWrite(led2, LOW);
      break;
    case 1:
      lcd.setCursor(8, 1);
      lcd.print("L2 on ");
      digitalWrite(led2, HIGH);
      break;
    case 2:
      lcd.setCursor(8, 1);
      lcd.print("L2 off");
      digitalWrite(led2, LOW);
      break;
  }
}

void menu3() {
  lcd.setCursor(0, 0);
  lcd.print("Teplota :");
aktualnicas =millis();
 
  if (merim) {
    if (aktualnicas- cas > 500) {
      cas =aktualnicas;
      int rawvolts = analogRead(analog0);
      float volts = rawvolts / 205.0;
      float tempCelsius = 100.0 * volts - 52;

      lcd.setCursor(0, 1);
      lcd.print(tempCelsius);
      lcd.setCursor(6, 1);
      lcd.print("C");
      //delay(10000);
      merim = LOW;
     

    }
  }
//zde je problem
  else if (aktualnicas- cas > 500 ) {
    cas =aktualnicas;
 //lcd.setCursor(14, 1);
     // lcd.print("t");
    //delay(1000);
    //lcd.clear();
    merim=HIGH;
  }

}

void menu4() {
  lcd.setCursor(0, 0);
  lcd.print("LCD 4");
}


[/code]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Cowley



Založen: Feb 04, 2005
Příspěvky: 3405

PříspěvekZaslal: so leden 16 2016, 14:23    Předmět: Citovat

Mozna nerozumim presne problemu, ale co ti brani prepisovat pred vlastnim zobrazenim jen danou pozici na displeji treba tremi mezerami, ktere zajisti odmazani nepotrebnych drive zobrazenych znaku a nepouzivat cely Clear.
A aby to nepoblikavalo, tak sledovat zmeny v dane promenne a zobrazit danou hodnotu jen jednou (nebo alespon jen jednou za cas) a ne vzdy kdyz jde program ve smycce "okolo".
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
saitt



Založen: Nov 11, 2015
Příspěvky: 107
Bydliště: Ostrava

PříspěvekZaslal: so leden 16 2016, 15:45    Předmět: Citovat

Tohle by přece mělo jednou za čas zobrazovat hodnotu teploty jednou za čas ... používal jsem předtím výpis hodnoty a delay a vymazat LCD a celé od začátku...
Takle se to zobrazuje celkem dobře ale lcd.clear nelze použít v různých variantách ....takže by to mělo třeba zobrazit 100 stupnu a výmaz ,nová hodnata 99 stupnu a výmaz.
Takže se to bude muset řešit asi přes ty prázdný místa,každopádně Díky za rady ani sem nedoufal,že se tady najde někdo přes Arduino.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
Přidat nové téma   Zaslat odpověď       Obsah fóra Diskuzní fórum Elektro Bastlírny -> Miniaturní počítače (Arduino, Raspberry a další) Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra.
Nemůžete odpovídat na témata v tomto fóru.
Nemůžete upravovat své příspěvky v tomto fóru.
Nemůžete mazat své příspěvky v tomto fóru.
Nemůžete hlasovat v tomto fóru.
Nemůžete připojovat soubory k příspěvkům
Můžete stahovat a prohlížet přiložené soubory

Powered by phpBB © 2001, 2005 phpBB Group
Forums ©
Nuke - Elektro Bastlirna

Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.


PHP-Nuke Copyright © 2005 by Francisco Burzi. This is free software, and you may redistribute it under the GPL. PHP-Nuke comes with absolutely no warranty, for details, see the license.
Čas potřebný ke zpracování stránky 0.28 sekund