diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md
new file mode 100644
index 0000000..cce1f76
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/Readme.md
@@ -0,0 +1,385 @@
+PinChangeInterrupt Library 1.2.9
+================================
+
+
+
+PinChangeInterrupt library with a resource friendly implementation (API and LowLevel).
+PinChangeInterrupts are different than normal Interrupts. See detail below.
+
+##### Features:
+* PinChangeInterrupt for a lot of pins
+* Rising, Falling or Change detection for every pin separately
+* Usable on a lot Arduino compatible boards
+* Implementation is fast, compact and resource friendly
+* Ports/Pins can be manually deactivated in the Settings file
+* API and LowLevel option
+* Full Port0-3 support
+* .a linkage optimization (Arduino IDE)
+
+
+
+#### Supported pins for PinChangeInterrupt:
+See [PCINT pin table](https://github.com/NicoHood/PinChangeInterrupt/#pinchangeinterrupt-table) at the bottom for more details.
+
+```
+Arduino Uno/Nano/Mini: All pins are usable
+Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
+ A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
+Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
+HoodLoader2: All (broken out 1-7) pins are usable
+Attiny24/44/84: All pins are usable
+Attiny25/45/85: All pins are usable
+Attiny13: All pins are usable
+Attiny441/841: All pins are usable
+Attiny261/461/861: All pins are usable
+Attiny2313/2313A/4313: PORTB is usable
+ATmega644/ATmega644P/ATmega1284P: All pins are usable
+ATmega162: PORTA and PORTC usable
+ATmega48/88/168/328/328PB: All pins are usable
+```
+
+Contact information can be found here:
+
+www.nicohood.de
+
+Installation
+============
+
+Download the zip, extract and remove the "-master" of the folder.
+Install the library [as described here](http://arduino.cc/en/pmwiki.php?n=Guide/Libraries).
+
+This library can also be used with the [DMBS AVR Library Collection](https://github.com/NicoHood/avr) and a pure makefile.
+
+How to use
+==========
+
+It is important that you know at least the basic difference between **PinInterrupts** and **PinChangeInterrupts**.
+I will explain the basics of **PinChangeInterrupts** (PCINTs) based on an Arduino Uno.
+
+On a standard Arduino Uno Pin 2 and 3 have **PinInterrupts**. Those are exclusively for a single pin and can detect RISING, FALLING and CHANGE.
+
+**PinChangeInterrupts** instead are used for a whole port (they should have better named them PortChangeInterrupts) and can only detect CHANGE for a whole port.
+Each pin row (0-7, 8-13, A0-A5) represents a port. If an interrupt (ISR) occurs on one pin of a port
+it is still unclear what pin of the port caused this interrupt. Therefore this library saves the state of the whole port and compares with the last state.
+This way we can also see if it was a RISING or FALLING edge instead of only knowing the CHANGE.
+
+A **PinChangeInterrupt** will only be triggered for the attached pins per port.
+Meaning if you set PCINT for a pin and another pin on the same port is changing a lot
+it will not interrupt your code.
+
+**PinChangeInterrupts** might be a tiny bit slower and not that reliable because of that detection overhead (talking about micro seconds).
+Make sure to not use longer function calls inside the ISR or Serial print.
+You have the same issues on normal **PinInterrupts** and interrupts in general.
+
+The library is coded to get maximum speed and minimum code size. The LowLevel example without the API takes 4uS to enter the interrupt function in the worst case
+which is pretty good and might be even better than the **PinInterrupt** code from the official Arduino core due to high optimization.
+If you need very precise interrupts you better use **PinInterrupts** without the Arduino IDE at all.
+
+### Examples
+To see how the code works just check the Led and TickTock example.
+The LowLevel example is for advanced users with more optimization and more direct access.
+The HowItWorks example shows the basic PinChangeInterrupt setup and decoding routine, similar to the library.
+See the notes in the examples about more details.
+
+An useful "real use" example of the PinChangeInterrupt library can be found here:
+https://github.com/NicoHood/IRLremote
+
+### API Reference
+
+##### Attach a PinChangeInterrupt
+```cpp
+// The pin has to be a PCINT number. Use the makro to convert a pin to a PCINT number.
+// Enables event functions which need to be defined in the sketch.
+// Valid interrupt modes are: RISING, FALLING or CHANGE
+attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick), tick, RISING);
+
+// You can also input the PCINT number (see table below)
+attachPinChangeInterrupt(5, tock, FALLING);
+
+// PinChangeInterrupt can always be abbreviated with PCINT
+attachPCINT(digitalPinToPCINT(pinBlink), blinkLed, CHANGE);
+```
+
+##### Detach a PinChangeInterrupt
+```cpp
+// Similar usage as the attachPCINT function.
+// Interrupts will no longer occur.
+detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+detachPinChangeInterrupt(5);
+detachPCINT(digitalPinToPCINT(pinTock));
+```
+
+##### Enable/Disable a PinChangeInterrupt
+```cpp
+// Similar usage as the attachPCINT function.
+// Use this to temporary enable/disable the Interrupt
+disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+disablePinChangeInterrupt(5);
+disablePCINT(digitalPinToPCINT(pinBlink));
+
+// Enable the PCINT with the old settings again (function + mode)
+enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+enablePinChangeInterrupt(5);
+enablePCINT(digitalPinToPCINT(pinBlink));
+```
+
+##### Get Trigger on mode CHANGE
+```cpp
+// Differenciate between RISING and FALLING on mode CHANGE.
+// Only use this in the attached interrupt function.
+uint8_t trigger = getPinChangeInterruptTrigger(digitalPinToPCINT(pinTick));
+if(trigger == RISING)
+ // Do something
+else if(trigger == FALLING)
+ // Do something
+else
+ // Wrong usage (trigger == CHANGE)
+```
+
+##### LowLevel API
+See [LowLevel example](examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino) for more details.
+```cpp
+// Use the attach function as you are used to, just leave out the function name
+attachPinChangeInterrupt(interruptBlink, CHANGE);
+
+// LowLevel function that is called when an interrupt occurs for a specific PCINT.
+// It is required to know the exact PCINT number, no Arduino pin number will work here.
+void PinChangeInterruptEvent(5)(void) {
+ // Do something
+}
+```
+
+PinchangeInterrupt Table
+========================
+Pins with * are not broken out/deactivated by default.
+You may activate them in the [setting file](https://github.com/NicoHood/PinChangeInterrupt/blob/master/src/PinChangeInterruptSettings.h#L98) (advanced).
+
+Each row section represents a port(0-3).
+Not all MCUs have all Ports/Pins physically available.
+
+**Note: Not all supported AVRs are listed here. There are way more supported, please refer to the shorter list above.**
+
+#### Official Arduinos
+```
+| PCINT | Uno/Nano/Mini | Mega/2560 | Leonardo/Micro | HL2 (8/16/32u2) |
+| ----- | --------------- | -------------- | -------------- | --------------- |
+| 0 | 8 (PB0) | 53 SS (PB0) | SS (PB0)* | 0 SS (PB0)* |
+| 1 | 9 (PB1) | 52 SCK (PB1) | SCK (PB1) | 1 SCK (PB1) |
+| 2 | 10 SS (PB2) | 51 MOSI (PB2) | MOSI (PB2) | 2 MOSI (PB2) |
+| 3 | 11 MISO (PB3) | 50 MISO (PB3) | MISO (PB3) | 3 MISO (PB3) |
+| 4 | 12 MOSI (PB4) | 10 (PB4) | 8/A8 (PB4) | 4 (PB4) |
+| 5 | 13 SCK (PB5) | 11 (PB5) | 9/A9 (PB5) | 5 (PB5) |
+| 6 | XTAL1 (PB6)* | 12 (PB6) | 10/A10 (PB6) | 6 (PB6) |
+| 7 | XTAL2 (PB7)* | 13 (PB7) | 11 (PB7) | 7 (PB7) |
+| ----- | --------------- | -------------- | -------------- | --------------- |
+| 8 | A0 (PC0) | 0 RX (PE0)* | | (PC6)* |
+| 9 | A1 (PC1) | 15 RX3 (PJ0)* | | (PC5)* |
+| 10 | A2 (PC2) | 14 TX3 (PJ1)* | | (PC4)* |
+| 11 | A3 (PC3) | NC (PJ2)* | | (PC2)* |
+| 12 | A4 SDA (PC4) | NC (PJ3)* | | (PD5)* |
+| 13 | A5 SDC (PC5) | NC (PJ4)* | | |
+| 14 | RST (PC6)* | NC (PJ5)* | | |
+| 15 | | NC (PJ6)* | | |
+| ----- | --------------- | -------------- | -------------- | --------------- |
+| 16 | 0 RX (PD0) | A8 (PK0) | | |
+| 17 | 1 TX (PD1) | A9 (PK1) | | |
+| 18 | 2 INT0 (PD2) | A10 (PK2) | | |
+| 19 | 3 INT1 (PD3) | A11 (PK3) | | |
+| 20 | 4 (PD4) | A12 (PK4) | | |
+| 21 | 5 (PD5) | A13 (PK5) | | |
+| 22 | 6 (PD6) | A14 (PK6) | | |
+| 23 | 7 (PD7) | A15 (PK7) | | |
+| ----- | --------------- | -------------- | -------------- | --------------- |
+```
+
+#### Atmel Attinys
+```
+| PCINT | Attiny13 | Attiny x4 | Attiny x5 | Attiny x41 |
+| ----- | ------------ | --------------- | ------------- | ------------------- |
+| 0 | 0 MOSI (PB0) | 0 (PA0) | 0 MOSI (PB0) | A0/D0 (PA0) |
+| 1 | 1 MISO (PB1) | 1 (PA1) | 1 MISO (PB1) | A1/D1 (PA1) |
+| 2 | 2 SCK (PB2) | 2 (PA2) | 2 SCK (PB2) | A2/D2 (PA2) |
+| 3 | 3 (PB3) | 3 (PA3) | 3 XTAL1 (PB3) | A3/D3 (PA3) |
+| 4 | 4 (PB4) | 4 SCK (PA4) | 4 XTAL2 (PB4) | A4/D4 (PA4) |
+| 5 | 5 RST (PB5) | 5 MISO (PA5) | 5 RST (PB5) | A5/D5 PWM (PA5) |
+| 6 | | 6 MOSI (PA6) | | A7/D7 PWM (PA6) |
+| 7 | | 7 (PA7) | | A6/D6 PWM (PA7) |
+| ----- | ------------ | --------------- | ------------- | ------------------- |
+| 8 | | 10 XTAL1 (PB0)* | | A10/D10 XTAL1 (PB0) |
+| 9 | | 9 XTAL2 (PB1)* | | A9/D9 XTAL2 (PB1) |
+| 10 | | 8 INT0 (PB2)* | | A8/D8 PWM (PB2) |
+| 11 | | RST (PB3)* | | RST (PB3) |
+| 12 | | | | |
+| 13 | | | | |
+| 14 | | | | |
+| 15 | | | | |
+| ----- | ------------ | --------------- | ------------- | ------------------- |
+```
+
+#### Other Atmel MCUs
+```
+| PCINT | ATmega644P/1284P |
+| ----- | ----------------- |
+| 0 | A0/D24 (PA0) |
+| 1 | A1/D25 (PA1) |
+| 2 | A2/D26 (PA2) |
+| 3 | A3/D27 (PA3) |
+| 4 | A4/D28 (PA4) |
+| 5 | A5/D29 (PA5) |
+| 6 | A6/D30 (PA6) |
+| 7 | A7/D31 (PA7) |
+| ----- | ----------------- |
+| 8 | 0 (PB0) |
+| 9 | 1 (PB1) |
+| 10 | 2 INT2 (PB2) |
+| 11 | 3 PWM (PB3) |
+| 12 | 4 SS/PWM (PB4) |
+| 13 | 5 MOSI/PWM (PB5) |
+| 14 | 6 MISO/PWM (PB6) |
+| 15 | 7 SCK (PB7) |
+| ----- | ----------------- |
+| 16 | 16 SCL (PC0) |
+| 17 | 17 SDA (PC1) |
+| 18 | 18 TCK (PC2) |
+| 19 | 19 TMS (PC3) |
+| 20 | 20 TDO (PC4) |
+| 21 | 21 TDI (PC5) |
+| 22 | 22 (PC6) |
+| 23 | 23 (PC7) |
+| ----- | ----------------- |
+| 24 | 8 RX0 (PD0) |
+| 25 | 9 TX0 (PD1) |
+| 26 | 10 RX1/INT0 (PD2) |
+| 27 | 11 TX1/INT1 (PD3) |
+| 28 | 12 PWM (PD4) |
+| 29 | 13 PWM (PD5) |
+| 30 | 14 PWM (PD6) |
+| 31 | 15 PWM (PD7) |
+| ----- | ----------------- |
+```
+
+Developer Information
+=====================
+If a PinChangeInterrupt occurs it will determine the triggered pin(s).
+The library uses weak callback functions that are called for the triggered pins(s).
+This way we can easily skip not triggered pins (I looked at the assembler) and also implement a fast LowLevel version.
+
+Also the order of the function execution is (normally) ordered from the lower pin number to the higher.
+Meaning pin 8 will be checked faster as pin 13 (Arduino Uno). Talking about micro seconds here! You can change the order in the settings.
+For example by default pin 0-3 have a low priority order than pin 4-7 (Arduino Uno). Because they are used for Serial and normal PinInterrupts.
+I don't expect anyone to use those pins at all with PCINT but at least the priority is lowered compared to the other pins.
+
+The API takes those weak functions and just overwrites all of them and call the function pointers of the attached functions instead.
+This way the function can be changed at runtime and its also easier to integrate into other libraries.
+The function pointers take a bit flash though (LowLevel: 1526/18, API: 1790/58 for Led example).
+
+You can get better performance and less code size if you deactivate the not used pins/ports manually in the settings file.
+This way only the needed pins get compiled and the code is optimized by the preprocessor.
+For a bit more comfortable/automatic optimization you can [install the library into the core](https://github.com/NicoHood/PinChangeInterrupt/#optional-installation)
+to get use of the .a linkage. This way only the used ports get compiled.
+So if you only use pins on a single port (eg 8-13) then only this port gets compiled. This only works with the core installation.
+
+
+That's it! I hope you like the library. I tried to make it as simple and small as possible.
+Keep in mind that PCINTs are not useful for every project but in most cases
+the new PinChangeInterrupts may help you a lot.
+
+
+Version History
+===============
+```
+1.2.9 Release (18.05.2021)
+* Added Attiny261/461/861 support #39
+* Added Attiny2313/2313A/4313 support #37
+* Added ATMega328PB support #30
+* Added ATMega48 support #38
+* Fixed ATMega88/168 support #38
+
+1.2.8 Release (22.11.2020)
+* Add support for ATmega644 #34
+
+1.2.7 Release (07.10.2018)
+* Add support for ATmega162 #21
+
+1.2.6 Release (10.02.2018)
+* Fix makefile compilation problems
+
+1.2.5 Release (02.09.2017)
+* Fixed makefile compilation
+* Added support to disable pcint/port via -DPCINT_DISABLE_PORT0 etc.
+* Added ATtinyX313 support
+* Fix ATmega1284P
+
+1.2.4 Release (16.04.2016)
+* Fixed Attinyx4/x5 Issue #8
+
+1.2.3 Release (24.12.2015)
+* Added Attiny441/841 support
+
+1.2.2 Release (05.12.2015)
+* Fixed initial value when enabled issue
+* Enabled official dot_a_linkage
+* Added Attiny13 support Issue #4
+* Updated documentation
+* Improved detaching function
+* Improved attaching and enabling
+
+1.2.1 Release (24.05.2015)
+* Fix Attiny Issue #1
+* Added enable/disable function
+* Added getPinChangeInterruptTrigger() function
+* Added to Arduino IDE library manager
+
+1.2 Release (19.04.2015)
+* Added weak interrupt function
+* Improved interrupt function calls
+* Fixed attach/detach array position when ports are deactivated
+* Improved manual PCINT deactivation by user
+* Improved definitions for different boards
+* HoodLoader2 definition fixes
+* Improved speed
+* Improved specific boards
+* Moved attach function to .cpp file
+* Updated examples
+* Added API and LowLevel
+* Added Port3 support (ATmega644P/ATmega1284P)
+* Added PCINT_VERSION definition
+
+1.1 Release (06.12.2014)
+* Added port deactivation
+* Ram usage improvements for AVRs with <3 PCINT ports
+
+1.0 Release (04.12.2014)
+* Added general PinChangeInterrupt functions
+* Added support for most Arduino boards
+* Added basic example
+* Added an example with IRLremote
+```
+
+
+License and Copyright
+=====================
+If you use this library for any cool project let me know!
+
+```
+Copyright (c) 2014-2021 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+```
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino
new file mode 100644
index 0000000..e23743e
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_HowItWorks/PinChangeInterrupt_HowItWorks.ino
@@ -0,0 +1,122 @@
+/*
+ Copyright (c) 2014-2015 NicoHood
+ See the readme for credit to other people.
+
+ PinChangeInterrupt_HowItWorks
+ Shows how to manually setup a single PCINT function with a few helper functions.
+
+ Connect a button/cable to pin 7 and ground.
+ The led will change its state if pin 7 changes.
+
+ PinChangeInterrupts are different than normal Interrupts.
+ See readme for more information.
+ Dont use Serial or delay inside interrupts!
+ This library is not compatible with SoftSerial.
+
+ The following pins are usable for PinChangeInterrupt:
+ Arduino Uno/Nano/Mini: All pins are usable
+ Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
+ A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
+ Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
+ HoodLoader2: All (broken out 1-7) pins are usable
+ Attiny 24/44/84: All pins are usable
+ Attiny 25/45/85: All pins are usable
+ Attiny 13: All pins are usable
+ Attiny 441/841: All pins are usable
+ ATmega644P/ATmega1284P: All pins are usable
+ */
+
+//================================================================================
+// User Settings
+//================================================================================
+
+// choose a valid PinChangeInterrupt pin of your Arduino board
+#define PCINT_PIN 7
+#define PCINT_MODE CHANGE
+#define PCINT_FUNCTION blinkLed
+
+void setup()
+{
+ // set pins to input with a pullup, led to output
+ pinMode(PCINT_PIN, INPUT_PULLUP);
+ pinMode(LED_BUILTIN, OUTPUT);
+
+ // attach the new PinChangeInterrupt
+ attachPinChangeInterrupt();
+}
+
+void loop() {
+ // empty
+}
+
+void blinkLed(void) {
+ // switch Led state
+ digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
+}
+
+//================================================================================
+// PCINT Definitions
+//================================================================================
+
+#define PCMSK *digitalPinToPCMSK(PCINT_PIN)
+#define PCINT digitalPinToPCMSKbit(PCINT_PIN)
+#define PCIE digitalPinToPCICRbit(PCINT_PIN)
+#define PCPIN *portInputRegister(digitalPinToPort(PCINT_PIN))
+
+#if (PCIE == 0)
+#define PCINT_vect PCINT0_vect
+#elif (PCIE == 1)
+#define PCINT_vect PCINT1_vect
+#elif (PCIE == 2)
+#define PCINT_vect PCINT2_vect
+#else
+#error This board doesnt support PCINT ?
+#endif
+
+volatile uint8_t oldPort = 0x00;
+
+void attachPinChangeInterrupt(void) {
+ // update the old state to the actual state
+ oldPort = PCPIN;
+
+ // pin change mask registers decide which pins are enabled as triggers
+ PCMSK |= (1 << PCINT);
+
+ // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors
+ PCICR |= (1 << PCIE);
+}
+
+void detachPinChangeInterrupt(void) {
+ // disable the mask.
+ PCMSK &= ~(1 << PCINT);
+
+ // if that's the last one, disable the interrupt.
+ if (PCMSK == 0)
+ PCICR &= ~(0x01 << PCIE);
+}
+
+ISR(PCINT_vect) {
+ // get the new and old pin states for port
+ uint8_t newPort = PCPIN;
+
+ // compare with the old value to detect a rising or falling
+ uint8_t change = newPort ^ oldPort;
+
+ // check which pins are triggered, compared with the settings
+ uint8_t trigger = 0x00;
+#if (PCINT_MODE == RISING) || (PCINT_MODE == CHANGE)
+ uint8_t rising = change & newPort;
+ trigger |= (rising & (1 << PCINT));
+#endif
+#if (PCINT_MODE == FALLING) || (PCINT_MODE == CHANGE)
+ uint8_t falling = change & oldPort;
+ trigger |= (falling & (1 << PCINT));
+#endif
+
+ // save the new state for next comparison
+ oldPort = newPort;
+
+ // if our needed pin has changed, call the IRL interrupt function
+ if (trigger & (1 << PCINT))
+ PCINT_FUNCTION();
+}
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino
new file mode 100644
index 0000000..21a7cb4
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_Led/PinChangeInterrupt_Led.ino
@@ -0,0 +1,55 @@
+/*
+ Copyright (c) 2014-2015 NicoHood
+ See the readme for credit to other people.
+
+ PinChangeInterrupt_TickTock
+ Demonstrates how to use the library
+
+ Connect a button/cable to pin 7 and ground.
+ The Led state will change if the pin state does.
+
+ PinChangeInterrupts are different than normal Interrupts.
+ See readme for more information.
+ Dont use Serial or delay inside interrupts!
+ This library is not compatible with SoftSerial.
+
+ The following pins are usable for PinChangeInterrupt:
+ Arduino Uno/Nano/Mini: All pins are usable
+ Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
+ A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
+ Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
+ HoodLoader2: All (broken out 1-7) pins are usable
+ Attiny 24/44/84: All pins are usable
+ Attiny 25/45/85: All pins are usable
+ Attiny 13: All pins are usable
+ Attiny 441/841: All pins are usable
+ ATmega644P/ATmega1284P: All pins are usable
+*/
+
+#include "PinChangeInterrupt.h"
+
+// Choose a valid PinChangeInterrupt pin of your Arduino board
+#define pinBlink 7
+
+void setup() {
+ // set pin to input with a pullup, led to output
+ pinMode(pinBlink, INPUT_PULLUP);
+ pinMode(LED_BUILTIN, OUTPUT);
+
+ // Manually blink once to test if LED is functional
+ blinkLed();
+ delay(1000);
+ blinkLed();
+
+ // Attach the new PinChangeInterrupt and enable event function below
+ attachPCINT(digitalPinToPCINT(pinBlink), blinkLed, CHANGE);
+}
+
+void blinkLed(void) {
+ // Switch Led state
+ digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
+}
+
+void loop() {
+ // Nothing to do here
+}
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino
new file mode 100644
index 0000000..615f3bb
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_LowLevel/PinChangeInterrupt_LowLevel.ino
@@ -0,0 +1,60 @@
+/*
+ Copyright (c) 2014-2015 NicoHood
+ See the readme for credit to other people.
+
+ PinChangeInterrupt_LowLevel
+ Demonstrates how to use the library without the API
+
+ Make sure to comment "//#define PCINT_API" in the settings file.
+
+ To maximize speed and size also uncomment all not used pins above.
+ Then you could also uncomment "#define PCINT_COMPILE_ENABLED_ISR"
+ to get away the .a linkage overhead.
+
+ Connect a button/cable to pin 7 and ground (Uno).
+ Strong overwritten callback functions are called when an interrupt occurs.
+ The Led state will change if the pin state does.
+
+ PinChangeInterrupts are different than normal Interrupts.
+ See readme for more information.
+ Dont use Serial or delay inside interrupts!
+ This library is not compatible with SoftSerial.
+
+ The following pins are usable for PinChangeInterrupt:
+ Arduino Uno/Nano/Mini: All pins are usable
+ Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
+ A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
+ Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
+ HoodLoader2: All (broken out 1-7) pins are usable
+ Attiny 24/44/84: All pins are usable
+ Attiny 25/45/85: All pins are usable
+ Attiny 13: All pins are usable
+ Attiny 441/841: All pins are usable
+ ATmega644P/ATmega1284P: All pins are usable
+ */
+
+#include "PinChangeInterrupt.h"
+
+// choose a valid PinChangeInterrupt pin of your Arduino board
+// manually defined pcint number
+#define pinBlink 7
+#define interruptBlink 23
+
+void setup()
+{
+ // set pin to input with a pullup, led to output
+ pinMode(pinBlink, INPUT_PULLUP);
+ pinMode(LED_BUILTIN, OUTPUT);
+
+ // attach the new PinChangeInterrupts and enable event functions below
+ attachPinChangeInterrupt(interruptBlink, CHANGE);
+}
+
+void PinChangeInterruptEvent(interruptBlink)(void) {
+ // switch Led state
+ digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
+}
+
+void loop() {
+ // nothing to do here
+}
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino
new file mode 100644
index 0000000..622c34d
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/examples/PinChangeInterrupt_TickTock/PinChangeInterrupt_TickTock.ino
@@ -0,0 +1,98 @@
+/*
+ Copyright (c) 2014-2015 NicoHood
+ See the readme for credit to other people.
+
+ PinChangeInterrupt_TickTock
+ Demonstrates how to use the library
+
+ Connect a button/cable to pin 10/11 and ground.
+ The value printed on the serial port will increase
+ if pin 10 is rising and decrease if pin 11 is falling.
+
+ PinChangeInterrupts are different than normal Interrupts.
+ See readme for more information.
+ Dont use Serial or delay inside interrupts!
+ This library is not compatible with SoftSerial.
+
+ The following pins are usable for PinChangeInterrupt:
+ Arduino Uno/Nano/Mini: All pins are usable
+ Arduino Mega: 10, 11, 12, 13, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64),
+ A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
+ Arduino Leonardo/Micro: 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
+ HoodLoader2: All (broken out 1-7) pins are usable
+ Attiny 24/44/84: All pins are usable
+ Attiny 25/45/85: All pins are usable
+ Attiny 13: All pins are usable
+ Attiny 441/841: All pins are usable
+ ATmega644P/ATmega1284P: All pins are usable
+*/
+
+#include "PinChangeInterrupt.h"
+
+// choose a valid PinChangeInterrupt pin of your Arduino board
+#define pinTick 10
+#define pinTock 11
+
+volatile long ticktocks = 0;
+
+void setup()
+{
+ // start serial debug output
+ Serial.begin(115200);
+ Serial.println(F("Startup"));
+
+ // set pins to input with a pullup
+ pinMode(pinTick, INPUT_PULLUP);
+ pinMode(pinTock, INPUT_PULLUP);
+
+ // attach the new PinChangeInterrupts and enable event functions below
+ attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick), tick, RISING);
+ attachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock), tock, FALLING);
+}
+
+void loop() {
+ // integer to count the number of prints
+ static int i = 0;
+ delay(1000);
+
+ // print values
+ Serial.print(i, DEC);
+ Serial.print(F(" "));
+ Serial.println(ticktocks);
+
+ // abort if we printed 100 times
+ if (i >= 100) {
+ Serial.println(F("Detaching Interrupts."));
+ detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+ detachPinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock));
+ return;
+ }
+ else
+ i++;
+
+ // Temporary pause interrupts
+ if (ticktocks > 500) {
+ Serial.println(F("Disabling Tick Interrupt."));
+ disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+ enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock));
+ }
+ else if (ticktocks < -500) {
+ Serial.println(F("Disabling Tock Interrupt."));
+ disablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock));
+ enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+ }
+ else {
+ enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTick));
+ enablePinChangeInterrupt(digitalPinToPinChangeInterrupt(pinTock));
+ }
+}
+
+void tick(void) {
+ // increase value
+ ticktocks++;
+}
+
+void tock(void) {
+ // decrease value
+ ticktocks--;
+}
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png
new file mode 100644
index 0000000..67818fc
Binary files /dev/null and b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/header.png differ
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt
new file mode 100644
index 0000000..1af2b5d
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/keywords.txt
@@ -0,0 +1,32 @@
+#######################################
+# Syntax Coloring Map For PinChangeInterrupt
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+attachPinChangeInterrupt KEYWORD2
+detachPinChangeInterrupt KEYWORD2
+attachPCINT KEYWORD2
+detachPCINT KEYWORD2
+PinChangeInterruptEvent KEYWORD2
+PCINTEvent KEYWORD2
+enablePCINT KEYWORD2
+enablePinChangeInterrupt KEYWORD2
+disablePCINT KEYWORD2
+disablePinChangeInterrupt KEYWORD2
+getPCINTTrigger KEYWORD2
+getPinChangeInterruptTrigger KEYWORD2
+
+#######################################
+# Instances (KEYWORD2)
+#######################################
+
+#######################################
+# Constants (LITERAL1)
+#######################################
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties
new file mode 100644
index 0000000..bb3a6e0
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/library.properties
@@ -0,0 +1,10 @@
+name=PinChangeInterrupt
+version=1.2.9
+author=NicoHood
+maintainer=NicoHood
+sentence=A simple & compact PinChangeInterrupt library for Arduino.
+paragraph=PinChangeInterrupt library with a resource friendly implementation (API and LowLevel). PinChangeInterrupts are different than normal Interrupts. See readme for more information.
+category=Signal Input/Output
+url=https://github.com/NicoHood/PinChangeInterrupt
+architectures=avr
+dot_a_linkage=true
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp
new file mode 100644
index 0000000..d83ef6b
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.cpp
@@ -0,0 +1,336 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "PinChangeInterrupt.h"
+
+// manually include cpp files here to save flash if only 1 ISR is present
+// or if the user knows he just wants to compile all enabled ports.
+#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR)
+#define PCINT_INCLUDE_FROM_CPP
+#include "PinChangeInterrupt0.cpp"
+#include "PinChangeInterrupt1.cpp"
+#include "PinChangeInterrupt2.cpp"
+#include "PinChangeInterrupt3.cpp"
+#else
+
+//================================================================================
+// Weak Callbacks
+//================================================================================
+
+// create all weak functions which are all (if not used) alias of the pcint_null_callback above
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("void PinChangeInterruptEventPCINT");
+Serial.print(i);
+Serial.println("(void) __attribute__((weak, alias(\"pcint_null_callback\")));");
+}
+*/
+void PinChangeInterruptEventPCINT0(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT1(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT2(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT3(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT4(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT5(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT6(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT7(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT8(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT9(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT10(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT11(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT12(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT13(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT14(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT15(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT16(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT17(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT18(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT19(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT20(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT21(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT22(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT23(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT24(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT25(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT26(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT27(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT28(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT29(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT30(void) __attribute__((weak, alias("pcint_null_callback")));
+void PinChangeInterruptEventPCINT31(void) __attribute__((weak, alias("pcint_null_callback")));
+
+#endif // PCINT_INCLUDE_FROM_CPP
+
+// useless function for weak implemented/not used functions, extern c needed for the alias
+extern "C" {
+ void pcint_null_callback(void) {
+ // useless
+ }
+}
+
+//================================================================================
+// PinChangeInterrupt User Functions
+//================================================================================
+
+// variables to save the last port states and the interrupt settings
+uint8_t oldPorts[PCINT_NUM_USED_PORTS] = { 0 };
+uint8_t fallingPorts[PCINT_NUM_USED_PORTS] = { 0 };
+uint8_t risingPorts[PCINT_NUM_USED_PORTS] = { 0 };
+
+void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask, const uint8_t arrayPos){
+ // Update the old state to the actual state
+ switch(pcintPort){
+#ifdef PCINT_INPUT_PORT0_USED
+ case 0:
+ oldPorts[arrayPos] = PCINT_INPUT_PORT0;
+ break;
+#endif
+#ifdef PCINT_INPUT_PORT1_USED
+ case 1:
+ oldPorts[arrayPos] = PCINT_INPUT_PORT1;
+ break;
+#endif
+#ifdef PCINT_INPUT_PORT2_USED
+ case 2:
+ oldPorts[arrayPos] = PCINT_INPUT_PORT2;
+ break;
+#endif
+#ifdef PCINT_INPUT_PORT3_USED
+ case 3:
+ oldPorts[arrayPos] = PCINT_INPUT_PORT3;
+ break;
+#endif
+ }
+
+ // Pin change mask registers decide which pins are ENABLE as triggers
+#ifdef PCMSK0
+#ifdef PCMSK1
+#ifdef PCMSK3
+ // Special case for ATmega1284P where PCMSK3 is not directly after PCMSK2
+ if(false){
+#else
+ // Special case for Attinyx4 where PCMSK1 and PCMSK0 are not next to each other
+ if(&PCMSK1 - &PCMSK0 == 1){
+#endif
+#endif
+ *(&PCMSK0 + pcintPort) |= pcintMask;
+#ifdef PCMSK1
+ }
+ else{
+ switch(pcintPort){
+ case 0:
+ PCMSK0 |= pcintMask;
+ break;
+ case 1:
+ PCMSK1 |= pcintMask;
+ break;
+#ifdef PCMSK2
+ case 2:
+ PCMSK2 |= pcintMask;
+ break;
+#endif
+#ifdef PCMSK3
+ case 3:
+ PCMSK3 |= pcintMask;
+ break;
+#endif
+ }
+ }
+#endif
+#elif defined(PCMSK)
+ *(&PCMSK + pcintPort) |= pcintMask;
+#endif
+
+ // PCICR: Pin Change Interrupt Control Register - enables interrupt vectors
+#ifdef PCICR
+ PCICR |= (1 << (pcintPort + PCIE0));
+#elif defined(GICR) /* e.g. ATmega162 */
+ GICR |= (1 << (pcintPort + PCIE0));
+#elif defined(GIMSK) && defined(PCIE0) /* e.g. ATtiny X4 */
+ GIMSK |= (1 << (pcintPort + PCIE0));
+#elif defined(GIMSK) && defined(PCIE) /* e.g. ATtiny X5 */
+ GIMSK |= (1 << (pcintPort + PCIE));
+#else
+#error MCU has no such a register
+#endif
+}
+
+void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask) {
+ bool disable = false;
+#ifdef PCMSK0
+#ifdef PCMSK1
+ // Special case for Attinyx4 where PCMSK1 and PCMSK0 are not next to each other
+ if(&PCMSK1 - &PCMSK0 == 1){
+#endif
+ // disable the mask.
+ *(&PCMSK0 + pcintPort) &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (*(&PCMSK0 + pcintPort) == 0)
+ disable = true;
+#ifdef PCMSK1
+ }
+ else{
+ switch(pcintPort){
+ case 0:
+ // disable the mask.
+ PCMSK0 &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (!PCMSK0)
+ disable = true;
+ break;
+ case 1:
+ // disable the mask.
+ PCMSK1 &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (!PCMSK1)
+ disable = true;
+ break;
+#ifdef PCMSK2
+ case 2:
+ // disable the mask.
+ PCMSK2 &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (!PCMSK2)
+ disable = true;
+ break;
+#endif
+#ifdef PCMSK3
+ case 3:
+ // disable the mask.
+ PCMSK3 &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (!PCMSK3)
+ disable = true;
+ break;
+#endif
+ }
+ }
+#endif
+#elif defined(PCMSK)
+ // disable the mask.
+ *(&PCMSK + pcintPort) &= ~pcintMask;
+
+ // if that's the last one, disable the interrupt.
+ if (*(&PCMSK + pcintPort) == 0)
+ disable = true;
+#endif
+ if(disable)
+ {
+#ifdef PCICR
+ PCICR &= ~(1 << (pcintPort + PCIE0));
+#elif defined(GICR) /* e.g. ATmega162 */
+ GICR &= ~(1 << (pcintPort + PCIE0));
+#elif defined(GIMSK) && defined(PCIE0) /* e.g. ATtiny X4 */
+ GIMSK &= ~(1 << (pcintPort + PCIE0));
+#elif defined(GIMSK) && defined(PCIE) /* e.g. ATtiny X5 */
+ GIMSK &= ~(1 << (pcintPort + PCIE));
+#else
+#error MCU has no such a register
+#endif
+ }
+}
+
+/*
+asm output (nothing to optimize here)
+
+ISR(PCINT0_vect) {
+push r1
+push r0
+in r0, 0x3f ; 63
+push r0
+eor r1, r1
+push r18
+push r19
+push r20
+push r21
+push r22
+push r23
+push r24
+push r25
+push r26
+push r27
+push r28
+push r30
+push r31
+
+// get the new and old pin states for port
+// uint8_t newPort = pinChangeInterruptPortToInput(port);
+in r24, 0x03; 3 //(1) loads byte into newPort from I/O register
+
+// loads old port and high + low setting
+lds r18, 0x011E //(1 or 2) loads oldPorts into register
+lds r28, 0x011B //(1 or 2) loads fallingPorts into register
+lds r25, 0x0118 //(1 or 2) loads risingPorts into register
+
+and r28, r18 // oldPorts & fallingPorts
+and r25, r24 // newPort & risingPorts
+or r28, r25 // (oldPorts & fallingPorts) | (newPort & risingPorts)
+eor r18, r24 // oldPorts^newPort
+and r28, r18 // ((oldPorts & fallingPorts) | (newPort & risingPorts)) & (oldPorts^newPort)
+
+// save the new state for next comparison
+// oldPorts[arrayPos] = newPort;
+sts 0x011E, r24
+
+// Execute all functions that should be triggered
+sbrc r28, 0
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+sbrc r28, 1
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+sbrc r28, 2
+call 0x318 ; 0x318 <_Z20PinChangeInterruptEventPCINT2v>
+sbrc r28, 3
+call 0x340 ; 0x340 <_Z20PinChangeInterruptEventPCINT3v>
+sbrc r28, 4
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+sbrc r28, 5
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+sbrc r28, 6
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+sbrc r28, 7
+call 0x37c ; 0x37c <_Z20PinChangeInterruptEventPCINT0v>
+
+pop r31
+pop r30
+pop r28
+pop r27
+pop r26
+pop r25
+pop r24
+pop r23
+pop r22
+pop r21
+pop r20
+pop r19
+pop r18
+pop r0
+out 0x3f, r0 ; 63
+pop r0
+pop r1
+reti
+}
+*/
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h
new file mode 100644
index 0000000..b30fb62
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt.h
@@ -0,0 +1,898 @@
+/*
+Copyright (c) 2014-2021 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// Include Guard
+#pragma once
+
+// Software Version
+#define PCINT_VERSION 129
+
+#include
+#include
+
+#ifdef ARDUINO
+#include "Arduino.h"
+
+#ifndef ARDUINO_ARCH_AVR
+#error This library can only be used with AVR
+#endif
+
+#else
+
+#ifndef LOW
+#define LOW 0x0
+#endif
+#ifndef CHANGE
+#define CHANGE 0x1
+#endif
+#ifndef FALLING
+#define FALLING 0x2
+#endif
+#ifndef RISING
+#define RISING 0x3
+#endif
+
+#endif
+
+//================================================================================
+// General Helper Definitions and Mappings
+//================================================================================
+
+// Settings and Board definitions are seperated to get an better overview.
+// The order and position of the inclusion is important!
+#include "PinChangeInterruptSettings.h"
+#include "PinChangeInterruptBoards.h"
+#include "PinChangeInterruptPins.h"
+
+#if !PCINT_NUM_USED_PORTS
+#error Please enable at least one PCINT port and pin!
+#endif
+
+// manually include cpp files to save flash if only 1 ISR is present
+// it includes all ISR files but only the 1 available ISR will/can be compiled
+#if (PCINT_NUM_USED_PORTS == 1)
+#ifndef PCINT_COMPILE_ENABLED_ISR
+#define PCINT_COMPILE_ENABLED_ISR
+#endif
+#endif
+
+//================================================================================
+// Makro Definitions
+//================================================================================
+
+// generates the callback for easier reordering in Settings
+#define PCINT_MACRO_BRACKETS ()
+#define PCINT_MACRO_TRUE == true)
+#define PCINT_CALLBACK(bit, pcint) \
+if (PCINT_USE_PCINT ## pcint PCINT_MACRO_TRUE \
+if (trigger & (1 << bit)) \
+PinChangeInterruptEventPCINT ## pcint PCINT_MACRO_BRACKETS
+
+// definition used by the user to create custom LowLevel PCINT Events
+#define PinChangeInterruptEvent_Wrapper(n) PinChangeInterruptEventPCINT ## n
+#define PinChangeInterruptEvent(n) PinChangeInterruptEvent_Wrapper(n)
+
+// missing 1.0.6 definition workaround
+#ifndef NOT_AN_INTERRUPT
+#define NOT_AN_INTERRUPT -1
+#endif
+
+// convert a normal pin to its PCINT number (0 - max 23), used by the user
+// calculates the pin by the Arduino definitions
+#if defined(PCIE0)
+#define digitalPinToPinChangeInterrupt(p) (digitalPinToPCICR(p) ? ((8 * (digitalPinToPCICRbit(p) - PCIE0)) + digitalPinToPCMSKbit(p)) : NOT_AN_INTERRUPT)
+#elif defined(PCIE)
+#define digitalPinToPinChangeInterrupt(p) (digitalPinToPCICR(p) ? ((8 * (digitalPinToPCICRbit(p) - PCIE)) + digitalPinToPCMSKbit(p)) : NOT_AN_INTERRUPT)
+#else
+#error MCU has no such a register
+#endif
+
+// alias for shorter writing
+#define PCINTEvent(n) PinChangeInterruptEvent_Wrapper(n)
+#define digitalPinToPCINT digitalPinToPinChangeInterrupt
+#define attachPCINT attachPinChangeInterrupt
+#define enablePCINT enablePinChangeInterrupt
+#define detachPCINT detachPinChangeInterrupt
+#define disablePCINT disablePinChangeInterrupt
+#define getPCINTTrigger getPinChangeInterruptTrigger
+
+//================================================================================
+// Function Prototypes + Variables
+//================================================================================
+
+// typedef for our callback function pointers
+typedef void(*callback)(void);
+
+// useless function for weak implemented/not used functions, extern c needed for the alias
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void pcint_null_callback(void);
+#ifdef __cplusplus
+}
+#endif
+
+void PinChangeInterruptEventPCINT0(void);
+void PinChangeInterruptEventPCINT1(void);
+void PinChangeInterruptEventPCINT2(void);
+void PinChangeInterruptEventPCINT3(void);
+void PinChangeInterruptEventPCINT4(void);
+void PinChangeInterruptEventPCINT5(void);
+void PinChangeInterruptEventPCINT6(void);
+void PinChangeInterruptEventPCINT7(void);
+void PinChangeInterruptEventPCINT8(void);
+void PinChangeInterruptEventPCINT9(void);
+void PinChangeInterruptEventPCINT10(void);
+void PinChangeInterruptEventPCINT11(void);
+void PinChangeInterruptEventPCINT12(void);
+void PinChangeInterruptEventPCINT13(void);
+void PinChangeInterruptEventPCINT14(void);
+void PinChangeInterruptEventPCINT15(void);
+void PinChangeInterruptEventPCINT16(void);
+void PinChangeInterruptEventPCINT17(void);
+void PinChangeInterruptEventPCINT18(void);
+void PinChangeInterruptEventPCINT19(void);
+void PinChangeInterruptEventPCINT20(void);
+void PinChangeInterruptEventPCINT21(void);
+void PinChangeInterruptEventPCINT22(void);
+void PinChangeInterruptEventPCINT23(void);
+void PinChangeInterruptEventPCINT24(void);
+void PinChangeInterruptEventPCINT25(void);
+void PinChangeInterruptEventPCINT26(void);
+void PinChangeInterruptEventPCINT27(void);
+void PinChangeInterruptEventPCINT28(void);
+void PinChangeInterruptEventPCINT29(void);
+void PinChangeInterruptEventPCINT30(void);
+void PinChangeInterruptEventPCINT31(void);
+
+extern uint8_t oldPorts[PCINT_NUM_USED_PORTS];
+extern uint8_t fallingPorts[PCINT_NUM_USED_PORTS];
+extern uint8_t risingPorts[PCINT_NUM_USED_PORTS];
+
+
+static inline uint8_t getArrayPosPCINT(uint8_t pcintPort) __attribute__((always_inline));
+uint8_t getArrayPosPCINT(uint8_t pcintPort) {
+ /*
+ Maps the port to the array.
+ This is needed since you can deactivate ports
+ and the array will dynamically resize to save ram.
+
+ The function does not need that much flash since the if and else
+ are known at compile time, so the compiler removes all the complex logic.
+ The return is is the input if all pins are activated for example.
+ That's why the function is inline.
+ */
+
+ if (PCINT_NUM_USED_PORTS == 1) {
+ // only the first element is used for a single port
+ return 0;
+ }
+ else if (PCINT_NUM_USED_PORTS == PCINT_NUM_PORTS) {
+ // use all ports and down remap the array position.
+ return pcintPort;
+ }
+ else if (PCINT_NUM_PORTS - PCINT_NUM_USED_PORTS == 1) {
+ // one port is not used
+ if (PCINT_USE_PORT0 == 0) {
+ // first port is not used, decrease all port numbers
+ return (pcintPort - 1);
+ }
+ else if (PCINT_HAS_PORT3 == 0) {
+ // 3 ports (standard)
+ if (PCINT_USE_PORT2 == 0) {
+ // last port not used, no mapping needed
+ return pcintPort;
+ }
+ else {
+ // worst case, port in the middle not used, remap
+ return ((pcintPort >> 1) & 0x01);
+ //if (pcintPort == 0) return 0;
+ //else return 1;
+ }
+ }
+ else {
+ // 4 ports (special case for a few AVRs)
+ if (PCINT_USE_PORT3 == 0) {
+ // last port not used, no mapping needed
+ return pcintPort;
+ }
+ else {
+ // worst case, one of two ports in the middle not used, remap
+ if (PCINT_USE_PORT1 == 0) {
+ // port1 not used, mapping needed
+ if (pcintPort == 0)
+ return 0;
+ else
+ return pcintPort - 1;
+ }
+ else if (PCINT_USE_PORT2 == 0) {
+ // port2 not used, mapping needed
+ if (pcintPort == 3)
+ return 2;
+ else
+ return pcintPort;
+ }
+ }
+ }
+
+ // use all ports and down remap the array position.
+ return pcintPort;
+ }
+ else if (PCINT_NUM_PORTS - PCINT_NUM_USED_PORTS == 2) {
+ if (PCINT_USE_PORT2 == 0 && PCINT_USE_PORT3 == 0) {
+ // no need for mapping
+ return pcintPort;
+ }
+ else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT3 == 0) {
+ // 1 offset
+ return (pcintPort - 1);
+ }
+ else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT1 == 0) {
+ // 2 offset
+ return (pcintPort - 2);
+ }
+ else if (PCINT_USE_PORT0 == 0 && PCINT_USE_PORT2 == 0) {
+ // 2 -> 1
+ return (pcintPort >> 1);
+ }
+ else if (PCINT_USE_PORT1 == 0 && PCINT_USE_PORT2 == 0) {
+ // 3 -> 1
+ return (pcintPort >> 1);
+ }
+ else if (PCINT_USE_PORT1 == 0 && PCINT_USE_PORT3 == 0) {
+ // 3 -> 1, 1 -> 0
+ return (pcintPort >> 1);
+ }
+ }
+
+ // error
+ return 0;
+}
+
+//================================================================================
+// Attach Function (partly inlined)
+//================================================================================
+
+void enablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask, const uint8_t arrayPos);
+void attachPinChangeInterrupt0(void);
+void attachPinChangeInterrupt1(void);
+void attachPinChangeInterrupt2(void);
+void attachPinChangeInterrupt3(void);
+
+#if defined(PCINT_API)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("extern volatile callback callbackPCINT");
+Serial.print(i);
+Serial.println(";");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_USE_PCINT0 == true)
+extern volatile callback callbackPCINT0;
+#endif
+#if (PCINT_USE_PCINT1 == true)
+extern volatile callback callbackPCINT1;
+#endif
+#if (PCINT_USE_PCINT2 == true)
+extern volatile callback callbackPCINT2;
+#endif
+#if (PCINT_USE_PCINT3 == true)
+extern volatile callback callbackPCINT3;
+#endif
+#if (PCINT_USE_PCINT4 == true)
+extern volatile callback callbackPCINT4;
+#endif
+#if (PCINT_USE_PCINT5 == true)
+extern volatile callback callbackPCINT5;
+#endif
+#if (PCINT_USE_PCINT6 == true)
+extern volatile callback callbackPCINT6;
+#endif
+#if (PCINT_USE_PCINT7 == true)
+extern volatile callback callbackPCINT7;
+#endif
+#if (PCINT_USE_PCINT8 == true)
+extern volatile callback callbackPCINT8;
+#endif
+#if (PCINT_USE_PCINT9 == true)
+extern volatile callback callbackPCINT9;
+#endif
+#if (PCINT_USE_PCINT10 == true)
+extern volatile callback callbackPCINT10;
+#endif
+#if (PCINT_USE_PCINT11 == true)
+extern volatile callback callbackPCINT11;
+#endif
+#if (PCINT_USE_PCINT12 == true)
+extern volatile callback callbackPCINT12;
+#endif
+#if (PCINT_USE_PCINT13 == true)
+extern volatile callback callbackPCINT13;
+#endif
+#if (PCINT_USE_PCINT14 == true)
+extern volatile callback callbackPCINT14;
+#endif
+#if (PCINT_USE_PCINT15 == true)
+extern volatile callback callbackPCINT15;
+#endif
+#if (PCINT_USE_PCINT16 == true)
+extern volatile callback callbackPCINT16;
+#endif
+#if (PCINT_USE_PCINT17 == true)
+extern volatile callback callbackPCINT17;
+#endif
+#if (PCINT_USE_PCINT18 == true)
+extern volatile callback callbackPCINT18;
+#endif
+#if (PCINT_USE_PCINT19 == true)
+extern volatile callback callbackPCINT19;
+#endif
+#if (PCINT_USE_PCINT20 == true)
+extern volatile callback callbackPCINT20;
+#endif
+#if (PCINT_USE_PCINT21 == true)
+extern volatile callback callbackPCINT21;
+#endif
+#if (PCINT_USE_PCINT22 == true)
+extern volatile callback callbackPCINT22;
+#endif
+#if (PCINT_USE_PCINT23 == true)
+extern volatile callback callbackPCINT23;
+#endif
+#if (PCINT_USE_PCINT24 == true)
+extern volatile callback callbackPCINT24;
+#endif
+#if (PCINT_USE_PCINT25 == true)
+extern volatile callback callbackPCINT25;
+#endif
+#if (PCINT_USE_PCINT26 == true)
+extern volatile callback callbackPCINT26;
+#endif
+#if (PCINT_USE_PCINT27 == true)
+extern volatile callback callbackPCINT27;
+#endif
+#if (PCINT_USE_PCINT28 == true)
+extern volatile callback callbackPCINT28;
+#endif
+#if (PCINT_USE_PCINT29 == true)
+extern volatile callback callbackPCINT29;
+#endif
+#if (PCINT_USE_PCINT30 == true)
+extern volatile callback callbackPCINT30;
+#endif
+#if (PCINT_USE_PCINT31 == true)
+extern volatile callback callbackPCINT31;
+#endif
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("if (pcintNum == ");
+Serial.print(i);
+Serial.println(")");
+Serial.print("callbackPCINT");
+Serial.print(i);
+Serial.println(" = userFunc;");
+Serial.println("#endif");
+}
+*/
+
+// API attach function
+static inline void attachPinChangeInterrupt(const uint8_t pcintNum, void(*userFunc)(void), const uint8_t mode) __attribute__((always_inline));
+void attachPinChangeInterrupt(const uint8_t pcintNum, void(*userFunc)(void), const uint8_t mode) {
+#else // no API attach function
+static inline void attachPinChangeInterrupt(const uint8_t pcintNum, const uint8_t mode) __attribute__((always_inline));
+void attachPinChangeInterrupt(const uint8_t pcintNum, const uint8_t mode) {
+#endif // PCINT_API
+
+ // check if pcint is a valid pcint, exclude deactivated ports
+ uint8_t pcintPort = pcintNum / 8;
+ uint8_t pcintBit = pcintNum % 8;
+
+ // port 0
+ if (pcintPort == 0 && PCINT_USE_PORT0 == true) {
+ // use fake functions to make the ISRs compile with .a linkage
+#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR)
+ attachPinChangeInterrupt0();
+#endif
+
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT0 == true)
+ if (pcintNum == 0)
+ callbackPCINT0 = userFunc;
+#endif
+#if (PCINT_USE_PCINT1 == true)
+ if (pcintNum == 1)
+ callbackPCINT1 = userFunc;
+#endif
+#if (PCINT_USE_PCINT2 == true)
+ if (pcintNum == 2)
+ callbackPCINT2 = userFunc;
+#endif
+#if (PCINT_USE_PCINT3 == true)
+ if (pcintNum == 3)
+ callbackPCINT3 = userFunc;
+#endif
+#if (PCINT_USE_PCINT4 == true)
+ if (pcintNum == 4)
+ callbackPCINT4 = userFunc;
+#endif
+#if (PCINT_USE_PCINT5 == true)
+ if (pcintNum == 5)
+ callbackPCINT5 = userFunc;
+#endif
+#if (PCINT_USE_PCINT6 == true)
+ if (pcintNum == 6)
+ callbackPCINT6 = userFunc;
+#endif
+#if (PCINT_USE_PCINT7 == true)
+ if (pcintNum == 7)
+ callbackPCINT7 = userFunc;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 1
+ else if (pcintPort == 1 && PCINT_USE_PORT1 == true) {
+ // use fake functions to make the ISRs compile with .a linkage
+#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR)
+ attachPinChangeInterrupt1();
+#endif
+
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT8 == true)
+ if (pcintNum == 8)
+ callbackPCINT8 = userFunc;
+#endif
+#if (PCINT_USE_PCINT9 == true)
+ if (pcintNum == 9)
+ callbackPCINT9 = userFunc;
+#endif
+#if (PCINT_USE_PCINT10 == true)
+ if (pcintNum == 10)
+ callbackPCINT10 = userFunc;
+#endif
+#if (PCINT_USE_PCINT11 == true)
+ if (pcintNum == 11)
+ callbackPCINT11 = userFunc;
+#endif
+#if (PCINT_USE_PCINT12 == true)
+ if (pcintNum == 12)
+ callbackPCINT12 = userFunc;
+#endif
+#if (PCINT_USE_PCINT13 == true)
+ if (pcintNum == 13)
+ callbackPCINT13 = userFunc;
+#endif
+#if (PCINT_USE_PCINT14 == true)
+ if (pcintNum == 14)
+ callbackPCINT14 = userFunc;
+#endif
+#if (PCINT_USE_PCINT15 == true)
+ if (pcintNum == 15)
+ callbackPCINT15 = userFunc;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 2
+ else if (pcintPort == 2 && PCINT_USE_PORT2 == true) {
+ // use fake functions to make the ISRs compile with .a linkage
+#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR)
+ attachPinChangeInterrupt2();
+#endif
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT16 == true)
+ if (pcintNum == 16)
+ callbackPCINT16 = userFunc;
+#endif
+#if (PCINT_USE_PCINT17 == true)
+ if (pcintNum == 17)
+ callbackPCINT17 = userFunc;
+#endif
+#if (PCINT_USE_PCINT18 == true)
+ if (pcintNum == 18)
+ callbackPCINT18 = userFunc;
+#endif
+#if (PCINT_USE_PCINT19 == true)
+ if (pcintNum == 19)
+ callbackPCINT19 = userFunc;
+#endif
+#if (PCINT_USE_PCINT20 == true)
+ if (pcintNum == 20)
+ callbackPCINT20 = userFunc;
+#endif
+#if (PCINT_USE_PCINT21 == true)
+ if (pcintNum == 21)
+ callbackPCINT21 = userFunc;
+#endif
+#if (PCINT_USE_PCINT22 == true)
+ if (pcintNum == 22)
+ callbackPCINT22 = userFunc;
+#endif
+#if (PCINT_USE_PCINT23 == true)
+ if (pcintNum == 23)
+ callbackPCINT23 = userFunc;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 3
+ else if (pcintPort == 3 && PCINT_USE_PORT3 == true) {
+ // use fake functions to make the ISRs compile with .a linkage
+#if defined(PCINT_ALINKAGE) && !defined(PCINT_COMPILE_ENABLED_ISR)
+ attachPinChangeInterrupt3();
+#endif
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT24 == true)
+ if (pcintNum == 24)
+ callbackPCINT24 = userFunc;
+#endif
+#if (PCINT_USE_PCINT25 == true)
+ if (pcintNum == 25)
+ callbackPCINT25 = userFunc;
+#endif
+#if (PCINT_USE_PCINT26 == true)
+ if (pcintNum == 26)
+ callbackPCINT26 = userFunc;
+#endif
+#if (PCINT_USE_PCINT27 == true)
+ if (pcintNum == 27)
+ callbackPCINT27 = userFunc;
+#endif
+#if (PCINT_USE_PCINT28 == true)
+ if (pcintNum == 28)
+ callbackPCINT28 = userFunc;
+#endif
+#if (PCINT_USE_PCINT29 == true)
+ if (pcintNum == 29)
+ callbackPCINT29 = userFunc;
+#endif
+#if (PCINT_USE_PCINT30 == true)
+ if (pcintNum == 30)
+ callbackPCINT30 = userFunc;
+#endif
+#if (PCINT_USE_PCINT31 == true)
+ if (pcintNum == 31)
+ callbackPCINT31 = userFunc;
+#endif
+#endif // PCINT_API
+ }
+ else return;
+
+ // get bitmask and array position
+ uint8_t pcintMask = (1 << pcintBit);
+ uint8_t arrayPos = getArrayPosPCINT(pcintPort);
+
+ // save settings related to mode and registers
+ if (mode == CHANGE || mode == RISING)
+ risingPorts[arrayPos] |= pcintMask;
+ if (mode == CHANGE || mode == FALLING)
+ fallingPorts[arrayPos] |= pcintMask;
+
+ // call the actual hardware attach function
+ enablePinChangeInterruptHelper(pcintPort, pcintMask, arrayPos);
+}
+
+// enable interrupt again if temporary disabled
+static inline void enablePinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline));
+void enablePinChangeInterrupt(const uint8_t pcintNum) {
+ // get PCINT registers
+ uint8_t pcintPort = pcintNum / 8;
+ uint8_t pcintBit = pcintNum % 8;
+
+ // check if pcint is a valid pcint, exclude deactivated ports
+ if (pcintPort == 0) {
+ if (PCINT_USE_PORT0 == false)
+ return;
+ }
+ else if (pcintPort == 1) {
+ if (PCINT_USE_PORT1 == false)
+ return;
+ }
+ else if (pcintPort == 2) {
+ if (PCINT_USE_PORT2 == false)
+ return;
+ }
+ else if (pcintPort == 3) {
+ if (PCINT_USE_PORT3 == false)
+ return;
+ }
+ else return;
+
+ // call the actual hardware attach function
+ uint8_t pcintMask = (1 << pcintBit);
+ uint8_t arrayPos = getArrayPosPCINT(pcintPort);
+ enablePinChangeInterruptHelper(pcintPort, pcintMask, arrayPos);
+}
+
+
+//================================================================================
+// Detach Function (partly inlined)
+//================================================================================
+
+void disablePinChangeInterruptHelper(const uint8_t pcintPort, const uint8_t pcintMask);
+static inline void detachPinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline));
+
+void detachPinChangeInterrupt(const uint8_t pcintNum) {
+ // get PCINT registers
+ uint8_t pcintPort = pcintNum / 8;
+ uint8_t pcintBit = pcintNum % 8;
+
+ // check if pcint is a valid pcint, exclude deactivated ports
+ // port 0
+ if (pcintPort == 0 && PCINT_USE_PORT0 == true) {
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT0 == true)
+ if (pcintNum == 0)
+ callbackPCINT0 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT1 == true)
+ if (pcintNum == 1)
+ callbackPCINT1 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT2 == true)
+ if (pcintNum == 2)
+ callbackPCINT2 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT3 == true)
+ if (pcintNum == 3)
+ callbackPCINT3 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT4 == true)
+ if (pcintNum == 4)
+ callbackPCINT4 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT5 == true)
+ if (pcintNum == 5)
+ callbackPCINT5 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT6 == true)
+ if (pcintNum == 6)
+ callbackPCINT6 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT7 == true)
+ if (pcintNum == 7)
+ callbackPCINT7 = pcint_null_callback;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 1
+ else if (pcintPort == 1 && PCINT_USE_PORT1 == true) {
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT8 == true)
+ if (pcintNum == 8)
+ callbackPCINT8 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT9 == true)
+ if (pcintNum == 9)
+ callbackPCINT9 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT10 == true)
+ if (pcintNum == 10)
+ callbackPCINT10 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT11 == true)
+ if (pcintNum == 11)
+ callbackPCINT11 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT12 == true)
+ if (pcintNum == 12)
+ callbackPCINT12 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT13 == true)
+ if (pcintNum == 13)
+ callbackPCINT13 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT14 == true)
+ if (pcintNum == 14)
+ callbackPCINT14 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT15 == true)
+ if (pcintNum == 15)
+ callbackPCINT15 = pcint_null_callback;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 2
+ else if (pcintPort == 2 && PCINT_USE_PORT2 == true) {
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT16 == true)
+ if (pcintNum == 16)
+ callbackPCINT16 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT17 == true)
+ if (pcintNum == 17)
+ callbackPCINT17 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT18 == true)
+ if (pcintNum == 18)
+ callbackPCINT18 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT19 == true)
+ if (pcintNum == 19)
+ callbackPCINT19 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT20 == true)
+ if (pcintNum == 20)
+ callbackPCINT20 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT21 == true)
+ if (pcintNum == 21)
+ callbackPCINT21 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT22 == true)
+ if (pcintNum == 22)
+ callbackPCINT22 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT23 == true)
+ if (pcintNum == 23)
+ callbackPCINT23 = pcint_null_callback;
+#endif
+#endif // PCINT_API
+ }
+
+ // port 3
+ else if (pcintPort == 3 && PCINT_USE_PORT3 == true) {
+ // attache the function pointers for the API
+#if defined(PCINT_API)
+#if (PCINT_USE_PCINT24 == true)
+ if (pcintNum == 24)
+ callbackPCINT24 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT25 == true)
+ if (pcintNum == 25)
+ callbackPCINT25 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT26 == true)
+ if (pcintNum == 26)
+ callbackPCINT26 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT27 == true)
+ if (pcintNum == 27)
+ callbackPCINT27 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT28 == true)
+ if (pcintNum == 28)
+ callbackPCINT28 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT29 == true)
+ if (pcintNum == 29)
+ callbackPCINT29 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT30 == true)
+ if (pcintNum == 30)
+ callbackPCINT30 = pcint_null_callback;
+#endif
+#if (PCINT_USE_PCINT31 == true)
+ if (pcintNum == 31)
+ callbackPCINT31 = pcint_null_callback;
+#endif
+#endif // PCINT_API
+ }
+ else return;
+
+ // get bitmask and array position
+ uint8_t pcintMask = (1 << pcintBit);
+ uint8_t arrayPos = getArrayPosPCINT(pcintPort);
+
+ // delete setting
+ risingPorts[arrayPos] &= ~pcintMask;
+ fallingPorts[arrayPos] &= ~pcintMask;
+
+ // call the actual hardware disable function
+ disablePinChangeInterruptHelper(pcintPort, pcintMask);
+}
+
+static inline void disablePinChangeInterrupt(const uint8_t pcintNum) __attribute__((always_inline));
+void disablePinChangeInterrupt(const uint8_t pcintNum) {
+ // get PCINT registers
+ uint8_t pcintPort = pcintNum / 8;
+ uint8_t pcintBit = pcintNum % 8;
+
+ // check if pcint is a valid pcint, exclude deactivated ports
+ if (pcintPort == 0) {
+ if (PCINT_USE_PORT0 == false)
+ return;
+ }
+ else if (pcintPort == 1) {
+ if (PCINT_USE_PORT1 == false)
+ return;
+ }
+ else if (pcintPort == 2) {
+ if (PCINT_USE_PORT2 == false)
+ return;
+ }
+ else if (pcintPort == 3) {
+ if (PCINT_USE_PORT3 == false)
+ return;
+ }
+ else return;
+
+ // get bitmask
+ uint8_t pcintMask = (1 << pcintBit);
+
+ // Do not delete mode settings nor detach the user function
+ // Just turn off interrupts
+
+ // call the actual hardware disable function
+ disablePinChangeInterruptHelper(pcintPort, pcintMask);
+}
+
+//================================================================================
+// getTrigger Function (inlined)
+//================================================================================
+
+static inline uint8_t getPinChangeInterruptTrigger(const uint8_t pcintNum) __attribute__((always_inline));
+uint8_t getPinChangeInterruptTrigger(const uint8_t pcintNum) {
+ // get PCINT registers
+ uint8_t pcintPort = pcintNum / 8;
+ uint8_t pcintBit = pcintNum % 8;
+
+ // check if pcint is a valid pcint, exclude deactivated ports
+ if (pcintPort == 0) {
+ if (PCINT_USE_PORT0 == false)
+ return CHANGE;
+ }
+ else if (pcintPort == 1) {
+ if (PCINT_USE_PORT1 == false)
+ return CHANGE;
+ }
+ else if (pcintPort == 2) {
+ if (PCINT_USE_PORT2 == false)
+ return CHANGE;
+ }
+ else if (pcintPort == 3) {
+ if (PCINT_USE_PORT3 == false)
+ return CHANGE;
+ }
+ else return CHANGE;
+
+ uint8_t arrayPos = getArrayPosPCINT(pcintPort);
+
+ // Check if no mode was set, return an error
+ if(!(risingPorts[arrayPos] & (1 << pcintBit)) && !(fallingPorts[arrayPos] & (1 << pcintBit)))
+ return CHANGE;
+
+ // specify the CHANGE mode
+ if (oldPorts[arrayPos] & (1 << pcintBit))
+ return RISING;
+ else
+ return FALLING;
+}
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp
new file mode 100644
index 0000000..c8dfba8
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt0.cpp
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "PinChangeInterrupt.h"
+
+//================================================================================
+// Interrupt Handler
+//================================================================================
+
+// prevent compilation twice if included from the .cpp to force compile all ISRs
+#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \
+ || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR)
+
+#if (PCINT_USE_PORT0 == true)
+
+void attachPinChangeInterrupt0(void) {
+ // fake function to make the IDE link this file
+}
+
+ISR(PCINT0_vect) {
+ // get the new and old pin states for port
+ uint8_t newPort = PCINT_INPUT_PORT0;
+
+ // compare with the old value to detect a rising or falling
+ uint8_t arrayPos = getArrayPosPCINT(0);
+ uint8_t change = newPort ^ oldPorts[arrayPos];
+ uint8_t rising = change & newPort;
+ uint8_t falling = change & oldPorts[arrayPos];
+
+ // check which pins are triggered, compared with the settings
+ uint8_t risingTrigger = rising & risingPorts[arrayPos];
+ uint8_t fallingTrigger = falling & fallingPorts[arrayPos];
+ uint8_t trigger = risingTrigger | fallingTrigger;
+
+ // save the new state for next comparison
+ oldPorts[arrayPos] = newPort;
+
+ // Execute all functions that should be triggered
+ // This way we can exclude a single function
+ // and the calling is also much faster
+ // We may also reorder the pins for different priority
+#if !defined(PCINT_CALLBACK_PORT0)
+ PCINT_CALLBACK(0, 0);
+ PCINT_CALLBACK(1, 1);
+ PCINT_CALLBACK(2, 2);
+ PCINT_CALLBACK(3, 3);
+ PCINT_CALLBACK(4, 4);
+ PCINT_CALLBACK(5, 5);
+ PCINT_CALLBACK(6, 6);
+ PCINT_CALLBACK(7, 7);
+#else
+ PCINT_CALLBACK_PORT0
+#endif
+}
+
+#if defined(PCINT_API)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("volatile callback callbackPCINT");
+Serial.print(i);
+Serial.println(" = pcint_null_callback;");
+Serial.print("void PinChangeInterruptEventPCINT");
+Serial.print(i);
+Serial.println("(void){");
+Serial.print(" callbackPCINT");
+Serial.print(i);
+Serial.println("();");
+Serial.println("}");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_USE_PCINT0 == true)
+volatile callback callbackPCINT0 = pcint_null_callback;
+void PinChangeInterruptEventPCINT0(void) {
+ callbackPCINT0();
+}
+#endif
+#if (PCINT_USE_PCINT1 == true)
+volatile callback callbackPCINT1 = pcint_null_callback;
+void PinChangeInterruptEventPCINT1(void) {
+ callbackPCINT1();
+}
+#endif
+#if (PCINT_USE_PCINT2 == true)
+volatile callback callbackPCINT2 = pcint_null_callback;
+void PinChangeInterruptEventPCINT2(void) {
+ callbackPCINT2();
+}
+#endif
+#if (PCINT_USE_PCINT3 == true)
+volatile callback callbackPCINT3 = pcint_null_callback;
+void PinChangeInterruptEventPCINT3(void) {
+ callbackPCINT3();
+}
+#endif
+#if (PCINT_USE_PCINT4 == true)
+volatile callback callbackPCINT4 = pcint_null_callback;
+void PinChangeInterruptEventPCINT4(void) {
+ callbackPCINT4();
+}
+#endif
+#if (PCINT_USE_PCINT5 == true)
+volatile callback callbackPCINT5 = pcint_null_callback;
+void PinChangeInterruptEventPCINT5(void) {
+ callbackPCINT5();
+}
+#endif
+#if (PCINT_USE_PCINT6 == true)
+volatile callback callbackPCINT6 = pcint_null_callback;
+void PinChangeInterruptEventPCINT6(void) {
+ callbackPCINT6();
+}
+#endif
+#if (PCINT_USE_PCINT7 == true)
+volatile callback callbackPCINT7 = pcint_null_callback;
+void PinChangeInterruptEventPCINT7(void) {
+ callbackPCINT7();
+}
+#endif
+
+#endif // PCINT_API
+
+#endif // PCINT_USE_PORT0
+
+#endif // PCINT_INCLUDE_FROM_CPP
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp
new file mode 100644
index 0000000..e9953cd
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt1.cpp
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "PinChangeInterrupt.h"
+
+//================================================================================
+// Interrupt Handler
+//================================================================================
+
+// prevent compilation twice if included from the .cpp to force compile all ISRs
+#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \
+ || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR)
+
+#if (PCINT_USE_PORT1 == true)
+
+void attachPinChangeInterrupt1(void) {
+ // fake function to make the IDE link this file
+}
+
+ISR(PCINT1_vect) {
+ // get the new and old pin states for port
+ uint8_t newPort = PCINT_INPUT_PORT1;
+
+ // compare with the old value to detect a rising or falling
+ uint8_t arrayPos = getArrayPosPCINT(1);
+ uint8_t change = newPort ^ oldPorts[arrayPos];
+ uint8_t rising = change & newPort;
+ uint8_t falling = change & oldPorts[arrayPos];
+
+ // check which pins are triggered, compared with the settings
+ uint8_t risingTrigger = rising & risingPorts[arrayPos];
+ uint8_t fallingTrigger = falling & fallingPorts[arrayPos];
+ uint8_t trigger = risingTrigger | fallingTrigger;
+
+ // save the new state for next comparison
+ oldPorts[arrayPos] = newPort;
+
+ // Execute all functions that should be triggered
+ // This way we can exclude a single function
+ // and the calling is also much faster
+ // We may also reorder the pins for different priority
+#if !defined(PCINT_CALLBACK_PORT1)
+ PCINT_CALLBACK(0, 8);
+ PCINT_CALLBACK(1, 9);
+ PCINT_CALLBACK(2, 10);
+ PCINT_CALLBACK(3, 11);
+ PCINT_CALLBACK(4, 12);
+ PCINT_CALLBACK(5, 13);
+ PCINT_CALLBACK(6, 14);
+ PCINT_CALLBACK(7, 15);
+#else
+ PCINT_CALLBACK_PORT1
+#endif
+}
+
+#if defined(PCINT_API)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("volatile callback callbackPCINT");
+Serial.print(i);
+Serial.println(" = pcint_null_callback;");
+Serial.print("void PinChangeInterruptEventPCINT");
+Serial.print(i);
+Serial.println("(void){");
+Serial.print(" callbackPCINT");
+Serial.print(i);
+Serial.println("();");
+Serial.println("}");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_USE_PCINT8 == true)
+volatile callback callbackPCINT8 = pcint_null_callback;
+void PinChangeInterruptEventPCINT8(void) {
+ callbackPCINT8();
+}
+#endif
+#if (PCINT_USE_PCINT9 == true)
+volatile callback callbackPCINT9 = pcint_null_callback;
+void PinChangeInterruptEventPCINT9(void) {
+ callbackPCINT9();
+}
+#endif
+#if (PCINT_USE_PCINT10 == true)
+volatile callback callbackPCINT10 = pcint_null_callback;
+void PinChangeInterruptEventPCINT10(void) {
+ callbackPCINT10();
+}
+#endif
+#if (PCINT_USE_PCINT11 == true)
+volatile callback callbackPCINT11 = pcint_null_callback;
+void PinChangeInterruptEventPCINT11(void) {
+ callbackPCINT11();
+}
+#endif
+#if (PCINT_USE_PCINT12 == true)
+volatile callback callbackPCINT12 = pcint_null_callback;
+void PinChangeInterruptEventPCINT12(void) {
+ callbackPCINT12();
+}
+#endif
+#if (PCINT_USE_PCINT13 == true)
+volatile callback callbackPCINT13 = pcint_null_callback;
+void PinChangeInterruptEventPCINT13(void) {
+ callbackPCINT13();
+}
+#endif
+#if (PCINT_USE_PCINT14 == true)
+volatile callback callbackPCINT14 = pcint_null_callback;
+void PinChangeInterruptEventPCINT14(void) {
+ callbackPCINT14();
+}
+#endif
+#if (PCINT_USE_PCINT15 == true)
+volatile callback callbackPCINT15 = pcint_null_callback;
+void PinChangeInterruptEventPCINT15(void) {
+ callbackPCINT15();
+}
+#endif
+
+#endif // PCINT_API
+
+#endif // PCINT_USE_PORT1
+
+#endif // PCINT_INCLUDE_FROM_CPP
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp
new file mode 100644
index 0000000..a3bd72e
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt2.cpp
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "PinChangeInterrupt.h"
+
+//================================================================================
+// Interrupt Handler
+//================================================================================
+
+// prevent compilation twice if included from the .cpp to force compile all ISRs
+#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \
+ || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR)
+
+#if (PCINT_USE_PORT2 == true)
+
+void attachPinChangeInterrupt2(void) {
+ // fake function to make the IDE link this file
+}
+
+ISR(PCINT2_vect) {
+ // get the new and old pin states for port
+ uint8_t newPort = PCINT_INPUT_PORT2;
+
+ // compare with the old value to detect a rising or falling
+ uint8_t arrayPos = getArrayPosPCINT(2);
+ uint8_t change = newPort ^ oldPorts[arrayPos];
+ uint8_t rising = change & newPort;
+ uint8_t falling = change & oldPorts[arrayPos];
+
+ // check which pins are triggered, compared with the settings
+ uint8_t risingTrigger = rising & risingPorts[arrayPos];
+ uint8_t fallingTrigger = falling & fallingPorts[arrayPos];
+ uint8_t trigger = risingTrigger | fallingTrigger;
+
+ // save the new state for next comparison
+ oldPorts[arrayPos] = newPort;
+
+ // Execute all functions that should be triggered
+ // This way we can exclude a single function
+ // and the calling is also much faster
+ // We may also reorder the pins for different priority
+#if !defined(PCINT_CALLBACK_PORT2)
+ PCINT_CALLBACK(0, 16);
+ PCINT_CALLBACK(1, 17);
+ PCINT_CALLBACK(2, 18);
+ PCINT_CALLBACK(3, 19);
+ PCINT_CALLBACK(4, 20);
+ PCINT_CALLBACK(5, 21);
+ PCINT_CALLBACK(6, 22);
+ PCINT_CALLBACK(7, 23);
+#else
+ PCINT_CALLBACK_PORT2
+#endif
+}
+
+#if defined(PCINT_API)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("volatile callback callbackPCINT");
+Serial.print(i);
+Serial.println(" = pcint_null_callback;");
+Serial.print("void PinChangeInterruptEventPCINT");
+Serial.print(i);
+Serial.println("(void){");
+Serial.print(" callbackPCINT");
+Serial.print(i);
+Serial.println("();");
+Serial.println("}");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_USE_PCINT16 == true)
+volatile callback callbackPCINT16 = pcint_null_callback;
+void PinChangeInterruptEventPCINT16(void) {
+ callbackPCINT16();
+}
+#endif
+#if (PCINT_USE_PCINT17 == true)
+volatile callback callbackPCINT17 = pcint_null_callback;
+void PinChangeInterruptEventPCINT17(void) {
+ callbackPCINT17();
+}
+#endif
+#if (PCINT_USE_PCINT18 == true)
+volatile callback callbackPCINT18 = pcint_null_callback;
+void PinChangeInterruptEventPCINT18(void) {
+ callbackPCINT18();
+}
+#endif
+#if (PCINT_USE_PCINT19 == true)
+volatile callback callbackPCINT19 = pcint_null_callback;
+void PinChangeInterruptEventPCINT19(void) {
+ callbackPCINT19();
+}
+#endif
+#if (PCINT_USE_PCINT20 == true)
+volatile callback callbackPCINT20 = pcint_null_callback;
+void PinChangeInterruptEventPCINT20(void) {
+ callbackPCINT20();
+}
+#endif
+#if (PCINT_USE_PCINT21 == true)
+volatile callback callbackPCINT21 = pcint_null_callback;
+void PinChangeInterruptEventPCINT21(void) {
+ callbackPCINT21();
+}
+#endif
+#if (PCINT_USE_PCINT22 == true)
+volatile callback callbackPCINT22 = pcint_null_callback;
+void PinChangeInterruptEventPCINT22(void) {
+ callbackPCINT22();
+}
+#endif
+#if (PCINT_USE_PCINT23 == true)
+volatile callback callbackPCINT23 = pcint_null_callback;
+void PinChangeInterruptEventPCINT23(void) {
+ callbackPCINT23();
+}
+#endif
+
+#endif // PCINT_API
+
+#endif // PCINT_USE_PORT2
+
+#endif // PCINT_INCLUDE_FROM_CPP
\ No newline at end of file
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp
new file mode 100644
index 0000000..71d2ea6
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterrupt3.cpp
@@ -0,0 +1,149 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#include "PinChangeInterrupt.h"
+
+//================================================================================
+// Interrupt Handler
+//================================================================================
+
+// prevent compilation twice if included from the .cpp to force compile all ISRs
+#if defined(PCINT_ALINKAGE) && defined(PCINT_COMPILE_ENABLED_ISR) && defined(PCINT_INCLUDE_FROM_CPP) \
+ || !defined(PCINT_ALINKAGE) || !defined(PCINT_COMPILE_ENABLED_ISR)
+
+#if (PCINT_USE_PORT3 == true)
+
+void attachPinChangeInterrupt3(void) {
+ // fake function to make the IDE link this file
+}
+
+ISR(PCINT3_vect) {
+ // get the new and old pin states for port
+ uint8_t newPort = PCINT_INPUT_PORT3;
+
+ // compare with the old value to detect a rising or falling
+ uint8_t arrayPos = getArrayPosPCINT(3);
+ uint8_t change = newPort ^ oldPorts[arrayPos];
+ uint8_t rising = change & newPort;
+ uint8_t falling = change & oldPorts[arrayPos];
+
+ // check which pins are triggered, compared with the settings
+ uint8_t risingTrigger = rising & risingPorts[arrayPos];
+ uint8_t fallingTrigger = falling & fallingPorts[arrayPos];
+ uint8_t trigger = risingTrigger | fallingTrigger;
+
+ // save the new state for next comparison
+ oldPorts[arrayPos] = newPort;
+
+ // Execute all functions that should be triggered
+ // This way we can exclude a single function
+ // and the calling is also much faster
+ // We may also reorder the pins for different priority
+#if !defined(PCINT_CALLBACK_PORT3)
+ PCINT_CALLBACK(0, 24);
+ PCINT_CALLBACK(1, 25);
+ PCINT_CALLBACK(2, 26);
+ PCINT_CALLBACK(3, 27);
+ PCINT_CALLBACK(4, 28);
+ PCINT_CALLBACK(5, 29);
+ PCINT_CALLBACK(6, 30);
+ PCINT_CALLBACK(7, 31);
+#else
+ PCINT_CALLBACK_PORT3
+#endif
+}
+
+#if defined(PCINT_API)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" == true)");
+Serial.print("volatile callback callbackPCINT");
+Serial.print(i);
+Serial.println(" = pcint_null_callback;");
+Serial.print("void PinChangeInterruptEventPCINT");
+Serial.print(i);
+Serial.println("(void){");
+Serial.print(" callbackPCINT");
+Serial.print(i);
+Serial.println("();");
+Serial.println("}");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_USE_PCINT24 == true)
+volatile callback callbackPCINT24 = pcint_null_callback;
+void PinChangeInterruptEventPCINT24(void) {
+ callbackPCINT24();
+}
+#endif
+#if (PCINT_USE_PCINT25 == true)
+volatile callback callbackPCINT25 = pcint_null_callback;
+void PinChangeInterruptEventPCINT25(void) {
+ callbackPCINT25();
+}
+#endif
+#if (PCINT_USE_PCINT26 == true)
+volatile callback callbackPCINT26 = pcint_null_callback;
+void PinChangeInterruptEventPCINT26(void) {
+ callbackPCINT26();
+}
+#endif
+#if (PCINT_USE_PCINT27 == true)
+volatile callback callbackPCINT27 = pcint_null_callback;
+void PinChangeInterruptEventPCINT27(void) {
+ callbackPCINT27();
+}
+#endif
+#if (PCINT_USE_PCINT28 == true)
+volatile callback callbackPCINT28 = pcint_null_callback;
+void PinChangeInterruptEventPCINT28(void) {
+ callbackPCINT28();
+}
+#endif
+#if (PCINT_USE_PCINT29 == true)
+volatile callback callbackPCINT29 = pcint_null_callback;
+void PinChangeInterruptEventPCINT29(void) {
+ callbackPCINT29();
+}
+#endif
+#if (PCINT_USE_PCINT30 == true)
+volatile callback callbackPCINT30 = pcint_null_callback;
+void PinChangeInterruptEventPCINT30(void) {
+ callbackPCINT30();
+}
+#endif
+#if (PCINT_USE_PCINT31 == true)
+volatile callback callbackPCINT31 = pcint_null_callback;
+void PinChangeInterruptEventPCINT31(void) {
+ callbackPCINT31();
+}
+#endif
+
+#endif // PCINT_API
+
+#endif // PCINT_USE_PORT3
+
+#endif // PCINT_INCLUDE_FROM_CPP
\ No newline at end of file
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h
new file mode 100644
index 0000000..fdcfa65
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptBoards.h
@@ -0,0 +1,174 @@
+/*
+Copyright (c) 2014-2021 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// include guard
+#pragma once
+
+//================================================================================
+// Board Definitions
+//================================================================================
+
+// Microcontroller specific definitions
+// Avr Variants are defined here: https://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/include/avr/io.h?view=markup
+
+#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328A__) || defined(__AVR_ATmega328PA__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328PB__) \
+ || defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PB__) \
+ || defined(__AVR_ATmega88__) || defined(__AVR_ATmega88A__) || defined(__AVR_ATmega88PA__) || defined(__AVR_ATmega88P__) || defined(__AVR_ATmega88PB__) \
+ || defined(__AVR_ATmega48__) || defined(__AVR_ATmega48A__) || defined(__AVR_ATmega48PA__) || defined(__AVR_ATmega48P__) || defined(__AVR_ATmega48PB__)
+// Arduino Uno
+#define PCINT_INPUT_PORT0 PINB
+#define PCINT_INPUT_PORT1 PINC
+#define PCINT_INPUT_PORT2 PIND
+
+#if defined(__AVR_ATmega328PB__)
+#define PCINT_INPUT_PORT3 PINE
+#endif
+
+#elif defined(__AVR_ATmega162__)
+
+#define PCINT_INPUT_PORT0 PINA
+#define PCINT_INPUT_PORT1 PINC
+
+#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega640__)
+// Arduino Mega/Mega2560
+#define PCINT_INPUT_PORT0 PINB
+#define PCINT_INPUT_PORT2 PINK
+
+// special Port1 case, pins are on 2 HW Pin Ports (E,J)
+#if defined(PCINT_ENABLE_PCINT16) // PortE
+#if defined(PCINT_ENABLE_PCINT17) || defined(PCINT_ENABLE_PCINT18) \
+ || defined(PCINT_ENABLE_PCINT19) || defined(PCINT_ENABLE_PCINT20) \
+|| defined(PCINT_ENABLE_PCINT21) || defined(PCINT_ENABLE_PCINT22) \
+|| defined(PCINT_ENABLE_PCINT23) // PortJ
+// PortE and PortJ selected
+#define PCINT_INPUT_PORT1 ((PINE & 0x01) | (PINJ << 1))
+#else
+// PortE only selected
+#define PCINT_INPUT_PORT1 PINE
+#endif
+#else
+// PortJ only selected
+// we still have to do the shift because the attach
+// function is not designed for this optimization
+#define PCINT_INPUT_PORT1 (PINJ << 1)
+#endif
+
+#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
+// Arduino Leonardo/Micro
+#define PCINT_INPUT_PORT0 PINB
+
+#elif defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
+// u2 Series/HoodLoader2
+// u2 Series has crappy pin mappings for port 1
+#define PCINT_INPUT_PORT0 PINB
+#define PCINT_INPUT_PORT1 (((PINC >> 6) & (1 << 0)) | ((PINC >> 4) & (1 << 1)) | ((PINC >> 2) & (1 << 2)) | ((PINC << 1) & (1 << 3)) | ((PIND >> 1) & (1 << 4)))
+
+#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
+// Attiny x5
+#define PCINT_INPUT_PORT0 PINB
+
+#elif defined(__AVR_ATtiny13__)
+// Attiny 13A
+#define PCINT_INPUT_PORT0 PINB
+// This is just a workaround for the missing definition in the following core: https://sourceforge.net/projects/ard-core13/
+// It should work fine with: https://github.com/MCUdude/MicroCore
+#ifndef portInputRegister
+#define portInputRegister(P) ( (volatile uint8_t *)(PINB) )
+#endif
+
+#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
+// Attiny x4
+#define PCINT_INPUT_PORT0 PINA
+#define PCINT_INPUT_PORT1 PINB
+
+#elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
+// 1284p and 644p, special 4 port case
+#define PCINT_INPUT_PORT0 PINA
+#define PCINT_INPUT_PORT1 PINB
+#define PCINT_INPUT_PORT2 PINC
+#define PCINT_INPUT_PORT3 PIND
+
+#elif defined(__AVR_ATtinyX41__) || defined(__AVR_ATtiny441__) || defined(__AVR_ATtiny841__)
+// Attiny x41
+#define PCINT_INPUT_PORT0 PINA
+#define PCINT_INPUT_PORT1 PINB
+
+// "iotn841.h" is missing those definitions, so we add them here
+#define PCINT0 0
+#define PCINT1 1
+#define PCINT2 2
+#define PCINT3 3
+#define PCINT4 4
+#define PCINT5 5
+#define PCINT6 6
+#define PCINT7 7
+
+#define PCINT8 0
+#define PCINT9 1
+#define PCINT10 2
+#define PCINT11 3
+
+#elif defined(__AVR_ATtiny2313__)
+#define PCINT_INPUT_PORT0 PINB
+
+#elif defined(__AVR_ATtiny2313A__) || defined(__AVR_ATtiny4313__)
+// All 8 pins
+#define PCINT_INPUT_PORT0 PINB
+// PinA has 3 PCINTs on the reset and clock lines, we do not use this port
+// PIND has 7 pins available, but the pin ordering is so messed up,
+// that it does not work with the current library structure.
+
+#elif defined(__AVR_ATtiny261__) || defined(__AVR_ATtiny461__) || defined(__AVR_ATtiny861__)
+// PORTB has Reset, clock and SPI while PORTA has I2C and Analog Pins. We just enable all pins.
+#define PCINT_INPUT_PORT0 PINA
+#define PCINT_INPUT_PORT1 PINB
+
+#else // Microcontroller not supported
+#error PinChangeInterrupt library does not support this MCU.
+#endif
+
+//================================================================================
+// Add missing definitions
+//================================================================================
+
+// add fakes if ports are not used
+#ifndef PCINT_INPUT_PORT0
+#define PCINT_INPUT_PORT0 0
+#else
+#define PCINT_INPUT_PORT0_USED
+#endif
+#ifndef PCINT_INPUT_PORT1
+#define PCINT_INPUT_PORT1 0
+#else
+#define PCINT_INPUT_PORT1_USED
+#endif
+#ifndef PCINT_INPUT_PORT2
+#define PCINT_INPUT_PORT2 0
+#else
+#define PCINT_INPUT_PORT2_USED
+#endif
+#ifndef PCINT_INPUT_PORT3
+#define PCINT_INPUT_PORT3 0
+#else
+#define PCINT_INPUT_PORT3_USED
+#endif
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h
new file mode 100644
index 0000000..832b6bd
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptPins.h
@@ -0,0 +1,926 @@
+/*
+Copyright (c) 2014-2017 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// include guard
+#pragma once
+
+/*
+The strategy in this file:
+
+0. Makefile optimization:
+ To disable PCINT/PORTs via makefile use -DPCINT_DISABLE_PORT0 etc.
+ This will undef a previously defined PCINT_ENABLE_PORT0.
+
+1. Reduce the user settings to the enabled pins.
+ If the whole port is deactivated, also disable all pins on this port.
+
+2. Define the hardware available pins/ports.
+
+3. Compare the hardware definition with the enabled pin definitions.
+ If the pin is available and enabled, create a makro to use the pin.
+
+4. Count all used pins (for each port).
+
+5. If there are no pins used on a port, do not use the port
+
+6. Finally we have a clear defintion of the used pins/ports like this:
+PCINT_USE_PCINT0 (true/false)
+PCINT_USE_PORT0 (true/false)
+
+Other definitions that can be used:
+PCINT_HAS_PORT0 (true/false)
+PCINT_HAS_PCINT0 (true/false)
+PCINT_NUM_PINS_PORT0 (0-8)
+PCINT_NUM_USED_PINS_PORT0 (0-8)
+EXTERNAL_NUM_PINCHANGEINTERRUPT (0-24)
+EXTERNAL_NUM_USED_PINCHANGEINTERRUPT (0-24)
+PCINT_NUM_PORTS (0-3)
+PCINT_NUM_USED_PORTS (0-3)
+*/
+
+//================================================================================
+// Disabled Pins
+//================================================================================
+/*
+for (int port = 0; port < 4; port++) {
+ Serial.print("#if defined(PCINT_ENABLE_PORT");
+ Serial.print(port);
+ Serial.print(") && defined(PCINT_DISABLE_PORT");
+ Serial.print(port);
+ Serial.println(")");
+ Serial.print("#undef PCINT_ENABLE_PORT");
+ Serial.println(port);
+ Serial.println("#endif");
+ Serial.println();
+}
+
+for (int i = 0; i < 32; i++) {
+ Serial.print("#if defined(PCINT_ENABLE_PCINT");
+ Serial.print(i);
+ Serial.print(") && defined(PCINT_DISABLE_PCINT");
+ Serial.print(i);
+ Serial.println(")");
+ Serial.print("#undef PCINT_ENABLE_PCINT");
+ Serial.println(i);
+ Serial.println("#endif");
+ Serial.println();
+}
+*/
+#if defined(PCINT_ENABLE_PORT0) && defined(PCINT_DISABLE_PORT0)
+#undef PCINT_ENABLE_PORT0
+#endif
+
+#if defined(PCINT_ENABLE_PORT1) && defined(PCINT_DISABLE_PORT1)
+#undef PCINT_ENABLE_PORT1
+#endif
+
+#if defined(PCINT_ENABLE_PORT2) && defined(PCINT_DISABLE_PORT2)
+#undef PCINT_ENABLE_PORT2
+#endif
+
+#if defined(PCINT_ENABLE_PORT3) && defined(PCINT_DISABLE_PORT3)
+#undef PCINT_ENABLE_PORT3
+#endif
+
+#if defined(PCINT_ENABLE_PCINT0) && defined(PCINT_DISABLE_PCINT0)
+#undef PCINT_ENABLE_PCINT0
+#endif
+
+#if defined(PCINT_ENABLE_PCINT1) && defined(PCINT_DISABLE_PCINT1)
+#undef PCINT_ENABLE_PCINT1
+#endif
+
+#if defined(PCINT_ENABLE_PCINT2) && defined(PCINT_DISABLE_PCINT2)
+#undef PCINT_ENABLE_PCINT2
+#endif
+
+#if defined(PCINT_ENABLE_PCINT3) && defined(PCINT_DISABLE_PCINT3)
+#undef PCINT_ENABLE_PCINT3
+#endif
+
+#if defined(PCINT_ENABLE_PCINT4) && defined(PCINT_DISABLE_PCINT4)
+#undef PCINT_ENABLE_PCINT4
+#endif
+
+#if defined(PCINT_ENABLE_PCINT5) && defined(PCINT_DISABLE_PCINT5)
+#undef PCINT_ENABLE_PCINT5
+#endif
+
+#if defined(PCINT_ENABLE_PCINT6) && defined(PCINT_DISABLE_PCINT6)
+#undef PCINT_ENABLE_PCINT6
+#endif
+
+#if defined(PCINT_ENABLE_PCINT7) && defined(PCINT_DISABLE_PCINT7)
+#undef PCINT_ENABLE_PCINT7
+#endif
+
+#if defined(PCINT_ENABLE_PCINT8) && defined(PCINT_DISABLE_PCINT8)
+#undef PCINT_ENABLE_PCINT8
+#endif
+
+#if defined(PCINT_ENABLE_PCINT9) && defined(PCINT_DISABLE_PCINT9)
+#undef PCINT_ENABLE_PCINT9
+#endif
+
+#if defined(PCINT_ENABLE_PCINT10) && defined(PCINT_DISABLE_PCINT10)
+#undef PCINT_ENABLE_PCINT10
+#endif
+
+#if defined(PCINT_ENABLE_PCINT11) && defined(PCINT_DISABLE_PCINT11)
+#undef PCINT_ENABLE_PCINT11
+#endif
+
+#if defined(PCINT_ENABLE_PCINT12) && defined(PCINT_DISABLE_PCINT12)
+#undef PCINT_ENABLE_PCINT12
+#endif
+
+#if defined(PCINT_ENABLE_PCINT13) && defined(PCINT_DISABLE_PCINT13)
+#undef PCINT_ENABLE_PCINT13
+#endif
+
+#if defined(PCINT_ENABLE_PCINT14) && defined(PCINT_DISABLE_PCINT14)
+#undef PCINT_ENABLE_PCINT14
+#endif
+
+#if defined(PCINT_ENABLE_PCINT15) && defined(PCINT_DISABLE_PCINT15)
+#undef PCINT_ENABLE_PCINT15
+#endif
+
+#if defined(PCINT_ENABLE_PCINT16) && defined(PCINT_DISABLE_PCINT16)
+#undef PCINT_ENABLE_PCINT16
+#endif
+
+#if defined(PCINT_ENABLE_PCINT17) && defined(PCINT_DISABLE_PCINT17)
+#undef PCINT_ENABLE_PCINT17
+#endif
+
+#if defined(PCINT_ENABLE_PCINT18) && defined(PCINT_DISABLE_PCINT18)
+#undef PCINT_ENABLE_PCINT18
+#endif
+
+#if defined(PCINT_ENABLE_PCINT19) && defined(PCINT_DISABLE_PCINT19)
+#undef PCINT_ENABLE_PCINT19
+#endif
+
+#if defined(PCINT_ENABLE_PCINT20) && defined(PCINT_DISABLE_PCINT20)
+#undef PCINT_ENABLE_PCINT20
+#endif
+
+#if defined(PCINT_ENABLE_PCINT21) && defined(PCINT_DISABLE_PCINT21)
+#undef PCINT_ENABLE_PCINT21
+#endif
+
+#if defined(PCINT_ENABLE_PCINT22) && defined(PCINT_DISABLE_PCINT22)
+#undef PCINT_ENABLE_PCINT22
+#endif
+
+#if defined(PCINT_ENABLE_PCINT23) && defined(PCINT_DISABLE_PCINT23)
+#undef PCINT_ENABLE_PCINT23
+#endif
+
+#if defined(PCINT_ENABLE_PCINT24) && defined(PCINT_DISABLE_PCINT24)
+#undef PCINT_ENABLE_PCINT24
+#endif
+
+#if defined(PCINT_ENABLE_PCINT25) && defined(PCINT_DISABLE_PCINT25)
+#undef PCINT_ENABLE_PCINT25
+#endif
+
+#if defined(PCINT_ENABLE_PCINT26) && defined(PCINT_DISABLE_PCINT26)
+#undef PCINT_ENABLE_PCINT26
+#endif
+
+#if defined(PCINT_ENABLE_PCINT27) && defined(PCINT_DISABLE_PCINT27)
+#undef PCINT_ENABLE_PCINT27
+#endif
+
+#if defined(PCINT_ENABLE_PCINT28) && defined(PCINT_DISABLE_PCINT28)
+#undef PCINT_ENABLE_PCINT28
+#endif
+
+#if defined(PCINT_ENABLE_PCINT29) && defined(PCINT_DISABLE_PCINT29)
+#undef PCINT_ENABLE_PCINT29
+#endif
+
+#if defined(PCINT_ENABLE_PCINT30) && defined(PCINT_DISABLE_PCINT30)
+#undef PCINT_ENABLE_PCINT30
+#endif
+
+#if defined(PCINT_ENABLE_PCINT31) && defined(PCINT_DISABLE_PCINT31)
+#undef PCINT_ENABLE_PCINT31
+#endif
+
+
+//================================================================================
+// Enabled Pins
+//================================================================================
+
+/* Disable all pins on a port, if port is deactivated
+We could then check every pin -> port definition
+But that'd be a mess and doesnt help
+Users who deactivate stuff should know
+what the are doing.
+So we use the enabled pins for all next definitions*/
+/*
+for (int port = 0; port < 4; port++) {
+Serial.print("#if !defined(PCINT_ENABLE_PORT");
+Serial.print(port);
+Serial.println(")");
+for (int i = 0; i < 8; i++) {
+Serial.print("#if defined(PCINT_ENABLE_PCINT");
+Serial.print(port * 8 + i);
+Serial.println(")");
+Serial.print("#undef PCINT_ENABLE_PCINT");
+Serial.println(port * 8 + i);
+Serial.println("#endif");
+}
+Serial.println("#endif");
+Serial.println();
+}
+*/
+#if !defined(PCINT_ENABLE_PORT0)
+#if defined(PCINT_ENABLE_PCINT0)
+#undef PCINT_ENABLE_PCINT0
+#endif
+#if defined(PCINT_ENABLE_PCINT1)
+#undef PCINT_ENABLE_PCINT1
+#endif
+#if defined(PCINT_ENABLE_PCINT2)
+#undef PCINT_ENABLE_PCINT2
+#endif
+#if defined(PCINT_ENABLE_PCINT3)
+#undef PCINT_ENABLE_PCINT3
+#endif
+#if defined(PCINT_ENABLE_PCINT4)
+#undef PCINT_ENABLE_PCINT4
+#endif
+#if defined(PCINT_ENABLE_PCINT5)
+#undef PCINT_ENABLE_PCINT5
+#endif
+#if defined(PCINT_ENABLE_PCINT6)
+#undef PCINT_ENABLE_PCINT6
+#endif
+#if defined(PCINT_ENABLE_PCINT7)
+#undef PCINT_ENABLE_PCINT7
+#endif
+#endif
+
+#if !defined(PCINT_ENABLE_PORT1)
+#if defined(PCINT_ENABLE_PCINT8)
+#undef PCINT_ENABLE_PCINT8
+#endif
+#if defined(PCINT_ENABLE_PCINT9)
+#undef PCINT_ENABLE_PCINT9
+#endif
+#if defined(PCINT_ENABLE_PCINT10)
+#undef PCINT_ENABLE_PCINT10
+#endif
+#if defined(PCINT_ENABLE_PCINT11)
+#undef PCINT_ENABLE_PCINT11
+#endif
+#if defined(PCINT_ENABLE_PCINT12)
+#undef PCINT_ENABLE_PCINT12
+#endif
+#if defined(PCINT_ENABLE_PCINT13)
+#undef PCINT_ENABLE_PCINT13
+#endif
+#if defined(PCINT_ENABLE_PCINT14)
+#undef PCINT_ENABLE_PCINT14
+#endif
+#if defined(PCINT_ENABLE_PCINT15)
+#undef PCINT_ENABLE_PCINT15
+#endif
+#endif
+
+#if !defined(PCINT_ENABLE_PORT2)
+#if defined(PCINT_ENABLE_PCINT16)
+#undef PCINT_ENABLE_PCINT16
+#endif
+#if defined(PCINT_ENABLE_PCINT17)
+#undef PCINT_ENABLE_PCINT17
+#endif
+#if defined(PCINT_ENABLE_PCINT18)
+#undef PCINT_ENABLE_PCINT18
+#endif
+#if defined(PCINT_ENABLE_PCINT19)
+#undef PCINT_ENABLE_PCINT19
+#endif
+#if defined(PCINT_ENABLE_PCINT20)
+#undef PCINT_ENABLE_PCINT20
+#endif
+#if defined(PCINT_ENABLE_PCINT21)
+#undef PCINT_ENABLE_PCINT21
+#endif
+#if defined(PCINT_ENABLE_PCINT22)
+#undef PCINT_ENABLE_PCINT22
+#endif
+#if defined(PCINT_ENABLE_PCINT23)
+#undef PCINT_ENABLE_PCINT23
+#endif
+#endif
+
+#if !defined(PCINT_ENABLE_PORT3)
+#if defined(PCINT_ENABLE_PCINT24)
+#undef PCINT_ENABLE_PCINT24
+#endif
+#if defined(PCINT_ENABLE_PCINT25)
+#undef PCINT_ENABLE_PCINT25
+#endif
+#if defined(PCINT_ENABLE_PCINT26)
+#undef PCINT_ENABLE_PCINT26
+#endif
+#if defined(PCINT_ENABLE_PCINT27)
+#undef PCINT_ENABLE_PCINT27
+#endif
+#if defined(PCINT_ENABLE_PCINT28)
+#undef PCINT_ENABLE_PCINT28
+#endif
+#if defined(PCINT_ENABLE_PCINT29)
+#undef PCINT_ENABLE_PCINT29
+#endif
+#if defined(PCINT_ENABLE_PCINT30)
+#undef PCINT_ENABLE_PCINT30
+#endif
+#if defined(PCINT_ENABLE_PCINT31)
+#undef PCINT_ENABLE_PCINT31
+#endif
+#endif
+
+
+//================================================================================
+// Hardware Definitions
+//================================================================================
+
+#if defined(PCINT0_vect)
+#define PCINT_HAS_PORT0 true
+#else
+#define PCINT_HAS_PORT0 false
+#endif
+#if defined(PCINT1_vect)
+#define PCINT_HAS_PORT1 true
+#else
+#define PCINT_HAS_PORT1 false
+#endif
+#if defined(PCINT2_vect)
+#define PCINT_HAS_PORT2 true
+#else
+#define PCINT_HAS_PORT2 false
+#endif
+#if defined(PCINT3_vect)
+#define PCINT_HAS_PORT3 true
+#else
+#define PCINT_HAS_PORT3 false
+#endif
+
+// number of available ports
+#define PCINT_NUM_PORTS ( \
+PCINT_HAS_PORT0 + \
+PCINT_HAS_PORT1 + \
+PCINT_HAS_PORT2 + \
+PCINT_HAS_PORT3)
+
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#ifdef PCINT");
+Serial.println(i);
+Serial.print("#define PCINT_HAS_PCINT");
+Serial.print(i);
+Serial.println(" true");
+Serial.println("#else");
+Serial.print("#define PCINT_HAS_PCINT");
+Serial.print(i);
+Serial.println(" false");
+Serial.println("#endif");
+}
+*/
+#ifdef PCINT0
+#define PCINT_HAS_PCINT0 true
+#else
+#define PCINT_HAS_PCINT0 false
+#endif
+#ifdef PCINT1
+#define PCINT_HAS_PCINT1 true
+#else
+#define PCINT_HAS_PCINT1 false
+#endif
+#ifdef PCINT2
+#define PCINT_HAS_PCINT2 true
+#else
+#define PCINT_HAS_PCINT2 false
+#endif
+#ifdef PCINT3
+#define PCINT_HAS_PCINT3 true
+#else
+#define PCINT_HAS_PCINT3 false
+#endif
+#ifdef PCINT4
+#define PCINT_HAS_PCINT4 true
+#else
+#define PCINT_HAS_PCINT4 false
+#endif
+#ifdef PCINT5
+#define PCINT_HAS_PCINT5 true
+#else
+#define PCINT_HAS_PCINT5 false
+#endif
+#ifdef PCINT6
+#define PCINT_HAS_PCINT6 true
+#else
+#define PCINT_HAS_PCINT6 false
+#endif
+#ifdef PCINT7
+#define PCINT_HAS_PCINT7 true
+#else
+#define PCINT_HAS_PCINT7 false
+#endif
+#ifdef PCINT8
+#define PCINT_HAS_PCINT8 true
+#else
+#define PCINT_HAS_PCINT8 false
+#endif
+#ifdef PCINT9
+#define PCINT_HAS_PCINT9 true
+#else
+#define PCINT_HAS_PCINT9 false
+#endif
+#ifdef PCINT10
+#define PCINT_HAS_PCINT10 true
+#else
+#define PCINT_HAS_PCINT10 false
+#endif
+#ifdef PCINT11
+#define PCINT_HAS_PCINT11 true
+#else
+#define PCINT_HAS_PCINT11 false
+#endif
+#ifdef PCINT12
+#define PCINT_HAS_PCINT12 true
+#else
+#define PCINT_HAS_PCINT12 false
+#endif
+#ifdef PCINT13
+#define PCINT_HAS_PCINT13 true
+#else
+#define PCINT_HAS_PCINT13 false
+#endif
+#ifdef PCINT14
+#define PCINT_HAS_PCINT14 true
+#else
+#define PCINT_HAS_PCINT14 false
+#endif
+#ifdef PCINT15
+#define PCINT_HAS_PCINT15 true
+#else
+#define PCINT_HAS_PCINT15 false
+#endif
+#ifdef PCINT16
+#define PCINT_HAS_PCINT16 true
+#else
+#define PCINT_HAS_PCINT16 false
+#endif
+#ifdef PCINT17
+#define PCINT_HAS_PCINT17 true
+#else
+#define PCINT_HAS_PCINT17 false
+#endif
+#ifdef PCINT18
+#define PCINT_HAS_PCINT18 true
+#else
+#define PCINT_HAS_PCINT18 false
+#endif
+#ifdef PCINT19
+#define PCINT_HAS_PCINT19 true
+#else
+#define PCINT_HAS_PCINT19 false
+#endif
+#ifdef PCINT20
+#define PCINT_HAS_PCINT20 true
+#else
+#define PCINT_HAS_PCINT20 false
+#endif
+#ifdef PCINT21
+#define PCINT_HAS_PCINT21 true
+#else
+#define PCINT_HAS_PCINT21 false
+#endif
+#ifdef PCINT22
+#define PCINT_HAS_PCINT22 true
+#else
+#define PCINT_HAS_PCINT22 false
+#endif
+#ifdef PCINT23
+#define PCINT_HAS_PCINT23 true
+#else
+#define PCINT_HAS_PCINT23 false
+#endif
+#ifdef PCINT24
+#define PCINT_HAS_PCINT24 true
+#else
+#define PCINT_HAS_PCINT24 false
+#endif
+#ifdef PCINT25
+#define PCINT_HAS_PCINT25 true
+#else
+#define PCINT_HAS_PCINT25 false
+#endif
+#ifdef PCINT26
+#define PCINT_HAS_PCINT26 true
+#else
+#define PCINT_HAS_PCINT26 false
+#endif
+#ifdef PCINT27
+#define PCINT_HAS_PCINT27 true
+#else
+#define PCINT_HAS_PCINT27 false
+#endif
+#ifdef PCINT28
+#define PCINT_HAS_PCINT28 true
+#else
+#define PCINT_HAS_PCINT28 false
+#endif
+#ifdef PCINT29
+#define PCINT_HAS_PCINT29 true
+#else
+#define PCINT_HAS_PCINT29 false
+#endif
+#ifdef PCINT30
+#define PCINT_HAS_PCINT30 true
+#else
+#define PCINT_HAS_PCINT30 false
+#endif
+#ifdef PCINT31
+#define PCINT_HAS_PCINT31 true
+#else
+#define PCINT_HAS_PCINT31 false
+#endif
+
+
+// count numbers of available pins on each port
+/*
+for (int port = 0; port < 4; port++) {
+Serial.print("#define PCINT_NUM_PINS_PORT");
+Serial.print(port);
+Serial.println(" ( \\");
+for (int i = 0; i < 8; i++) {
+Serial.print("PCINT_HAS_PCINT");
+Serial.print(port * 8 + i);
+if (i != 7)
+Serial.println(" + \\");
+}
+Serial.println(")");
+Serial.println();
+}
+*/
+#define PCINT_NUM_PINS_PORT0 ( \
+PCINT_HAS_PCINT0 + \
+PCINT_HAS_PCINT1 + \
+PCINT_HAS_PCINT2 + \
+PCINT_HAS_PCINT3 + \
+PCINT_HAS_PCINT4 + \
+PCINT_HAS_PCINT5 + \
+PCINT_HAS_PCINT6 + \
+PCINT_HAS_PCINT7)
+
+#define PCINT_NUM_PINS_PORT1 ( \
+PCINT_HAS_PCINT8 + \
+PCINT_HAS_PCINT9 + \
+PCINT_HAS_PCINT10 + \
+PCINT_HAS_PCINT11 + \
+PCINT_HAS_PCINT12 + \
+PCINT_HAS_PCINT13 + \
+PCINT_HAS_PCINT14 + \
+PCINT_HAS_PCINT15)
+
+#define PCINT_NUM_PINS_PORT2 ( \
+PCINT_HAS_PCINT16 + \
+PCINT_HAS_PCINT17 + \
+PCINT_HAS_PCINT18 + \
+PCINT_HAS_PCINT19 + \
+PCINT_HAS_PCINT20 + \
+PCINT_HAS_PCINT21 + \
+PCINT_HAS_PCINT22 + \
+PCINT_HAS_PCINT23)
+
+#define PCINT_NUM_PINS_PORT3 ( \
+PCINT_HAS_PCINT24 + \
+PCINT_HAS_PCINT25 + \
+PCINT_HAS_PCINT26 + \
+PCINT_HAS_PCINT27 + \
+PCINT_HAS_PCINT28 + \
+PCINT_HAS_PCINT29 + \
+PCINT_HAS_PCINT30 + \
+PCINT_HAS_PCINT31)
+
+
+// number of available hardware pins
+#define EXTERNAL_NUM_PINCHANGEINTERRUPT ( \
+PCINT_NUM_PINS_PORT0 + \
+PCINT_NUM_PINS_PORT1 + \
+PCINT_NUM_PINS_PORT2 + \
+PCINT_NUM_PINS_PORT3)
+
+
+//================================================================================
+// Used Pins
+//================================================================================
+
+// check if pins are physically available and enabled
+/*
+for (int i = 0; i < 32; i++) {
+Serial.print("#if (PCINT_HAS_PCINT");
+Serial.print(i);
+Serial.print(" == true) && defined(PCINT_ENABLE_PCINT");
+Serial.print(i);
+Serial.println(")");
+Serial.print("#define PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" true");
+Serial.println("#else");
+Serial.print("#define PCINT_USE_PCINT");
+Serial.print(i);
+Serial.println(" false");
+Serial.println("#endif");
+}
+*/
+#if (PCINT_HAS_PCINT0 == true) && defined(PCINT_ENABLE_PCINT0)
+#define PCINT_USE_PCINT0 true
+#else
+#define PCINT_USE_PCINT0 false
+#endif
+#if (PCINT_HAS_PCINT1 == true) && defined(PCINT_ENABLE_PCINT1)
+#define PCINT_USE_PCINT1 true
+#else
+#define PCINT_USE_PCINT1 false
+#endif
+#if (PCINT_HAS_PCINT2 == true) && defined(PCINT_ENABLE_PCINT2)
+#define PCINT_USE_PCINT2 true
+#else
+#define PCINT_USE_PCINT2 false
+#endif
+#if (PCINT_HAS_PCINT3 == true) && defined(PCINT_ENABLE_PCINT3)
+#define PCINT_USE_PCINT3 true
+#else
+#define PCINT_USE_PCINT3 false
+#endif
+#if (PCINT_HAS_PCINT4 == true) && defined(PCINT_ENABLE_PCINT4)
+#define PCINT_USE_PCINT4 true
+#else
+#define PCINT_USE_PCINT4 false
+#endif
+#if (PCINT_HAS_PCINT5 == true) && defined(PCINT_ENABLE_PCINT5)
+#define PCINT_USE_PCINT5 true
+#else
+#define PCINT_USE_PCINT5 false
+#endif
+#if (PCINT_HAS_PCINT6 == true) && defined(PCINT_ENABLE_PCINT6)
+#define PCINT_USE_PCINT6 true
+#else
+#define PCINT_USE_PCINT6 false
+#endif
+#if (PCINT_HAS_PCINT7 == true) && defined(PCINT_ENABLE_PCINT7)
+#define PCINT_USE_PCINT7 true
+#else
+#define PCINT_USE_PCINT7 false
+#endif
+#if (PCINT_HAS_PCINT8 == true) && defined(PCINT_ENABLE_PCINT8)
+#define PCINT_USE_PCINT8 true
+#else
+#define PCINT_USE_PCINT8 false
+#endif
+#if (PCINT_HAS_PCINT9 == true) && defined(PCINT_ENABLE_PCINT9)
+#define PCINT_USE_PCINT9 true
+#else
+#define PCINT_USE_PCINT9 false
+#endif
+#if (PCINT_HAS_PCINT10 == true) && defined(PCINT_ENABLE_PCINT10)
+#define PCINT_USE_PCINT10 true
+#else
+#define PCINT_USE_PCINT10 false
+#endif
+#if (PCINT_HAS_PCINT11 == true) && defined(PCINT_ENABLE_PCINT11)
+#define PCINT_USE_PCINT11 true
+#else
+#define PCINT_USE_PCINT11 false
+#endif
+#if (PCINT_HAS_PCINT12 == true) && defined(PCINT_ENABLE_PCINT12)
+#define PCINT_USE_PCINT12 true
+#else
+#define PCINT_USE_PCINT12 false
+#endif
+#if (PCINT_HAS_PCINT13 == true) && defined(PCINT_ENABLE_PCINT13)
+#define PCINT_USE_PCINT13 true
+#else
+#define PCINT_USE_PCINT13 false
+#endif
+#if (PCINT_HAS_PCINT14 == true) && defined(PCINT_ENABLE_PCINT14)
+#define PCINT_USE_PCINT14 true
+#else
+#define PCINT_USE_PCINT14 false
+#endif
+#if (PCINT_HAS_PCINT15 == true) && defined(PCINT_ENABLE_PCINT15)
+#define PCINT_USE_PCINT15 true
+#else
+#define PCINT_USE_PCINT15 false
+#endif
+#if (PCINT_HAS_PCINT16 == true) && defined(PCINT_ENABLE_PCINT16)
+#define PCINT_USE_PCINT16 true
+#else
+#define PCINT_USE_PCINT16 false
+#endif
+#if (PCINT_HAS_PCINT17 == true) && defined(PCINT_ENABLE_PCINT17)
+#define PCINT_USE_PCINT17 true
+#else
+#define PCINT_USE_PCINT17 false
+#endif
+#if (PCINT_HAS_PCINT18 == true) && defined(PCINT_ENABLE_PCINT18)
+#define PCINT_USE_PCINT18 true
+#else
+#define PCINT_USE_PCINT18 false
+#endif
+#if (PCINT_HAS_PCINT19 == true) && defined(PCINT_ENABLE_PCINT19)
+#define PCINT_USE_PCINT19 true
+#else
+#define PCINT_USE_PCINT19 false
+#endif
+#if (PCINT_HAS_PCINT20 == true) && defined(PCINT_ENABLE_PCINT20)
+#define PCINT_USE_PCINT20 true
+#else
+#define PCINT_USE_PCINT20 false
+#endif
+#if (PCINT_HAS_PCINT21 == true) && defined(PCINT_ENABLE_PCINT21)
+#define PCINT_USE_PCINT21 true
+#else
+#define PCINT_USE_PCINT21 false
+#endif
+#if (PCINT_HAS_PCINT22 == true) && defined(PCINT_ENABLE_PCINT22)
+#define PCINT_USE_PCINT22 true
+#else
+#define PCINT_USE_PCINT22 false
+#endif
+#if (PCINT_HAS_PCINT23 == true) && defined(PCINT_ENABLE_PCINT23)
+#define PCINT_USE_PCINT23 true
+#else
+#define PCINT_USE_PCINT23 false
+#endif
+#if (PCINT_HAS_PCINT24 == true) && defined(PCINT_ENABLE_PCINT24)
+#define PCINT_USE_PCINT24 true
+#else
+#define PCINT_USE_PCINT24 false
+#endif
+#if (PCINT_HAS_PCINT25 == true) && defined(PCINT_ENABLE_PCINT25)
+#define PCINT_USE_PCINT25 true
+#else
+#define PCINT_USE_PCINT25 false
+#endif
+#if (PCINT_HAS_PCINT26 == true) && defined(PCINT_ENABLE_PCINT26)
+#define PCINT_USE_PCINT26 true
+#else
+#define PCINT_USE_PCINT26 false
+#endif
+#if (PCINT_HAS_PCINT27 == true) && defined(PCINT_ENABLE_PCINT27)
+#define PCINT_USE_PCINT27 true
+#else
+#define PCINT_USE_PCINT27 false
+#endif
+#if (PCINT_HAS_PCINT28 == true) && defined(PCINT_ENABLE_PCINT28)
+#define PCINT_USE_PCINT28 true
+#else
+#define PCINT_USE_PCINT28 false
+#endif
+#if (PCINT_HAS_PCINT29 == true) && defined(PCINT_ENABLE_PCINT29)
+#define PCINT_USE_PCINT29 true
+#else
+#define PCINT_USE_PCINT29 false
+#endif
+#if (PCINT_HAS_PCINT30 == true) && defined(PCINT_ENABLE_PCINT30)
+#define PCINT_USE_PCINT30 true
+#else
+#define PCINT_USE_PCINT30 false
+#endif
+#if (PCINT_HAS_PCINT31 == true) && defined(PCINT_ENABLE_PCINT31)
+#define PCINT_USE_PCINT31 true
+#else
+#define PCINT_USE_PCINT31 false
+#endif
+
+
+//================================================================================
+// Number Used Pins
+//================================================================================
+
+// count numbers of used pins on each port
+/*
+for (int port = 0; port < 4; port++) {
+Serial.print("#define PCINT_NUM_USED_PINS_PORT");
+Serial.print(port);
+Serial.println(" ( \\");
+for (int i = 0; i < 8; i++) {
+Serial.print("PCINT_USE_PCINT");
+Serial.print(port * 8 + i);
+if (i != 7)
+Serial.println(" + \\");
+}
+Serial.println(")");
+Serial.println();
+}
+*/
+#define PCINT_NUM_USED_PINS_PORT0 ( \
+PCINT_USE_PCINT0 + \
+PCINT_USE_PCINT1 + \
+PCINT_USE_PCINT2 + \
+PCINT_USE_PCINT3 + \
+PCINT_USE_PCINT4 + \
+PCINT_USE_PCINT5 + \
+PCINT_USE_PCINT6 + \
+PCINT_USE_PCINT7)
+
+#define PCINT_NUM_USED_PINS_PORT1 ( \
+PCINT_USE_PCINT8 + \
+PCINT_USE_PCINT9 + \
+PCINT_USE_PCINT10 + \
+PCINT_USE_PCINT11 + \
+PCINT_USE_PCINT12 + \
+PCINT_USE_PCINT13 + \
+PCINT_USE_PCINT14 + \
+PCINT_USE_PCINT15)
+
+#define PCINT_NUM_USED_PINS_PORT2 ( \
+PCINT_USE_PCINT16 + \
+PCINT_USE_PCINT17 + \
+PCINT_USE_PCINT18 + \
+PCINT_USE_PCINT19 + \
+PCINT_USE_PCINT20 + \
+PCINT_USE_PCINT21 + \
+PCINT_USE_PCINT22 + \
+PCINT_USE_PCINT23)
+
+#define PCINT_NUM_USED_PINS_PORT3 ( \
+PCINT_USE_PCINT24 + \
+PCINT_USE_PCINT25 + \
+PCINT_USE_PCINT26 + \
+PCINT_USE_PCINT27 + \
+PCINT_USE_PCINT28 + \
+PCINT_USE_PCINT29 + \
+PCINT_USE_PCINT30 + \
+PCINT_USE_PCINT31)
+
+
+// number of used hardware pins
+#define EXTERNAL_NUM_USED_PINCHANGEINTERRUPT ( \
+PCINT_NUM_USED_PINS_PORT0 + \
+PCINT_NUM_USED_PINS_PORT1 + \
+PCINT_NUM_USED_PINS_PORT2 + \
+PCINT_NUM_USED_PINS_PORT3)
+
+//================================================================================
+// Used Ports
+//================================================================================
+
+// check if ports are used
+#if PCINT_NUM_USED_PINS_PORT0
+#define PCINT_USE_PORT0 true
+#else
+#define PCINT_USE_PORT0 false
+#endif
+#if PCINT_NUM_USED_PINS_PORT1
+#define PCINT_USE_PORT1 true
+#else
+#define PCINT_USE_PORT1 false
+#endif
+#if PCINT_NUM_USED_PINS_PORT2
+#define PCINT_USE_PORT2 true
+#else
+#define PCINT_USE_PORT2 false
+#endif
+#if PCINT_NUM_USED_PINS_PORT3
+#define PCINT_USE_PORT3 true
+#else
+#define PCINT_USE_PORT3 false
+#endif
+
+// number of used ports
+#define PCINT_NUM_USED_PORTS ( \
+PCINT_USE_PORT0 + \
+PCINT_USE_PORT1 + \
+PCINT_USE_PORT2 + \
+PCINT_USE_PORT3)
diff --git a/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h
new file mode 100644
index 0000000..c485b84
--- /dev/null
+++ b/Display Code/mbraidsv3/Libraries/PinChangeInterrupt/src/PinChangeInterruptSettings.h
@@ -0,0 +1,230 @@
+/*
+Copyright (c) 2014-2015 NicoHood
+See the readme for credit to other people.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+// include guard
+#pragma once
+
+//================================================================================
+// General Settings
+//================================================================================
+
+/* Settings to de/activate ports/pins
+This will save you flash and ram because the arrays
+are managed dynamically with the definitions below.
+Make sure you still have all needed ports activated.
+Each deactivated port saves 3 bytes of ram.
+If you deactivate the whole port,
+you dont need to deactivate the pins.
+Same for the port if you deactivate all 8 pins.
+You dont have to deactivate pins/ports that dont exist.
+That is done by the macros. */
+
+#ifndef PCINT_ENABLE_MANUAL
+
+#define PCINT_ENABLE_PORT0
+#define PCINT_ENABLE_PORT1
+#define PCINT_ENABLE_PORT2
+#define PCINT_ENABLE_PORT3
+
+#define PCINT_ENABLE_PCINT0
+#define PCINT_ENABLE_PCINT1
+#define PCINT_ENABLE_PCINT2
+#define PCINT_ENABLE_PCINT3
+#define PCINT_ENABLE_PCINT4
+#define PCINT_ENABLE_PCINT5
+#define PCINT_ENABLE_PCINT6
+#define PCINT_ENABLE_PCINT7
+#define PCINT_ENABLE_PCINT8
+#define PCINT_ENABLE_PCINT9
+#define PCINT_ENABLE_PCINT10
+#define PCINT_ENABLE_PCINT11
+#define PCINT_ENABLE_PCINT12
+#define PCINT_ENABLE_PCINT13
+#define PCINT_ENABLE_PCINT14
+#define PCINT_ENABLE_PCINT15
+#define PCINT_ENABLE_PCINT16
+#define PCINT_ENABLE_PCINT17
+#define PCINT_ENABLE_PCINT18
+#define PCINT_ENABLE_PCINT19
+#define PCINT_ENABLE_PCINT20
+#define PCINT_ENABLE_PCINT21
+#define PCINT_ENABLE_PCINT22
+#define PCINT_ENABLE_PCINT23
+#define PCINT_ENABLE_PCINT24
+#define PCINT_ENABLE_PCINT25
+#define PCINT_ENABLE_PCINT26
+#define PCINT_ENABLE_PCINT27
+#define PCINT_ENABLE_PCINT28
+#define PCINT_ENABLE_PCINT29
+#define PCINT_ENABLE_PCINT30
+#define PCINT_ENABLE_PCINT31
+
+#endif
+
+#ifdef ARDUINO
+// use API with function pointers (better optimized with .a linkage)
+#define PCINT_API
+
+// is the library compiled via .a file?
+// see readme for more information
+#define PCINT_ALINKAGE
+
+// force compile all enabled port ISRs (with .a linkage)
+//#define PCINT_COMPILE_ENABLED_ISR
+
+#endif
+
+//================================================================================
+// Suggested Settings
+//================================================================================
+
+// Arduino Uno (328)
+#if defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega88__)
+/* Reordering interrupt callbacks priority
+Port0 has SPI on higher pins, ordering is fine
+Port1 has I2C on higher pins, ordering is fine
+Port2 has USART and Pin Interrupt on lower pins,
+move the priority down
+Its more likely the user will use pin 4-7
+*/
+#if !defined(PCINT_CALLBACK_PORT2)
+#define PCINT_CALLBACK_PORT2 \
+PCINT_CALLBACK(4, 20); \
+PCINT_CALLBACK(5, 21); \
+PCINT_CALLBACK(6, 22); \
+PCINT_CALLBACK(7, 23); \
+PCINT_CALLBACK(0, 16); /* USART RX */ \
+PCINT_CALLBACK(1, 17); /* USART TX */ \
+PCINT_CALLBACK(2, 18); /* Pin Interrupt 0 */ \
+PCINT_CALLBACK(3, 19); /* Pin Interrupt 1 */
+#endif
+
+// deactivate crystal and reset pins by default
+#if defined(PCINT_ENABLE_PCINT6)
+#undef PCINT_ENABLE_PCINT6 // crystal
+#endif
+#if defined(PCINT_ENABLE_PCINT7)
+#undef PCINT_ENABLE_PCINT7 // crystal
+#endif
+#if defined(PCINT_ENABLE_PCINT14)
+#undef PCINT_ENABLE_PCINT14 // reset
+#endif
+#endif
+
+// Arduino Mega (2560)
+#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA)
+/* Port1 is structured a bit more complicated
+Also only 3 pins are connected on standard boards
+Seeeduino Mega has these pins optional!
+Disabling Port1 gives more speed and uses less flash
+Pins: 0(RX0), 14(TX3), 15(RX3) */
+#if defined(PCINT_ENABLE_PORT1)
+#undef PCINT_ENABLE_PORT1 // better performence
+#endif
+
+/* Reordering interrupt callbacks priority
+Port2 has SPI on lower pins, move the priority down
+Its more likely the user will use pin 10-13
+Port1 by default deactivated, ordering is fine
+Port2 only has ADCs, ordering is fine
+*/
+#if !defined(PCINT_CALLBACK_PORT0)
+#define PCINT_CALLBACK_PORT0 \
+PCINT_CALLBACK(4, 4); \
+PCINT_CALLBACK(5, 5); \
+PCINT_CALLBACK(6, 6); \
+PCINT_CALLBACK(7, 7); \
+PCINT_CALLBACK(0, 0); /* SPI SS */ \
+PCINT_CALLBACK(1, 1); /* SPI SCK */ \
+PCINT_CALLBACK(2, 2); /* SPI MISO */ \
+PCINT_CALLBACK(3, 3); /* SPI MOSI */
+#endif
+#endif
+
+// Arduino Leonardo/Micro (32u4)
+#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)
+/* Reordering interrupt callbacks priority
+Port0 has SPI on lower pins, move the priority down
+Its more likely the user will use pin 8-11 */
+#if !defined(PCINT_CALLBACK_PORT0)
+#define PCINT_CALLBACK_PORT0 \
+PCINT_CALLBACK(4, 4); \
+PCINT_CALLBACK(5, 5); \
+PCINT_CALLBACK(6, 6); \
+PCINT_CALLBACK(7, 7); \
+PCINT_CALLBACK(0, 0); /* SPI SS / RX LED */ \
+PCINT_CALLBACK(1, 1); /* SPI SCK */ \
+PCINT_CALLBACK(2, 2); /* SPI MISO */ \
+PCINT_CALLBACK(3, 3); /* SPI MOSI */
+#endif
+
+// RX LED on normal leonardo/micro
+#if defined(PCINT_ENABLE_PCINT0) && (defined(ARDUINO_AVR_LEONARDO) || defined(ARDUINO_AVR_MICRO))
+#undef PCINT_ENABLE_PCINT0
+#endif
+#endif
+
+// Hoodloader2 (u2 Series)
+#if defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)
+#if defined(ARDUINO_HOODLOADER2)
+// on HoodLoader2 Arduino boards only PB1-7 (port0) is broken out, save this flash
+#if defined(PCINT_ENABLE_PORT1)
+#undef PCINT_ENABLE_PORT1
+#endif
+
+// SS (PB0) is not connected on normal Arduino boards
+#if defined(PCINT_ENABLE_PCINT0)
+#undef PCINT_ENABLE_PCINT0
+#endif
+
+/* Reordering interrupt callbacks priority
+Port0 has SPI on lower pins, move the priority down
+Its more likely the user will use PB4-7
+Pretend the User has not soldered the 4 Pinheader
+so only do this for non Arduino boards. */
+#else
+#if !defined(PCINT_CALLBACK_PORT0)
+#define PCINT_CALLBACK_PORT0 \
+PCINT_CALLBACK(4, 4); \
+PCINT_CALLBACK(5, 5); \
+PCINT_CALLBACK(6, 6); \
+PCINT_CALLBACK(7, 7); \
+PCINT_CALLBACK(0, 0); /* SPI SS */ \
+PCINT_CALLBACK(1, 1); /* SPI SCK */ \
+PCINT_CALLBACK(2, 2); /* SPI MISO */ \
+PCINT_CALLBACK(3, 3); /* SPI MOSI */
+#endif
+#endif
+#endif
+
+/* Attiny 25/45/85 only has a very few pins
+activate all by default
+The order is also okay. */
+
+#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
+// Port1 is connected to reset, crystal and Pin Interrupt 0
+// Deactivate it by default
+#if defined(PCINT_ENABLE_PORT1)
+#undef PCINT_ENABLE_PORT1
+#endif
+#endif
diff --git a/Display Code/mbraidsv3/mbraidsv3.ino b/Display Code/mbraidsv3/mbraidsv3.ino
index 9ec54a9..b54d613 100644
--- a/Display Code/mbraidsv3/mbraidsv3.ino
+++ b/Display Code/mbraidsv3/mbraidsv3.ino
@@ -1,5 +1,5 @@
#include
-
+#include
#include
#include
#include
@@ -22,12 +22,17 @@ elapsedMillis sinceMux;
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
+constexpr int NUM_SEGMENTS = 14;
void setup() {
//char select inputs
- pinMode(2, INPUT);
- pinMode(3, INPUT);
- pinMode(4, INPUT);
- pinMode(5, INPUT);
+ pinMode(readIndex[0], INPUT);
+ attachPCINT(digitalPinToPCINT(readIndex[0]), dispcharISR0, RISING);
+ pinMode(readIndex[1], INPUT);
+ attachPCINT(digitalPinToPCINT(readIndex[1]), dispcharISR1, RISING);
+ pinMode(readIndex[2], INPUT);
+ attachPCINT(digitalPinToPCINT(readIndex[2]), dispcharISR2, RISING);
+ pinMode(readIndex[3], INPUT);
+ attachPCINT(digitalPinToPCINT(readIndex[3]), dispcharISR3, RISING);
//
pinMode(A0, INPUT); //mux in
pinMode(A1, OUTPUT); //s0
@@ -43,7 +48,6 @@ void setup() {
void loop()
{
- multiplexer();
if (sinceDisplay > 20)
{
testOutput();
@@ -149,4 +153,24 @@ void multiplexer()
digitalWrite(A4, muxCount & 0b1000);
inputDetect();
muxCount = (muxCount + 1) % 14;
+}
+
+inline void dispcharISR(int selected) {
+ for (uint8_t mux_count = 0; mux_count < NUM_SEGMENTS; mux_count++) {
+ PORTC = mux_count << 1;
+ bitWrite(character[selected], mux_count, PINC & 0b1);
+ }
+}
+
+void dispcharISR0(){
+ dispcharISR(0);
+}
+void dispcharISR1(){
+ dispcharISR(1);
+}
+void dispcharISR2(){
+ dispcharISR(2);
+}
+void dispcharISR3(){
+ dispcharISR(3);
}