Stránka 2 z 2

Re: Challenge

Napsal: 04 pro 2021, 15:07
od peterple
OK tu je moje riešenie:

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);
      }
  }
}
Riešenie je zámerne trochu netypické. V prvom rade chcem povedať že je v ňom jedna zámerná chyba aby ste mali po čom pátrať. Tá vedie k tomu že niektoré uvolnenia tlačítok nebudú zbadané. Skúste navrhnúť ako tú chybu najjednoduchšie odstrániť. Vodítko sa dá nájsť aj v programe.

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é.

Re: Challenge

Napsal: 05 pro 2021, 14:17
od Caster
Nic proti Challenge, ale připadá mi to trochu mimo mísu. Osobně bych radši viděl nějaké praktické tipy, např. odečet údajů z plynoměru, měření obsahu septiku apod. než řešit kraviny ;) .

Re: Challenge

Napsal: 05 pro 2021, 14:38
od kiRRow
Caster píše:
05 pro 2021, 14:17
Nic proti Challenge, ale připadá mi to trochu mimo mísu. Osobně bych radši viděl nějaké praktické tipy, např. odečet údajů z plynoměru, měření obsahu septiku apod. než řešit kraviny ;) .
Máš to? Vyřešil jsi to? Pochlub se :)

Re: Challenge

Napsal: 05 pro 2021, 22:13
od Caster
Pracují na mikro lokátoru GPS/LoRa (8 x 35 mm) zašitý do obojku s výdrží 3 měsíce, aktuálně ladím zesilovač GPS signálu. Z chystaných projektů jde o pájení SMD součástek na jednoplotýnkovém vařiči na listu pilu, měřič obsahu septiku poklepem na jeho vnější stěnu a autonomní dron s programovatelnou trasou letu a rozpoznáním překážek pomocí umělé inteligence. Dokončené projekty: dálkové měření napětí autobaterie (SigFox) a náhrada externího čidla teploty Oregon Scientific THN132N pomocí MCU ATtiny202.