Kód: Vybrat vše
// Arduino UNO
// Projekt zaberá 2230 bytov (6%) pamäte pre program. Maximum je 32256 bytov.
// Globálne premenné zaberajú 192 bytov (9%) dynamickej pamäti, 1856 bytov zostáva pre lokálne premenné. Maximum je 2048 bytov.
// počet trestných bodov 3952
#include <TimerOne.h>
#include <util/atomic.h>
#define TL1_PIN 2
#define TL1_PIN_AVR 2
#define TL2_PIN 3
#define TL2_PIN_AVR 3
#define TL3_PIN 4
#define TL3_PIN_AVR 4
#define DEBUG false
volatile uint8_t release;
int8_t counter=0;
void setup() {
pinMode(TL1_PIN, INPUT_PULLUP);
pinMode(TL2_PIN, INPUT_PULLUP);
pinMode(TL3_PIN, INPUT_PULLUP);
Serial.begin(9600);
Timer1.initialize(50000); //pretecenie kazdych 50ms, pozor na postranne efekty - je to urcene pre PWM
Timer1.attachInterrupt(timer1Callback);
}
void timer1Callback()
{
static uint8_t lastPin=(1 << TL1_PIN_AVR) | (1 << TL2_PIN_AVR) | (1 << TL3_PIN_AVR); //globalna privatna premenna
uint8_t pin; //aktualny stav na pinoch portu
uint8_t changePin; //piny ktore sa zmenili od posledneho prerusenia
//precita stav pinov kde su tlacitka (teraz jedno)
pin = PIND & ((1 << TL1_PIN_AVR) | (1 << TL2_PIN_AVR) | (1 << TL3_PIN_AVR)); //Plati pre UNO!!!
changePin = lastPin ^ pin; //vypocita pozicie kde sa hodnota oproti predoslemu stavu zmenila
//ak bola zmena stavu tlacitka a sucasne je pin v HIGH tak bolo uvolnenie stlacenia
if ((changePin & (1<<TL1_PIN_AVR)) && (pin&(1<<TL1_PIN_AVR))){
release |= 1 << TL1_PIN_AVR;
}
if ((changePin & (1<<TL2_PIN_AVR)) && (pin&(1<<TL2_PIN_AVR))){
release |= 1 << TL2_PIN_AVR;
}
if ((changePin & (1<<TL3_PIN_AVR)) && (pin&(1<<TL3_PIN_AVR))){
release |= 1 << TL3_PIN_AVR;
}
if (DEBUG){
Serial.print(F("timer - ") ); Serial.print(lastPin);
Serial.print(F(" , ") ); Serial.print(pin);
Serial.print(F(" , ") ); Serial.print(changePin);
Serial.print(F(" , ") ); Serial.println(release);
}
lastPin=pin; //odpameta sa novy stav
}
void loop() {
uint8_t temp;
temp = release;
release=0;
if (temp){
if (temp & (1<<TL1_PIN_AVR)){
counter++;
}
if (temp & (1<<TL2_PIN_AVR)){
counter--;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
if (temp & (1<<TL3_PIN_AVR)){
Serial.print(F("ENTER ") );
} else {
Serial.print(F("novy stav ") );
}
Serial.println(counter);
}
}
}
Ako vidno celá detekcia sa odohráva v obsluhe prerušenia časovača. Hlavný program nemusí nič riešiť stačí ak si kontroluje premennú release.
Potenciál na šetrenie je tu ešte veľký, ale to som práve moc nechcel. Preto je aj použitá nejaká "knižnica" pre prácu s čítačom, ktorá má plno zbytočností a vytvátra úplne zbytočný statický objekt a pridáva zbytočný kód programu.
Riešenie má potenciál obslúžiť až 8 tlačítok s minimálnimi úpravami kódu. Bonus som neriešil ale opäť je to veľmi jednoduché.