├── library.properties ├── keywords.txt ├── examples ├── AlienDelay │ └── AlienDelay.ino ├── AlienState │ └── AlienState.ino ├── ButtonExample │ └── ButtonExample.ino ├── Instruments │ ├── Theremin │ │ └── Theremin.ino │ └── Cyclick │ │ └── Cyclick.ino ├── LdrExample │ └── LdrExample.ino ├── TemperatureExample │ └── TemperatureExample.ino ├── ScrollingText │ ├── ScrollingText.ino │ ├── font_bold.h │ └── font_thin.h ├── Pets │ ├── Mouse │ │ └── Mouse.ino │ ├── Cat │ │ └── Cat.ino │ ├── Robot │ │ └── Robot.ino │ ├── Dog │ │ └── Dog.ino │ ├── Monster │ │ └── Monster.ino │ └── Rabbit │ │ └── Rabbit.ino ├── Games │ ├── PushIt │ │ └── PushIt.ino │ ├── Snake │ │ └── Snake.ino │ ├── FlappyBird │ │ └── FlappyBird.ino │ └── DotDotRevolution │ │ └── DotDotRevolution.ino ├── ScrollingTextState │ ├── font_bold.h │ ├── font_thin.h │ └── ScrollingTextState.ino └── TheEye │ └── TheEye.ino ├── README.md └── src ├── Petduino.h └── Petduino.cpp /library.properties: -------------------------------------------------------------------------------- 1 | name=Petduino 2 | version=1.1.0 3 | author=Matt Brailsford aka Circuitbeard 4 | maintainer=Matt Brailsford aka Circuitbeard 5 | sentence=Arduino library for interacting with a Petduino. 6 | paragraph=Provides a collection of helper methods for creating animations, melodies and interactions with a Petduino. 7 | category=Device Control 8 | url=http://circuitbeard.co.uk/petduino/ 9 | architectures=* 10 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Petduino 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Petduino KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | update KEYWORD2 17 | setLed KEYWORD2 18 | toggleLed KEYWORD2 19 | getLed KEYWORD2 20 | getTemperature KEYWORD2 21 | getLightLevel KEYWORD2 22 | isBtn1Pressed KEYWORD2 23 | isBtn1Held KEYWORD2 24 | isBtn2Pressed KEYWORD2 25 | isBtn2Held KEYWORD2 26 | playTone KEYWORD2 27 | playMelody KEYWORD2 28 | stopTone KEYWORD2 29 | setScreenBrightness KEYWORD2 30 | fillScreen KEYWORD2 31 | clearScreen KEYWORD2 32 | drawRow KEYWORD2 33 | drawImage KEYWORD2 34 | playAnimation KEYWORD2 35 | stopAnimation KEYWORD2 36 | getState KEYWORD2 37 | setState KEYWORD2 38 | setNextState KEYWORD2 39 | wait KEYWORD2 40 | 41 | ####################################### 42 | # Constants (LITERAL1) 43 | ####################################### 44 | -------------------------------------------------------------------------------- /examples/AlienDelay/AlienDelay.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * AlienDelay.ino - Alien example using delay and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte alien1[8]={ 31 | B00011000, 32 | B00111100, 33 | B01111110, 34 | B11011011, 35 | B11111111, 36 | B01011010, 37 | B10000001, 38 | B01000010 39 | }; 40 | 41 | byte alien2[8]={ 42 | B00011000, 43 | B00111100, 44 | B01111110, 45 | B11011011, 46 | B11111111, 47 | B00100100, 48 | B01011010, 49 | B10100101 50 | }; 51 | 52 | Petduino pet = Petduino(); 53 | 54 | void setup() { 55 | 56 | // Setup Petduino 57 | pet.begin(); 58 | 59 | } 60 | 61 | void loop() { 62 | 63 | // Update pet 64 | pet.update(); 65 | 66 | // Alien1 67 | pet.drawImage(alien1); 68 | pet.playTone(200, 200); 69 | delay(1000); 70 | 71 | // Alien2 72 | pet.drawImage(alien2); 73 | pet.playTone(100, 200); 74 | delay(1000); 75 | 76 | } 77 | -------------------------------------------------------------------------------- /examples/AlienState/AlienState.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * AlienState.ino - Alien example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte alien1[8]={ 31 | B00011000, 32 | B00111100, 33 | B01111110, 34 | B11011011, 35 | B11111111, 36 | B01011010, 37 | B10000001, 38 | B01000010 39 | }; 40 | 41 | byte alien2[8]={ 42 | B00011000, 43 | B00111100, 44 | B01111110, 45 | B11011011, 46 | B11111111, 47 | B00100100, 48 | B01011010, 49 | B10100101 50 | }; 51 | 52 | #define ALIEN1_STATE 0 53 | #define ALIEN2_STATE 1 54 | 55 | Petduino pet = Petduino(); 56 | 57 | void setup() { 58 | 59 | // Setup Petduino 60 | pet.begin(); 61 | 62 | // Set initial state 63 | pet.setState(ALIEN1_STATE); 64 | 65 | } 66 | 67 | void loop() { 68 | 69 | // Update pet 70 | pet.update(); 71 | 72 | // Update display based on current state 73 | switch(pet.getState()){ 74 | 75 | case ALIEN1_STATE: 76 | pet.drawImage(alien1); 77 | pet.playTone(200, 200); 78 | pet.setNextState(ALIEN2_STATE, 1000); 79 | break; 80 | 81 | case ALIEN2_STATE: 82 | pet.drawImage(alien2); 83 | pet.playTone(100, 200); 84 | pet.setNextState(ALIEN1_STATE, 1000); 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Petduino 2 | Provides a collection of helper methods for creating animations, melodies and interactions with a Petduino. 3 | 4 | ## Installation 5 | 1. Download and install the latest version of the [Arduino IDE](http://www.arduino.cc/en/main/software). 6 | 2. Download and install the latest [CH340G chip drivers](http://www.wch.cn/downloads.php?name=pro&proid=65). 7 | 3. Download the latest [LedControl arduino library](https://github.com/wayoda/LedControl/releases). 8 | 4. Install the LedControl library using [the standard Arduino library install procedure](http://www.arduino.cc/en/Guide/Libraries#.UwxndHX5PtY). 9 | 5. Download the latest Petduino library from the [Releases page](https://github.com/circuitbeard/petduino/releases). 10 | 6. Install this library using [the standard Arduino library install procedure](http://www.arduino.cc/en/Guide/Libraries#.UwxndHX5PtY). 11 | 12 | ## Getting Started 13 | Every Petduino project starts with the same basic code structure. 14 | 15 | #include 16 | #include 17 | 18 | Petduino pet = Petduino(); 19 | 20 | void setup() { 21 | 22 | // Setup Petduino 23 | pet.begin(); 24 | 25 | } 26 | 27 | void loop() { 28 | 29 | // Update pet 30 | pet.update(); 31 | 32 | // Do your thing... 33 | 34 | } 35 | 36 | From here Petduino exposes a number of methods to help you handle interactions from your Petduinos various inputs, methods to help you draw graphics to the Petduinos display and a simple state manager to help create non blocking animations. 37 | 38 | To explore all the things you can do with your Petduino, checkout the various examples in the [examples folder](https://github.com/circuitbeard/petduino/tree/master/examples). 39 | 40 | ## Examples 41 | | Example | Description | 42 | | ------- | ----------- | 43 | | **AlienDelay** | Basic example to show rendering graphics to the display and playing simple tones. | 44 | | **AlienState** | The same as the AlienDelay example, however this time showing the use of Petduinos state manager to create not blocking animations. | 45 | | **ButtonExample** | Example project showing how to interact with the Petduinos buttons. | 46 | | **LdrExample** | Example of reading the Petduinos light level (LDR) sensor. | 47 | | **TemperatureExample** | Example of how to read the temperature from your Petduino. | 48 | | **ScrollingText** | Example of how to turn your Petduino into a scrolling text display. | 49 | | **TheEye** | Aadvanced example showing how to render dynamic grphics to the Petduinos display. | 50 | | **Pets** | A collection of simple pet face to give your Petduino instant personality and a starting point to add your own stamp. Incorporating animations, sounds and button inteactions. | 51 | | **Games** | A collection of games to show how you can do more with your Petduino than just animations. | 52 | | **Instruments** | A collection of musical instrument examples for the Petduino. | 53 | 54 | ## Contributing 55 | TODO 56 | -------------------------------------------------------------------------------- /examples/ButtonExample/ButtonExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * ButtonExample.ino - Button example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte question[8] = { 31 | B01111110, 32 | B11111111, 33 | B11000011, 34 | B00001110, 35 | B00011100, 36 | B00011000, 37 | B00000000, 38 | B00011000 39 | }; 40 | 41 | byte leftArrow[8] = { 42 | B00010000, 43 | B00110000, 44 | B01110000, 45 | B11111111, 46 | B11111111, 47 | B01110000, 48 | B00110000, 49 | B00010000 50 | }; 51 | 52 | byte rightArrow[8] = { 53 | B00001000, 54 | B00001100, 55 | B00001110, 56 | B11111111, 57 | B11111111, 58 | B00001110, 59 | B00001100, 60 | B00001000 61 | }; 62 | 63 | #define QUESTION_STATE 0 64 | #define LEFT_STATE 1 65 | #define RIGHT_STATE 2 66 | 67 | Petduino pet = Petduino(); 68 | 69 | void setup() { 70 | 71 | // Setup Petduino 72 | pet.begin(); 73 | 74 | // Set initial state 75 | pet.setState(QUESTION_STATE); 76 | 77 | } 78 | 79 | void loop() { 80 | 81 | // Update pet 82 | pet.update(); 83 | 84 | // Check button 1 85 | if(pet.isBtn1Pressed()) { 86 | pet.setState(LEFT_STATE); 87 | } 88 | 89 | // Check button 2 90 | if(pet.isBtn2Pressed()) { 91 | pet.setState(RIGHT_STATE); 92 | } 93 | 94 | // Handle current state 95 | switch(pet.getState()){ 96 | case QUESTION_STATE: 97 | pet.drawImage(question); 98 | pet.wait(); 99 | break; 100 | case LEFT_STATE: 101 | pet.drawImage(leftArrow); 102 | pet.setNextState(QUESTION_STATE, 1000); 103 | break; 104 | case RIGHT_STATE: 105 | pet.drawImage(rightArrow); 106 | pet.setNextState(QUESTION_STATE, 1000); 107 | break; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /examples/Instruments/Theremin/Theremin.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Theremin.ino - Theremin example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | int speed = 20; 31 | 32 | byte screen[8]; 33 | 34 | #define LOOP_STATE 0 35 | 36 | Petduino pet = Petduino(); 37 | 38 | void setup() { 39 | 40 | // Setup Petduino 41 | pet.begin(); 42 | 43 | // Set initial state 44 | pet.setState(LOOP_STATE); 45 | 46 | } 47 | 48 | void loop() { 49 | 50 | // Update pet 51 | pet.update(); 52 | 53 | 54 | // Update based on state 55 | switch(pet.getState()) { 56 | 57 | case LOOP_STATE: 58 | 59 | // Shift all screens bits left 60 | for(int r=0;r<8;r++){ 61 | screen[r] = screen[r] << 1; 62 | } 63 | 64 | // Only play a sound of a button is held down 65 | if(pet.isBtn1Held() || pet.isBtn2Held()){ 66 | 67 | // Sample light level 68 | int lightLevel = pet.getLightLevel(); 69 | 70 | // Play tone 71 | int toneToPlay = map(lightLevel, 0, 1023, 261, 524); 72 | pet.playTone(toneToPlay, speed); 73 | 74 | // Append level to screen 75 | int level = map(lightLevel, 0, 1023, 0, 8); 76 | for(int r=(8-level);r<8;r++) { 77 | screen[r] |= 1; 78 | } 79 | 80 | } 81 | 82 | // Draw screen 83 | pet.drawImage(screen); 84 | 85 | // Loop 86 | pet.setNextState(LOOP_STATE, speed); 87 | 88 | break; 89 | 90 | } 91 | 92 | } 93 | 94 | int wrap(int num, int numMax) { 95 | if(num < 0){ 96 | while(num < 0){ 97 | num += numMax; 98 | } 99 | return num; 100 | } else { 101 | return num % numMax; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /examples/LdrExample/LdrExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * LdrExample.ino - LDR example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #define FRAME_COUNT 8 31 | byte frames[FRAME_COUNT][8] = { 32 | { 33 | B00000000, 34 | B00000000, 35 | B00000000, 36 | B00000000, 37 | B00000000, 38 | B00000000, 39 | B00000000, 40 | B10000000 41 | }, 42 | { 43 | B00000000, 44 | B00000000, 45 | B00000000, 46 | B00000000, 47 | B00000000, 48 | B00000000, 49 | B01000000, 50 | B11000000 51 | }, 52 | { 53 | B00000000, 54 | B00000000, 55 | B00000000, 56 | B00000000, 57 | B00000000, 58 | B00100000, 59 | B01100000, 60 | B11100000 61 | }, 62 | { 63 | B00000000, 64 | B00000000, 65 | B00000000, 66 | B00000000, 67 | B00010000, 68 | B00110000, 69 | B01110000, 70 | B11110000 71 | }, 72 | { 73 | B00000000, 74 | B00000000, 75 | B00000000, 76 | B00001000, 77 | B00011000, 78 | B00111000, 79 | B01111000, 80 | B11111000 81 | }, 82 | { 83 | B00000000, 84 | B00000000, 85 | B00000100, 86 | B00001100, 87 | B00011100, 88 | B00111100, 89 | B01111100, 90 | B11111100 91 | }, 92 | { 93 | B00000000, 94 | B00000010, 95 | B00000110, 96 | B00001110, 97 | B00011110, 98 | B00111110, 99 | B01111110, 100 | B11111110 101 | }, 102 | { 103 | B00000001, 104 | B00000011, 105 | B00000111, 106 | B00001111, 107 | B00011111, 108 | B00111111, 109 | B01111111, 110 | B11111111 111 | } 112 | }; 113 | 114 | unsigned int currentFrame; 115 | 116 | Petduino pet = Petduino(); 117 | 118 | void setup() { 119 | 120 | // Setup Petduino 121 | pet.begin(); 122 | 123 | } 124 | 125 | void loop() { 126 | 127 | // Update pet 128 | pet.update(); 129 | 130 | // Map reading to a frame 131 | currentFrame = map(pet.getLightLevel(), 0, 1023, 0, FRAME_COUNT); 132 | 133 | // Draw the frame 134 | pet.drawImage(frames[currentFrame]); 135 | delay(200); 136 | 137 | } 138 | -------------------------------------------------------------------------------- /examples/TemperatureExample/TemperatureExample.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TemperatureExample.ino - Temperature example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #define NUMBER_COUNT 10 31 | byte numbers[NUMBER_COUNT][8] = { 32 | { 33 | B11100000, 34 | B10100000, 35 | B10100000, 36 | B10100000, 37 | B10100000, 38 | B10100000, 39 | B10100000, 40 | B11100000, 41 | }, 42 | { 43 | B01100000, 44 | B00100000, 45 | B00100000, 46 | B00100000, 47 | B00100000, 48 | B00100000, 49 | B00100000, 50 | B00100000, 51 | }, 52 | { 53 | B11100000, 54 | B00100000, 55 | B00100000, 56 | B11100000, 57 | B10000000, 58 | B10000000, 59 | B10000000, 60 | B11100000, 61 | }, 62 | { 63 | B11100000, 64 | B00100000, 65 | B00100000, 66 | B11100000, 67 | B00100000, 68 | B00100000, 69 | B00100000, 70 | B11100000, 71 | }, 72 | { 73 | B10100000, 74 | B10100000, 75 | B10100000, 76 | B11100000, 77 | B00100000, 78 | B00100000, 79 | B00100000, 80 | B00100000, 81 | }, 82 | { 83 | B11100000, 84 | B10000000, 85 | B10000000, 86 | B11100000, 87 | B00100000, 88 | B00100000, 89 | B00100000, 90 | B11100000, 91 | }, 92 | { 93 | B11100000, 94 | B10000000, 95 | B10000000, 96 | B11100000, 97 | B10100000, 98 | B10100000, 99 | B10100000, 100 | B11100000, 101 | }, 102 | { 103 | B11100000, 104 | B00100000, 105 | B00100000, 106 | B00100000, 107 | B00100000, 108 | B00100000, 109 | B00100000, 110 | B00100000, 111 | }, 112 | { 113 | B11100000, 114 | B10100000, 115 | B10100000, 116 | B11100000, 117 | B10100000, 118 | B10100000, 119 | B10100000, 120 | B11100000, 121 | }, 122 | { 123 | B11100000, 124 | B10100000, 125 | B10100000, 126 | B11100000, 127 | B00100000, 128 | B00100000, 129 | B00100000, 130 | B11100000, 131 | } 132 | }; 133 | 134 | float temp; 135 | unsigned int ones, tens; 136 | 137 | Petduino pet = Petduino(); 138 | 139 | void setup() { 140 | 141 | // Setup Petduino 142 | pet.begin(); 143 | 144 | } 145 | 146 | void loop() { 147 | 148 | // Update pet 149 | pet.update(); 150 | 151 | // Get the temperature 152 | temp = pet.getTemperature(); 153 | 154 | // Split the digits 155 | tens = temp/10; 156 | ones = temp-tens*10; 157 | 158 | // Generate & draw number graphic 159 | for(int b = 0; b < 8; b++){ 160 | pet.drawRow(b, numbers[tens][b] | numbers[ones][b] >> 4); 161 | } 162 | 163 | // Wait for a second 164 | delay(1000); 165 | 166 | } 167 | -------------------------------------------------------------------------------- /examples/ScrollingText/ScrollingText.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * ScrollingText.ino - Scrolling text example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include "font_thin.h" 31 | 32 | #define CHAR_HEIGHT 8 33 | #define BUFFER_SIZE CHAR_HEIGHT*2 34 | #define SCROLL_SPEED 75 35 | #define MIN_CHAR 0x20 36 | #define MAX_CHAR 0x7f 37 | 38 | const unsigned char scrollText[] PROGMEM = {"HELLO WORLD #CIRCUITBEARD 2015 \0"}; // Make sure you have enough space on the end to fill the buffer and ensure all chars scroll across screen 39 | unsigned long charBuffer[BUFFER_SIZE] = {0}; 40 | 41 | Petduino pet = Petduino(); 42 | 43 | void setup() { 44 | 45 | // Setup Petduino 46 | pet.begin(); 47 | 48 | } 49 | 50 | void loop() { 51 | 52 | // Call pet loop 53 | pet.update(); 54 | 55 | // Scroll message 56 | scrollMessage(scrollText); 57 | 58 | } 59 | 60 | // Scroll Message 61 | void scrollMessage(const unsigned char *messageString) { 62 | int counter = 0; 63 | int myChar=0; 64 | do { 65 | // read back a char 66 | myChar = pgm_read_byte_near(messageString + counter); 67 | if (myChar != 0){ 68 | loadCharIntoBuffer(myChar); 69 | } 70 | counter++; 71 | } 72 | while (myChar != 0); 73 | } 74 | 75 | // Load character into buffer 76 | void loadCharIntoBuffer(int ascii){ 77 | if (ascii >= MIN_CHAR && ascii <= MAX_CHAR){ 78 | for (int a=0; a 30 | 31 | class Petduino { 32 | 33 | protected: 34 | 35 | // Keywords 36 | #define DIN 12 37 | #define CS 11 38 | #define CLK 10 39 | #define LED 2 40 | #define BUZZER 3 41 | #define TMP 16 //A2 42 | #define BTN1 14 //A0 43 | #define BTN2 15 //A1 44 | #define LDR 17 //A3 45 | 46 | #define DEBOUNCE_TIME 10 //ms 47 | 48 | #define WAIT_INTERVAL_STATE 65535 //UInt Max 49 | #define WAIT_STATE 65534 //UInt Max - 1 50 | 51 | // Variables 52 | LedControl lc = LedControl(DIN, CLK, CS, 1); 53 | 54 | int btn1State = HIGH; 55 | int btn1LastState = HIGH; 56 | unsigned long btn1DebounceTimestamp; 57 | 58 | int btn2State = HIGH; 59 | int btn2LastState = HIGH; 60 | unsigned long btn2DebounceTimestamp; 61 | 62 | unsigned int* melodyFrequencies; 63 | unsigned long* melodyDurations; 64 | unsigned long melodyLength; 65 | unsigned long melodyLoopCount; 66 | unsigned long melodyIdx; 67 | unsigned long melodyTimestamp; 68 | unsigned long melodyLoopCounter; 69 | 70 | byte (*animFrames)[8]; 71 | unsigned long* animFrameDurations; 72 | unsigned long animLength; 73 | unsigned long animLoopCount; 74 | unsigned long animIdx; 75 | unsigned long animTimestamp; 76 | unsigned long animLoopCounter; 77 | 78 | unsigned int currentState; 79 | unsigned int nextState; 80 | unsigned long stateTimestamp; 81 | unsigned long stateInterval; 82 | 83 | // Methods 84 | bool stateIntervalExpired(); 85 | bool debounce(uint8_t pin, int &state, int &lastState, unsigned long &debounceTimestamp); 86 | 87 | void updateMelody(); 88 | void playMelodyTone(unsigned long idx); 89 | 90 | void updateAnimation(); 91 | void playAnimationFrame(unsigned long idx); 92 | 93 | public: 94 | 95 | Petduino(); 96 | 97 | // Methods 98 | virtual void begin(); 99 | virtual void update(); 100 | 101 | virtual void setLed(bool value); 102 | virtual void toggleLed(); 103 | virtual bool getLed(); 104 | 105 | virtual float getTemperature(); 106 | virtual int getLightLevel(); 107 | 108 | virtual bool isBtn1Pressed(); 109 | virtual bool isBtn1Held(); 110 | virtual bool isBtn2Pressed(); 111 | virtual bool isBtn2Held(); 112 | 113 | virtual void playTone(unsigned int frequency, unsigned long duration); 114 | virtual void playMelody(unsigned int frequencies[], unsigned long durations[], unsigned long length, unsigned long loopCount); 115 | virtual void stopTone(); 116 | 117 | virtual void setScreenBrightness(unsigned int level); 118 | virtual void fillScreen(); 119 | virtual void clearScreen(); 120 | virtual void drawRow(int row, byte val); 121 | virtual void drawImage(byte img[]); 122 | virtual void playAnimation(byte frames[][8], unsigned long frameDurations[], unsigned long length, unsigned long loopCount); 123 | virtual void stopAnimation(); 124 | 125 | virtual unsigned int getState(); 126 | virtual void setState(unsigned int state); 127 | virtual void setNextState(unsigned int state, unsigned long interval); 128 | virtual void wait(); 129 | 130 | }; 131 | 132 | #endif //Petduino.h 133 | -------------------------------------------------------------------------------- /examples/Instruments/Cyclick/Cyclick.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Cyclick.ino - Cyclick synth example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #define WAIT_ANIM_FRAMES 2 31 | byte waitF[WAIT_ANIM_FRAMES][8]={ 32 | { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }, 33 | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } 34 | }; 35 | unsigned long waitD[WAIT_ANIM_FRAMES] = { 300, 300 }; 36 | 37 | bool waiting = true; 38 | 39 | int cursorX = 0; 40 | int cursorY = 0; 41 | bool cursorFlash = false; 42 | 43 | int playHeadX = 0; 44 | int speed = 300; 45 | 46 | bool btn1Pressed = false; 47 | bool btn2Pressed = false; 48 | 49 | int tones[8] = { 261, 294, 329, 349, 392, 440, 493, 523 }; 50 | byte sequence[8]; 51 | byte screen[8]; 52 | 53 | #define WAIT_STATE 0 54 | #define LOOP_STATE 1 55 | 56 | Petduino pet = Petduino(); 57 | 58 | void setup() { 59 | 60 | // Setup Petduino 61 | pet.begin(); 62 | 63 | // Set initial state 64 | pet.setState(WAIT_STATE); 65 | 66 | } 67 | 68 | void loop() { 69 | 70 | // Update pet 71 | pet.update(); 72 | 73 | // Check buttons 74 | if(pet.isBtn1Pressed()){ 75 | if(waiting) { 76 | waiting = false; 77 | pet.stopAnimation(); 78 | pet.setState(LOOP_STATE); 79 | } else { 80 | btn1Pressed = true; 81 | } 82 | } 83 | 84 | if(pet.isBtn2Pressed()){ 85 | if(waiting) { 86 | waiting = false; 87 | pet.stopAnimation(); 88 | pet.setState(LOOP_STATE); 89 | } else { 90 | btn2Pressed = true; 91 | } 92 | } 93 | 94 | // Update based on state 95 | switch(pet.getState()) { 96 | 97 | case WAIT_STATE: 98 | 99 | pet.playAnimation(waitF, waitD, WAIT_ANIM_FRAMES, 1); 100 | pet.setNextState(WAIT_STATE, 600); 101 | break; 102 | 103 | case LOOP_STATE: 104 | 105 | // Clear the screen 106 | clearScreen(); 107 | 108 | // Handle key presses 109 | if(btn1Pressed && btn2Pressed) { 110 | bool isOn = sequence[cursorY] & (0x80 >> cursorX); 111 | for(int r=0;r<8;r++){ // Turn off all in column 112 | sequence[r] &= ~(0x80 >> cursorX); 113 | } 114 | if(!isOn){ // Turn on selected cell (if was previously off) 115 | sequence[cursorY] |= (0x80 >> cursorX); 116 | } 117 | } else if (btn1Pressed) { 118 | cursorY = wrap(cursorY + 1, 8); 119 | } else if (btn2Pressed) { 120 | cursorX = wrap(cursorX + 1, 8); 121 | } 122 | 123 | // Move playhead 124 | playHeadX = wrap(playHeadX + 1, 8); 125 | 126 | // Draw sequence 127 | for(int r=0; r<8;r++) { 128 | for(int c=0;c<8;c++) { 129 | if((r != cursorY || c != cursorX) && (sequence[r] & (0x80 >> c))){ 130 | screen[r] |= (0x80 >> c); 131 | } 132 | } 133 | } 134 | 135 | // Draw playhead & play notes 136 | for(int r=0;r<8;r++){ 137 | screen[r] ^= (0x80 >> playHeadX); 138 | if(sequence[r] & (0x80 >> playHeadX)) { 139 | pet.playTone(tones[r], speed); 140 | } 141 | } 142 | 143 | // Draw cursor 144 | if(cursorFlash) { 145 | screen[cursorY] |= (0x80 >> cursorX); 146 | } 147 | 148 | // Draw screen 149 | pet.drawImage(screen); 150 | 151 | // Flash cursor 152 | cursorFlash = !cursorFlash; 153 | 154 | // Reset btn presses 155 | btn1Pressed = false; 156 | btn2Pressed = false; 157 | 158 | // Loop 159 | pet.setNextState(LOOP_STATE, speed); 160 | 161 | break; 162 | 163 | } 164 | 165 | } 166 | 167 | void clearScreen() { 168 | for(unsigned int r=0;r<8;r++){ 169 | screen[r] = 0x00; 170 | } 171 | } 172 | 173 | int wrap(int num, int numMax) { 174 | if(num < 0){ 175 | while(num < 0){ 176 | num += numMax; 177 | } 178 | return num; 179 | } else { 180 | return num % numMax; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /examples/Pets/Mouse/Mouse.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Mouse.ino - Mouse example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte mouse[8]={ 31 | B00000000, 32 | B01100110, 33 | B01100110, 34 | B01000010, 35 | B10011001, 36 | B01011010, 37 | B10000001, 38 | B00011000 39 | }; 40 | 41 | byte mouseBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01100110, 45 | B00000000, 46 | B10011001, 47 | B01011010, 48 | B10000001, 49 | B00011000 50 | }; 51 | 52 | #define MOUSE_SPEAK_FRAMES 2 53 | byte mouseSpeakF[MOUSE_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01100110, 57 | B01100110, 58 | B01000010, 59 | B10011001, 60 | B01011010, 61 | B10000001, 62 | B00011100 63 | }, 64 | { 65 | B00000000, 66 | B01100110, 67 | B01100110, 68 | B01000010, 69 | B10011001, 70 | B01011010, 71 | B10000001, 72 | B00011000 73 | } 74 | }; 75 | unsigned long mouseSpeakD[MOUSE_SPEAK_FRAMES] = { 200, 200 }; 76 | 77 | #define MOUSE_SPEAK_TONES 2 78 | unsigned int mouseSpeakToneF[MOUSE_SPEAK_TONES] = { 1800, 0 }; 79 | unsigned long mouseSpeakToneD[MOUSE_SPEAK_TONES] = { 200, 200 }; 80 | 81 | #define MOUSE_LOOK_FRAMES 6 82 | byte mouseLookF[MOUSE_LOOK_FRAMES][8]= { 83 | { 84 | B00000000, 85 | B01100110, 86 | B01000010, 87 | B01100110, 88 | B10011001, 89 | B01011010, 90 | B10000001, 91 | B00011000 92 | }, 93 | { 94 | B00000000, 95 | B01000010, 96 | B01100110, 97 | B01100110, 98 | B10011001, 99 | B01011010, 100 | B10000001, 101 | B00011000 102 | }, 103 | { 104 | B00000000, 105 | B00100100, 106 | B01100110, 107 | B01100110, 108 | B10011001, 109 | B01011010, 110 | B10000001, 111 | B00011000 112 | }, 113 | { 114 | B00000000, 115 | B01100110, 116 | B00100100, 117 | B01100110, 118 | B10011001, 119 | B01011010, 120 | B10000001, 121 | B00011000 122 | }, 123 | { 124 | B00000000, 125 | B01100110, 126 | B01100110, 127 | B00100100, 128 | B10011001, 129 | B01011010, 130 | B10000001, 131 | B00011000 132 | }, 133 | { 134 | B00000000, 135 | B01100110, 136 | B01100110, 137 | B01000010, 138 | B10011001, 139 | B01011010, 140 | B10000001, 141 | B00011000 142 | } 143 | }; 144 | unsigned long mouseLookD[MOUSE_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100 }; 145 | 146 | #define DEFAULT_STATE 0 147 | #define BLINK_STATE 1 148 | #define LOOK_STATE 2 149 | #define SPEAK_STATE 3 150 | 151 | Petduino pet = Petduino(); 152 | 153 | void setup() { 154 | 155 | // Setup Petduino 156 | pet.begin(); 157 | 158 | // Set initial state 159 | pet.setState(DEFAULT_STATE); 160 | 161 | // Initialize random seed 162 | randomSeed(analogRead(0)); 163 | 164 | } 165 | 166 | void loop() { 167 | 168 | // Update pet 169 | pet.update(); 170 | 171 | // Check buttons 172 | if(pet.isBtn1Pressed()){ 173 | pet.setState(LOOK_STATE); 174 | } 175 | 176 | if(pet.isBtn2Pressed()){ 177 | pet.setState(SPEAK_STATE); 178 | } 179 | 180 | // Update display based on current state 181 | switch(pet.getState()){ 182 | 183 | case DEFAULT_STATE: 184 | if (random(0, 5) == 0) { 185 | pet.setState(BLINK_STATE); // Random blink 186 | } else if(random(0, 10) == 0) { 187 | pet.setState(SPEAK_STATE); // Random speak 188 | } else if(random(0, 5) == 0) { 189 | pet.setState(LOOK_STATE); // Random look 190 | } else { 191 | pet.drawImage(mouse); 192 | pet.setNextState(DEFAULT_STATE, 3000); 193 | } 194 | break; 195 | 196 | case BLINK_STATE: 197 | pet.drawImage(mouseBlink); 198 | pet.setNextState(DEFAULT_STATE, 100); 199 | break; 200 | 201 | case LOOK_STATE: 202 | pet.playAnimation(mouseLookF, mouseLookD, MOUSE_LOOK_FRAMES, 2); 203 | pet.setNextState(DEFAULT_STATE, 2000); 204 | break; 205 | 206 | case SPEAK_STATE: 207 | pet.playAnimation(mouseSpeakF, mouseSpeakD, MOUSE_SPEAK_FRAMES, 2); 208 | pet.playMelody(mouseSpeakToneF, mouseSpeakToneD, MOUSE_SPEAK_TONES, 2); 209 | pet.setNextState(DEFAULT_STATE, 2000); 210 | break; 211 | } 212 | 213 | } 214 | -------------------------------------------------------------------------------- /examples/Games/PushIt/PushIt.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * PushIt.ino - PushIt game example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | #define INTRO_ANIM_FRAMES 2 31 | byte introF[INTRO_ANIM_FRAMES][8]={ 32 | { 33 | B00100100, 34 | B00100100, 35 | B00100100, 36 | B00011000, 37 | B00000000, 38 | B00111100, 39 | B00111100, 40 | B11111111 41 | }, 42 | { 43 | B00100100, 44 | B00100100, 45 | B00100100, 46 | B00100100, 47 | B00100100, 48 | B00011000, 49 | B00111100, 50 | B11111111 51 | } 52 | }; 53 | unsigned long introD[INTRO_ANIM_FRAMES] = { 500, 500 }; 54 | 55 | #define NUMBER_COUNT 10 56 | byte numbers[NUMBER_COUNT][8] = { 57 | { 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0 }, 58 | { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 59 | { 0xE0, 0x20, 0x20, 0xE0, 0x80, 0x80, 0x80, 0xE0 }, 60 | { 0xE0, 0x20, 0x20, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 61 | { 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20 }, 62 | { 0xE0, 0x80, 0x80, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 63 | { 0xE0, 0x80, 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 64 | { 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 65 | { 0xE0, 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 66 | { 0xE0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0xE0 } 67 | }; 68 | 69 | unsigned int count = 0; 70 | unsigned int score = 0; 71 | bool gameReady = true; 72 | bool gameStarted = false; 73 | 74 | unsigned int scoreOnes; 75 | unsigned int scoreTens; 76 | 77 | #define INTRO_STATE 0 78 | #define GAME_START_STATE 1 79 | #define GAME_LOOP_STATE 2 80 | #define GAME_OVER_STATE 3 81 | 82 | Petduino pet = Petduino(); 83 | 84 | void setup() { 85 | 86 | Serial.begin(9600); 87 | 88 | // Setup Petduino 89 | pet.begin(); 90 | 91 | // Set initial state 92 | pet.setState(INTRO_STATE); 93 | 94 | } 95 | 96 | void loop() { 97 | 98 | // Update pet 99 | pet.update(); 100 | 101 | // Check buttons 102 | if(pet.isBtn1Pressed()){ 103 | if(gameReady){ 104 | pet.setState(GAME_START_STATE); 105 | } else if(gameStarted) { 106 | score++; 107 | } 108 | } 109 | 110 | if(pet.isBtn2Pressed()){ 111 | if(gameReady){ 112 | pet.setState(GAME_START_STATE); 113 | } else if(gameStarted) { 114 | score++; 115 | } 116 | } 117 | 118 | // Update based on state 119 | switch(pet.getState()) { 120 | 121 | case INTRO_STATE: 122 | 123 | // Stop any pevious games 124 | gameReady = true; 125 | 126 | // Show intro anim 127 | pet.playAnimation(introF, introD, INTRO_ANIM_FRAMES, 1); 128 | pet.setNextState(INTRO_STATE, 1000); // Wait for button press 129 | 130 | break; 131 | 132 | case GAME_START_STATE: 133 | 134 | // Flag game started 135 | gameReady = false; 136 | gameStarted = true; 137 | 138 | // Stop the intro animation 139 | pet.stopAnimation(); 140 | 141 | // Reset variables 142 | score = 0; 143 | count = 0; 144 | 145 | pet.setState(GAME_LOOP_STATE); 146 | break; 147 | 148 | case GAME_LOOP_STATE: 149 | 150 | if(count < 64) { 151 | 152 | count++; 153 | 154 | // Draw bubbles 155 | for(int r=0;r<8;r++){ 156 | byte row = 0x00; 157 | for(int c=0;c<8;c++){ 158 | if((r*8)+c > count){ 159 | row |= (0x80 >> c); 160 | } 161 | } 162 | pet.drawRow(r, row); 163 | } 164 | 165 | // Loop 166 | pet.setNextState(GAME_LOOP_STATE, 60); 167 | 168 | } else { 169 | 170 | gameStarted = false; 171 | pet.setState(GAME_OVER_STATE); 172 | 173 | } 174 | break; 175 | 176 | case GAME_OVER_STATE: 177 | 178 | // Split the score digits 179 | scoreTens = score/10; 180 | scoreOnes = score-scoreTens*10; 181 | 182 | // Generate & draw score number graphic 183 | for(int b = 0; b < 8; b++){ 184 | pet.drawRow(b, numbers[scoreTens][b] | numbers[scoreOnes][b] >> 4); 185 | } 186 | 187 | // Go back to intro 188 | pet.setNextState(INTRO_STATE, 5000); 189 | break; 190 | 191 | } 192 | 193 | } 194 | -------------------------------------------------------------------------------- /examples/Pets/Cat/Cat.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Cat.ino - Cat example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte cat[8]={ 31 | B00000000, 32 | B01100110, 33 | B01100110, 34 | B01000010, 35 | B10111101, 36 | B00011000, 37 | B01000010, 38 | B00111100 39 | }; 40 | 41 | byte catBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01100110, 45 | B00000000, 46 | B10111101, 47 | B00011000, 48 | B01000010, 49 | B00111100 50 | }; 51 | 52 | #define CAT_SPEAK_FRAMES 3 53 | byte catSpeakF[CAT_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01100110, 57 | B01100110, 58 | B01000010, 59 | B10111101, 60 | B00011000, 61 | B01111110, 62 | B00111100 63 | }, 64 | { 65 | B00000000, 66 | B01100110, 67 | B01100110, 68 | B01000010, 69 | B10111101, 70 | B00011000, 71 | B01011010, 72 | B00111100 73 | }, 74 | { 75 | B00000000, 76 | B01100110, 77 | B01100110, 78 | B01000010, 79 | B10111101, 80 | B00011000, 81 | B01000010, 82 | B00111100 83 | } 84 | }; 85 | unsigned long catSpeakD[CAT_SPEAK_FRAMES] = { 100, 900, 100 }; 86 | 87 | #define CAT_SPEAK_TONES 4 88 | unsigned int catSpeakToneF[CAT_SPEAK_TONES] = { 400, 200, 100, 50 }; 89 | unsigned long catSpeakToneD[CAT_SPEAK_TONES] = { 100, 100, 100, 700 }; 90 | 91 | #define CAT_LOOK_FRAMES 6 92 | byte catLookF[CAT_LOOK_FRAMES][8]= { 93 | { 94 | B00000000, 95 | B01100110, 96 | B01000010, 97 | B01100110, 98 | B10111101, 99 | B00011000, 100 | B01000010, 101 | B00111100 102 | }, 103 | { 104 | B00000000, 105 | B01000010, 106 | B01100110, 107 | B01100110, 108 | B10111101, 109 | B00011000, 110 | B01000010, 111 | B00111100 112 | }, 113 | { 114 | B00000000, 115 | B00100100, 116 | B01100110, 117 | B01100110, 118 | B10111101, 119 | B00011000, 120 | B01000010, 121 | B00111100 122 | }, 123 | { 124 | B00000000, 125 | B01100110, 126 | B00100100, 127 | B01100110, 128 | B10111101, 129 | B00011000, 130 | B01000010, 131 | B00111100 132 | }, 133 | { 134 | B00000000, 135 | B01100110, 136 | B01100110, 137 | B00100100, 138 | B10111101, 139 | B00011000, 140 | B01000010, 141 | B00111100 142 | }, 143 | { 144 | B00000000, 145 | B01100110, 146 | B01100110, 147 | B01000010, 148 | B10111101, 149 | B00011000, 150 | B01000010, 151 | B00111100 152 | } 153 | }; 154 | unsigned long catLookD[CAT_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100 }; 155 | 156 | #define DEFAULT_STATE 0 157 | #define BLINK_STATE 1 158 | #define LOOK_STATE 2 159 | #define SPEAK_STATE 3 160 | 161 | Petduino pet = Petduino(); 162 | 163 | void setup() { 164 | 165 | // Setup Petduino 166 | pet.begin(); 167 | 168 | // Set initial state 169 | pet.setState(DEFAULT_STATE); 170 | 171 | // Initialize random seed 172 | randomSeed(analogRead(0)); 173 | 174 | } 175 | 176 | void loop() { 177 | 178 | // Update pet 179 | pet.update(); 180 | 181 | // Check buttons 182 | if(pet.isBtn1Pressed()){ 183 | pet.setState(LOOK_STATE); 184 | } 185 | 186 | if(pet.isBtn2Pressed()){ 187 | pet.setState(SPEAK_STATE); 188 | } 189 | 190 | // Update display based on current state 191 | switch(pet.getState()){ 192 | 193 | case DEFAULT_STATE: 194 | if (random(0, 5) == 0) { 195 | pet.setState(BLINK_STATE); // Random blink 196 | } else if(random(0, 10) == 0) { 197 | pet.setState(SPEAK_STATE); // Random speak 198 | } else if(random(0, 5) == 0) { 199 | pet.setState(LOOK_STATE); // Random look 200 | } else { 201 | pet.drawImage(cat); 202 | pet.setNextState(DEFAULT_STATE, 3000); 203 | } 204 | break; 205 | 206 | case BLINK_STATE: 207 | pet.drawImage(catBlink); 208 | pet.setNextState(DEFAULT_STATE, 100); 209 | break; 210 | 211 | case LOOK_STATE: 212 | pet.playAnimation(catLookF, catLookD, CAT_LOOK_FRAMES, 2); 213 | pet.setNextState(DEFAULT_STATE, 2000); 214 | break; 215 | 216 | case SPEAK_STATE: 217 | pet.playAnimation(catSpeakF, catSpeakD, CAT_SPEAK_FRAMES, 1); 218 | pet.playMelody(catSpeakToneF, catSpeakToneD, CAT_SPEAK_TONES, 1); 219 | pet.setNextState(DEFAULT_STATE, 2000); 220 | break; 221 | } 222 | 223 | } 224 | -------------------------------------------------------------------------------- /examples/ScrollingText/font_bold.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char font[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5, // 5 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 3, //! 6 | 0xD8, 0xD8, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 6, //" 7 | 0x66, 0xFF, 0xFF, 0x66, 0x66, 0xFF, 0xFF, 0x66, 9, //# 8 | 0x7F, 0xFF, 0xD8, 0xFE, 0x7F, 0x1B, 0xFF, 0xFE, 9, //$ 9 | 0xE3, 0xE7, 0xEE, 0x1C, 0x38, 0x77, 0xE7, 0xC7, 9, //% 10 | 0x70, 0xF8, 0xD8, 0x73, 0xFF, 0xDE, 0xFF, 0x7B, 9, //& 11 | 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 3, //' 12 | 0x70, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xF0, 0x70, 5, //( 13 | 0xE0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0xF0, 0xE0, 5, //) 14 | 0xDB, 0xFF, 0x7E, 0x3C, 0x3C, 0x7E, 0xFF, 0xDB, 9, //* 15 | 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 9, //+ 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 3, //, 17 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 9, //- 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 3, //. 19 | 0x03, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC0, 9, /// 20 | 0x7E, 0xFF, 0xC3, 0xDB, 0xDB, 0xC3, 0xFF, 0x7E, 9, //0 21 | 0xE0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 5, //1 22 | 0xFE, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //2 23 | 0xFE, 0xFF, 0x03, 0x7E, 0x7F, 0x03, 0xFF, 0xFE, 9, //3 24 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7F, 0x03, 0x03, 0x03, 9, //4 25 | 0xFF, 0xFF, 0xC0, 0xFE, 0xFF, 0x03, 0xFF, 0xFE, 9, //5 26 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFF, 0xC3, 0xFF, 0x7E, 9, //6 27 | 0x7E, 0xFF, 0xC3, 0xC3, 0x03, 0x03, 0x03, 0x03, 9, //7 28 | 0x7E, 0xFF, 0xC3, 0x7E, 0xFF, 0xC3, 0xFF, 0x7E, 9, //8 29 | 0x7E, 0xFF, 0xC3, 0xFF, 0x7F, 0x03, 0xFF, 0xFE, 9, //9 30 | 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 3, //: 31 | 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x40, 3, //; 32 | 0x18, 0x38, 0x70, 0xE0, 0xE0, 0x70, 0x38, 0x18, 6, //< 33 | 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 9, //= 34 | 0xC0, 0xE0, 0x70, 0x38, 0x38, 0x70, 0xE0, 0xC0, 6, //> 35 | 0x7E, 0xFF, 0xC3, 0x1F, 0x1E, 0x00, 0x18, 0x18, 9, //? 36 | 0x7E, 0xFF, 0xC3, 0xDF, 0xDF, 0xDB, 0xFF, 0x7F, 9, //@ 37 | 0x7E, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //A 38 | 0xFE, 0xFF, 0xC3, 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 9, //B 39 | 0x7E, 0xFF, 0xC3, 0xC0, 0xC0, 0xC3, 0xFF, 0x7E, 9, //C 40 | 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFE, 9, //D 41 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xFF, 0x7F, 9, //E 42 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 9, //F 43 | 0x7F, 0xFF, 0xC0, 0xDF, 0xDF, 0xC3, 0xFF, 0x7F, 9, //G 44 | 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //H 45 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //I 46 | 0x03, 0x03, 0x03, 0x03, 0xC3, 0xC3, 0xFF, 0x7E, 9, //J 47 | 0xC3, 0xC3, 0xC3, 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 9, //K 48 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 9, //L 49 | 0x7E, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 9, //M 50 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 9, //N 51 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //O 52 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC0, 0xC0, 0xC0, 9, //P 53 | 0x7E, 0xFF, 0xC3, 0xC3, 0xCF, 0xCF, 0xFF, 0x7F, 9, //Q 54 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC3, 0xC3, 0xC3, 9, //R 55 | 0x7F, 0xFF, 0xC0, 0xFE, 0x7F, 0x03, 0xFF, 0xFE, 9, //S 56 | 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 9, //T 57 | 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //U 58 | 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x18, 9, //V 59 | 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x7E, 9, //W 60 | 0xC3, 0xC3, 0xC3, 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 9, //X 61 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 0x18, 0x18, 0x18, 9, //Y 62 | 0xFF, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //Z 63 | 0xF0, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xF0, 0xF0, 5, //[ 64 | 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 9, //(Backslash) 65 | 0xF0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0xF0, 0xF0, 5, //] 66 | 0x70, 0xF8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 6, //^ 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9, //_ 68 | 0xC0, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 4, //` 69 | 0x7E, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //a 70 | 0xFE, 0xFF, 0xC3, 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 9, //b 71 | 0x7E, 0xFF, 0xC3, 0xC0, 0xC0, 0xC3, 0xFF, 0x7E, 9, //c 72 | 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFE, 9, //d 73 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xFF, 0x7F, 9, //e 74 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 9, //f 75 | 0x7F, 0xFF, 0xC0, 0xDF, 0xDF, 0xC3, 0xFF, 0x7F, 9, //g 76 | 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //h 77 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //i 78 | 0x03, 0x03, 0x03, 0x03, 0xC3, 0xC3, 0xFF, 0x7E, 9, //j 79 | 0xC3, 0xC3, 0xC3, 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 9, //k 80 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 9, //l 81 | 0x7E, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 9, //m 82 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 9, //n 83 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //o 84 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC0, 0xC0, 0xC0, 9, //p 85 | 0x7E, 0xFF, 0xC3, 0xC3, 0xCF, 0xCF, 0xFF, 0x7F, 9, //q 86 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC3, 0xC3, 0xC3, 9, //r 87 | 0x7F, 0xFF, 0xC0, 0xFE, 0x7F, 0x03, 0xFF, 0xFE, 9, //s 88 | 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 9, //t 89 | 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //u 90 | 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x18, 9, //v 91 | 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x7E, 9, //w 92 | 0xC3, 0xC3, 0xC3, 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 9, //x 93 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 0x18, 0x18, 0x18, 9, //y 94 | 0xFF, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //z 95 | 0x38, 0x78, 0x60, 0xE0, 0xE0, 0x60, 0x78, 0x38, 6, //{ 96 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //| 97 | 0xE0, 0xF0, 0x30, 0x38, 0x38, 0x30, 0xF0, 0xE0, 6, //} 98 | 0x76, 0xFE, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 8, //~ 99 | 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 3 // 100 | }; 101 | -------------------------------------------------------------------------------- /examples/ScrollingText/font_thin.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char font[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5, // 5 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 2, //! 6 | 0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 4, //" 7 | 0x50, 0x50, 0xF8, 0x50, 0x50, 0xF8, 0x50, 0x50, 6, //# 8 | 0x20, 0x70, 0xA8, 0x70, 0x28, 0xA8, 0x70, 0x20, 6, //$ 9 | 0xC8, 0xD0, 0x10, 0x20, 0x20, 0x40, 0x58, 0x98, 6, //% 10 | 0x60, 0x90, 0xA0, 0x40, 0xA0, 0x90, 0x98, 0x60, 6, //& 11 | 0xC0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 3, //' 12 | 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x20, 4, //( 13 | 0x80, 0x40, 0x20, 0x20, 0x20, 0x20, 0x40, 0x80, 4, //) 14 | 0x00, 0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00, 6, //* 15 | 0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 6, //+ 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 2, //, 17 | 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 6, //- 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 2, //. 19 | 0x08, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 6, /// 20 | 0x70, 0x88, 0x98, 0xA8, 0xA8, 0xC8, 0x88, 0x70, 6, //0 21 | 0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //1 22 | 0x70, 0x88, 0x08, 0x30, 0x40, 0x80, 0x80, 0xF8, 6, //2 23 | 0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x88, 0x70, 6, //3 24 | 0x10, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10, 6, //4 25 | 0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x88, 0x70, 6, //5 26 | 0x70, 0x88, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x70, 6, //6 27 | 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 6, //7 28 | 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x88, 0x70, 6, //8 29 | 0x70, 0x88, 0x88, 0x78, 0x08, 0x08, 0x10, 0x60, 6, //9 30 | 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 2, //: 31 | 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 2, //; 32 | 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 5, //< 33 | 0x00, 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 6, //= 34 | 0x80, 0x40, 0x20, 0x10, 0x10, 0x20, 0x40, 0x80, 5, //> 35 | 0x70, 0x88, 0x08, 0x08, 0x30, 0x20, 0x00, 0x20, 6, //? 36 | 0x70, 0x88, 0xB8, 0xA8, 0xA8, 0xB8, 0x80, 0x70, 6, //@ 37 | 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x88, 6, //A 38 | 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0x88, 0xF0, 6, //B 39 | 0x70, 0x88, 0x80, 0x80, 0x80, 0x80, 0x88, 0x70, 6, //C 40 | 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0, 6, //D 41 | 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0xF8, 6, //E 42 | 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x80, 6, //F 43 | 0x70, 0x88, 0x80, 0x80, 0xB8, 0x88, 0x88, 0x78, 6, //G 44 | 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x88, 6, //H 45 | 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //I 46 | 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 6, //J 47 | 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88, 0x88, 6, //K 48 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8, 6, //L 49 | 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88, 0x88, 6, //M 50 | 0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x88, 6, //N 51 | 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 6, //O 52 | 0xF0, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80, 6, //P 53 | 0x70, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68, 6, //Q 54 | 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88, 0x88, 6, //R 55 | 0x70, 0x88, 0x80, 0x70, 0x08, 0x08, 0x88, 0x70, 6, //S 56 | 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 6, //T 57 | 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 6, //U 58 | 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 6, //V 59 | 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0xA8, 0x50, 6, //W 60 | 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x88, 6, //X 61 | 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, 6, //Y 62 | 0xF8, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80, 0xF8, 6, //Z 63 | 0xE0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xE0, 4, //[ 64 | 0x80, 0x80, 0x40, 0x20, 0x20, 0x10, 0x08, 0x08, 6, //(Backslash) 65 | 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0, 4, //] 66 | 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 6, //^ 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 6, //_ 68 | 0xC0, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 3, //` 69 | 0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78, 6, //a 70 | 0x80, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0, 6, //b 71 | 0x00, 0x00, 0x00, 0x78, 0x80, 0x80, 0x80, 0x78, 6, //c 72 | 0x08, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78, 6, //d 73 | 0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70, 6, //e 74 | 0x30, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 5, //f 75 | 0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70, 6, //g 76 | 0x80, 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88, 6, //h 77 | 0x00, 0x40, 0x00, 0xC0, 0x40, 0x40, 0x40, 0xE0, 4, //i 78 | 0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60, 5, //j 79 | 0x80, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 5, //k 80 | 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //l 81 | 0x00, 0x00, 0x00, 0xF0, 0xA8, 0xA8, 0xA8, 0xA8, 6, //m 82 | 0x00, 0x00, 0x00, 0xA0, 0xD0, 0x90, 0x90, 0x90, 5, //n 83 | 0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 6, //o 84 | 0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80, 6, //p 85 | 0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x08, 6, //q 86 | 0x00, 0x00, 0x00, 0xB0, 0xC0, 0x80, 0x80, 0x80, 5, //r 87 | 0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0, 6, //s 88 | 0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20, 4, //t 89 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 6, //u 90 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 6, //v 91 | 0x00, 0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50, 6, //w 92 | 0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 6, //x 93 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70, 6, //y 94 | 0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 6, //z 95 | 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x40, 0x30, 5, //{ 96 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 2, //| 97 | 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0xC0, 5, //} 98 | 0x00, 0x00, 0x00, 0x50, 0xA8, 0x00, 0x00, 0x00, 6, //~ 99 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 // 100 | }; 101 | -------------------------------------------------------------------------------- /examples/ScrollingTextState/font_bold.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char font[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5, // 5 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 3, //! 6 | 0xD8, 0xD8, 0xD8, 0xD8, 0x00, 0x00, 0x00, 0x00, 6, //" 7 | 0x66, 0xFF, 0xFF, 0x66, 0x66, 0xFF, 0xFF, 0x66, 9, //# 8 | 0x7F, 0xFF, 0xD8, 0xFE, 0x7F, 0x1B, 0xFF, 0xFE, 9, //$ 9 | 0xE3, 0xE7, 0xEE, 0x1C, 0x38, 0x77, 0xE7, 0xC7, 9, //% 10 | 0x70, 0xF8, 0xD8, 0x73, 0xFF, 0xDE, 0xFF, 0x7B, 9, //& 11 | 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 3, //' 12 | 0x70, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xF0, 0x70, 5, //( 13 | 0xE0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0xF0, 0xE0, 5, //) 14 | 0xDB, 0xFF, 0x7E, 0x3C, 0x3C, 0x7E, 0xFF, 0xDB, 9, //* 15 | 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18, 0x18, 0x18, 9, //+ 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 3, //, 17 | 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 9, //- 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 3, //. 19 | 0x03, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0xC0, 9, /// 20 | 0x7E, 0xFF, 0xC3, 0xDB, 0xDB, 0xC3, 0xFF, 0x7E, 9, //0 21 | 0xE0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 5, //1 22 | 0xFE, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //2 23 | 0xFE, 0xFF, 0x03, 0x7E, 0x7F, 0x03, 0xFF, 0xFE, 9, //3 24 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7F, 0x03, 0x03, 0x03, 9, //4 25 | 0xFF, 0xFF, 0xC0, 0xFE, 0xFF, 0x03, 0xFF, 0xFE, 9, //5 26 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFF, 0xC3, 0xFF, 0x7E, 9, //6 27 | 0x7E, 0xFF, 0xC3, 0xC3, 0x03, 0x03, 0x03, 0x03, 9, //7 28 | 0x7E, 0xFF, 0xC3, 0x7E, 0xFF, 0xC3, 0xFF, 0x7E, 9, //8 29 | 0x7E, 0xFF, 0xC3, 0xFF, 0x7F, 0x03, 0xFF, 0xFE, 9, //9 30 | 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x00, 3, //: 31 | 0x00, 0xC0, 0xC0, 0x00, 0x00, 0xC0, 0xC0, 0x40, 3, //; 32 | 0x18, 0x38, 0x70, 0xE0, 0xE0, 0x70, 0x38, 0x18, 6, //< 33 | 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 9, //= 34 | 0xC0, 0xE0, 0x70, 0x38, 0x38, 0x70, 0xE0, 0xC0, 6, //> 35 | 0x7E, 0xFF, 0xC3, 0x1F, 0x1E, 0x00, 0x18, 0x18, 9, //? 36 | 0x7E, 0xFF, 0xC3, 0xDF, 0xDF, 0xDB, 0xFF, 0x7F, 9, //@ 37 | 0x7E, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //A 38 | 0xFE, 0xFF, 0xC3, 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 9, //B 39 | 0x7E, 0xFF, 0xC3, 0xC0, 0xC0, 0xC3, 0xFF, 0x7E, 9, //C 40 | 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFE, 9, //D 41 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xFF, 0x7F, 9, //E 42 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 9, //F 43 | 0x7F, 0xFF, 0xC0, 0xDF, 0xDF, 0xC3, 0xFF, 0x7F, 9, //G 44 | 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //H 45 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //I 46 | 0x03, 0x03, 0x03, 0x03, 0xC3, 0xC3, 0xFF, 0x7E, 9, //J 47 | 0xC3, 0xC3, 0xC3, 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 9, //K 48 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 9, //L 49 | 0x7E, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 9, //M 50 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 9, //N 51 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //O 52 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC0, 0xC0, 0xC0, 9, //P 53 | 0x7E, 0xFF, 0xC3, 0xC3, 0xCF, 0xCF, 0xFF, 0x7F, 9, //Q 54 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC3, 0xC3, 0xC3, 9, //R 55 | 0x7F, 0xFF, 0xC0, 0xFE, 0x7F, 0x03, 0xFF, 0xFE, 9, //S 56 | 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 9, //T 57 | 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //U 58 | 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x18, 9, //V 59 | 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x7E, 9, //W 60 | 0xC3, 0xC3, 0xC3, 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 9, //X 61 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 0x18, 0x18, 0x18, 9, //Y 62 | 0xFF, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //Z 63 | 0xF0, 0xF0, 0xC0, 0xC0, 0xC0, 0xC0, 0xF0, 0xF0, 5, //[ 64 | 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x07, 0x03, 9, //(Backslash) 65 | 0xF0, 0xF0, 0x30, 0x30, 0x30, 0x30, 0xF0, 0xF0, 5, //] 66 | 0x70, 0xF8, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 6, //^ 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 9, //_ 68 | 0xC0, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 4, //` 69 | 0x7E, 0xFF, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //a 70 | 0xFE, 0xFF, 0xC3, 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 9, //b 71 | 0x7E, 0xFF, 0xC3, 0xC0, 0xC0, 0xC3, 0xFF, 0x7E, 9, //c 72 | 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFE, 9, //d 73 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xFF, 0x7F, 9, //e 74 | 0x7F, 0xFF, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 9, //f 75 | 0x7F, 0xFF, 0xC0, 0xDF, 0xDF, 0xC3, 0xFF, 0x7F, 9, //g 76 | 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 9, //h 77 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //i 78 | 0x03, 0x03, 0x03, 0x03, 0xC3, 0xC3, 0xFF, 0x7E, 9, //j 79 | 0xC3, 0xC3, 0xC3, 0xFE, 0xFF, 0xC3, 0xC3, 0xC3, 9, //k 80 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 9, //l 81 | 0x7E, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 9, //m 82 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 9, //n 83 | 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //o 84 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC0, 0xC0, 0xC0, 9, //p 85 | 0x7E, 0xFF, 0xC3, 0xC3, 0xCF, 0xCF, 0xFF, 0x7F, 9, //q 86 | 0xFE, 0xFF, 0xC3, 0xFF, 0xFE, 0xC3, 0xC3, 0xC3, 9, //r 87 | 0x7F, 0xFF, 0xC0, 0xFE, 0x7F, 0x03, 0xFF, 0xFE, 9, //s 88 | 0xFF, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 9, //t 89 | 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 9, //u 90 | 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7E, 0x3C, 0x18, 9, //v 91 | 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xFF, 0x7E, 9, //w 92 | 0xC3, 0xC3, 0xC3, 0x7E, 0xFF, 0xC3, 0xC3, 0xC3, 9, //x 93 | 0xC3, 0xC3, 0xC3, 0xFF, 0x7E, 0x18, 0x18, 0x18, 9, //y 94 | 0xFF, 0xFF, 0x03, 0x7F, 0xFE, 0xC0, 0xFF, 0xFF, 9, //z 95 | 0x38, 0x78, 0x60, 0xE0, 0xE0, 0x60, 0x78, 0x38, 6, //{ 96 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 3, //| 97 | 0xE0, 0xF0, 0x30, 0x38, 0x38, 0x30, 0xF0, 0xE0, 6, //} 98 | 0x76, 0xFE, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 8, //~ 99 | 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 3 // 100 | }; 101 | -------------------------------------------------------------------------------- /examples/ScrollingTextState/font_thin.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | const unsigned char font[] PROGMEM = { 4 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5, // 5 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 2, //! 6 | 0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 4, //" 7 | 0x50, 0x50, 0xF8, 0x50, 0x50, 0xF8, 0x50, 0x50, 6, //# 8 | 0x20, 0x70, 0xA8, 0x70, 0x28, 0xA8, 0x70, 0x20, 6, //$ 9 | 0xC8, 0xD0, 0x10, 0x20, 0x20, 0x40, 0x58, 0x98, 6, //% 10 | 0x60, 0x90, 0xA0, 0x40, 0xA0, 0x90, 0x98, 0x60, 6, //& 11 | 0xC0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 3, //' 12 | 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x20, 4, //( 13 | 0x80, 0x40, 0x20, 0x20, 0x20, 0x20, 0x40, 0x80, 4, //) 14 | 0x00, 0x00, 0x20, 0xA8, 0x70, 0xA8, 0x20, 0x00, 6, //* 15 | 0x00, 0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 6, //+ 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 2, //, 17 | 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0x00, 6, //- 18 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 2, //. 19 | 0x08, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 6, /// 20 | 0x70, 0x88, 0x98, 0xA8, 0xA8, 0xC8, 0x88, 0x70, 6, //0 21 | 0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //1 22 | 0x70, 0x88, 0x08, 0x30, 0x40, 0x80, 0x80, 0xF8, 6, //2 23 | 0xF8, 0x10, 0x20, 0x10, 0x08, 0x88, 0x88, 0x70, 6, //3 24 | 0x10, 0x30, 0x50, 0x90, 0x90, 0xF8, 0x10, 0x10, 6, //4 25 | 0xF8, 0x80, 0xF0, 0x08, 0x08, 0x88, 0x88, 0x70, 6, //5 26 | 0x70, 0x88, 0x80, 0xF0, 0x88, 0x88, 0x88, 0x70, 6, //6 27 | 0xF8, 0x08, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 6, //7 28 | 0x70, 0x88, 0x88, 0x70, 0x88, 0x88, 0x88, 0x70, 6, //8 29 | 0x70, 0x88, 0x88, 0x78, 0x08, 0x08, 0x10, 0x60, 6, //9 30 | 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 2, //: 31 | 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 2, //; 32 | 0x10, 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x10, 5, //< 33 | 0x00, 0x00, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0x00, 6, //= 34 | 0x80, 0x40, 0x20, 0x10, 0x10, 0x20, 0x40, 0x80, 5, //> 35 | 0x70, 0x88, 0x08, 0x08, 0x30, 0x20, 0x00, 0x20, 6, //? 36 | 0x70, 0x88, 0xB8, 0xA8, 0xA8, 0xB8, 0x80, 0x70, 6, //@ 37 | 0x70, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x88, 6, //A 38 | 0xF0, 0x88, 0x88, 0xF0, 0x88, 0x88, 0x88, 0xF0, 6, //B 39 | 0x70, 0x88, 0x80, 0x80, 0x80, 0x80, 0x88, 0x70, 6, //C 40 | 0xF0, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0xF0, 6, //D 41 | 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0xF8, 6, //E 42 | 0xF8, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x80, 6, //F 43 | 0x70, 0x88, 0x80, 0x80, 0xB8, 0x88, 0x88, 0x78, 6, //G 44 | 0x88, 0x88, 0x88, 0xF8, 0x88, 0x88, 0x88, 0x88, 6, //H 45 | 0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //I 46 | 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 6, //J 47 | 0x88, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 0x88, 0x88, 6, //K 48 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF8, 6, //L 49 | 0x88, 0xD8, 0xA8, 0xA8, 0x88, 0x88, 0x88, 0x88, 6, //M 50 | 0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x88, 6, //N 51 | 0x70, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 6, //O 52 | 0xF0, 0x88, 0x88, 0x88, 0xF0, 0x80, 0x80, 0x80, 6, //P 53 | 0x70, 0x88, 0x88, 0x88, 0x88, 0xA8, 0x90, 0x68, 6, //Q 54 | 0xF0, 0x88, 0x88, 0xF0, 0xA0, 0x90, 0x88, 0x88, 6, //R 55 | 0x70, 0x88, 0x80, 0x70, 0x08, 0x08, 0x88, 0x70, 6, //S 56 | 0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 6, //T 57 | 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x70, 6, //U 58 | 0x88, 0x88, 0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 6, //V 59 | 0x88, 0x88, 0x88, 0xA8, 0xA8, 0xA8, 0xA8, 0x50, 6, //W 60 | 0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x88, 6, //X 61 | 0x88, 0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, 6, //Y 62 | 0xF8, 0x08, 0x10, 0x20, 0x20, 0x40, 0x80, 0xF8, 6, //Z 63 | 0xE0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xE0, 4, //[ 64 | 0x80, 0x80, 0x40, 0x20, 0x20, 0x10, 0x08, 0x08, 6, //(Backslash) 65 | 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0, 4, //] 66 | 0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 6, //^ 67 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 6, //_ 68 | 0xC0, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 3, //` 69 | 0x00, 0x00, 0x00, 0x70, 0x08, 0x78, 0x88, 0x78, 6, //a 70 | 0x80, 0x80, 0x80, 0xF0, 0x88, 0x88, 0x88, 0xF0, 6, //b 71 | 0x00, 0x00, 0x00, 0x78, 0x80, 0x80, 0x80, 0x78, 6, //c 72 | 0x08, 0x08, 0x08, 0x78, 0x88, 0x88, 0x88, 0x78, 6, //d 73 | 0x00, 0x00, 0x00, 0x70, 0x88, 0xF8, 0x80, 0x70, 6, //e 74 | 0x30, 0x40, 0x40, 0xF0, 0x40, 0x40, 0x40, 0x40, 5, //f 75 | 0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x70, 6, //g 76 | 0x80, 0x80, 0x80, 0xB0, 0xC8, 0x88, 0x88, 0x88, 6, //h 77 | 0x00, 0x40, 0x00, 0xC0, 0x40, 0x40, 0x40, 0xE0, 4, //i 78 | 0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x90, 0x60, 5, //j 79 | 0x80, 0x80, 0x80, 0x90, 0xA0, 0xC0, 0xA0, 0x90, 5, //k 80 | 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 4, //l 81 | 0x00, 0x00, 0x00, 0xF0, 0xA8, 0xA8, 0xA8, 0xA8, 6, //m 82 | 0x00, 0x00, 0x00, 0xA0, 0xD0, 0x90, 0x90, 0x90, 5, //n 83 | 0x00, 0x00, 0x00, 0x70, 0x88, 0x88, 0x88, 0x70, 6, //o 84 | 0x00, 0x00, 0x00, 0xF0, 0x88, 0xF0, 0x80, 0x80, 6, //p 85 | 0x00, 0x00, 0x00, 0x78, 0x88, 0x78, 0x08, 0x08, 6, //q 86 | 0x00, 0x00, 0x00, 0xB0, 0xC0, 0x80, 0x80, 0x80, 5, //r 87 | 0x00, 0x00, 0x00, 0x78, 0x80, 0x70, 0x08, 0xF0, 6, //s 88 | 0x00, 0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x20, 4, //t 89 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x98, 0x68, 6, //u 90 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x88, 0x50, 0x20, 6, //v 91 | 0x00, 0x00, 0x00, 0x88, 0x88, 0xA8, 0xA8, 0x50, 6, //w 92 | 0x00, 0x00, 0x00, 0x88, 0x50, 0x20, 0x50, 0x88, 6, //x 93 | 0x00, 0x00, 0x00, 0x88, 0x88, 0x78, 0x08, 0x70, 6, //y 94 | 0x00, 0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 6, //z 95 | 0x30, 0x40, 0x40, 0x80, 0x40, 0x40, 0x40, 0x30, 5, //{ 96 | 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 2, //| 97 | 0xC0, 0x20, 0x20, 0x10, 0x20, 0x20, 0x20, 0xC0, 5, //} 98 | 0x00, 0x00, 0x00, 0x50, 0xA8, 0x00, 0x00, 0x00, 6, //~ 99 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 5 // 100 | }; 101 | -------------------------------------------------------------------------------- /examples/Pets/Robot/Robot.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Robot.ino - Robot example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte robot[8]={ 31 | B00000000, 32 | B01111110, 33 | B01100110, 34 | B01100110, 35 | B01111110, 36 | B00000000, 37 | B11111111, 38 | B00000000 39 | }; 40 | 41 | byte robotBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01111110, 45 | B00000000, 46 | B00000000, 47 | B00000000, 48 | B11111111, 49 | B00000000 50 | }; 51 | 52 | #define ROBOT_SPEAK_FRAMES 2 53 | byte robotSpeakF[ROBOT_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01111110, 57 | B01100110, 58 | B01100110, 59 | B01111110, 60 | B00000000, 61 | B10101010, 62 | B01010101 63 | }, 64 | { 65 | B00000000, 66 | B01111110, 67 | B01100110, 68 | B01100110, 69 | B01111110, 70 | B00000000, 71 | B01010101, 72 | B10101010 73 | } 74 | }; 75 | unsigned long robotSpeakD[ROBOT_SPEAK_FRAMES] = { 200, 200 }; 76 | 77 | #define ROBOT_SPEAK_TONES 2 78 | unsigned int robotSpeakToneF[ROBOT_SPEAK_TONES] = { 100, 60 }; 79 | unsigned long robotSpeakToneD[ROBOT_SPEAK_TONES] = { 200, 200 }; 80 | 81 | #define ROBOT_LOOK_FRAMES 8 82 | byte robotLookF[ROBOT_LOOK_FRAMES][8]= { 83 | { 84 | B00000000, 85 | B01111110, 86 | B01001110, 87 | B01001110, 88 | B01111110, 89 | B00000000, 90 | B11111111, 91 | B00000000 92 | }, 93 | { 94 | B00000000, 95 | B01111110, 96 | B00011110, 97 | B00011110, 98 | B01111110, 99 | B00000000, 100 | B11111111, 101 | B00000000 102 | }, 103 | { 104 | B00000000, 105 | B01111110, 106 | B00111110, 107 | B00111110, 108 | B01111110, 109 | B00000000, 110 | B11111111, 111 | B00000000 112 | }, 113 | { 114 | B00000000, 115 | B01111110, 116 | B01111110, 117 | B01111110, 118 | B01111110, 119 | B00000000, 120 | B11111111, 121 | B00000000 122 | }, 123 | { 124 | B00000000, 125 | B01111110, 126 | B01111100, 127 | B01111100, 128 | B01111110, 129 | B00000000, 130 | B11111111, 131 | B00000000 132 | }, 133 | { 134 | B00000000, 135 | B01111110, 136 | B01111000, 137 | B01111000, 138 | B01111110, 139 | B00000000, 140 | B11111111, 141 | B00000000 142 | }, 143 | { 144 | B00000000, 145 | B01111110, 146 | B01110010, 147 | B01110010, 148 | B01111110, 149 | B00000000, 150 | B11111111, 151 | B00000000 152 | }, 153 | { 154 | B00000000, 155 | B01111110, 156 | B01100110, 157 | B01100110, 158 | B01111110, 159 | B00000000, 160 | B11111111, 161 | B00000000 162 | } 163 | }; 164 | unsigned long robotLookD[ROBOT_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100, 100, 100 }; 165 | 166 | #define DEFAULT_STATE 0 167 | #define BLINK_STATE 1 168 | #define LOOK_STATE 2 169 | #define SPEAK_STATE 3 170 | 171 | Petduino pet = Petduino(); 172 | 173 | void setup() { 174 | 175 | // Setup Petduino 176 | pet.begin(); 177 | 178 | // Set initial state 179 | pet.setState(DEFAULT_STATE); 180 | 181 | // Initialize random seed 182 | randomSeed(analogRead(0)); 183 | 184 | } 185 | 186 | void loop() { 187 | 188 | // Update pet 189 | pet.update(); 190 | 191 | // Check buttons 192 | if(pet.isBtn1Pressed()){ 193 | pet.setState(LOOK_STATE); 194 | } 195 | 196 | if(pet.isBtn2Pressed()){ 197 | pet.setState(SPEAK_STATE); 198 | } 199 | 200 | // Update display based on current state 201 | switch(pet.getState()){ 202 | 203 | case DEFAULT_STATE: 204 | if (random(0, 5) == 0) { 205 | pet.setState(BLINK_STATE); // Random blink 206 | } else if(random(0, 10) == 0) { 207 | pet.setState(SPEAK_STATE); // Random speak 208 | } else if(random(0, 5) == 0) { 209 | pet.setState(LOOK_STATE); // Random look 210 | } else { 211 | pet.drawImage(robot); 212 | pet.setNextState(DEFAULT_STATE, 3000); 213 | } 214 | break; 215 | 216 | case BLINK_STATE: 217 | pet.drawImage(robotBlink); 218 | pet.setNextState(DEFAULT_STATE, 100); 219 | break; 220 | 221 | case LOOK_STATE: 222 | pet.playAnimation(robotLookF, robotLookD, ROBOT_LOOK_FRAMES, 2); 223 | pet.setNextState(DEFAULT_STATE, 2000); 224 | break; 225 | 226 | case SPEAK_STATE: 227 | pet.playAnimation(robotSpeakF, robotSpeakD, ROBOT_SPEAK_FRAMES, 4); 228 | pet.playMelody(robotSpeakToneF, robotSpeakToneD, ROBOT_SPEAK_TONES, 4); 229 | pet.setNextState(DEFAULT_STATE, 1600); 230 | break; 231 | } 232 | 233 | } 234 | -------------------------------------------------------------------------------- /examples/Pets/Dog/Dog.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Dog.ino - Dog example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte dog[8]={ 31 | B00000000, 32 | B01100110, 33 | B01100110, 34 | B01000010, 35 | B01111110, 36 | B00111100, 37 | B10000001, 38 | B01111110 39 | }; 40 | 41 | byte dogBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01100110, 45 | B00000000, 46 | B01111110, 47 | B00111100, 48 | B10000001, 49 | B01111110 50 | }; 51 | 52 | #define DOG_SPEAK_FRAMES 4 53 | byte dogSpeakF[DOG_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01100110, 57 | B01100110, 58 | B01000010, 59 | B01111110, 60 | B00111100, 61 | B10011001, 62 | B01111110 63 | }, 64 | { 65 | B00000000, 66 | B01100110, 67 | B01100110, 68 | B01000010, 69 | B01111110, 70 | B00111100, 71 | B11111111, 72 | B01111110 73 | }, 74 | { 75 | B00000000, 76 | B01100110, 77 | B01100110, 78 | B01000010, 79 | B01111110, 80 | B00111100, 81 | B10011001, 82 | B01111110 83 | }, 84 | { 85 | B00000000, 86 | B01100110, 87 | B01100110, 88 | B01000010, 89 | B01111110, 90 | B00111100, 91 | B10000001, 92 | B01111110 93 | } 94 | }; 95 | unsigned long dogSpeakD[DOG_SPEAK_FRAMES] = { 100, 100, 100, 100 }; 96 | 97 | #define DOG_SPEAK_TONES 11 98 | unsigned int dogSpeakToneF[DOG_SPEAK_TONES] = { 50, 100, 400, 220, 300, 50, 250, 150, 70, 200, 100 }; 99 | unsigned long dogSpeakToneD[DOG_SPEAK_TONES] = { 20, 50, 20, 10, 100, 50, 40, 20, 80, 20, 30 }; 100 | 101 | #define DOG_LOOK_FRAMES 6 102 | byte dogLookF[DOG_LOOK_FRAMES][8]= { 103 | { 104 | B00000000, 105 | B01100110, 106 | B01000010, 107 | B01100110, 108 | B01111110, 109 | B00111100, 110 | B10000001, 111 | B01111110 112 | }, 113 | { 114 | B00000000, 115 | B01000010, 116 | B01100110, 117 | B01100110, 118 | B01111110, 119 | B00111100, 120 | B10000001, 121 | B01111110 122 | }, 123 | { 124 | B00000000, 125 | B00100100, 126 | B01100110, 127 | B01100110, 128 | B01111110, 129 | B00111100, 130 | B10000001, 131 | B01111110 132 | }, 133 | { 134 | B00000000, 135 | B01100110, 136 | B00100100, 137 | B01100110, 138 | B01111110, 139 | B00111100, 140 | B10000001, 141 | B01111110 142 | }, 143 | { 144 | B00000000, 145 | B01100110, 146 | B01100110, 147 | B00100100, 148 | B01111110, 149 | B00111100, 150 | B10000001, 151 | B01111110 152 | }, 153 | { 154 | B00000000, 155 | B01100110, 156 | B01100110, 157 | B01000010, 158 | B01111110, 159 | B00111100, 160 | B10000001, 161 | B01111110 162 | } 163 | }; 164 | unsigned long dogLookD[DOG_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100 }; 165 | 166 | #define DEFAULT_STATE 0 167 | #define BLINK_STATE 1 168 | #define LOOK_STATE 2 169 | #define SPEAK_STATE 3 170 | 171 | Petduino pet = Petduino(); 172 | 173 | void setup() { 174 | 175 | // Setup Petduino 176 | pet.begin(); 177 | 178 | // Set initial state 179 | pet.setState(DEFAULT_STATE); 180 | 181 | // Initialize random seed 182 | randomSeed(analogRead(0)); 183 | 184 | } 185 | 186 | void loop() { 187 | 188 | // Update pet 189 | pet.update(); 190 | 191 | // Check buttons 192 | if(pet.isBtn1Pressed()){ 193 | pet.setState(LOOK_STATE); 194 | } 195 | 196 | if(pet.isBtn2Pressed()){ 197 | pet.setState(SPEAK_STATE); 198 | } 199 | 200 | // Update display based on current state 201 | switch(pet.getState()){ 202 | 203 | case DEFAULT_STATE: 204 | if (random(0, 5) == 0) { 205 | pet.setState(BLINK_STATE); // Random blink 206 | } else if(random(0, 10) == 0) { 207 | pet.setState(SPEAK_STATE); // Random speak 208 | } else if(random(0, 5) == 0) { 209 | pet.setState(LOOK_STATE); // Random look 210 | } else { 211 | pet.drawImage(dog); 212 | pet.setNextState(DEFAULT_STATE, 3000); 213 | } 214 | break; 215 | 216 | case BLINK_STATE: 217 | pet.drawImage(dogBlink); 218 | pet.setNextState(DEFAULT_STATE, 100); 219 | break; 220 | 221 | case LOOK_STATE: 222 | pet.playAnimation(dogLookF, dogLookD, DOG_LOOK_FRAMES, 2); 223 | pet.setNextState(DEFAULT_STATE, 2000); 224 | break; 225 | 226 | case SPEAK_STATE: 227 | pet.playAnimation(dogSpeakF, dogSpeakD, DOG_SPEAK_FRAMES, 4); 228 | pet.playMelody(dogSpeakToneF, dogSpeakToneD, DOG_SPEAK_TONES, 3); 229 | pet.setNextState(DEFAULT_STATE, 2000); 230 | break; 231 | } 232 | 233 | } 234 | -------------------------------------------------------------------------------- /examples/Pets/Monster/Monster.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Monster.ino - Monster example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte monster[8]={ 31 | B00000000, 32 | B01100110, 33 | B01100110, 34 | B01000010, 35 | B00011000, 36 | B01000010, 37 | B01000010, 38 | B11111111 39 | }; 40 | 41 | byte monsterBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01100110, 45 | B00000000, 46 | B00011000, 47 | B01000010, 48 | B01000010, 49 | B11111111 50 | }; 51 | 52 | #define MONSTER_SPEAK_FRAMES 4 53 | byte monsterSpeakF[MONSTER_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01100110, 57 | B01100110, 58 | B01000010, 59 | B00011000, 60 | B01000010, 61 | B01111110, 62 | B11111111 63 | }, 64 | { 65 | B00000000, 66 | B01100110, 67 | B01100110, 68 | B01000010, 69 | B00011000, 70 | B01111110, 71 | B01000010, 72 | B11111111 73 | }, 74 | { 75 | B00000000, 76 | B01100110, 77 | B01100110, 78 | B01000010, 79 | B00011000, 80 | B01000010, 81 | B01111110, 82 | B11111111 83 | }, 84 | { 85 | B00000000, 86 | B01100110, 87 | B01100110, 88 | B01000010, 89 | B00011000, 90 | B01000010, 91 | B01000010, 92 | B11111111 93 | } 94 | }; 95 | unsigned long monsterSpeakD[MONSTER_SPEAK_FRAMES] = { 60, 800, 60, 100 }; 96 | 97 | #define MONSTER_SPEAK_TONES 4 98 | unsigned int monsterSpeakToneF[MONSTER_SPEAK_TONES] = { 40, 50, 40, 0 }; 99 | unsigned long monsterSpeakToneD[MONSTER_SPEAK_TONES] = { 60, 800, 60, 100 }; 100 | 101 | #define MONSTER_LOOK_FRAMES 6 102 | byte monsterLookF[MONSTER_LOOK_FRAMES][8]= { 103 | { 104 | B00000000, 105 | B01100110, 106 | B01000010, 107 | B01100110, 108 | B00011000, 109 | B01000010, 110 | B01000010, 111 | B11111111 112 | }, 113 | { 114 | B00000000, 115 | B01000010, 116 | B01100110, 117 | B01100110, 118 | B00011000, 119 | B01000010, 120 | B01000010, 121 | B11111111 122 | }, 123 | { 124 | B00000000, 125 | B00100100, 126 | B01100110, 127 | B01100110, 128 | B00011000, 129 | B01000010, 130 | B01000010, 131 | B11111111 132 | }, 133 | { 134 | B00000000, 135 | B01100110, 136 | B00100100, 137 | B01100110, 138 | B00011000, 139 | B01000010, 140 | B01000010, 141 | B11111111 142 | }, 143 | { 144 | B00000000, 145 | B01100110, 146 | B01100110, 147 | B00100100, 148 | B00011000, 149 | B01000010, 150 | B01000010, 151 | B11111111 152 | }, 153 | { 154 | B00000000, 155 | B01100110, 156 | B01100110, 157 | B01000010, 158 | B00011000, 159 | B01000010, 160 | B01000010, 161 | B11111111 162 | } 163 | }; 164 | unsigned long monsterLookD[MONSTER_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100 }; 165 | 166 | #define DEFAULT_STATE 0 167 | #define BLINK_STATE 1 168 | #define LOOK_STATE 2 169 | #define SPEAK_STATE 3 170 | 171 | Petduino pet = Petduino(); 172 | 173 | void setup() { 174 | 175 | // Setup Petduino 176 | pet.begin(); 177 | 178 | // Set initial state 179 | pet.setState(DEFAULT_STATE); 180 | 181 | // Initialize random seed 182 | randomSeed(analogRead(0)); 183 | 184 | } 185 | 186 | void loop() { 187 | 188 | // Update pet 189 | pet.update(); 190 | 191 | // Check buttons 192 | if(pet.isBtn1Pressed()){ 193 | pet.setState(LOOK_STATE); 194 | } 195 | 196 | if(pet.isBtn2Pressed()){ 197 | pet.setState(SPEAK_STATE); 198 | } 199 | 200 | // Update display based on current state 201 | switch(pet.getState()){ 202 | 203 | case DEFAULT_STATE: 204 | if (random(0, 5) == 0) { 205 | pet.setState(BLINK_STATE); // Random blink 206 | } else if(random(0, 10) == 0) { 207 | pet.setState(SPEAK_STATE); // Random speak 208 | } else if(random(0, 5) == 0) { 209 | pet.setState(LOOK_STATE); // Random look 210 | } else { 211 | pet.drawImage(monster); 212 | pet.setNextState(DEFAULT_STATE, 3000); 213 | } 214 | break; 215 | 216 | case BLINK_STATE: 217 | pet.drawImage(monsterBlink); 218 | pet.setNextState(DEFAULT_STATE, 100); 219 | break; 220 | 221 | case LOOK_STATE: 222 | pet.playAnimation(monsterLookF, monsterLookD, MONSTER_LOOK_FRAMES, 2); 223 | pet.setNextState(DEFAULT_STATE, 2000); 224 | break; 225 | 226 | case SPEAK_STATE: 227 | pet.playAnimation(monsterSpeakF, monsterSpeakD, MONSTER_SPEAK_FRAMES, 1); 228 | pet.playMelody(monsterSpeakToneF, monsterSpeakToneD, MONSTER_SPEAK_TONES, 1); 229 | pet.setNextState(DEFAULT_STATE, 2000); 230 | break; 231 | } 232 | 233 | } 234 | -------------------------------------------------------------------------------- /examples/Pets/Rabbit/Rabbit.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Rabbit.ino - Rabbit example using state and the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte rabbit[8]={ 31 | B00000000, 32 | B01100110, 33 | B01100110, 34 | B01000010, 35 | B10011001, 36 | B01111110, 37 | B00011000, 38 | B00011000 39 | }; 40 | 41 | byte rabbitBlink[8]={ 42 | B00000000, 43 | B00000000, 44 | B01100110, 45 | B00000000, 46 | B10011001, 47 | B01111110, 48 | B00011000, 49 | B00011000 50 | }; 51 | 52 | #define RABBIT_SPEAK_FRAMES 4 53 | byte rabbitSpeakF[RABBIT_SPEAK_FRAMES][8]= { 54 | { 55 | B00000000, 56 | B01100110, 57 | B01100110, 58 | B01000010, 59 | B10011001, 60 | B01111110, 61 | B00111100, 62 | B00011000 63 | }, 64 | { 65 | B00000000, 66 | B01100110, 67 | B01100110, 68 | B01000010, 69 | B10011001, 70 | B01111110, 71 | B01111110, 72 | B00111100 73 | }, 74 | { 75 | B00000000, 76 | B01100110, 77 | B01100110, 78 | B01000010, 79 | B10011001, 80 | B01111110, 81 | B00111100, 82 | B00011000 83 | }, 84 | { 85 | B00000000, 86 | B01100110, 87 | B01100110, 88 | B01000010, 89 | B10011001, 90 | B01111110, 91 | B00011000, 92 | B00011000 93 | } 94 | }; 95 | unsigned long rabbitSpeakD[RABBIT_SPEAK_FRAMES] = { 100, 100, 100, 100 }; 96 | 97 | #define RABBIT_SPEAK_TONES 11 98 | unsigned int rabbitSpeakToneF[RABBIT_SPEAK_TONES] = { 100, 200, 70, 150, 250, 50, 300, 220, 400, 100, 50 }; 99 | unsigned long rabbitSpeakToneD[RABBIT_SPEAK_TONES] = { 20, 50, 20, 10, 100, 50, 40, 20, 80, 20, 30 }; 100 | 101 | #define RABBIT_LOOK_FRAMES 6 102 | byte rabbitLookF[RABBIT_LOOK_FRAMES][8]= { 103 | { 104 | B00000000, 105 | B01100110, 106 | B01000010, 107 | B01100110, 108 | B10011001, 109 | B01111110, 110 | B00011000, 111 | B00011000 112 | }, 113 | { 114 | B00000000, 115 | B01000010, 116 | B01100110, 117 | B01100110, 118 | B10011001, 119 | B01111110, 120 | B00011000, 121 | B00011000 122 | }, 123 | { 124 | B00000000, 125 | B00100100, 126 | B01100110, 127 | B01100110, 128 | B10011001, 129 | B01111110, 130 | B00011000, 131 | B00011000 132 | }, 133 | { 134 | B00000000, 135 | B01100110, 136 | B00100100, 137 | B01100110, 138 | B10011001, 139 | B01111110, 140 | B00011000, 141 | B00011000 142 | }, 143 | { 144 | B00000000, 145 | B01100110, 146 | B01100110, 147 | B00100100, 148 | B10011001, 149 | B01111110, 150 | B00011000, 151 | B00011000 152 | }, 153 | { 154 | B00000000, 155 | B01100110, 156 | B01100110, 157 | B01000010, 158 | B10011001, 159 | B01111110, 160 | B00011000, 161 | B00011000 162 | } 163 | }; 164 | unsigned long rabbitLookD[RABBIT_LOOK_FRAMES] = { 100, 100, 100, 100, 100, 100 }; 165 | 166 | #define DEFAULT_STATE 0 167 | #define BLINK_STATE 1 168 | #define LOOK_STATE 2 169 | #define SPEAK_STATE 3 170 | 171 | Petduino pet = Petduino(); 172 | 173 | void setup() { 174 | 175 | // Setup Petduino 176 | pet.begin(); 177 | 178 | // Set initial state 179 | pet.setState(DEFAULT_STATE); 180 | 181 | // Initialize random seed 182 | randomSeed(analogRead(0)); 183 | 184 | } 185 | 186 | void loop() { 187 | 188 | // Update pet 189 | pet.update(); 190 | 191 | // Check buttons 192 | if(pet.isBtn1Pressed()){ 193 | pet.setState(LOOK_STATE); 194 | } 195 | 196 | if(pet.isBtn2Pressed()){ 197 | pet.setState(SPEAK_STATE); 198 | } 199 | 200 | // Update display based on current state 201 | switch(pet.getState()){ 202 | 203 | case DEFAULT_STATE: 204 | if (random(0, 5) == 0) { 205 | pet.setState(BLINK_STATE); // Random blink 206 | } else if(random(0, 10) == 0) { 207 | pet.setState(SPEAK_STATE); // Random speak 208 | } else if(random(0, 5) == 0) { 209 | pet.setState(LOOK_STATE); // Random look 210 | } else { 211 | pet.drawImage(rabbit); 212 | pet.setNextState(DEFAULT_STATE, 3000); 213 | } 214 | break; 215 | 216 | case BLINK_STATE: 217 | pet.drawImage(rabbitBlink); 218 | pet.setNextState(DEFAULT_STATE, 100); 219 | break; 220 | 221 | case LOOK_STATE: 222 | pet.playAnimation(rabbitLookF, rabbitLookD, RABBIT_LOOK_FRAMES, 2); 223 | pet.setNextState(DEFAULT_STATE, 2000); 224 | break; 225 | 226 | case SPEAK_STATE: 227 | pet.playAnimation(rabbitSpeakF, rabbitSpeakD, RABBIT_SPEAK_FRAMES, 4); 228 | pet.playMelody(rabbitSpeakToneF, rabbitSpeakToneD, RABBIT_SPEAK_TONES, 3); 229 | pet.setNextState(DEFAULT_STATE, 2000); 230 | break; 231 | } 232 | 233 | } 234 | -------------------------------------------------------------------------------- /examples/ScrollingTextState/ScrollingTextState.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * ScrollingTextState.ino - Scrolling text example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include "font_bold.h" 31 | 32 | #define SCREEN_WIDTH 8 33 | #define SCREEN_HEIGHT 8 34 | 35 | #define CHAR_HEIGHT SCREEN_HEIGHT 36 | #define BUFFER_SIZE CHAR_HEIGHT*2 37 | #define SCROLL_SPEED 75 38 | #define MIN_CHAR 0x20 39 | #define MAX_CHAR 0x7f 40 | 41 | const unsigned char scrollText[] PROGMEM = {"CB 2015\0"}; 42 | unsigned long charBuffer[BUFFER_SIZE] = {0}; 43 | 44 | unsigned int charCounter = 0; 45 | unsigned int nextChar = 0; 46 | 47 | unsigned int scrollLen = 0; 48 | unsigned int scrollCount = 0; 49 | 50 | #define INIT_STATE 0 51 | #define LOAD_CHAR_STATE 1 52 | #define LOOP_STATE 2 53 | 54 | Petduino pet = Petduino(); 55 | 56 | void setup() { 57 | 58 | Serial.begin(9600); 59 | 60 | // Setup Petduino 61 | pet.begin(); 62 | 63 | // Set initial state 64 | pet.setState(INIT_STATE); 65 | 66 | } 67 | 68 | void loop() { 69 | 70 | // Call pet loop 71 | pet.update(); 72 | 73 | // Update based on state 74 | switch(pet.getState()) { 75 | 76 | case INIT_STATE: 77 | 78 | // Reset vars 79 | charCounter = 0; 80 | nextChar = 0; 81 | scrollLen = 0; 82 | scrollCount = 0; 83 | 84 | // Clear any existing buffer 85 | clearBuffer(); 86 | 87 | // Start loading text into buffer 88 | pet.setState(LOAD_CHAR_STATE); 89 | break; 90 | 91 | case LOAD_CHAR_STATE: 92 | 93 | // Grab the next character 94 | nextChar = pgm_read_byte_near(scrollText + charCounter); 95 | 96 | if (nextChar != 0){ 97 | 98 | // Load char into buffer and reset scroll vars 99 | scrollLen = loadCharIntoBuffer(nextChar); 100 | scrollCount = 0; 101 | 102 | // Increment char counter 103 | charCounter++; 104 | 105 | // Scroll char into view 106 | pet.setState(LOOP_STATE); 107 | 108 | } else { 109 | 110 | // End of message 111 | scrollLen = SCREEN_WIDTH; 112 | scrollCount = 0; 113 | 114 | // Scroll buffer till clear 115 | pet.setState(LOOP_STATE); 116 | 117 | } 118 | 119 | break; 120 | case LOOP_STATE: 121 | 122 | // Keep scrolling untill incoming char is completely onscreen 123 | if(scrollCount < scrollLen){ 124 | 125 | // Shift the buffer along 1px 126 | scrollBufferLeftOne(); 127 | 128 | // Draw the current buffer 129 | drawBuffer(); 130 | 131 | // Increment the scroll counter 132 | scrollCount++; 133 | 134 | // Loop 135 | pet.setNextState(LOOP_STATE, SCROLL_SPEED); 136 | 137 | } else { 138 | 139 | // Check to see if message has ended 140 | if(nextChar != 0) { 141 | // Load next char 142 | pet.setState(LOAD_CHAR_STATE); 143 | } else { 144 | // No more chars and buffer clear, so start again 145 | pet.setState(INIT_STATE); 146 | } 147 | 148 | } 149 | 150 | break; 151 | } 152 | 153 | } 154 | 155 | unsigned int loadCharIntoBuffer(unsigned int ascii){ 156 | 157 | if (ascii >= MIN_CHAR && ascii <= MAX_CHAR){ 158 | for (int a=0; a 28 | #include 29 | 30 | byte intro[8]={ 31 | B00000000, 32 | B01111010, 33 | B01000000, 34 | B01111110, 35 | B00000010, 36 | B00000010, 37 | B01111110, 38 | B00000000 39 | }; 40 | 41 | #define NUMBER_COUNT 10 42 | byte numbers[NUMBER_COUNT][8] = { 43 | { 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0 }, 44 | { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 45 | { 0xE0, 0x20, 0x20, 0xE0, 0x80, 0x80, 0x80, 0xE0 }, 46 | { 0xE0, 0x20, 0x20, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 47 | { 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20 }, 48 | { 0xE0, 0x80, 0x80, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 49 | { 0xE0, 0x80, 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 50 | { 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 51 | { 0xE0, 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 52 | { 0xE0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0xE0 } 53 | }; 54 | 55 | unsigned int goalX = 0; 56 | unsigned int goalY = 0; 57 | int headX = 0; 58 | int headY = 0; 59 | int snakeLength = 2; 60 | int score = 0; 61 | int dir = 0; 62 | int speed = 700; 63 | 64 | #define MAX_HISTORY 64 // 8x8 65 | int historyX[MAX_HISTORY]; 66 | int historyY[MAX_HISTORY]; 67 | int historyF = 0; 68 | 69 | bool gameStarted = false; 70 | byte gameBoard[8]; 71 | 72 | unsigned int scoreOnes; 73 | unsigned int scoreTens; 74 | 75 | #define DIR_UP 0 76 | #define DIR_RIGHT 1 77 | #define DIR_DOWN 2 78 | #define DIR_LEFT 3 79 | #define DIR_MAX 3 80 | 81 | #define INTRO_STATE 0 82 | #define GAME_START_STATE 1 83 | #define GAME_LOOP_STATE 2 84 | #define GAME_OVER_STATE 3 85 | 86 | Petduino pet = Petduino(); 87 | 88 | void setup() { 89 | 90 | // Setup Petduino 91 | pet.begin(); 92 | 93 | // Set initial state 94 | pet.setState(INTRO_STATE); 95 | 96 | // Initialize random seed 97 | randomSeed(analogRead(0)); 98 | 99 | } 100 | 101 | void loop() { 102 | 103 | // Update pet 104 | pet.update(); 105 | 106 | // Check buttons 107 | if(pet.isBtn1Pressed()){ 108 | if(!gameStarted){ 109 | pet.setState(GAME_START_STATE); 110 | } else { 111 | dir = wrap(dir - 1, DIR_MAX + 1); 112 | } 113 | } 114 | 115 | if(pet.isBtn2Pressed()){ 116 | if(!gameStarted){ 117 | pet.setState(GAME_START_STATE); 118 | } else { 119 | dir = wrap(dir + 1, DIR_MAX + 1); 120 | } 121 | } 122 | 123 | // Update based on state 124 | switch(pet.getState()) { 125 | 126 | case INTRO_STATE: 127 | pet.drawImage(intro); 128 | pet.wait(); // Wait for button press 129 | break; 130 | 131 | case GAME_START_STATE: 132 | 133 | // Flag game started 134 | gameStarted = true; 135 | 136 | // Clear any previous history 137 | clearHistory(); 138 | 139 | // Reset variables 140 | score = 0; 141 | snakeLength = 2; 142 | 143 | // Start in bottom left corner 144 | headX = 0; 145 | headY = 6; 146 | 147 | // Start moving right 148 | dir = DIR_RIGHT; 149 | 150 | // Draw initial snake 151 | appendHistoryPoint(headX, headY); 152 | for(int i=0;i 20) { 203 | speed = 500; 204 | } else if (score > 15) { 205 | speed = 550; 206 | } else if (score > 10) { 207 | speed = 600; 208 | } else if (score > 5) { 209 | speed = 650; 210 | } else { 211 | speed = 700; 212 | } 213 | 214 | // Loop 215 | pet.setNextState(GAME_LOOP_STATE, speed); 216 | break; 217 | 218 | case GAME_OVER_STATE: 219 | 220 | // Stop the game 221 | gameStarted = false; 222 | 223 | // Split the score digits 224 | scoreTens = score/10; 225 | scoreOnes = score-scoreTens*10; 226 | 227 | // Generate & draw score number graphic 228 | for(int b = 0; b < 8; b++){ 229 | pet.drawRow(b, numbers[scoreTens][b] | numbers[scoreOnes][b] >> 4); 230 | } 231 | 232 | // Go back to intro 233 | pet.setNextState(INTRO_STATE, 3000); 234 | break; 235 | 236 | } 237 | 238 | } 239 | 240 | bool detectSnakeCollision() { 241 | for(int i=1;i> x); 259 | } else { 260 | gameBoard[y] ^= (B10000000 >> x); 261 | } 262 | } 263 | 264 | void drawSnakeToGameBoard() { 265 | for(int i=0;i 28 | #include 29 | 30 | #define INTRO_ANIM_FRAMES 4 31 | byte introF[INTRO_ANIM_FRAMES][8]={ 32 | { 33 | B00001100, 34 | B00010010, 35 | B00010110, 36 | B11110111, 37 | B10010010, 38 | B10000010, 39 | B01100100, 40 | B00111000 41 | }, 42 | { 43 | B00001100, 44 | B00010010, 45 | B00010110, 46 | B00010111, 47 | B01110010, 48 | B10000010, 49 | B10010100, 50 | B11111000 51 | }, 52 | { 53 | B00001100, 54 | B00010010, 55 | B00010110, 56 | B11110111, 57 | B10010010, 58 | B10000010, 59 | B01100100, 60 | B00111000 61 | }, 62 | { 63 | B00001100, 64 | B00010010, 65 | B00010010, 66 | B00010111, 67 | B01110010, 68 | B10000010, 69 | B10010100, 70 | B11111000 71 | } 72 | }; 73 | unsigned long introD[INTRO_ANIM_FRAMES] = { 400, 400, 400, 400 }; 74 | 75 | #define NUMBER_COUNT 10 76 | byte numbers[NUMBER_COUNT][8] = { 77 | { 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0 }, 78 | { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 79 | { 0xE0, 0x20, 0x20, 0xE0, 0x80, 0x80, 0x80, 0xE0 }, 80 | { 0xE0, 0x20, 0x20, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 81 | { 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20 }, 82 | { 0xE0, 0x80, 0x80, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 83 | { 0xE0, 0x80, 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 84 | { 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 85 | { 0xE0, 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 86 | { 0xE0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0xE0 } 87 | }; 88 | 89 | int birdY = 0; 90 | int wingY = 0; 91 | 92 | byte pipe1; 93 | int pipe1X = 0; 94 | unsigned int pipe1GapSize = 0; 95 | unsigned int pipe1GapOffset = 0; 96 | 97 | byte pipe2; 98 | int pipe2X = 0; 99 | unsigned int pipe2GapSize = 0; 100 | unsigned int pipe2GapOffset = 0; 101 | 102 | unsigned int score = 0; 103 | unsigned int speed = 0; 104 | 105 | bool oldBtnPressed = false; 106 | bool btnPressed = false; 107 | bool gameStarted = false; 108 | 109 | byte gameBoard[8]; 110 | 111 | unsigned int scoreOnes; 112 | unsigned int scoreTens; 113 | 114 | #define INTRO_STATE 0 115 | #define GAME_START_STATE 1 116 | #define GAME_LOOP_STATE 2 117 | #define GAME_OVER_STATE 3 118 | 119 | Petduino pet = Petduino(); 120 | 121 | void setup() { 122 | 123 | // Setup Petduino 124 | pet.begin(); 125 | 126 | // Set initial state 127 | pet.setState(INTRO_STATE); 128 | 129 | // Initialize random seed 130 | randomSeed(analogRead(0)); 131 | 132 | } 133 | 134 | void loop() { 135 | 136 | // Update pet 137 | pet.update(); 138 | 139 | // Check buttons 140 | if(pet.isBtn1Pressed()){ 141 | if(!gameStarted){ 142 | pet.setState(GAME_START_STATE); 143 | } else { 144 | btnPressed = true; 145 | } 146 | } 147 | 148 | if(pet.isBtn2Pressed()){ 149 | if(!gameStarted){ 150 | pet.setState(GAME_START_STATE); 151 | } else { 152 | btnPressed = true; 153 | } 154 | } 155 | 156 | // Update based on state 157 | switch(pet.getState()) { 158 | 159 | case INTRO_STATE: 160 | 161 | // Stop any pevious games 162 | gameStarted = false; 163 | 164 | // Show intro anim 165 | pet.playAnimation(introF, introD, INTRO_ANIM_FRAMES, 1); 166 | pet.setNextState(INTRO_STATE, 1600); // Wait for button press 167 | 168 | break; 169 | 170 | case GAME_START_STATE: 171 | 172 | // Flag game started 173 | gameStarted = true; 174 | 175 | // Stop the intro animation 176 | pet.stopAnimation(); 177 | 178 | // Reset variables 179 | score = 0; 180 | birdY = 0; 181 | wingY = 0; 182 | oldBtnPressed = false; 183 | btnPressed = false; 184 | 185 | // Generate pipes 186 | pipe1 = generatePipe(); 187 | pipe1X = 7; // Screen size 188 | pipe2 = generatePipe(); 189 | pipe2X = 11; // Screen size * 1.5 190 | 191 | pet.setState(GAME_LOOP_STATE); 192 | break; 193 | 194 | case GAME_LOOP_STATE: 195 | 196 | // Clear the previous game board 197 | clearGameBoard(); 198 | 199 | // Set wing y to previous bird y 200 | wingY = birdY; 201 | 202 | // Update bird position 203 | if(btnPressed) { 204 | birdY--; 205 | } else if(!oldBtnPressed) { 206 | birdY++; 207 | } 208 | 209 | // If bird goes off screen, game over 210 | if(birdY > 7 || birdY < 0) { 211 | pet.setState(GAME_OVER_STATE); 212 | break; 213 | } 214 | 215 | // Update pipe position 216 | pipe1X--; 217 | if(pipe1X < 0) { 218 | pipe1 = generatePipe(); 219 | pipe1X = 7; 220 | } 221 | 222 | pipe2X--; 223 | if(pipe2X < 0) { 224 | pipe2 = generatePipe(); 225 | pipe2X = 7; 226 | } 227 | 228 | // Detect collision with either pipe 229 | // NB: No need to check for wing, collision as it's 230 | // always one move behind the bird, so if the bird 231 | // makes it, the wing is guaranteed to make it 232 | if(pipe1X == 2 && pipe1 & (0x80 >> birdY) ) { 233 | pet.setState(GAME_OVER_STATE); 234 | break; 235 | } 236 | 237 | if(pipe2X == 2 && pipe2 & (0x80 >> birdY) ) { 238 | pet.setState(GAME_OVER_STATE); 239 | break; 240 | } 241 | 242 | // Got through the pipe, so increase the score 243 | if(pipe1X == 0 || pipe2X == 0) { 244 | score++; 245 | } 246 | 247 | // Draw bird + wing 248 | drawPointToGameBoard(2, birdY, HIGH); 249 | drawPointToGameBoard(1, wingY, HIGH); 250 | 251 | // Draw pipes to screen 252 | drawPipeToGameBoard(pipe1, pipe1X); 253 | drawPipeToGameBoard(pipe2, pipe2X); 254 | 255 | // Draw game board to screen 256 | pet.drawImage(gameBoard); 257 | 258 | // Reset button pressed state 259 | oldBtnPressed = btnPressed; 260 | btnPressed = false; 261 | 262 | // Update speed based on score 263 | if(score > 50) { 264 | speed = 175; 265 | } else { 266 | speed = 200; 267 | } 268 | 269 | pet.setNextState(GAME_LOOP_STATE, speed); 270 | break; 271 | 272 | case GAME_OVER_STATE: 273 | 274 | // Split the score digits 275 | scoreTens = score/10; 276 | scoreOnes = score-scoreTens*10; 277 | 278 | // Generate & draw score number graphic 279 | for(int b = 0; b < 8; b++){ 280 | pet.drawRow(b, numbers[scoreTens][b] | numbers[scoreOnes][b] >> 4); 281 | } 282 | 283 | // Go back to intro 284 | pet.setNextState(INTRO_STATE, 3000); 285 | break; 286 | 287 | } 288 | 289 | } 290 | 291 | void clearGameBoard() { 292 | for(int r=0;r<8;r++) { 293 | gameBoard[r] = 0x00; 294 | } 295 | } 296 | 297 | void drawPointToGameBoard(int x, int y, int val) { 298 | if(val == HIGH){ 299 | gameBoard[y] |= (B10000000 >> x); 300 | } else { 301 | gameBoard[y] ^= (B10000000 >> x); 302 | } 303 | } 304 | 305 | byte generatePipe() { 306 | unsigned int minGap = 3; 307 | unsigned int maxGap = 6; 308 | 309 | // Decrease possible hole size based on score 310 | if(score > 20) { 311 | minGap = 2; 312 | maxGap = 5; 313 | } 314 | 315 | byte gap = random(minGap, maxGap); 316 | byte punch = (1 << gap) - 1; 317 | byte slide = random(1, 8 - gap); 318 | return 0xff & ~(punch << slide); 319 | } 320 | 321 | void drawPipeToGameBoard(byte &pipe, int &pipeX) { 322 | if (pipeX >= 0 && pipeX < 8) { 323 | for (byte r=0; r<8; r++) { 324 | if(pipe & (0x80 >> r)) { 325 | gameBoard[r] |= (0x80 >> pipeX); 326 | } 327 | } 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /examples/TheEye/TheEye.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * TheEye.ino - The Eye example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte eye[8]={ 31 | B00111100, 32 | B01111110, 33 | B11111111, 34 | B11111111, 35 | B11111111, 36 | B11111111, 37 | B01111110, 38 | B00111100 39 | }; 40 | 41 | byte pupil = B00011000; 42 | 43 | int currentPupilX = 0; 44 | int currentPupilY = 0; 45 | int targetPupilX = 0; 46 | int targetPupilY = 0; 47 | int blinkState = 0; 48 | 49 | #define PUPIL_MIN_OFFSET -2 50 | #define PUPIL_MAX_OFFSET 2 51 | #define PUPIL_SPEED 50 52 | 53 | #define BLINK_SPEED 20 54 | #define SPIN_SPEED 10 55 | #define SPIN_COUNT 3 56 | 57 | #define DEFAULT_STATE 0 58 | #define PUPIL_ANIM_STATE 100 59 | #define PUPIL_ANIM_LOOP_STATE 101 60 | #define BLINK_ANIM_STATE 200 61 | #define BLINK_ANIM_OPEN_LOOP_STATE 201 62 | #define BLINK_ANIM_CLOSE_LOOP_STATE 202 63 | #define HORIZONTAL_SPIN_STATE 300 64 | #define ROUND_SPIN_STATE 400 65 | 66 | Petduino pet = Petduino(); 67 | 68 | void setup() { 69 | 70 | // Setup Petduino 71 | pet.begin(); 72 | 73 | // Set initial state 74 | pet.setState(DEFAULT_STATE); 75 | 76 | // Initialize random seed 77 | randomSeed(analogRead(0)); 78 | 79 | } 80 | 81 | void loop() { 82 | 83 | // Update the pet 84 | pet.update(); 85 | 86 | // Check buttons 87 | if(pet.isBtn1Pressed()){ 88 | pet.setState(HORIZONTAL_SPIN_STATE); 89 | } 90 | 91 | if(pet.isBtn2Pressed()){ 92 | pet.setState(ROUND_SPIN_STATE); 93 | } 94 | 95 | // Update display based on current state 96 | switch(pet.getState()){ 97 | 98 | case DEFAULT_STATE: 99 | if (random(0, 5) == 0) { 100 | pet.setState(BLINK_ANIM_STATE); // Random blink 101 | } else { 102 | drawEye(); 103 | pet.setNextState(PUPIL_ANIM_STATE, random(5, 7) * 500); // Move pupil 104 | } 105 | break; 106 | 107 | case PUPIL_ANIM_STATE: 108 | // Choose random pupil position 109 | targetPupilX = random(PUPIL_MIN_OFFSET, PUPIL_MAX_OFFSET + 1); 110 | targetPupilY = random(PUPIL_MIN_OFFSET, PUPIL_MAX_OFFSET + 1); 111 | // Don't break so we fall throuh to first loop straight away 112 | case PUPIL_ANIM_LOOP_STATE: 113 | if(currentPupilX != targetPupilX || currentPupilY != targetPupilY){ 114 | updatePupilAnim(); 115 | pet.setNextState(PUPIL_ANIM_LOOP_STATE, PUPIL_SPEED); 116 | } else { 117 | pet.setState(DEFAULT_STATE); 118 | } 119 | break; 120 | 121 | case BLINK_ANIM_STATE: 122 | blinkState = 0; 123 | // Don't break so we fall throuh to first loop straight away 124 | case BLINK_ANIM_CLOSE_LOOP_STATE: 125 | if(blinkState < 4) { 126 | updateBlinkAnim(); 127 | blinkState++; 128 | pet.setNextState(BLINK_ANIM_CLOSE_LOOP_STATE, BLINK_SPEED); 129 | } else { 130 | pet.setState(BLINK_ANIM_OPEN_LOOP_STATE); 131 | } 132 | break; 133 | case BLINK_ANIM_OPEN_LOOP_STATE: 134 | if(blinkState > 0) { 135 | updateBlinkAnim(); 136 | blinkState--; 137 | pet.setNextState(BLINK_ANIM_OPEN_LOOP_STATE, BLINK_SPEED); 138 | } else { 139 | drawEye(); 140 | pet.setState(DEFAULT_STATE); 141 | } 142 | break; 143 | 144 | case HORIZONTAL_SPIN_STATE: 145 | horizontalSpin(); 146 | pet.setNextState(DEFAULT_STATE, 1000); 147 | break; 148 | 149 | case ROUND_SPIN_STATE: 150 | roundSpin(); 151 | pet.setNextState(DEFAULT_STATE, 1000); 152 | break; 153 | } 154 | 155 | } 156 | 157 | // Spin the eye around in a circle [BLOCKING] 158 | void roundSpin() { 159 | 160 | // Force eye open 161 | while(blinkState > 0) { 162 | blinkState--; 163 | updateBlinkAnim(); 164 | delay(BLINK_SPEED); 165 | } 166 | 167 | // Position the pupil 168 | targetPupilX = 2; 169 | targetPupilY = 0; 170 | 171 | while(currentPupilX != targetPupilX || currentPupilY != targetPupilY) { 172 | updatePupilAnim(); 173 | delay(PUPIL_SPEED); 174 | } 175 | 176 | delay(200); 177 | 178 | // Perform spin 179 | for (int t=0; t 0) { 201 | blinkState--; 202 | updateBlinkAnim(); 203 | delay(BLINK_SPEED); 204 | } 205 | 206 | // Position the pupil 207 | targetPupilX = 0; 208 | targetPupilY = 0; 209 | 210 | while(currentPupilX != targetPupilX || currentPupilY != targetPupilY) { 211 | updatePupilAnim(); 212 | delay(PUPIL_SPEED); 213 | } 214 | 215 | delay(200); 216 | 217 | // Perform the spin 218 | for (int t=0; t -4){ 221 | currentPupilX--; 222 | drawEye(); 223 | delay(SPIN_SPEED); 224 | } 225 | 226 | currentPupilX = 4; 227 | 228 | while(currentPupilX > 0){ 229 | currentPupilX--; 230 | drawEye(); 231 | delay(SPIN_SPEED); 232 | } 233 | } 234 | } 235 | 236 | // Redraw blinking eye 237 | void updateBlinkAnim() { 238 | for(int b=0; b<8; b++){ 239 | if(b <= blinkState || b >= 7-blinkState){ 240 | pet.drawRow(b, B00000000); 241 | } else { 242 | drawEyeRow(b, eye[b]); 243 | } 244 | } 245 | } 246 | 247 | // Calculate and apply next anim step 248 | void updatePupilAnim() { 249 | 250 | // Calculate number of steps needed 251 | int stepsX = abs(currentPupilX - targetPupilX); 252 | int stepsY = abs(currentPupilY - targetPupilY); 253 | 254 | // Make sure we have at least 1 step 255 | if ((stepsX == 0) && (stepsY == 0)) 256 | return; 257 | 258 | // Calculate max steps 259 | int dirX = (targetPupilX >= currentPupilX) ? 1 : -1; 260 | int dirY = (targetPupilY >= currentPupilY) ? 1 : -1; 261 | int steps = (stepsX > stepsY) ? stepsX : stepsY; 262 | 263 | // Calculate next step 264 | float changeX = (float)stepsX / (float)steps; 265 | float changeY = (float)stepsY / (float)steps; 266 | 267 | // Apply next step 268 | int newX = limitPupilOffset(currentPupilX + round(changeX * dirX)); 269 | int newY = limitPupilOffset(currentPupilY + round(changeY * dirY)); 270 | 271 | // Redraw eye 272 | moveEye(newX, newY); 273 | 274 | } 275 | 276 | // Move the eye to a specific offset 277 | void moveEye(int xOffset, int yOffset) { 278 | currentPupilX = xOffset; 279 | currentPupilY = yOffset; 280 | drawEye(); 281 | } 282 | 283 | // Redraw the current eye 284 | void drawEye() { 285 | for(int r=0; r<8; r++) { 286 | drawEyeRow(r, eye[r]); 287 | } 288 | } 289 | 290 | // Draw eye row merging in the current pupil 291 | void drawEyeRow(int r, byte value) { 292 | 293 | // Calculate indexes for pupil rows (perform offset Y) 294 | int row1 = 3 - currentPupilY; 295 | int row2 = 4 - currentPupilY; 296 | 297 | if(r == row1 || r == row2){ 298 | if(currentPupilX >= 0){ 299 | pet.drawRow(r, value ^ (pupil >> currentPupilX)); 300 | } else { 301 | pet.drawRow(r, value ^ (pupil << abs(currentPupilX))); 302 | } 303 | } else { 304 | pet.drawRow(r, value); 305 | } 306 | } 307 | 308 | // Ensure value falls within offset limits 309 | int limitPupilOffset(int value) { 310 | if (value > PUPIL_MAX_OFFSET) 311 | return PUPIL_MAX_OFFSET; 312 | else if (value < PUPIL_MIN_OFFSET) 313 | return PUPIL_MIN_OFFSET; 314 | else 315 | return value; 316 | } 317 | -------------------------------------------------------------------------------- /examples/Games/DotDotRevolution/DotDotRevolution.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * DotDotRevolution.ino - Dot dot revolution game example using the Petduino library 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include 29 | 30 | byte intro[8]= { 31 | B01100000, 32 | B11110000, 33 | B11110000, 34 | B01100000, 35 | B00000110, 36 | B00001111, 37 | B00001111, 38 | B00000110 39 | }; 40 | 41 | #define COUNTDOWN_FRAME_COUNT 5 42 | byte countdownF[COUNTDOWN_FRAME_COUNT][8]={ 43 | { 44 | B00111100, 45 | B01111110, 46 | B11111111, 47 | B11111111, 48 | B11111111, 49 | B11111111, 50 | B01111110, 51 | B00111100 52 | }, 53 | { 54 | B00110000, 55 | B01110000, 56 | B11110000, 57 | B11110000, 58 | B11111111, 59 | B11111111, 60 | B01111110, 61 | B00111100 62 | }, 63 | { 64 | B00110000, 65 | B01110000, 66 | B11110000, 67 | B11110000, 68 | B11110000, 69 | B11110000, 70 | B01110000, 71 | B00110000 72 | }, 73 | { 74 | B00110000, 75 | B01110000, 76 | B11110000, 77 | B11110000, 78 | B00000000, 79 | B00000000, 80 | B00000000, 81 | B00000000 82 | }, 83 | { 84 | B00000000, 85 | B00000000, 86 | B00000000, 87 | B00000000, 88 | B00000000, 89 | B00000000, 90 | B00000000, 91 | B00000000 92 | } 93 | }; 94 | unsigned long countdownD[COUNTDOWN_FRAME_COUNT] = { 1000, 1000, 1000, 1000, 1000 }; 95 | 96 | #define NUMBER_COUNT 10 97 | byte numbers[NUMBER_COUNT][8] = { 98 | { 0xE0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xE0 }, 99 | { 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 100 | { 0xE0, 0x20, 0x20, 0xE0, 0x80, 0x80, 0x80, 0xE0 }, 101 | { 0xE0, 0x20, 0x20, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 102 | { 0xA0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0x20 }, 103 | { 0xE0, 0x80, 0x80, 0xE0, 0x20, 0x20, 0x20, 0xE0 }, 104 | { 0xE0, 0x80, 0x80, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 105 | { 0xE0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 106 | { 0xE0, 0xA0, 0xA0, 0xE0, 0xA0, 0xA0, 0xA0, 0xE0 }, 107 | { 0xE0, 0xA0, 0xA0, 0xE0, 0x20, 0x20, 0x20, 0xE0 } 108 | }; 109 | 110 | byte gameBoard[8] { 111 | B00000000, 112 | B00000000, 113 | B00000000, 114 | B00000000, 115 | B00000000, 116 | B00000000, 117 | B00000000, 118 | B00011000 119 | }; 120 | 121 | unsigned int score = 0; 122 | unsigned int lives = 6; 123 | 124 | byte emptyMask = B00000000; 125 | byte leftMask = B11000000; 126 | byte rightMask = B00000011; 127 | byte leftAndRightMask = B11000011; 128 | byte middleMask = B00011000; 129 | 130 | byte prevRowMask; 131 | byte lastRowMask; 132 | long nextMove; 133 | bool gameStarted = false; 134 | bool btn1Pressed = false; 135 | bool btn2Pressed = false; 136 | 137 | unsigned long speed; 138 | unsigned int scoreOnes; 139 | unsigned int scoreTens; 140 | 141 | #define INTRO_STATE 0 142 | #define COUNTDOWN_STATE 1 143 | #define GAME_START_STATE 2 144 | #define GAME_LOOP_STATE 3 145 | #define GAME_OVER_STATE 4 146 | 147 | Petduino pet = Petduino(); 148 | 149 | void setup() { 150 | 151 | // Setup Petduino 152 | pet.begin(); 153 | 154 | // Set initial state 155 | pet.setState(INTRO_STATE); 156 | 157 | // Initialize random seed 158 | randomSeed(analogRead(0)); 159 | 160 | } 161 | 162 | void loop() { 163 | 164 | // Update pet 165 | pet.update(); 166 | 167 | // Check buttons 168 | if(pet.isBtn1Pressed()){ 169 | if(!gameStarted){ 170 | pet.setState(COUNTDOWN_STATE); 171 | } else { 172 | btn1Pressed = true; 173 | } 174 | } 175 | 176 | if(pet.isBtn2Pressed()){ 177 | if(!gameStarted){ 178 | pet.setState(COUNTDOWN_STATE); 179 | } else { 180 | btn2Pressed = true; 181 | } 182 | } 183 | 184 | // Update based on state 185 | switch(pet.getState()) { 186 | 187 | case INTRO_STATE: 188 | pet.drawImage(intro); 189 | pet.wait(); // Wait for button press 190 | break; 191 | 192 | case COUNTDOWN_STATE: 193 | pet.playAnimation(countdownF, countdownD, COUNTDOWN_FRAME_COUNT, 1); 194 | pet.setNextState(GAME_START_STATE, 5000); 195 | break; 196 | 197 | case GAME_START_STATE: 198 | 199 | // Reset variables 200 | score = 0; 201 | lives = 6; 202 | gameStarted = true; 203 | btn1Pressed = false; 204 | btn2Pressed = false; 205 | 206 | // Reset board 207 | for(int i=0; i<8; i++){ 208 | gameBoard[i] = gameBoard[i] & middleMask; 209 | } 210 | 211 | // Start game 212 | pet.setState(GAME_LOOP_STATE); 213 | break; 214 | 215 | case GAME_LOOP_STATE: 216 | 217 | // Check buttons 218 | lastRowMask = gameBoard[7] & leftAndRightMask; 219 | 220 | if(lastRowMask == leftAndRightMask) { 221 | if(btn1Pressed && btn2Pressed){ 222 | score++; 223 | } else { 224 | lives--; 225 | } 226 | } else if(lastRowMask == leftMask) { 227 | if(btn1Pressed && !btn2Pressed){ 228 | score++; 229 | } else { 230 | lives--; 231 | } 232 | } else if(lastRowMask == rightMask) { 233 | if(!btn1Pressed && btn2Pressed){ 234 | score++; 235 | } else { 236 | lives--; 237 | } 238 | } else if(lastRowMask == emptyMask) { 239 | if(btn1Pressed || btn2Pressed) { 240 | lives--; 241 | } 242 | } 243 | 244 | // Check to see if we've used up all our lives 245 | if(lives <= 0) { 246 | 247 | // No lives left, go to game over screen 248 | pet.setState(GAME_OVER_STATE); 249 | 250 | } else { 251 | 252 | // Shift items down 253 | for(int i = 7; i>=1; --i){ 254 | prevRowMask = gameBoard[i-1] & leftAndRightMask; 255 | gameBoard[i] = gameBoard[i] & middleMask; 256 | gameBoard[i] = gameBoard[i] | prevRowMask; 257 | } 258 | 259 | // Choose next move 260 | gameBoard[0] = gameBoard[0] & middleMask; 261 | 262 | nextMove = random(0, 6); 263 | if(nextMove == 1) { 264 | gameBoard[0] = gameBoard[0] | leftMask; 265 | } else if(nextMove == 2) { 266 | gameBoard[0] = gameBoard[0] | rightMask; 267 | } else if(nextMove == 3) { 268 | gameBoard[0] = gameBoard[0] | leftAndRightMask; 269 | } 270 | 271 | // Update lives display 272 | for(int i=5; i>=0; --i){ 273 | if(i+1 > lives){ 274 | gameBoard[5-i] = gameBoard[5-i] & leftAndRightMask; 275 | } else { 276 | gameBoard[5-i] = gameBoard[5-i] | middleMask; 277 | } 278 | } 279 | 280 | // Reset button presses 281 | btn1Pressed = false; 282 | btn2Pressed = false; 283 | 284 | // Increase speed as score goes up 285 | if(score > 70) { 286 | speed = 300; 287 | } else if(score > 60) { 288 | speed = 350; 289 | } else if(score > 50) { 290 | speed = 400; 291 | } else if(score > 40) { 292 | speed = 450; 293 | } else if(score > 30) { 294 | speed = 500; 295 | } else if(score > 20) { 296 | speed = 550; 297 | } else if(score > 10) { 298 | speed = 600; 299 | } else { 300 | speed = 700; 301 | } 302 | 303 | // Draw the board and loop 304 | pet.drawImage(gameBoard); 305 | pet.setNextState(GAME_LOOP_STATE, speed); 306 | 307 | } 308 | 309 | break; 310 | 311 | case GAME_OVER_STATE: 312 | 313 | // Stop the game 314 | gameStarted = false; 315 | 316 | // Split the score digits 317 | scoreTens = score/10; 318 | scoreOnes = score-scoreTens*10; 319 | 320 | // Generate & draw score number graphic 321 | for(int b = 0; b < 8; b++){ 322 | pet.drawRow(b, numbers[scoreTens][b] | numbers[scoreOnes][b] >> 4); 323 | } 324 | 325 | // Go back to intro 326 | pet.setNextState(INTRO_STATE, 3000); 327 | break; 328 | 329 | } 330 | 331 | } 332 | -------------------------------------------------------------------------------- /src/Petduino.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Petduino.cpp - An Arduino library for interacting with a Petduino 3 | * Copyright (c) 2015 Circuitbeard 4 | * 5 | * Permission is hereby granted, free of charge, to any person 6 | * obtaining a copy of this software and associated documentation 7 | * files (the "Software"), to deal in the Software without 8 | * restriction, including without limitation the rights to use, 9 | * copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following 12 | * conditions: 13 | * 14 | * This permission notice shall be included in all copies or 15 | * substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 19 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 21 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 22 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24 | * OTHER DEALINGS IN THE SOFTWARE. 25 | */ 26 | 27 | #include "Petduino.h" 28 | 29 | // Constructor 30 | Petduino::Petduino() { 31 | } 32 | 33 | // Setup inputs, outputs, etc. Call this from main arduino setup() method 34 | void Petduino::begin(){ 35 | 36 | //Serial.begin(9600); 37 | 38 | // Setup outputs ----------------------------------- 39 | 40 | // MAX72XX is in power-saving mode on startup, we have to do a wakeup call 41 | lc.shutdown(0, false); 42 | 43 | // set the brightness to low 44 | lc.setIntensity(0, 1); 45 | 46 | // Setup pins 47 | pinMode(LED, OUTPUT); 48 | pinMode(BUZZER, OUTPUT); 49 | 50 | // Setup inputs ------------------------------------ 51 | pinMode(BTN1, INPUT); 52 | digitalWrite(BTN1, HIGH); 53 | pinMode(BTN2, INPUT); 54 | digitalWrite(BTN2, HIGH); 55 | pinMode(LDR, INPUT); 56 | pinMode(TMP, INPUT); 57 | 58 | // Flash LED to show ready 59 | setLed(true); 60 | delay(100); 61 | setLed(false); 62 | delay(100); 63 | setLed(true); 64 | delay(100); 65 | setLed(false); 66 | 67 | } 68 | 69 | // Update function to be called from main loop() method 70 | void Petduino::update() { 71 | updateMelody(); 72 | updateAnimation(); 73 | } 74 | 75 | // Protected =========================================== 76 | 77 | // Check to see if the state timer has expired and thus a change of state needs to occur 78 | bool Petduino::stateIntervalExpired() { 79 | if (stateInterval > 0 && millis() - stateTimestamp >= stateInterval) { 80 | stateTimestamp = millis(); 81 | return true; 82 | } 83 | return false; 84 | } 85 | 86 | // Read pin state with debounce 87 | bool Petduino::debounce(uint8_t pin, int &state, int &lastState, unsigned long &debounceTimestamp) { 88 | bool changed = false; 89 | int reading = digitalRead(pin); 90 | if(reading != lastState) { 91 | debounceTimestamp = millis(); 92 | } 93 | if((millis() - debounceTimestamp) > DEBOUNCE_TIME) 94 | { 95 | if (reading != state) { 96 | state = reading; 97 | changed = true; 98 | } 99 | } 100 | lastState = reading; 101 | return changed; 102 | } 103 | 104 | // Helper method to perform melody updates. Should be called in loop() 105 | void Petduino::updateMelody() { 106 | if(melodyLength > 0){ 107 | unsigned long ts = millis(); 108 | if(ts - melodyTimestamp > melodyDurations[melodyIdx] + 5) { // Add 5 to give tone time between calls (Seems to need it) 109 | unsigned int nextIdx = melodyIdx + 1; 110 | if(nextIdx < melodyLength){ 111 | melodyIdx = nextIdx; 112 | melodyTimestamp = ts; 113 | playMelodyTone(melodyIdx); 114 | } else { 115 | if(melodyLoopCounter < melodyLoopCount - 1) { 116 | melodyIdx = 0; 117 | melodyTimestamp = ts; 118 | melodyLoopCounter++; 119 | playMelodyTone(melodyIdx); 120 | } else { 121 | stopTone(); 122 | } 123 | } 124 | } 125 | } 126 | } 127 | 128 | // Helper method to play a melody tone at the given index 129 | void Petduino::playMelodyTone(unsigned long idx) { 130 | if(melodyFrequencies[idx] > 0){ 131 | tone(BUZZER, melodyFrequencies[idx], melodyDurations[idx]); 132 | } else { 133 | noTone(BUZZER); 134 | } 135 | } 136 | 137 | // Helper method to perform animation updates. Should be called in loop() 138 | void Petduino::updateAnimation() { 139 | if(animLength > 0) { 140 | unsigned long ts = millis(); 141 | if(ts - animTimestamp > animFrameDurations[animIdx] + 5) { // Add 5 to give tone time between calls (Seems to need it) 142 | unsigned int nextIdx = animIdx + 1; 143 | if(nextIdx < animLength){ 144 | animIdx = nextIdx; 145 | animTimestamp = ts; 146 | playAnimationFrame(animIdx); 147 | } else { 148 | if(animLoopCounter < animLoopCount - 1) { 149 | animIdx = 0; 150 | animTimestamp = ts; 151 | animLoopCounter++; 152 | playAnimationFrame(animIdx); 153 | } else { 154 | stopAnimation(); 155 | } 156 | } 157 | } 158 | } 159 | } 160 | 161 | // Helper method to render an animation frame at the given index 162 | void Petduino::playAnimationFrame(unsigned long idx) { 163 | drawImage(animFrames[idx]); 164 | } 165 | 166 | // Public ============================================ 167 | 168 | // Set the value of the Petduino LED 169 | void Petduino::setLed(bool value) { 170 | digitalWrite(LED, value); 171 | } 172 | 173 | // Toggle the Petduino LED 174 | void Petduino::toggleLed() { 175 | digitalWrite(LED, !digitalRead(LED)); 176 | } 177 | 178 | // Get the Petduino LED state 179 | bool Petduino::getLed() { 180 | return digitalRead(LED) == HIGH; 181 | } 182 | 183 | // Get's the current temperature reading in °C from the temperature sensor 184 | float Petduino::getTemperature() { 185 | float temp = analogRead(TMP)*5/1024.0; // Convert reading to voltage 186 | temp = temp - 0.5; // Calibrate to 0°C 187 | temp = temp / 0.01; // Divide by mV per step 188 | return temp; 189 | } 190 | 191 | // Get's the current light level reading from the ldr sensor 192 | int Petduino::getLightLevel() { 193 | return analogRead(LDR); 194 | } 195 | 196 | // Returns true if button 1 is pressed 197 | bool Petduino::isBtn1Pressed() { 198 | bool changed = debounce(BTN1, btn1State, btn1LastState, btn1DebounceTimestamp); 199 | return btn1State == LOW && changed; 200 | } 201 | 202 | // Returns true while button 1 is held down 203 | bool Petduino::isBtn1Held() { 204 | debounce(BTN1, btn1State, btn1LastState, btn1DebounceTimestamp); 205 | return btn1State == LOW; 206 | } 207 | 208 | // Returns true if button 2 is pressed 209 | bool Petduino::isBtn2Pressed() { 210 | bool changed = debounce(BTN2, btn2State, btn2LastState, btn2DebounceTimestamp); 211 | return btn2State == LOW && changed; 212 | } 213 | 214 | // Returns true while button 2 is held down 215 | bool Petduino::isBtn2Held() { 216 | debounce(BTN2, btn2State, btn2LastState, btn2DebounceTimestamp); 217 | return btn2State == LOW; 218 | } 219 | 220 | // Plays a tone at the given frequency for the specified duration 221 | void Petduino::playTone(unsigned int frequency, unsigned long duration) { 222 | stopTone(); 223 | tone(BUZZER, frequency, duration); 224 | } 225 | 226 | // Plays a melody specified by the freq / duration arrays 227 | void Petduino::playMelody(unsigned int frequencies[], unsigned long durations[], unsigned long length, unsigned long loopCount) { 228 | stopTone(); 229 | melodyFrequencies = frequencies; 230 | melodyDurations = durations; 231 | melodyLength = length; 232 | melodyLoopCount = loopCount; 233 | melodyTimestamp = millis(); 234 | playMelodyTone(melodyIdx); 235 | } 236 | 237 | // Stops the current tone 238 | void Petduino::stopTone() { 239 | melodyLength = 0; 240 | melodyLoopCount = 0; 241 | melodyIdx = 0; 242 | melodyLoopCounter = 0; 243 | noTone(BUZZER); 244 | } 245 | 246 | // Sets the brightness of the screen from 0 to 8 247 | void Petduino::setScreenBrightness(unsigned int level) { 248 | lc.setIntensity(0, level); 249 | } 250 | 251 | // Turns on all pixels on the screen 252 | void Petduino::fillScreen() { 253 | byte b = B11111111; 254 | for (int r=0; r<8; r++) 255 | { 256 | drawRow(r, b); 257 | } 258 | } 259 | 260 | // Turns off all pixels on the screen 261 | void Petduino::clearScreen() { 262 | lc.clearDisplay(0); 263 | } 264 | 265 | // Draw a row to the display 266 | void Petduino::drawRow(int row, byte val) { 267 | // Because the screen is rotated, fill the oposite row and use setColumn not setRow 268 | row = abs(row - 7); 269 | lc.setColumn(0, row, val); 270 | } 271 | 272 | // Draw an image to the screen 273 | void Petduino::drawImage(byte img[]) { 274 | for(int r=0; r<8; r++) { 275 | drawRow(r, img[r]); 276 | } 277 | } 278 | 279 | // Draw an animation seuquence to the screen 280 | void Petduino::playAnimation(byte frames[][8], unsigned long frameDurations[], unsigned long length, unsigned long loopCount) { 281 | stopAnimation(); 282 | animFrames = frames; 283 | animFrameDurations = frameDurations; 284 | animLength = length; 285 | animLoopCount = loopCount; 286 | animTimestamp = millis(); 287 | playAnimationFrame(animIdx); 288 | } 289 | 290 | // Stops the current animation 291 | void Petduino::stopAnimation() { 292 | animLength = 0; 293 | animLoopCount = 0; 294 | animIdx = 0; 295 | animLoopCounter = 0; 296 | } 297 | 298 | // Gets the current state, switching state if next action should occur 299 | unsigned int Petduino::getState() { 300 | if(currentState == WAIT_INTERVAL_STATE && stateIntervalExpired()) { 301 | setState(nextState); 302 | } 303 | return currentState; 304 | } 305 | 306 | // Sets the current state without waiting, canceling any previously scheduled states 307 | void Petduino::setState(unsigned int state) { 308 | setNextState(state, 0); 309 | } 310 | 311 | // Lines up the next state to move to after the given interval 312 | void Petduino::setNextState(unsigned int state, unsigned long interval) { 313 | if(interval == 0) { 314 | currentState = state; // Apply the state imediatly 315 | stateInterval = 0; // Reset state interval 316 | } else { 317 | currentState = WAIT_INTERVAL_STATE; // Set to wait mode 318 | nextState = state; // Store next state 319 | stateInterval = interval; // Store interval to wait 320 | stateTimestamp = millis(); // Store current time 321 | } 322 | } 323 | 324 | // Wait indefinately 325 | void Petduino::wait() { 326 | setState(WAIT_STATE); 327 | } 328 | --------------------------------------------------------------------------------