Zastavení smyčky

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Axamith
Příspěvky: 533
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Zastavení smyčky

Příspěvek od Axamith » 10 úno 2018, 07:47

Existuje možnost, jak dočasně zastavit průběh smyčky?
Potřebuji provést měření hmotnosti, následně pozastavit smyčku, provést výměnu závaží a pokračovat v měření. Informaci, že potřebuji zastavit bych řešil podmínkou při stisku tlačítka. Jde to, nebo chci po Arduinu už moc?

jankop
Příspěvky: 1034
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od jankop » 10 úno 2018, 08:30

Ptáš se na zastavení void loop(void) ?
To zřejmě nejde, ale nevidím k tomu ani reálný důvod.
Když si to představím zjednodušeně, tak opakovaně vážím a v okamžiku stisku tlačítka prostě podmínkou to vážení obejdu. Maximálně tam přibudou nějaké příznaky stisku tlačítka apod. Můžeš to nějak precizovat?

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od petan » 10 úno 2018, 08:59

Přesně jak píše jankop...
Pozastavit jde provedením příkazu delay(); Ale není k tomu nejmenší důvod. Při každém průchodu smyčkou by se kontrolovalo, jestli není stisknuto tlačítko. Pokud ne, tak by se vážilo. Pokud ano, tak by se vážení přeskočilo... nebo opačně. Záleží na tom, co přesně to má dělat.

Axamith
Příspěvky: 533
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od Axamith » 10 úno 2018, 08:59

Před samotnou realizací váhy je potřeba provést kalibraci tenzometru. Stanovit kalibrační faktor, případně nulový faktor, zde je to popsáno https://learn.sparkfun.com/tutorials/lo ... duino-code
Běžně se vypočítá v samostatné sketchi a následně přepíše do sketce s vlastním měřením. Chci mít možnost provést kalibraci v terénu, bez potřeby zásahu do kódu. Takže podmínkou (button_1 - ON) spustím smyčku kalibrace, pak bych potřeboval vyřešit tu pauzu (button_2 - ON), na váhu dám známou zátěž (např. 10 kg), start druhého vážení, porovnám výsledek s přednastavenou hodnotou (v potřebné toleranci), bude-li vše OK, kalibraci uložím do EEPROM a kalibrační hodnoty budu načítat z ní.
Co tím získám? Možnost kalibrace v terénu bez PC (např. 1x za rok) a hlavně, při restartu již zatížené váhy se nebude ona zátěž počítat jako nulová hodnota (nebude v běžné proměnné, ale v EEPROM).

petan
Příspěvky: 358
Registrován: 23 črc 2017, 10:19
Reputation: 0
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od petan » 10 úno 2018, 12:12

Můžeš použít třeba podmínku Switch - https://arduino.cz/pokrocilejsi-struktu ... ka-wiring/

Pomocí tlačítek nastavíš nějakou proměnnou a podle proměnné se ti bude spouštět požadovaná část kódu. Hooodně hrubej nástřel je dole

Kód: Vybrat vše

//přečte stav tlačítek
if (!digitalRead(btn1) && !digitalRead(btn2)) state = 0
if (!digitalRead(btn1) && digitalRead(btn2)) state = 1
if (digitalRead(btn1) && !digitalRead(btn2)) state = 2
if (digitalRead(btn1) && digitalRead(btn2)) state = 3

//podle stisknutých tlačítek něco proveď
switch (state){
case 1:
 //kalibrace
 break;
case 2:
 //vazeni
  break;
case 3:
 //něco dalšího
 break;
default: 
 //pokud hodnota neodpovídá proveď toto...
}

jankop
Příspěvky: 1034
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od jankop » 10 úno 2018, 12:24

Nebo se můžeš zkusit inspirovat v tomhle

Kód: Vybrat vše

#include <Ticker.h>
#define BUTTONZERO       0        // pin pro tlacitko nulovani
#define BUTTONGAIN       14       // pin pro tlacitko nastaveni zisku
#define BUTTONTIME      0.25      // perioda cteni tlacitek v sekundach
bool    ButtonZero      = false;  // priznak stisku tlacitka
bool    ButtonGain      = false;  // priznak stisku tlacitka
bool    VazeniFlag      = true;   // priznak - mam vazit
char    ButtonZeroCount = 0;      // citac doby stisku tlacitka
char    ButtonGainCount = 0;      // citac doby stisku tlacitka
Ticker TickerButtonRead;

//-----------------------------------------------------------------
void setup(void) {
  Serial.begin(115200);
  pinMode(BUTTONZERO, INPUT);     // definice vstupu tlacitko
  pinMode(BUTTONGAIN, INPUT);     // definice vstupu tlacitko
  TickerButtonRead.attach(BUTTONTIME, GetButton);
}
//-----------------------------------------------------------------
void loop(void) {

  if (ButtonZero) Nulovani();
  if (ButtonGain) Zesileni();
  if (VazeniFlag) Vazeni();
  delay(1000);
}//-----------------------------------------------------------------

/* Read buttons */
void GetButton(void) {
  if (digitalRead(BUTTONZERO) == false ) ++ButtonZeroCount;
  if (digitalRead(BUTTONZERO) == true && ButtonZeroCount > 1 && ButtonZeroCount < 12 ) {
    ButtonZeroCount = 0;
    VazeniFlag  = false;
    ButtonGain = false;
    ButtonZero = true;
  }
  if (digitalRead(BUTTONZERO) == true ) ButtonGainCount = 0;

  if (digitalRead(BUTTONGAIN) == false ) ++ButtonGainCount;
  if (digitalRead(BUTTONGAIN) == true && ButtonGainCount > 1 && ButtonGainCount < 12 ) {
    ButtonGainCount = 0;
    VazeniFlag  = false;
    ButtonGain = true;
    ButtonZero = false;
  }
  if (digitalRead(BUTTONGAIN) == true ) ButtonGainCount = 0;
}
void Nulovani(void) {
  Serial.println("Nulovani");
  // ...
  VazeniFlag  = true;
  ButtonZero = false;
}
void Zesileni(void) {
  Serial.println("Zesileni");
  // ...
  VazeniFlag  = true;
  ButtonGain = false;
  }
void Vazeni(void) {
  Serial.println("Vazeni");
  // ...
}

Periodicky se čtou tlačítka. Když stiskneš při odlehčené váze jedno, tak rutinou Nulovaní odečteš nulovou hodnotu a uložíš ji. Když při zatížené váze stiskneš druhé tlačítko, tak odečteš zesílení a uložíš ho. A jinak vážíš. Základní princip příznaků od tlačítek můžeš pochopitelně libovolně modifikovat.
Příkaz delay(1000); je tam jen proto, aby bylo vidět, že tato simulace funguje, bez ní je to moc rychlé.

Axamith
Příspěvky: 533
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od Axamith » 10 úno 2018, 12:46

Pánové, díky za nakopnutí správným směrem. V podstatě jde o to, že smyčka neustále jede a stiskem tlačítka (podmínkou) chod přesměruji na vykonání potřebné procedury. Zkusím a dám vědět, jak jsem si natloukl nos :-)
Naposledy upravil(a) Axamith dne 10 úno 2018, 12:57, celkem upraveno 1 x.

jankop
Příspěvky: 1034
Registrován: 06 zář 2017, 20:04
Reputation: 0
Bydliště: Brno
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od jankop » 10 úno 2018, 12:55

Pochopils to naprosto správně.

Axamith
Příspěvky: 533
Registrován: 09 srp 2017, 08:17
Reputation: 0
Kontaktovat uživatele:

Re: Zastavení smyčky

Příspěvek od Axamith » 14 úno 2018, 17:07

Dal jsem dohromady základ vyhodnocení stisku tlačítek a přesměrování na potřebnou proceduru. Zatím jen blikám, abych měl jasno, jak to směrování funguje. Na začátku podmínek vyhodnocuji, jestli nejsou stisknuta obě tlačítka. V praxi to nebudu potřebovat, tlačítka nahradí kolíková lišta a jumper, ale jeden nikdy neví ... Teď už "jen" dodatluji výpočty a práci s EEPROM.

Kód: Vybrat vše

const int SW_1 = 2;     // SW_1
const int SW_2 = 3;     // SW_2
const int LED =  13;    
int buttonSW_1 = 0;    // stav SW_1
int buttonSW_2 = 0;    // stav SW_1
void setup() {
    pinMode(LED, OUTPUT);
    pinMode(SW_1, INPUT);
    pinMode(SW_2, INPUT);
    Serial.begin(9600);
}
void loop(){
    // stav SW_1,2:
   buttonSW_1 = digitalRead(SW_1);
   buttonSW_2 = digitalRead(SW_2); 
  Serial.print("SW_1 = ");
  Serial.print(buttonSW_1);
  Serial.println();
  Serial.print("SW_2 = ");
  Serial.print(buttonSW_2);
  Serial.println();
  delay(1000);
   if (buttonSW_1 + buttonSW_2 > 1) { //SW_1,2 ON = Error
Err();
}
  else
    if (buttonSW_1 == HIGH) { //SW_1 ON
        blikSW_1();
    }
    else
if (buttonSW_2 == HIGH) {  //SW_2 ON
        blikSW_2();
    }      
}

void blikSW_1()               //SW_1 ON
{
  digitalWrite(LED, HIGH); 
  delay(200);               
  digitalWrite(LED, LOW);    
  delay(200); 
  digitalWrite(LED, HIGH); 
  delay(200);               
  digitalWrite(LED, LOW);    
  delay(200);  
  digitalWrite(LED, HIGH); 
  delay(200);               
  digitalWrite(LED, LOW);    
  delay(1000);  
}

void blikSW_2()               //SW_2 ON
{
  digitalWrite(LED, HIGH); 
  delay(2000);               
  digitalWrite(LED, LOW);     
  delay(1000);  
}

void Err()               //Error - SW_1,2 ON
{
Serial.println("Error");  
  delay(500); 
  
  }

ok1vkt
Příspěvky: 26
Registrován: 06 úno 2018, 16:29
Reputation: 0

Re: Zastavení smyčky

Příspěvek od ok1vkt » 10 bře 2018, 18:52

co zkusit použít Interupt funkci??? Je k ní přímo i HW vstup. Pokud vim ta by měla provést přerušení hlavního programu.
Pokud se pletu, nekamenujte mně :-)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti