• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
przycisk start stop
#1
Witam

zaczynam swoją przygodę z arduino i mam pewien problem, buduję stoper który odlicza czas kod odpowiedniego programu udało mi się znaleźć lecz mam pewien problem.. Nie potrafię dodać uruchamiania stopera przez przycisk. Bardzo proszę o pomoc i proszę o wyrozumiałość jestem starym elektronikiem a z programowaniem dopiero rozpoczynam przygodę.

O to kod który posiadam

#include <LiquidCrystal.h>  // biblioteka LCD 
int sek = 0;      // zmienna typu intiger z wartością początkową 0
int minuty = 0;     // zmienna typu intiger z wartością początkową 0  
int godziny =0;     // zmienna typu intiger z wartością początkową 0
int dni = 0;      // zmienna typu intiger z wartością początkową 0 
int pin_przycisk = 7; 
LiquidCrystal lcd(12,11,5,4,3,2);       //definiujemy zmienną lcd, przez którą będziemy się
        //komunikować z modułem; podajemy do których 
        //pinów podłączyliśmy się w Arduino
        //ustawienia dla pinu przycisku   
void setup()      // parametry przygotowawcze
{
  pinMode(pin_przycisk, INPUT_PULLUP); //pracuje jako wejscie
  digitalWrite(pin_przycisk, HIGH); //spoczynkowy stan wysoki (rezystory podciagajace wlaczone)

lcd.begin(16,2);    // parametry wyświetlacza   
}

void loop()     // główna pętla
{
 int przycisk = digitalRead(pin_przycisk); //odczytujemy stan przycisku
 int stan;

 if(przycisk == HIGH) //jesli przycisk nie jest wcisniety
 {
  stan=0;
 }

 else // w przeciwnym wypadku
 {
  stan=1;
  delay(100);
  
 }

 if(stan==0)
 {
  int sek = 0;
  }
 lcd.setCursor(8,0);    // ustawienie kursora
 lcd.print ("Godzin ");   // wyświetlenie tekstu
 lcd.print (godziny);   // wyświetlenie wartości przypisanej do godziny
 lcd.print (" ");   // wyświetlenie tekstu -spacja
 lcd.setCursor (0,0);   // ustaw kursor
 lcd.print ("DNI ");    // wyświetlenie tekstu
 lcd.print (dni);   // wyświetlenie wartości przypisanej do dni
 if ( minuty == 60)   // pętla -wejście gdy spełniony zostaje warunek
{         
 delay (32);      // czekaj 32ms = 0,32s
 minuty = 0;      // przypisz wartość 0
 godziny ++;      // zwiększ godziny
 }
 if (godziny> 23)   // wywołanie instrukcji warunkowej -wejście gdy 
 {        // spełniony zostaje warunek
 dni++;       // zwiększ dni o 1
 godziny = 0;     // przypisz wartość 0
 }

 lcd.setCursor (0,1);   // ustaw kursor     
 lcd.print (minuty);    // wyświetlenie wartości przypisanej do minuty
 lcd.print (" min ");   // wyświetlenie tekstu
 lcd.setCursor (8,1);   // ustaw kursor
 lcd.print (sek);   // wyświetlenie wartości przypisanej do sek
 lcd.print (" SEC ");   // wyświetlenie tekstu
 if (sek >59)     // analogicznie jak wyżej 
 {
 minuty ++;     // zwiększ minuty     
 sek = 0;     // przypisz 0
 delay (58);      // czekaj 58ms – 0,58s
 }
 if (sek < 60)      // analogicznie jak wyżej   
 {
 delay (988);     // czekaj 988ms=0,988 s
 sek ++;      // zwiększ sek
 }



Pozdrawiam
 
Odpowiedź
#2
Nie brnij w ten kod dalej. Zapoznaj się na początek z millis, jest w przykładach w IDE blinkWithOutdelay, jest tu na kursie, jest w tysiącach przykładów na sieci, tu na forum kilkadziesiąt. Niestety zabawa będzie prostsza, jeśli przejdziesz jakiś kurs podstaw, nawet jeśli nie potrzebujesz do niczego realizowanych w nich projektów: https://forbot.pl/blog/kurs-arduino-pods...rsu-id5290 .
Sprawdzenie stanu przycisku trwa z us, wciśnięcie przycisku kilka ms, ty trzymasz na delayach procek przez tysiące ms. Nigdy to dobrze działać nie będzie.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#3
Dziękuję za odpowiedź, czytam kurs forbota i coś zaczynam jarzyć Smile dzięki jeszcze raz
A co do tego kodu.. znalazłem po prostu, wyglądał ok, działa(liczy czas itd ) na moje potrzeby w sam raz ale potrzebuję start i stop Smile
Pozdrawiam
 
Odpowiedź
#4
Millis to coś na dobry początek w Arduino, delay jest OK by coś na szybko przetestować, ale to taki patyk w szprychy. Można migać sobie np. 1 led, czytać 1 czujnik i nawet drukować, bo to jest robione synchronicznie, ale tu masz mierzenie asynchroniczne, przycisk ma być odczytany natychmiast, dodanie polecenia wymaga od razu korekcji delay by pętla trwała sekundę. Normalnie loop w ciągu sekundy tysiące razy może sprawdzić stan przycisku, jeśli przez 5ms jest wciśnięty można robić akcję. W tych samych obiegach pętli zliczane są us, ms, s, itd. W czasie delay wykonywane są tylko przerwania.
A jak potrzeba jeszcze większych szybkości to trzeba sięgnąć bezpośrednio do timerów.
Na początek wystarczy taki sposób pisania w pętli loop, by tu żadna funkcja i żadne polecenie nie zawierało delay.
Do przycisków można też użyć gotowych bibliotek jak bounce2.
Dla porównania zegarek na millis z przykładu w Arduino:
Kod:
/*
 Blink without Delay

 Turns on and off a light emitting diode (LED) connected to a digital pin,
 without using the delay() function. This means that other code can run at the
 same time without being interrupted by the LED code.

 The circuit:
 - Use the onboard LED.
 - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
   and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
   is set to the correct LED pin independent of which board is used.
   If you want to know what pin the on-board LED is connected to on your
   Arduino model, check the Technical Specs of your board at:
   https://www.arduino.cc/en/Main/Products

 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 modified 11 Nov 2013
 by Scott Fitzgerald
 modified 9 Jan 2017
 by Arturo Guadalupi

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin

// Variables will change:
int ledState = LOW;             // ledState used to set the LED
uint8_t ms100, s, m, g, f100ms, fs, fm, fg;
String wydrukczasu;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis, poczatek,koniec,dlugosc;        // will store last time LED was updated


// constants won't change:
const unsigned long interval = 100;           // zamienione na 100ms

void setup() {
pinMode(ledPin,OUTPUT);
Serial.begin(115200);
}

void loop() {
poczatek=micros(); //poczatek pomiaru ile trwa funkcja
 czas(); //ustawienie czasu na poczatku petli
koniec=micros(); //koniec pomiaru ile trwa funkcja
dlugosc=koniec-poczatek; //mozna przeniesc te trzy linijki na koniec loop i sprawdzic, ze petla trwa max 16us
koniec=poczatek; //a bez tych wyliczen oczywiscie szybciej


if(fs)
{
digitalWrite(ledPin,!digitalRead(ledPin));
if(s%2==0) Serial.println(dlugosc);
if(s%5==0) Serial.println( String(g)+':'+String(m)+':'+String(s));  
}




 flagi();//zerowanie flag na koniec petli
}



inline void czas()
{
unsigned long currentMillis = millis();
 if (currentMillis - previousMillis >= interval) {  //minal interval, 100ms
   previousMillis = currentMillis; //zerujemy licznik ms
   f100ms=1; //ustawienie flagi 100ms
   ms100++; //zwiekszenie liczby setek
       if (ms100>=10) //minela sekunda
       {
         ms100=0; //zerujemy licznik setek ms
         fs=1; //ustawinie flagi wybicia sekundy
         s++; //zwiekszenie sekund
       
             if(s>=60)
             {
               s=0; //zerujemy licznik  
               fm=1; //ustawinie flagi  
               m++; //zwiekszenie

               if(m>=60)
                 {
                   m=0; //zerujemy licznik  
                   fg=1; //ustawinie flagi  
                   g++; //zwiekszenie  
                 }
             }
               
       
       }

   
 }
}

inline  void flagi() //zerowanie flag na koniec petli
 {
  f100ms=0;
  fs=0;
  fm=0;
  fg=0;
 }
Zaraz tu zajrzy pewien pan i wytknie, że sprzętowym timerem byłoby szybciej to liczyć, ale zaletą Arduino jest to, że zamienia się UNO na ESP8266, ESP32, STM ARM, DUE ARM czy inną płytkę zdefiniowaną w Arduino i bez zmieniania jednej linijki ten kod działa na wszystkich.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#5
Dzięki za zainteresowanie moim problemem Co do sprzętowego timera posiadam takowy ale chcę zrobić to tylko za pomocą samego arduino. Buduję tester akumulatorów żelowych który będzie kontrolował poziom rozładowania i stąd pomysł aby użyć arduino do mierzenia czasu rozładowania. Układ który zabezpiecza akumulator przed zbyt dużym rozładowanie już zrobiłem opierając się o pewien kit avt tylko potrzebuję go jakoś połączyć tym nieszczęsnym licznikiem
Pozdrawiam
 
Odpowiedź
#6
Liczenie czasu zrób na przerwaniach. Wszystko co potrzebne do tego znajdziesz w bibliotece "timer.h". Przycisk obsłuż biblioteką likwidującą drżenie styków np debounce, nie będziesz potrzebował delay w obsłudze przycisku. Wyswietlanie może zostać jak jest.
 
Odpowiedź
#7
Sprzętowy timer to jeden z tych wbudowanych w Arduino 0,1, i 2. Nie chodzi o taki do gniazdka z Biedronki. Arduino używa np. Timera 0 do odliczania czasu i napędzania funkcji micros/millis, a te z kolei są wykorzystywane również w timer.h (ta biblioteka działa jak podany przykład, tylko bardziej elegancko - jest poukłada w klasy C++). Jak zaczniesz grzebać w sprzętowych przerwaniach i timerach to zniknie możliwość zamiennego użycia na różnych platformach dostępnych w Arduino. Używając Arduino do takich pierdół jak sekundy nie warto w to wnikać.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#8
(15-08-2018, 13:30)kaczakat napisał(a): Jak zaczniesz  grzebać w sprzętowych przerwaniach i timerach to zniknie możliwość zamiennego użycia na różnych platformach dostępnych w Arduino.

Biblioteka timer.h jest na wszystkie platformy.
Nawet jesli by nie była to nie ma co patrzeć na przenośność bo dotyczy ona prostych programów jak miganie diodą. Bardziej zaawansowane nie mają szansy działać albo działają po japońsku (jako-tako).
 
Odpowiedź
#9
Trochę pogrzebałem i potrafię już to zerować przyciskiem ale jak zatrzymać odliczanie? Przepraszam że tak drążę ale dla mnie temat w którym raczkuję i każda pomoc osób siedzących w temacie jest przydatna. Dziękuję oczywiście za podpowiedzi..

Kod :

#include <LiquidCrystal.h> // biblioteka LCD
#define OK 7
int sek = 0; // zmienna typu intiger z wartością początkową 0
int minuty = 0; // zmienna typu intiger z wartością początkową 0
int godziny =0; // zmienna typu intiger z wartością początkową 0
int dni = 0; // zmienna typu intiger z wartością początkową 0

LiquidCrystal lcd(12,11,5,4,3,2); //definiujemy zmienną lcd, przez którą będziemy się
//komunikować z modułem; podajemy do których
//pinów podłączyliśmy się w Arduino
//ustawienia dla pinu przycisku
void setup() // parametry przygotowawcze
{
pinMode(OK, INPUT_PULLUP); //pracuje jako wejscie


lcd.begin(16,2); // parametry wyświetlacza
}

void loop() // główna pętla
{
if(digitalRead(OK)==LOW) // gdy wcisniemy przycisk
{
sek = 0;
minuty = 0;
godziny = 0;
dni = 0;
}


{


}


{
int sek = 0;
}
lcd.setCursor(8,0); // ustawienie kursora
lcd.print ("Godzin "); // wyświetlenie tekstu
lcd.print (godziny); // wyświetlenie wartości przypisanej do godziny
lcd.print (" "); // wyświetlenie tekstu -spacja
lcd.setCursor (0,0); // ustaw kursor
lcd.print ("DNI "); // wyświetlenie tekstu
lcd.print (dni); // wyświetlenie wartości przypisanej do dni
if ( minuty == 60) // pętla -wejście gdy spełniony zostaje warunek
{
delay (32); // czekaj 32ms = 0,32s
minuty = 0; // przypisz wartość 0
godziny ++; // zwiększ godziny
}
if (godziny> 23) // wywołanie instrukcji warunkowej -wejście gdy
{ // spełniony zostaje warunek
dni++; // zwiększ dni o 1
godziny = 0; // przypisz wartość 0
}

lcd.setCursor (0,1); // ustaw kursor
lcd.print (minuty); // wyświetlenie wartości przypisanej do minuty
lcd.print (" min "); // wyświetlenie tekstu
lcd.setCursor (8,1); // ustaw kursor
lcd.print (sek); // wyświetlenie wartości przypisanej do sek
lcd.print (" SEC "); // wyświetlenie tekstu
if (sek >59) // analogicznie jak wyżej
{
minuty ++; // zwiększ minuty
sek = 0; // przypisz 0
delay (58); // czekaj 58ms – 0,58s
}
if (sek < 60) // analogicznie jak wyżej
{
delay (988); // czekaj 988ms=0,988 s
sek ++; // zwiększ sek
}
 
Odpowiedź
#10
(15-08-2018, 14:00)mobbi napisał(a): Trochę pogrzebałem i potrafię już to zerować przyciskiem ale jak zatrzymać odliczanie?

Musisz reagowac na zmiane stanu przycisku a nie na konkretny stan. Aby ta funkcja działała poprawnie musisz pozbyć się drżenia styków.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości