Czasy w Arduino- jak sobie poradzić?

Masz problem z Arduino? Tutaj możesz szukać pomocy.
filozof
Młodszy majsterkowicz
Posty: 23
Rejestracja: 14 lut 2013, 19:27

Czasy w Arduino- jak sobie poradzić?

Post autor: filozof » 14 lut 2013, 19:48

Witam bardzo serdecznie jako nowy, całkiem świeży posiadacz cudeńka o nazwie Arduino UNO R3. Na wstępie króciutko się przedstawię. Na imię mam Wojtek, zacząłem studia na kierunku automatyka i robotyka i zaczynam swoje pierwsze malutkie kroczki z Arudino, gdyż jak wiadomo- bez włąsnych chęci i samozaparcia wiele osiągnąć się nie da ! ;-)

A teraz odnośnie wątku:
Mam pytanie odnośnie napisania prostego raczej programu który obsłuży diodę w następujący sposób:

Wciskam klawisz(button) i jeśli trzymam go mniej niż 2 sekundy- dioda nie świeci, natomiast jeśli trzymam go więcej jak 2 sekundy- dioda zaświeca się na 4 sekundy. Gdy naciskam przycisk podczas świecenia- dioda gaśnie i czas liczony jest od nowa.

Stworzyłem zmienną tim i napisałem programik jak poniżej, natomiast bolączką jest to że nie do końca działa to jak należy i nie do końca rozumiem dlaczego takie a nie inne wartości np. 150000 odpowiadają około trzem sekundom.

Przepraszam jeśli problem był już poruszany i jeśli na prawdę zadaję zbyt banalne pytania.

Na pewno to nie mój pierwszy i ostatni post na tym forum. Dzuękuję z góry za odpowiedź :)

float tim;
int ledPin=13;
int buttonPin=9;
int stan=1;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT);
}
void loop()
{
switch (stan)
{
case 1: digitalWrite(ledPin, LOW);
delay(100);
if(digitalRead(buttonPin)==HIGH)
{delay(1000), stan=2, tim=150000;} break;
case 2: digitalWrite(ledPin, HIGH);
if(!tim){stan=1;}
else if(digitalRead(buttonPin)==HIGH){stan=1;}
break;
}
if (tim) --tim;
}

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Awatar użytkownika
Maxik
Starszy majsterkowicz
Posty: 405
Rejestracja: 6 lip 2012, 18:27
Lokalizacja: Gdańsk
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Maxik » 14 lut 2013, 20:01

Funkcja millis() zwraca ile milisekund upłynęło od uruchomienia mikrokontrolera, typ danych to long. Zapisujesz sobie czas do zmiennej, potem sprawdzasz czy millis()>=startTime+3000.

W tym co napisałeś odejmujesz od zmiennej tim 1 w każdym przebiegu pętli, dodasz po drodze jakąś instrukcję i czasy się zmienią.
Awatar użytkownika
krzxsiek
Majsterkowicz
Posty: 145
Rejestracja: 24 wrz 2012, 22:50
Lokalizacja: Lublin
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: krzxsiek » 22 lut 2013, 18:36

A może mi ktoś pomóc jak zrobić funkcje która po odpaleniu przyciskiem uruchomi się tylko na powiedzmy 5sek. i jeśli przycisk przez ten czas nie został ponownie wciśnięty to się wyłączy? Bo jeśli przez ten czas przycisk był wciśnięty to dodaje do tego czasu kolejne 5 sekund aby się nie wyłączyła podczas przyciskania.

Będę bardzo wdzięczny za pomoc bo nigdzie nie mogę znaleźć informacji jak to zrobić a angielskich poradników za bardzo nie mogę pojąć :)
Awatar użytkownika
Maxik
Starszy majsterkowicz
Posty: 405
Rejestracja: 6 lip 2012, 18:27
Lokalizacja: Gdańsk
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Maxik » 22 lut 2013, 19:24

Musisz sobie to przemyśleć i skonstruować tę funkcję tak, aby wszystko działo się w pętli lub mogło być wywoływane kilka razy. Musisz podać szczegóły to będzie można powiedzieć coś więcej w tej kwestii.

Ogólnie można tak:

Kod: Zaznacz cały

unsigned long endTime = millis()+5000;
while(millis()<=endTime) {
//coś tam się dzieje
if(digitalRead(buttonPin)==HIGH) endTime+=5000;
}
lub piszesz funkcję która będzie wywoływana w każdej iteracji pętli loop, regulowała, sprawdzała czy co tam sobie wymyślisz jeśli ustawiona jest jakaś flaga boolean runFunc = true; Sprawdzasz też w każdym przejściu czy czas już upłynął, jeśli tak to wyłączasz co ma być wyłączone i flagę przestawiasz na false, obok sprawdzasz przycisk i ewentualnie dodajesz 5000 do endTime. Wiele zależy od konkretnego algorytmu.
Awatar użytkownika
krzxsiek
Majsterkowicz
Posty: 145
Rejestracja: 24 wrz 2012, 22:50
Lokalizacja: Lublin
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: krzxsiek » 1 mar 2013, 11:37

Jakoś sobie poradziłem :)

Jeśli chodzi o automatyczne wyłączenie po 5 sek. to tak sobie poradziłem:

Kod: Zaznacz cały

unsigned long wcisniety; //przechowuje stan licznika
byte opcja = 0; //domyślna opcja 0

const int redLED = 4; //pin czerwonej diody
const int greenLED = 5; //pin zielonej diody
const int przycisk = 2; //pin przycisku

void setup() {
  pinMode(redLED, OUTPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(przycisk, INPUT); 
}

void loop() {
  
  if (przycisk == HIGH) {     
    opcja = 1;
    wcisniety = millis(); //licznik startuje
  } 

  if (opcja == 0){ //domyślnie włączona opcja
    wcisniety = 0; //resetuje licznik
    digitalWrite(greenLED, HIGH); //zielona dioda włączona
    digitalWrite(redLED, LOW); //czerwona dioda wyłączona
  }


  if (opcja == 1){ //opcja włączana po wciśnięciu przycisku
    
    digitalWrite(redLED, HIGH); //czerwona dioda włączona

    jakas_funkcja();

    int czasWcisniecia = millis() - wcisniety;
    if(czasWcisniecia >= 5000) {
      opcja = 0; // po 5sek. powraca do opcji 0
      if(digitalRead(przycisk)==HIGH) wcisniety=millis(); //resetuje licznik podczas wciskania
    }

  }
}

void jakas_funkcja() {
  //coś się tutaj wykonuje
}
A co do przycisku który reaguje na krótkie lub długie wciśnięcia to skorzystałem z tego kodu:

Kod: Zaznacz cały

unsigned long keyPrevMillis = 0;
const unsigned long keySampleIntervalMs = 25;
byte longKeyPressCountMax = 80;    // 80 * 25 = 2000 ms
byte longKeyPressCount = 0;

byte prevKeyState = HIGH;         // button is active low
const byte keyPin = 2;            // button is connected to pin 2 and GND


// called when button is kept pressed for less than 2 seconds
void shortKeyPress() {
  Serial.println("krotkie wcisniecie");
}


// called when button is kept pressed for more than 2 seconds
void longKeyPress() {
  Serial.println("dlugie wcisniecie");
}


// called when key goes from not pressed to pressed
void keyPress() {
  Serial.println("przycisk wcisniety");
  longKeyPressCount = 0;
}


// called when key goes from pressed to not pressed
void keyRelease() {
  Serial.println("przycisk zwolniony");

  if (longKeyPressCount >= longKeyPressCountMax) {
    longKeyPress();
  }
  else {
    shortKeyPress();
  }
}


void setup() {
  Serial.begin(115200);
  pinMode(keyPin, INPUT_PULLUP);
}


void loop() {
  // Sekcja zarządzania przyciskiem
  if (millis() - keyPrevMillis >= keySampleIntervalMs) {
    keyPrevMillis = millis();

    byte currKeyState = digitalRead(keyPin);

    if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
      keyPress();
    }
    else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
      keyRelease();
    }
    else if (currKeyState == LOW) {
      longKeyPressCount++;
    }

    prevKeyState = currKeyState;
  }


  // Inny kod wprowadzamy tutaj
}
Mi się udało to rozwiązać :) Mam nadzieję że tym postem również komuś pomogę ;)
filozof
Młodszy majsterkowicz
Posty: 23
Rejestracja: 14 lut 2013, 19:27

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: filozof » 8 mar 2013, 16:44

Drodzy Majsterkowicze. Mam problem ze swoim prostym programikiem z wykorzystaniem funkcji millis().
W miejscach zaznaczonych pojawia się problem. Nie mogę tego zrozumieć, dlaczego porównując millis z czasem w przypadku pierwszym z opcją ">=" instrukcja if zwraca 1, natomiast w przypadku 2 gdy dam operator porównania "==" funkcja if zwraca 0? Przecież millis w pewnym czasie musi osiągnąć wartość czas = millis() + 1000 i operator porównania powinien zwrócić 1.
int ledPinB = 3;
int buttonPlus = 9;
int stan = 1;
unsigned long czas = millis();


void setup()
{

  Serial.begin(9600);
  pinMode(buttonPlus, INPUT);
}


void loop()
{  
  switch(stan)
  {
  case 1:
    if(digitalRead(buttonPlus)== HIGH)
    {
      czas = millis() + 2000;
      stan = 2;
    } 
    break;
  case 2:
    analogWrite(ledPinB, 7.2);
    if(millis() >= czas) // <<<<<---------- przypadek 1: idzie do stanu numer 3
    { 
      stan = 3;
    }
    break;
  case 3:
    analogWrite(ledPinB, 0);
    if(digitalRead(buttonPlus)== HIGH)
    {
      czas = millis() + 1000;
      stan = 4;
    } 
    break;
  case 4:
    analogWrite(ledPinB, 7.2);
    if(millis() == czas) // <<<<<<---------- przypadek 2: nie wchodzi do stanu nr 1
      stan = 1;
  }
  unsigned long tim=millis();
  Serial.println(stan);

}

Awatar użytkownika
cube
Złota rączka
Posty: 834
Rejestracja: 2 gru 2012, 17:02

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: cube » 8 mar 2013, 17:13

Masakryczny ten kod.
Kod obsługi przycisku (zmiana jakiejś wartości) wrzuć w przerwanie attachInterrupt(). Dopiero potem w kodzie powołuj się na tą zmienną.
Operator porównania == jest zły w tym wypadku, musiał by wywołać funkcję millis() dokładnie w momencie gdy ta przyjmie wartość "czas". Funkcja millis działa w tle i jej wartość jest pobierana dopiero jak program sobie tego zażyczy.
W czwartej linijce usuń przypisanie millis do zmiennej. Zrób je dopiero w momencie jak będziesz potrzebował wartość czasu, a na co Ci wartość czasu zaraz po włączeniu programu?
Wiesz jak twój program działa? O tak (opiszę pętlę główną):
wykonaj case1 => przypisz millis() do tim => print serial => wykonaj case2 => przypisz millis do tim => print serial => wykonaj case3 => przypisz millis do tim => print serial => wykonaj case4 => przypisz millis do tim => print serial => wykonaj case1 => przypisz millis do tim => print serial => itd.
jest źle napisany.
filozof
Młodszy majsterkowicz
Posty: 23
Rejestracja: 14 lut 2013, 19:27

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: filozof » 8 mar 2013, 20:06

Dzięki za odpowiedź i podpowiedzi.

Mam natomiast pytanie odnośnie attachInterrupt, gdyż zaciekawiła mnie ta funkcja przy okazji.
Pod pin 0 wpiąłem przycisk zasilany 5V i zmasowany przez rezystor. Tak więc na przycisku stan ustalony mam na LOW. Piszę najprostszy program, który wykonuje to właśnie "przerwanie" i okazuje się że coś robię nie tak, gdyż dioda nie zmienia stanu po wciśnięciu przycisku(nie świeci). Gdy zbliżę palec do pinu 0, dioda wariuje(mruga z różną częstotliwością). Co robię nie tak? Button jest na pewno dobrze podłączony, gdyż nie pierwszy raz to robię i mam 100% pewności.
int ledPin = 13;
boolean val=LOW;

void setup()

  pinMode(ledPin, OUTPUT);
  digitalWrite(0, LOW);
  attachInterrupt(0, blink, FALLING);
}

void loop()
{
}

void blink()
{
  value= !value;
  digitalWrite(pin, value);
}



Awatar użytkownika
cube
Złota rączka
Posty: 834
Rejestracja: 2 gru 2012, 17:02

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: cube » 8 mar 2013, 21:32

Jeśli korzystasz z laptopa - być może kwestia wariowania leda to brak uziemienia. Spróbuj podłączyć pin gnd do kaloryfera (mówię serio) albo do bolca w gnieździe 230V (ostrożnie! sprawdź próbnikiem czy przypadkiem nie ma tam fazy!)
W przerwaniu, zamiast FALLING spróbuj CHANGE.
W funkcji blink() używasz zmienną value a zadeklarowaną na początku masz val.
W przerwaniu powinieneś mieć funkcję czytającą stan przycisku a nie nadającą wartość!
Awatar użytkownika
Maxik
Starszy majsterkowicz
Posty: 405
Rejestracja: 6 lip 2012, 18:27
Lokalizacja: Gdańsk
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Maxik » 8 mar 2013, 22:59

Kompilator nie wyrzucił Ci błędu o nie zadeklarowaniu zmiennej value? Na górze jest val, w funkcji blink operujesz na value.

Dodatkowo powinno się ograniczać ilość instrukcji wykonywanych w przerwaniu, a zmienne na których w nim operujesz powinny być volatile, żeby kompilator nic nie namieszał podczas optymalizacji kodu.
gwidon
Młodszy majsterkowicz
Posty: 9
Rejestracja: 30 lip 2015, 23:11

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: gwidon » 31 lip 2015, 20:35

Witam.
Widzę, że temat stary ale mój problem chyba tu pasuje, więc nie będę zakładał nowego.
Jestem początkujący w temacie programowania i zaczynam od Arduino dla tego proszę o wyrozumiałość.
Problem mój polega na tym, że chcę zrobić sterownik włączający dwie diody LED dwoma przyciskami (jeden przycisk włącza jedną diodę). Każda z diod ma być włączona tak długo jak będzie wciśnięty przycisk a kiedy puszczę przycisk ma się świecić jeszcze przez jakiś czas zanim zgaśnie. Diody mają zapalać się i gasnąć niezależnie.
Napisałem program, ale coś mi nie idzie bo co prawda każda dioda zapala się i gaśnie z opóźnieniem ale tylko przy krótkim wciśnięciu przycisku. Jeśli przytrzymam przycisk dłużej to dioda gaśnie od razu kiedy tylko go puszczę.
Pomoże ktoś?

Kod: Zaznacz cały

int button = 4;
int button1 = 5;
int lednieb = 3;
int ledczer = 2;
int buttonState = HIGH;
int buttonState1 = HIGH;
unsigned long ledniebTime = millis();
unsigned long ledczerTime = millis();

void setup() {
  pinMode(button, INPUT_PULLUP);
  pinMode(button1, INPUT_PULLUP);
  pinMode(lednieb, OUTPUT);
  pinMode(ledczer, OUTPUT);

  digitalWrite(lednieb, LOW);
  digitalWrite(ledczer, LOW);

}

void loop() {
  buttonState = digitalRead(button);
  if(buttonState == LOW) {
    delay(25);
    digitalWrite(lednieb, HIGH);
  }
   if(buttonState == HIGH) {
    unsigned long time = millis();
    if(time >= ledniebTime){
        digitalWrite(lednieb, LOW); 
        ledniebTime = time + 4000;
      } 
  }
  
  
  buttonState1 = digitalRead(button1);
  if(buttonState1 == LOW) {
    delay(25);
    digitalWrite(ledczer, HIGH);
    }
  if(buttonState1 == HIGH) {
    unsigned long time = millis();
    if(time >= ledczerTime) {
      digitalWrite(ledczer, LOW);
      ledczerTime = time + 5000;
    }
  }
  
}

stiven
Złota rączka
Posty: 1594
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: stiven » 31 lip 2015, 21:51

Masz tego ifa gaszącego:

Kod: Zaznacz cały

if(time >= ledniebTime){
        digitalWrite(lednieb, LOW); 
        ledniebTime = time + 4000;
      } 
Zobacz, że dopiero wewnątrz tego ifa do zmiennej ledniebTime wpisujesz odpowiednie opóźnienie. Już po wyłączeniu diody, bez sensu. Musisz tę zmienną ustawić wcześniej, przed tym ifem, bo jeśli nie, to warunek w tym ifie od razu po puszczeniu przycisku jest prawdą i dioda jest gaszona właśnie od razu. Dla jednej diody (zmienna time jest niepotrzebna):

Kod: Zaznacz cały

  buttonState = digitalRead(button);
  if(buttonState == LOW) {
    delay(25);
    digitalWrite(lednieb, HIGH);
    ledniebTime = millis() + 4000;
  }
   if(buttonState == HIGH) {
    if(millis() >= ledniebTime){
        digitalWrite(lednieb, LOW); 
      } 
  }
gwidon
Młodszy majsterkowicz
Posty: 9
Rejestracja: 30 lip 2015, 23:11

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: gwidon » 31 lip 2015, 22:46

Kolego stiven strasznie bardzo dziękuję Ci za odpowiedź. Męczyłem się z tym dwa tygodnie i nie dawało mi to spokoju.
Pozdrawiam serdecznie :)
Kordiasz
Młodszy majsterkowicz
Posty: 4
Rejestracja: 4 lip 2016, 14:00

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Kordiasz » 4 lip 2016, 14:11

Mam mały problem, ponieważ chciałem sobie zrobić 2-funkcyjny termometr. Plany jest taki, żeby jednym przyciskiem:
1. Przycisk wciśnięty raz przełącza na temperaturę zewnętrzną, a po wciśnięciu drugi raz pokazało temperaturę wewnętrzną. Kolejne wciśnięcia powodują zmianę na drugą opcję.
lub
2. Wciśnięcie przycisku powoduję przełączenie temperatury i po określonym czasie powoduje powrót do poprzedniego stanu.

Kod: Zaznacz cały

#include <OneWire.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
#define BACKLIGHT_PIN 3
#define DHTPIN 7         
#define DHTTYPE DHT11      
 
DHT dht(DHTPIN, DHTTYPE); 

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);
 
void setup(void) 
{
Serial.begin(9600);
dht.begin();
lcd.begin(16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
pinMode(8,INPUT);		
digitalWrite(8,HIGH);		
lcd.setCursor(0,0); 
lcd.print("Witaj");
lcd.setCursor(0,1); 
lcd.print("04-07-2016");
}
 
void loop() 
  
{
  if (digitalRead(8)==LOW)		 
  {
  termometr();			
  }
}

void termometr()
{
float t = dht.readTemperature();
float h = dht.readHumidity();
lcd.print("Wilg: ");
lcd.print(h);
lcd.print(" %");
lcd.setCursor(0, 1);
lcd.print("Temp: ");
lcd.print(t);
lcd.print(" 'C");
lcd.setCursor(0, 0);
delay(2000);
}
Niestety po wielu próbach stanąłem na takim programie. Wiem, że drugą funkcję wyświetlania powinienem umieścić w kodzie void loop, a nie setup. Nie dałem rady tego umieścić w opcji loop, bo wtedy nic się nie działo.

Proszę o pomoc
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Marhef » 4 lip 2016, 14:38

A może w ifie w funkcji loop() sprawdź tylko, czy jest wciśnięty przycisk. Jeżeli tak, zwiększ wartość zmiennej (np przycisk) o 1. A następnie wpisujesz drugiego ifa, gdzie sprawdzasz, czy przycisk jest 0, 1 czy więcej niż jeden. Jeżeli większe od 1, to robisz funkcję modulo (reszta z dzielenia). Jak równe 0, wyświetlasz temperaturę z pierwszego termometru, jak równe 1, to z drugiego.
A wcześniej, przed funkcją setup() deklarujesz drugiego DHT11, w taki sam sposób, jak robisz to teraz.
To jest rozwiązanie dla pierwszego pomysłu.
Aha, jeszcze jedno. Musisz pomyśleć o niwelowaniu drgań styków (szukaj pod hasłem "debouncing").
Używasz wyświetlacza ze sterownikiem HD44780? Masz tam symbol stopnia, nie musisz używać znaku '
Kordiasz
Młodszy majsterkowicz
Posty: 4
Rejestracja: 4 lip 2016, 14:00

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Kordiasz » 4 lip 2016, 17:10

Zrobiłem na dwóch czujnikach, oraz dwóch przyciskach. Niestety nie jest to w 100% poprawne, bo parametry zmieniają się dopiero po odświeżeniu (kliknięciu przycisku/przycisków).

Kod: Zaznacz cały

#include <OneWire.h>
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS18B20.h>
 
#define BACKLIGHT_PIN 3
#define DHTPIN 7        
#define DHTTYPE DHT11  
 
DHT dht(DHTPIN, DHTTYPE);

#define BACKLIGHT_PIN 3
#define ONEWIRE_PIN 2
 
float temperature = 0;
 
byte address[8] = {0x28, 0xFF, 0xFF, 0x6, 0x56, 0x16, 0x3, 0x86};

byte temp[8] = {
	0b01110,
	0b01010,
	0b01110,
	0b00000,
	0b00000,
	0b00000,
	0b00000,
	0b00000
};

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);
 
OneWire onewire(ONEWIRE_PIN);
DS18B20 sensors(&onewire);
 
 
void setup() 
{
lcd.begin(16,2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
Serial.begin(9600);
sensors.begin();
sensors.request(address);
dht.begin();
lcd.createChar(0, temp);
pinMode(8,INPUT);
digitalWrite(8,HIGH);
pinMode(4,INPUT);
digitalWrite(4,HIGH);  
lcd.setCursor(0,0);
lcd.print("Termometr");
lcd.setCursor(0,1);
lcd.print("domowy");
}

void loop() 
  
{
  if (digitalRead(8)==LOW)
  {
  DH();
  }
  if (digitalRead(4)==LOW)
  {
  DS();
  }
}


void DH()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temp. otoczenia");
int h = dht.readHumidity();
lcd.setCursor(0,1);
lcd.print("W:");
lcd.print(h);
lcd.print("%");
int t = dht.readTemperature();
lcd.setCursor(7,1);
lcd.print("T:");
lcd.print(t);
lcd.write(byte(0));
lcd.print("C");
delay(2000);
}

void DS()
{
temperature = sensors.readTemperature(address);
sensors.request(address);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temp. w pokoju");
lcd.setCursor(0,1); 
lcd.print("Temp: ");
lcd.print(temperature);
lcd.setCursor(10,1);
lcd.write(byte(0));
lcd.print("C");
delay(2000);
}
Nie bardzo rozumiem co masz na myśli czy po wciśnięciu przycisku jest 0,1 czy coś więcej. Jeżeli wcisnę to jest przejście, jak nie to nie ma przejścia. Jeszcze coś wieczorem doczytam o tej funkcji modulo.
Dzięki za wskazówki.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Marhef » 4 lip 2016, 18:18

Chodzi mi o to, że tworzysz zmienną:

Kod: Zaznacz cały

int przycisk = 0;
A pętlę loop() masz np. taką:

Kod: Zaznacz cały

if (digitalRead(8) == LOW) przycisk++;
if (przycisk > 1) przycisk %= 2;
if (przycisk == 0) DH();
else if (przycisk == 1) DS();
Jeżeli nic nie wciśniesz, będziesz miał temperaturę z funkcji DH();
Jeżeli wciśniesz raz, będziesz miał wywołaną funkcję DS();
Jeśli wciśniesz po raz trzeci, zmienna przycisk będzie miała wartość 2, zadziała

Kod: Zaznacz cały

if (przycisk > 1) przycisk %= 2;
i do zmiennej przycisk zostanie przypisana wartość reszty z dzielenia zmiennej przycisk przez 2 (czyli 0).
Ale w ten sposób to się nie do końca sprawdzi, bo masz drganie styków, więc jednorazowe naciśnięcie przycisku spowoduje dodanie do zmiennej przycisk kilka razy wartości 1. Jak to rozwiązać - doczytaj. Nawet w przykładach w arduino ide to jest
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: ethanak » 4 lip 2016, 19:02

w ten sposób nie wyjdzie - musisz złapać zmianę a nie pozycję klawisza.
coś w stylu

Kod: Zaznacz cały

int getPressed()
{
    thisKey = digitalRead(pin);
    diff = !thisKey && lastKey;
    lastKey = thisKey;
    return diff;
}
Inaczej przy przytrzymaniu przycisku będziesz miał bajkę o wilku i zającu.
Pisze człowiek ambitnie, a tu przychodzi prostak i wszystko rozumie.
To jest ewidentna bezczelność!
Awatar użytkownika
Marhef
Złota rączka
Posty: 1188
Rejestracja: 18 lis 2011, 02:18

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Marhef » 4 lip 2016, 20:28

Racja, pisałem na szybko. Ale chciałem podać sposób, a nie dawać gotowca
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: ethanak » 4 lip 2016, 20:49

...i na szybko podałeś niedziałającego gotowca?
Pisze człowiek ambitnie, a tu przychodzi prostak i wszystko rozumie.
To jest ewidentna bezczelność!
Kordiasz
Młodszy majsterkowicz
Posty: 4
Rejestracja: 4 lip 2016, 14:00

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Kordiasz » 4 lip 2016, 23:55

OK, już wiem gdzie złapać punkt zaczepienia. Będę próbował jak podał ethanak, bo to są przyciski monostabilne i faktycznie trzeba złapać ten moment.
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: ethanak » 5 lip 2016, 09:07

Jeszcze jedno - ponieważ trochę nieprecyzyjnie określiłeś reakcję układu na wciśnięcie klawisza.
Rozumiem to tak:

a) wciśnięcie klawisza powoduje przełączenie z wyświetlania temperatury wewnętrznej na zewnętrzną lub odwrotnie
b) jeśli wyświetlana jest temperatura zewnętrzna, po upływie określonego czasu termometr wraca do wyświetlania temperatury wewnętrznej.

Czy o to chodziło?

Poza tym nie rób czegoś takiego jak delay(2000) - w takiej sytuacji układ będzie czytał pozycję klawisza nie częściej niż co dwie sekundy, a chyba nie jest to pożądany objaw ;) Pisałem już o tym - optymalny czas obrotu pętli to 20 msec, opóźnienie reakcji na klawisz jest niezauważalne a w tym czasie najprawdopodobniej zdążysz wszystko odczytać/wyświetlić.
Powinno to wyglądać mniej więcej tak:

Kod: Zaznacz cały

void loop()
{
    odczyt_temperatury();
    odczyt_klawisza();
    decyzja_co_wyświetlić();
    wyświetlenie();
    delay(20);
}
gdzie funkcja odczyt_temperatury sama powinna zadecydować, czy przyszedł czas na nowy odczyt (tzn. czy upłynęły już 2 sekundy od ostatniego), a funkcja wyświetlenie przesyła dane do wyświetlacza tylko wtedy, gdy się zmieniły.

A tak przy okazji - zakładaj następnym razem nowy wątek.
Pisze człowiek ambitnie, a tu przychodzi prostak i wszystko rozumie.
To jest ewidentna bezczelność!
zgoda
Majsterkowicz
Posty: 60
Rejestracja: 23 cze 2016, 09:58

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: zgoda » 5 lip 2016, 09:17

A ja bym w loop() robił nie odczyt stanu klawisza, tylko odczyt zmiennej ustawianej naciśnięciem guzika w obsłudze przerwania na tym guziku. Wtedy żadne naciśnięcie ci nie umknie.
Awatar użytkownika
ethanak
Złota rączka
Posty: 764
Rejestracja: 21 lis 2015, 14:41
Kontakt:

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: ethanak » 5 lip 2016, 09:54

Można, ale tak jest prościej.
Poza tym jeśli klawiszy będzie więcej niż jeden (np. sześć), to sprawa z przerwaniem zaczyna się komplikować - trzeba dodawać jakieś dodatkowe elementy elektroniczne.
Poza tym ja nie potrafię nacisnąć klawisza na krócej niż 20 msec :)
Pisze człowiek ambitnie, a tu przychodzi prostak i wszystko rozumie.
To jest ewidentna bezczelność!
Kordiasz
Młodszy majsterkowicz
Posty: 4
Rejestracja: 4 lip 2016, 14:00

Re: Czasy w Arduino- jak sobie poradzić?

Post autor: Kordiasz » 5 lip 2016, 10:41

ethanak pisze: a) wciśnięcie klawisza powoduje przełączenie z wyświetlania temperatury wewnętrznej na zewnętrzną lub odwrotnie
b) jeśli wyświetlana jest temperatura zewnętrzna, po upływie określonego czasu termometr wraca do wyświetlania temperatury wewnętrznej.

W przykładzie a chodzi o zrobienie pętli. Jest temp. wewnętrzna>przycisk>temp. zewnętrzna>przycisk>temp. wewnętrzna itd. Ta opcja była by fajna, bo można by wykorzystać większą liczbę czujników i taka pętla się dobrze sprawdzi. W przypadku opcji b dobrze by się sprawdzała w obecnym zestawieniu i zapewne jest łatwiejsze w zaprogramowaniu.

Chodzi o delay(2000) w funkcji void DS() oraz void DH()? Jak zmienię opóźnienie to w tym czasie nie będzie występował częstszy odczyt z czujników?

W tym ostatnim przykładzie co podałeś to odczyt musi być z dwóch czujników czy z jednego i dwie takie pętle?
ethanak pisze:A tak przy okazji - zakładaj następnym razem nowy wątek.
W tym temacie było o opóźnieniach przycisku i dlatego się dopisałem. Będę pamiętał na przyszłość.

P.S. Przepraszam za takie laickie pytania, ale to mój 3 dzień przy programowaniu z możliwością tego przeniesienia na układ, bo wcześniej tylko teoria.
ODPOWIEDZ

Strony partnerskie: