-
Notifications
You must be signed in to change notification settings - Fork 0
examples(mcp23009e): Add practical usage examples. #74 #187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
ec1e494
feat(mcp23009e): Add SimonSays example sketch.
DumontALINE 0a91b67
feat(mcp23009e): Add ReactionTime example sketch.
DumontALINE ed52008
feat(mcp23009e): Add MelodyPlayer example sketch.
DumontALINE be56459
feat(mcp23009e): Add MorseDecoder example.
DumontALINE fc0433e
style(mcp23009e): Rename example sketches to snake_case.
DumontALINE 5fe8808
fix(mcp23009e): Fix melody_player setup and startup message.
DumontALINE ee26a74
fix(mcp23009e): Fix simon_game startup message.
DumontALINE 85eabb6
fix(mcp23009e): Fix morce_code startup message.
DumontALINE af0963a
fix(mcp23009e): Prevent early press from skewing reaction_time measur…
DumontALINE fa3446a
fix(mcp23009e): Simplify Morse decoder interaction.
Charly-sketch 3040ad2
docs(mcp23009e): Add examples in readme.
Charly-sketch File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
| // | ||
| // MorseDecoder — enter Morse code using the UP button on the D-PAD. | ||
| // A short UP press (< 300 ms) inputs a dot. | ||
| // A long UP press (>= 300 ms) inputs a dash. | ||
| // Press DOWN to decode the current Morse sequence. | ||
|
|
||
| #include <Arduino.h> | ||
| #include <MCP23009E.h> | ||
| #include <Wire.h> | ||
|
|
||
| #include <map> | ||
|
|
||
| constexpr uint32_t kDotThresholdMs = 300; | ||
| constexpr uint32_t kDebounceDelayMs = 50; | ||
|
|
||
| static const std::map<String, char> kMorseTable = { | ||
| {".-", 'A'}, {"-...", 'B'}, {"-.-.", 'C'}, {"-..", 'D'}, {".", 'E'}, {"..-.", 'F'}, | ||
| {"--.", 'G'}, {"....", 'H'}, {"..", 'I'}, {".---", 'J'}, {"-.-", 'K'}, {".-..", 'L'}, | ||
| {"--", 'M'}, {"-.", 'N'}, {"---", 'O'}, {".--.", 'P'}, {"--.-", 'Q'}, {".-.", 'R'}, | ||
| {"...", 'S'}, {"-", 'T'}, {"..-", 'U'}, {"...-", 'V'}, {".--", 'W'}, {"-..-", 'X'}, | ||
| {"-.--", 'Y'}, {"--..", 'Z'}, | ||
| }; | ||
|
|
||
| String code = ""; | ||
|
|
||
| bool upWasPressed = false; | ||
| uint32_t upPressStart = 0; | ||
|
|
||
| TwoWire internalI2C(I2C_INT_SDA, I2C_INT_SCL); | ||
| MCP23009E expander(internalI2C, RST_EXPANDER, MCP23009_I2C_ADDR, INT_EXPANDER); | ||
|
|
||
| void decodeMorse() { | ||
| if (code == "") { | ||
| Serial.println("No Morse code to decode."); | ||
| return; | ||
| } | ||
|
|
||
| auto it = kMorseTable.find(code); | ||
| if (it != kMorseTable.end()) { | ||
| Serial.print("Decoded: "); | ||
| Serial.println(it->second); | ||
| } else { | ||
| Serial.print("Unknown code: "); | ||
| Serial.println(code); | ||
| } | ||
|
|
||
| code = ""; | ||
| } | ||
|
|
||
| void setup() { | ||
| Serial.begin(115200); | ||
| while (!Serial && millis() < 2000) { | ||
| // Wait up to 2 s for the serial monitor. | ||
| } | ||
|
|
||
| internalI2C.begin(); | ||
| expander.begin(); | ||
|
|
||
| expander.setup(MCP23009_BTN_UP, MCP23009_DIR_INPUT, MCP23009_PULLUP); | ||
| expander.setup(MCP23009_BTN_DOWN, MCP23009_DIR_INPUT, MCP23009_PULLUP); | ||
|
|
||
| Serial.println("MorseDecoder"); | ||
| Serial.println("UP short press: dot"); | ||
| Serial.println("UP long press: dash"); | ||
| Serial.println("DOWN: decode current code"); | ||
| } | ||
|
|
||
| void loop() { | ||
| bool upPressed = expander.getLevel(MCP23009_BTN_UP) == MCP23009_LOGIC_LOW; | ||
| bool downPressed = expander.getLevel(MCP23009_BTN_DOWN) == MCP23009_LOGIC_LOW; | ||
|
|
||
| if (upPressed && !upWasPressed) { | ||
| upPressStart = millis(); | ||
| upWasPressed = true; | ||
| } | ||
|
|
||
| if (!upPressed && upWasPressed) { | ||
| uint32_t pressDuration = millis() - upPressStart; | ||
|
|
||
| if (pressDuration < kDotThresholdMs) { | ||
| code += "."; | ||
| Serial.println("Dot"); | ||
| } else { | ||
| code += "-"; | ||
| Serial.println("Dash"); | ||
| } | ||
|
|
||
| Serial.print("Current code: "); | ||
| Serial.println(code); | ||
|
|
||
| upWasPressed = false; | ||
| delay(kDebounceDelayMs); | ||
| } | ||
|
|
||
| if (downPressed) { | ||
| decodeMorse(); | ||
|
|
||
| while (expander.getLevel(MCP23009_BTN_DOWN) == MCP23009_LOGIC_LOW) { | ||
| delay(10); | ||
| } | ||
|
|
||
| delay(kDebounceDelayMs); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
Charly-sketch marked this conversation as resolved.
|
||
| // | ||
| // MelodyPlayer — play a different 8-bit melody on the on-board buzzer | ||
| // depending on which D-PAD button is pressed: UP plays Tetris, DOWN plays | ||
| // Mario, LEFT plays Zelda and RIGHT plays Pokemon. | ||
| // | ||
| // The MCP23009E sits on the STeaMi internal I2C bus, so spin up a | ||
| // dedicated TwoWire pointed at the variant pin macros and hand it to the | ||
| // driver. Open the serial monitor at 115200 baud to see the active button. | ||
|
|
||
| #include <Arduino.h> | ||
| #include <MCP23009E.h> | ||
| #include <Wire.h> | ||
|
|
||
| #include <functional> | ||
| #include <map> | ||
|
|
||
| #define NOTE_E4 330 | ||
| #define NOTE_G4 392 | ||
| #define NOTE_C5 523 | ||
| #define NOTE_E5 659 | ||
| #define NOTE_G5 784 | ||
| #define NOTE_A5 880 | ||
| #define NOTE_B5 988 | ||
| #define NOTE_F5 698 | ||
| #define NOTE_A4 440 | ||
| #define NOTE_F4 349 | ||
| #define NOTE_D5 587 | ||
| #define NOTE_B4 494 | ||
|
|
||
| int tetrisMelody[] = {NOTE_E5, NOTE_B4, NOTE_C5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_A4, | ||
| NOTE_A4, NOTE_C5, NOTE_E5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_C5, | ||
| NOTE_D5, NOTE_E5, NOTE_C5, NOTE_A4, NOTE_A4}; | ||
| int tetrisDurations[] = {200, 100, 100, 200, 100, 100, 200, 100, 100, 200, | ||
| 100, 100, 150, 100, 200, 200, 200, 200, 400}; | ||
|
|
||
| int marioMelody[] = {NOTE_E5, NOTE_E5, 0, NOTE_E5, 0, NOTE_C5, NOTE_E5, 0, NOTE_G5, 0, NOTE_G4, 0}; | ||
| int marioDurations[] = {150, 150, 150, 150, 150, 150, 150, 150, 300, 300, 300, 300}; | ||
|
|
||
| int zeldaMelody[] = {NOTE_A4, NOTE_F4, NOTE_C5, NOTE_A4, NOTE_F4, | ||
| NOTE_C5, NOTE_A4, NOTE_G4, NOTE_E4}; | ||
| int zeldaDurations[] = {300, 300, 400, 300, 300, 400, 200, 200, 600}; | ||
|
|
||
| int pokemonMelody[] = {NOTE_D5, NOTE_D5, NOTE_D5, NOTE_G4, NOTE_D5, NOTE_C5, NOTE_B4, | ||
| NOTE_A4, NOTE_G4, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_G4}; | ||
| int pokemonDurations[] = {200, 200, 200, 400, 200, 200, 200, 400, 200, 200, 200, 200, 600}; | ||
|
|
||
| void playTetris() { | ||
| for (int i = 0; i < 19; i++) { | ||
| tone(SPEAKER, tetrisMelody[i], tetrisDurations[i]); | ||
| delay(tetrisDurations[i] * 1.3); | ||
| noTone(SPEAKER); | ||
| } | ||
| } | ||
|
|
||
| void playPokemon() { | ||
| for (int i = 0; i < 13; i++) { | ||
| tone(SPEAKER, pokemonMelody[i], pokemonDurations[i]); | ||
| delay(pokemonDurations[i] * 1.3); | ||
| noTone(SPEAKER); | ||
| } | ||
| } | ||
|
|
||
| void playZelda() { | ||
| for (int i = 0; i < 9; i++) { | ||
| tone(SPEAKER, zeldaMelody[i], zeldaDurations[i]); | ||
| delay(zeldaDurations[i] * 1.3); | ||
| noTone(SPEAKER); | ||
| } | ||
| } | ||
|
|
||
| void playMario() { | ||
| for (int i = 0; i < 12; i++) { | ||
| if (marioMelody[i] == 0) { | ||
| noTone(SPEAKER); | ||
| } else { | ||
| tone(SPEAKER, marioMelody[i], marioDurations[i]); | ||
| } | ||
| delay(marioDurations[i] * 1.3); | ||
| noTone(SPEAKER); | ||
| } | ||
| } | ||
|
|
||
| static const std::map<uint8_t, std::function<void()>> kMelodies = { | ||
| {MCP23009_BTN_UP, playTetris}, | ||
| {MCP23009_BTN_DOWN, playMario}, | ||
| {MCP23009_BTN_LEFT, playZelda}, | ||
| {MCP23009_BTN_RIGHT, playPokemon}, | ||
| }; | ||
|
|
||
| TwoWire internalI2C(I2C_INT_SDA, I2C_INT_SCL); | ||
| MCP23009E expander(internalI2C, RST_EXPANDER, MCP23009_I2C_ADDR, INT_EXPANDER); | ||
|
|
||
| void setup() { | ||
| Serial.begin(115200); | ||
| while (!Serial && millis() < 2000) { | ||
| // Wait up to 2 s for a connected monitor — on the STeaMi USB CDC | ||
| // !Serial stays true until the host enumerates. | ||
| } | ||
|
|
||
| for (const auto& [pinNumber, melody] : kMelodies) { | ||
| expander.setup(pinNumber, MCP23009_DIR_INPUT, MCP23009_PULLUP); | ||
| } | ||
|
|
||
| internalI2C.begin(); | ||
| expander.begin(); | ||
|
|
||
| Serial.println("MusicPlayer — UP: Tetris, DOWN: Mario, LEFT: Zelda, RIGHT: Pokemon."); | ||
| } | ||
|
|
||
| void loop() { | ||
| for (const auto& [pinNumber, melody] : kMelodies) { | ||
| if (expander.getLevel(pinNumber) == MCP23009_LOGIC_LOW) { | ||
| melody(); | ||
|
Charly-sketch marked this conversation as resolved.
|
||
| break; | ||
| } | ||
| } | ||
| delay(100); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| // SPDX-License-Identifier: GPL-3.0-or-later | ||
|
Charly-sketch marked this conversation as resolved.
|
||
| // | ||
| // ReactionTime — measure how fast you press the D-PAD button after the | ||
| // red LED lights up. The LED turns on after a random delay between 300 | ||
| // and 1500 ms; your reaction time is printed to the serial monitor. | ||
| // | ||
| // The MCP23009E sits on the STeaMi internal I2C bus, so spin up a | ||
| // dedicated TwoWire pointed at the variant pin macros and hand it to the | ||
| // driver. Open the serial monitor at 115200 baud to see your results. | ||
|
|
||
| #include <Arduino.h> | ||
| #include <MCP23009E.h> | ||
| #include <Wire.h> | ||
|
|
||
| TwoWire internalI2C(I2C_INT_SDA, I2C_INT_SCL); | ||
| MCP23009E expander(internalI2C, RST_EXPANDER, MCP23009_I2C_ADDR, INT_EXPANDER); | ||
|
|
||
| void setup() { | ||
| Serial.begin(115200); | ||
| while (!Serial && millis() < 2000) { | ||
| } | ||
|
|
||
| internalI2C.begin(); | ||
| expander.begin(); | ||
|
Charly-sketch marked this conversation as resolved.
|
||
|
|
||
| expander.setup(MCP23009_BTN_UP, MCP23009_DIR_INPUT, MCP23009_PULLUP); | ||
|
|
||
| pinMode(LED_RED, OUTPUT); | ||
| randomSeed(analogRead(0)); | ||
| } | ||
|
|
||
| void loop() { | ||
| while (expander.getLevel(MCP23009_BTN_UP) == MCP23009_LOGIC_LOW) { | ||
| delay(10); | ||
| } | ||
|
|
||
| delay(random(300, 1500)); | ||
| digitalWrite(LED_RED, HIGH); | ||
| uint32_t startTime = millis(); | ||
| while (true) { | ||
| if (expander.getLevel(MCP23009_BTN_UP) == MCP23009_LOGIC_LOW) { | ||
|
Charly-sketch marked this conversation as resolved.
|
||
| uint32_t reactionTime = millis() - startTime; | ||
| digitalWrite(LED_RED, LOW); | ||
| Serial.println("Reaction time: " + String(reactionTime) + " ms"); | ||
| break; | ||
| } | ||
| } | ||
| delay(2000); | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.