Funkcja "millis" - kłopot ze zrozumieniem - sp9svn - 09-02-2019
Witam
proszę o pomoc w zrozumieniu działania funkcji "millis" .
Założyłem sobie do wykonania proste (tak myślałem na starcie) zadanie:
- trzy wyjścia
- jedno wejście
- po podaniu na wejście "H", wystaw kolejno "H" na wyjścia.
Na pierwsze wyjście po 2s i każde następne po kolejnej sekundzie.
Nie chciałem tego robić z wykorzystaniem "delay" lecz za pomocą "millis".
Efekt mojej twórczości powoduje po podaniu "H" na wejście wystawianie natychmiastowe wystawienie "H" na wszystkich wyjściach.
Proszę o podpowiedź gdzie popełniam błąd
Kod: #define L1 2 //blue
#define L2 3 //green
#define L3 4 //red
#define start 8 //sw1
int stateL1 = LOW;
int stateL2 = LOW;
int stateL3 = LOW;
const unsigned long period2 = 2000;
const unsigned long period3 = 3000;
//const unsigned long period4 = 4000;
unsigned long startMillis;
unsigned long current2Millis;
unsigned long current3Millis;
//unsigned long current4Millis;
void setup()
{
//Serial.begin(9600);
pinMode(L1, OUTPUT);
pinMode(L2, OUTPUT);
pinMode(L3, OUTPUT);
pinMode(start, INPUT);
startMillis = millis();
}
void loop()
{
if (digitalRead(start) == HIGH)
{
digitalWrite(L1,!digitalRead(L1));
current2Millis = startMillis; //przepisanie startMillis do current2Millis
if(current2Millis + period2 >= startMillis)
{
digitalWrite(L2,!digitalRead(L2));
current3Millis = startMillis;
}
if(current3Millis + period3 >= startMillis)
{
digitalWrite(L3,!digitalRead(L3));
}
}
}
RE: Funkcja "millis" - kłopot ze zrozumieniem - kaczakat - 10-02-2019
Masz przykład z blinkWithOutDelay, wykorzystaj dokładnie tę konstrukcję do zliczania sekund. Po prostu zamiast zmieniać stan led to w to miejsce wstawiasz zmienną globalną uint8_t sekundy i robisz jej ++. Może być oczywiście większa zmienna. Jak już masz w zmiennej sekundy zmieniające się na wartości 1,2,3,4.... to zwykłym if i porównaniem sterujesz całym programem. Program jest oczywiście napisany dobrze, gdy loop wykona się tysiące razy w ciągu każdej sekundy, więc w osobnej zmiennej należy trzymać zmienną, która informuje, że jest właśnie NOWA sekunda, tak by kod dla np. sukundy==3 wykonał się tylko raz. Np. jeśli co 3 sekundy chcesz zmienić stan led to kod:
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
uint16_t sekundy;
bool flaga1s;
// Variables will change:
int ledState = LOW; // ledState used to set the LED
// 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 = 0; // will store last time LED was updated
// constants won't change:
const long interval = 1000; // interval at which to blink (milliseconds)
void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
}
void loop() {
// here is where you'd put code that needs to be running all the time.
// check to see if it's time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();
if ((uint32_t)(currentMillis - previousMillis) >= interval) {
// save the last time you blinked the LED
flaga1s=1;
sekundy++;
previousMillis = currentMillis;
}
if(flaga1s&&(sekundy%3==0) digitalWrite(ledPin,! digitalRead(ledPin); //jak jest to "nowa sekunda" i reszta z dzielenia sekund/3==0 to zmien stan led na przeciwny
flaga1s=0;
}
RE: Funkcja "millis" - kłopot ze zrozumieniem - sp9svn - 13-02-2019
Witam kaczakat, witam wszystkich
Kaczakat - bardzo dziękuję za pomoc i natchnienie - rozwiązałem swój problem, chwilę to zajęło.
Do rozwiązania doszedłem trochę inną ścieżką ale, podkreślę raz jeszcze; z Twoją pomocą.
Dołożyłem jeszcze blok odpowiedzialny za wyłączanie, oraz zmieniłem kolejność działania:
Kod: const int L1 = 2;//blue
const int L2 = 3;//green
const int L3 = 4;//red
#define start 8 //sw1
int stateL1 = LOW;
int stateL2 = LOW;
int stateL3 = LOW;
int czyH = 0;
int czyL = 0;
const unsigned long t1 = 2000;
const unsigned long t2 = 4000;
const unsigned long t3 = 6000;
unsigned long czasHigh = 0;
unsigned long czasLow = 0;
unsigned long czasL3 = 0;
void setup()
{
//Serial.begin(9600);
pinMode(L1, OUTPUT);
pinMode(L2, OUTPUT);
pinMode(L3, OUTPUT);
pinMode(start, INPUT);
}
void loop()
{
//check start
if((digitalRead(start)==LOW)&&(czyH==0))
{
return;
}
unsigned long currentMillis = millis();
//go start
if((digitalRead (start) == HIGH) && (czyL==0))
{
czyH=1;
if (czasHigh == 0)
{
czasLow = 0;
czasHigh = currentMillis;
}
if (currentMillis - czasHigh >= t1)
{
digitalWrite(L1,HIGH);
digitalWrite(L2,HIGH);
}
if (currentMillis - czasHigh >= t3)
{
digitalWrite(L3,HIGH);
}
}
//end
if((digitalRead (start) == LOW)||(czyL==1))
{
delay(5);
if((digitalRead(start) == HIGH) && (czyL==0))
{
return;
}
czyL = 1;
czasHigh = 0;
if (czasLow == 0)
{
czasLow = currentMillis;
}
if (currentMillis - czasLow >= t1)
{
digitalWrite(L1,LOW);
digitalWrite(L3,LOW);
//czyL=0;
}
if (currentMillis - czasLow >= t3)
{
digitalWrite(L2,LOW);
czyL=0;
}
}
}
Płenta:
- wiem że mogę na Was liczyć
- "szpej" działa
- pora teraz na "wygłaskanie"
Pzdr
Grzegorz
sp9svn
|