From AnalysIR WiKi
This is the main Arduino sketch file, containing both the setup and loop functions.
- First we init the MCU frequency divider to match the setting selected in the Arduino IDE. The crystal used is 16MHz, so for 8MHz operation the clock needs to be divided by a factor of 2. We suggest using 8Mhz with this firmware for the best balance between battery and IR performance. With other firmware loaded (e.g. IRremote), by all means use 16MHz etc.
- Then we initialise all non-keypad related pins - for the optional IR receivers and I2C EEPROM and their related power supply via GPIO. The default state for these devices is powered down.
- Next we init the keypad buttons. Each button is mapped to a particular Row/Col combination.(see section on pin outs) The 7 Cols are defaulted to INPUT_PULLUP and the 7 Rows are defaulted to OUTPUT LOW. This allows us to make use of PCINT interrupts on the COL pins to detect when a button is pressed during PWR_DOWN mode. Once the MCU wakes up (Triggered by the PCINT interrupt), we immediately check to see which COL was pulled LOW and then search each ROW to find the actual button that was (is still) pressed. If more than one button was pressed we assume the first one found is the one that was pressed. Users could extend this logic to support multiple key presses etc.
- Next we init the LED pin as output and it defaults LOW or off. This is one of a set of LED control macros available in the header file.
- Then we output a set of debug info over Serial, if debug mode is on. We also check to see if we are running on battery or not. If the supply voltage is greater than 4 Volts we assume we are being powered by USB, otherwise by the 2xAAA batteries. KontroLIR is never put to sleep when powered from USB.
- Next we init the low power mode settings for sleeping. Essentially we turn off any unnecessary peripherals to reduce power consumption and set the sleep mode to PWR_DOWM.
- Then we init the Pin change interrupts on the COL pins and subsequently enable the relevant PCINT interrupts.
At the end of the setup function, control automatically passes to the loop portion of the firmware.
The flow here is relatively simple:
- Everthing is wrapped in a while loop to avoid the unneccessary Arduino processing at the end of each loop.
- The variable which records the PCINT Col that woke KontroLIR up from sleep is always reset to 0 to indicate a button has not been pressed. (Cols and Rows go from 1->7)
- If we are running on batteries, we send KontroLIR to sleep (PWR_DOWN mode). We calculae Vcc in tenths of volts and assume if the voltage is greater than 4 volts (value 40) that we are powered from USB instead of 2xAAA batteries.
- Once a PCINT is detected, pcIntCol will be set to the Col # withinin the PCINT ISR
- We then call isButtonPressed, which checks if we can still detect a row with a button pressed.
- If there is confirmation that we have both a Col and Row value, we assume a particular button was pressed.
- We then turn on the LED as a visual indicator
- doButtonPressed is called to implement the functionality for that button in the current mode
- Once processing is completed the LED is turned off.
- The while loop repeats and goes back to sleep when waiting for the next button to be pressed. (If not running on batteries the loop runs continuously, waiting for a button to be pressed.)
- The reason for not going to sleep when powered from USB, is that there can be some issues entering the bootloader when KontroLIR is in PWN_DOWN mode.