├── .gitignore ├── .vscode └── launch.json ├── .yotta.json ├── .yotta_ignore ├── LICENSE ├── README.md ├── debugOnVisualStudioCode.gif ├── module.json └── source ├── examples ├── accelerometer │ └── main.cpp ├── bluetooth-eddystone-uid │ ├── config.json │ └── main.cpp ├── bluetooth-eddystone-url │ ├── config.json │ └── main.cpp ├── bluetooth-services │ ├── config.json │ └── main.cpp ├── bluetooth-uart │ ├── config.json │ └── main.cpp ├── button-events │ └── main.cpp ├── greyscale │ └── main.cpp ├── hello-world │ └── main.cpp ├── invaders │ └── main.cpp ├── logic-gates │ └── main.cpp ├── out-of-box-experience │ ├── config.json │ └── main.cpp ├── proximity-heart │ ├── config.json │ └── main.cpp ├── simple-animation │ └── main.cpp ├── simple-radio-rx │ ├── config.json │ └── main.cpp ├── simple-radio-tx │ ├── config.json │ └── main.cpp └── snake │ └── main.cpp └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | yotta_targets 3 | yotta_modules 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Microbit Debug", 6 | "type": "cppdbg", 7 | "request": "launch", 8 | "program": "${workspaceRoot}\\build\\bbc-microbit-classic-gcc\\source\\microbit-samples-combined.hex", 9 | "args": [], 10 | "stopAtEntry": true, 11 | "cwd": "${workspaceRoot}", 12 | "environment": [], 13 | "externalConsole": true, 14 | "debugServerArgs": "--persist -t nrf51 -bh -r", 15 | "serverLaunchTimeout": 20000, 16 | "filterStderr": true, 17 | "filterStdout": false, 18 | "serverStarted": "GDB\\ server\\ started", 19 | "logging": { 20 | "moduleLoad": false, 21 | "trace": true, 22 | "engineLogging": true, 23 | "programOutput": true, 24 | "exceptions": false 25 | }, 26 | "windows": { 27 | "MIMode": "gdb", 28 | "MIDebuggerPath": "C:\\Program Files (x86)\\GNU Tools Arm Embedded\\4.9 2015q2\\bin\\arm-none-eabi-gdb.exe", 29 | "debugServerPath": "C:\\yotta\\workspace\\Scripts\\pyocd-gdbserver.exe", 30 | "debugServerArgs": "--persist -t nrf51 -bh -r", 31 | "setupCommands": [ 32 | { "text": "-environment-cd ${workspaceRoot}\\build\\bbc-microbit-classic-gcc\\source" }, 33 | { "text": "-target-select remote localhost:3333", "description": "connect to target", "ignoreFailures": false }, 34 | { "text": "-interpreter-exec console \"monitor reset\"", "ignoreFailures": false }, 35 | { "text": "-interpreter-exec console \"monitor halt\"", "ignoreFailures": false }, 36 | { "text": "-interpreter-exec console \"monitor soft_reset_halt\"", "ignoreFailures": false }, 37 | { "text": "-file-exec-file ./microbit-samples-combined.hex", "description": "load file", "ignoreFailures": false}, 38 | { "text": "-file-symbol-file ./microbit-samples", "description": "load synbol file", "ignoreFailures": false}, 39 | ] 40 | } 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /.yotta.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "target": "bbc-microbit-classic-gcc,https://github.com/lancaster-university/yotta-target-bbc-microbit-classic-gcc" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.yotta_ignore: -------------------------------------------------------------------------------- 1 | source/examples 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 British Broadcasting Corporation. 4 | This software is provided by Lancaster University by arrangement with the BBC. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a 7 | copy of this software and associated documentation files (the "Software"), 8 | to deal in the Software without restriction, including without limitation 9 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # microbit-samples 2 | 3 | A collection of example programs using the micro:bit runtime. 4 | 5 | The source/examples folder contains a selection of samples demonstrating the capabilities and usage of the runtime APIs. 6 | To select a sample, simply copy the .cpp files from the relevant folder into the source/ folder. 7 | 8 | e.g. to select the "invaders" example: 9 | 10 | ``` 11 | cp source/examples/invaders/* source 12 | ``` 13 | 14 | and then to compile your sample: 15 | 16 | ``` 17 | yt clean 18 | yt build 19 | ``` 20 | 21 | The HEX file for you micro:bit with then be generated and stored in build\bbc-microbit-classic-gcc\source\microbit-samples-combined.hex 22 | 23 | n.b. Any samples using the low level RADIO APIs (such as simple-radio-rx and simple-radio-tx) require the bluetooth capabilities of the 24 | micro:bit to be disabled. To do this, simply copy the config.json file from the sample to the top level of your project. Don't forget to 25 | remove this file again later if you then want to use Bluetooth! For example: 26 | 27 | 28 | ``` 29 | cp source/examples/simple-radio-rx/config.json . 30 | ``` 31 | 32 | 33 | ## Overview 34 | 35 | The micro:bit runtime provides an easy to use environment for programming the BBC micro:bit in the C/C++ language, written by Lancaster University. It contains device drivers for all the hardware capabilities of the micro:bit, and also a suite of runtime mechanisms to make programming the micro:bit easier and more flexible. These range from control of the LED matrix display to peer-to-peer radio communication and secure Bluetooth Low Energy services. The micro:bit runtime is proudly built on the ARM mbed and Nordic nrf51 platforms. 36 | 37 | In addition to supporting development in C/C++, the runtime is also designed specifically to support higher level languages provided by our partners that target the micro:bit. It is currently used as a support library for all the languages on the BBC www.microbit.co.uk website, including Microsoft Block, Microsoft TouchDevelop, Code Kingdoms JavaScript and Micropython languages. 38 | 39 | ## Links 40 | 41 | [micro:bit runtime docs](http://lancaster-university.github.io/microbit-docs/) | [microbit-dal](https://github.com/lancaster-university/microbit-dal) | [uBit](https://github.com/lancaster-university/microbit) 42 | 43 | ## Build Environments 44 | 45 | | Build Environment | Documentation | 46 | | ------------- |-------------| 47 | | ARM mbed online | http://lancaster-university.github.io/microbit-docs/online-toolchains/#mbed | 48 | | yotta | http://lancaster-university.github.io/microbit-docs/offline-toolchains/#yotta | 49 | 50 | ## microbit-dal Configuration 51 | 52 | The DAL also contains a number of compile time options can be modified. A full list and explanation 53 | can be found in our [documentation](http://lancaster-university.github.io/microbit-docs/advanced/#compile-time-options-with-microbitconfigh). 54 | 55 | Alternately, `yotta` can be used to configure the dal regardless of module/folder structure, through providing a 56 | `config.json` in this directory. 57 | 58 | Here is an example of `config.json` with all available options configured: 59 | ```json 60 | { 61 | "microbit-dal":{ 62 | "bluetooth":{ 63 | "enabled": 1, 64 | "pairing_mode": 1, 65 | "private_addressing": 0, 66 | "open": 0, 67 | "whitelist": 1, 68 | "advertising_timeout": 0, 69 | "tx_power": 0, 70 | "dfu_service": 1, 71 | "event_service": 1, 72 | "device_info_service": 1 73 | }, 74 | "reuse_sd": 1, 75 | "default_pullmode":"PullDown", 76 | "gatt_table_size": "0x300", 77 | "heap_allocator": 1, 78 | "nested_heap_proportion": 0.75, 79 | "system_tick_period": 6, 80 | "system_components": 10, 81 | "idle_components": 6, 82 | "use_accel_lsb": 0, 83 | "min_display_brightness": 1, 84 | "max_display_brightness": 255, 85 | "display_scroll_speed": 120, 86 | "display_scroll_stride": -1, 87 | "display_print_speed": 400, 88 | "panic_on_heap_full": 1, 89 | "debug": 0, 90 | "heap_debug": 0, 91 | "stack_size":2048, 92 | "sram_base":"0x20000008", 93 | "sram_end":"0x20004000", 94 | "sd_limit":"0x20002000", 95 | "gatt_table_start":"0x20001900" 96 | } 97 | } 98 | ``` 99 | ## Debug on Visual Studio Code (Windows) 100 | 101 | 1. build sample. You can build "HELLO WORLD! :)" program. 102 | 2. Copy microbit-samples\build\bbc-microbit-classic-gcc\source\microbit-samples-combined.hex to micro:bit. 103 | 3. Launch the Visual Studio Code 104 | 4. File -> Open Folder... and select "microbit-samples" folder. 105 | 5. Set break point to "main()" function. 106 | 6. View -> Debug (Ctrl + Shift + D) 107 | 7. Debug -> Start Debugging (F5) 108 | 109 | ![Debug on Visual Studio Code](/debugOnVisualStudioCode.gif) 110 | 111 | ## BBC Community Guidelines 112 | 113 | [BBC Community Guidelines](https://www.microbit.co.uk/help#sect_cg) 114 | -------------------------------------------------------------------------------- /debugOnVisualStudioCode.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lancaster-university/microbit-samples/285f9acfb54fce2381339164b6fe5c1a7ebd39d5/debugOnVisualStudioCode.gif -------------------------------------------------------------------------------- /module.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "microbit-samples", 3 | "version": "2.1.1", 4 | "description": "The micro:bit runtime common abstraction with examples.", 5 | "license": "MIT", 6 | "dependencies": { 7 | "microbit": "lancaster-university/microbit#v2.1.1" 8 | }, 9 | "targetDependencies": {}, 10 | "bin": "./source" 11 | } 12 | -------------------------------------------------------------------------------- /source/examples/accelerometer/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | // 31 | // Scales the given value that is in the -1024 to 1024 range 32 | // int a value between 0 and 4. 33 | // 34 | int pixel_from_g(int value) 35 | { 36 | int x = 0; 37 | 38 | if (value > -750) 39 | x++; 40 | if (value > -250) 41 | x++; 42 | if (value > 250) 43 | x++; 44 | if (value > 750) 45 | x++; 46 | 47 | return x; 48 | } 49 | 50 | int main() 51 | { 52 | // Initialise the micro:bit runtime. 53 | uBit.init(); 54 | 55 | // 56 | // Periodically read the accelerometer x and y values, and plot a 57 | // scaled version of this ont the display. 58 | // 59 | while(1) 60 | { 61 | int x = pixel_from_g(uBit.accelerometer.getX()); 62 | int y = pixel_from_g(uBit.accelerometer.getY()); 63 | 64 | uBit.display.image.clear(); 65 | uBit.display.image.setPixelValue(x, y, 255); 66 | 67 | uBit.sleep(100); 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /source/examples/bluetooth-eddystone-uid/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal": { 3 | "bluetooth": { 4 | "enabled": 1, 5 | "pairing_mode": 0, 6 | "private_addressing": 0, 7 | "open": 0, 8 | "whitelist": 0, 9 | "advertising_timeout": 0, 10 | "tx_power": 0, 11 | "dfu_service": 0, 12 | "event_service": 0, 13 | "device_info_service": 0, 14 | "eddystone_url": 0, 15 | "eddystone_uid": 1, 16 | "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" 17 | }, 18 | "gatt_table_size": "0x600" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/examples/bluetooth-eddystone-uid/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MicroBit.h" 2 | 3 | MicroBit uBit; 4 | 5 | char UID_NAMESPACE[] = {0x0E,0x67,0x47,0x04,0x42,0xD0,0x14,0x06,0xD5,0x83}; // sha-1 hash of "com.bittysoftware" 6 | char UID_INSTANCE[] = {0x00 , 0x00, 0x00, 0x00, 0x00, 0x01}; 7 | const int8_t CALIBRATED_POWERS[] = {-49, -37, -33, -28, -25, -20, -15, -10}; 8 | 9 | uint8_t advertising = 0; 10 | uint8_t tx_power_level = 6; 11 | 12 | void startAdvertising() { 13 | uBit.bleManager.advertiseEddystoneUid(UID_NAMESPACE, UID_INSTANCE, CALIBRATED_POWERS[tx_power_level-1], false); 14 | uBit.bleManager.setTransmitPower(6); 15 | uBit.display.scroll("ADV"); 16 | advertising = 1; 17 | } 18 | 19 | void stopAdvertising() { 20 | uBit.bleManager.stopAdvertising(); 21 | uBit.display.scroll("OFF"); 22 | advertising = 0; 23 | } 24 | 25 | void onButtonA(MicroBitEvent) 26 | { 27 | if (advertising == 1) { 28 | return; 29 | } 30 | startAdvertising(); 31 | } 32 | 33 | void onButtonB(MicroBitEvent) 34 | { 35 | if (advertising == 0) { 36 | return; 37 | } 38 | stopAdvertising(); 39 | } 40 | 41 | int main() 42 | { 43 | // Initialise the micro:bit runtime. 44 | uBit.init(); 45 | 46 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA); 47 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB); 48 | 49 | startAdvertising(); 50 | 51 | release_fiber(); 52 | } 53 | -------------------------------------------------------------------------------- /source/examples/bluetooth-eddystone-url/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal": { 3 | "bluetooth": { 4 | "enabled": 1, 5 | "pairing_mode": 0, 6 | "private_addressing": 0, 7 | "open": 0, 8 | "whitelist": 0, 9 | "advertising_timeout": 0, 10 | "tx_power": 0, 11 | "dfu_service": 0, 12 | "event_service": 0, 13 | "device_info_service": 0, 14 | "eddystone_url": 1, 15 | "eddystone_uid": 0, 16 | "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" 17 | }, 18 | "gatt_table_size": "0x600" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /source/examples/bluetooth-eddystone-url/main.cpp: -------------------------------------------------------------------------------- 1 | #include "MicroBit.h" 2 | 3 | MicroBit uBit; 4 | 5 | char URL[] = "https://goo.gl/TlUTF7"; 6 | const int8_t CALIBRATED_POWERS[] = {-49, -37, -33, -28, -25, -20, -15, -10}; 7 | 8 | uint8_t advertising = 0; 9 | uint8_t tx_power_level = 6; 10 | 11 | void startAdvertising() { 12 | uBit.bleManager.advertiseEddystoneUrl(URL, CALIBRATED_POWERS[tx_power_level-1], false); 13 | uBit.bleManager.setTransmitPower(tx_power_level); 14 | uBit.display.scroll("ADV"); 15 | advertising = 1; 16 | } 17 | 18 | void stopAdvertising() { 19 | uBit.bleManager.stopAdvertising(); 20 | uBit.display.scroll("OFF"); 21 | advertising = 0; 22 | } 23 | 24 | void onButtonA(MicroBitEvent) 25 | { 26 | if (advertising == 1) { 27 | return; 28 | } 29 | startAdvertising(); 30 | } 31 | 32 | void onButtonB(MicroBitEvent) 33 | { 34 | if (advertising == 0) { 35 | return; 36 | } 37 | stopAdvertising(); 38 | } 39 | 40 | int main() 41 | { 42 | // Initialise the micro:bit runtime. 43 | uBit.init(); 44 | 45 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA); 46 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB); 47 | 48 | startAdvertising(); 49 | 50 | release_fiber(); 51 | } 52 | -------------------------------------------------------------------------------- /source/examples/bluetooth-services/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal": { 3 | "bluetooth": { 4 | "enabled": 1, 5 | "pairing_mode": 1, 6 | "private_addressing": 0, 7 | "open": 0, 8 | "whitelist": 1, 9 | "advertising_timeout": 0, 10 | "tx_power": 0, 11 | "dfu_service": 0, 12 | "event_service": 0, 13 | "device_info_service": 1, 14 | "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" 15 | }, 16 | "gatt_table_size": "0x700" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/examples/bluetooth-services/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | // we use events abd the 'connected' variable to keep track of the status of the Bluetooth connection 31 | void onConnected(MicroBitEvent) 32 | { 33 | uBit.display.print("C"); 34 | } 35 | 36 | void onDisconnected(MicroBitEvent) 37 | { 38 | uBit.display.print("D"); 39 | } 40 | 41 | int main() 42 | { 43 | // Initialise the micro:bit runtime. 44 | uBit.init(); 45 | 46 | // Configuration Tips 47 | // 48 | // config.json contains various Bluetooth related properties some of which are explained here: 49 | // 50 | // "dfu_service": 1, // 1 will cause the DFU service to be instantiated 51 | // "event_service": 1, // 1 causes the event service to be instantiated 52 | // "device_info_service": 1 53 | // "enabled": 1, // 1 means the Bluetooth stack will be included as standard. 0 means it will not. 54 | // "pairing_mode": 1, // 1 means it's possible to go into pairing mode which will include bringing up the Bluetooth stack whilst in that mode. 55 | // "open": 0, // 1 means there's no Bluetooth security i.e. no need to pair the micro:bit with other devices that want to communicate with it. 56 | // "tx_power": 7, // Transmission power of the Bluetooth radio. A value of 0 - 7 with 0 the lowest power and 7 the highest power. 57 | // "gatt_table_size": "0x700" // Amount of memory (in hex bytes) set aside for the Bluetooth GATT table 58 | // "nested_heap_proportion": 0.75, // Reducing this can sometimes help make enough memory available for all the Bluetooth services you want. Only experiment with this as a last resort. 59 | 60 | // MicrobitConfig.h in yotta_modules\microbit-dal\inc\core contains MICROBIT_BLE_SECURITY_LEVEL which can be set to SECURITY_MODE_ENCRYPTION_WITH_MITM for passkey authentication when 61 | // pairing or SECURITY_MODE_ENCRYPTION_NO_MITM to use Just Works pairing. 62 | 63 | // A cunning code to indicate during start-up the particular Bluetooth configuration in the build 64 | // 65 | // SERVICE CODES 66 | // A: Accelerometer Service 67 | // B: Button Service 68 | // D: Device Information Service 69 | // E: Event Service 70 | // F: DFU Service 71 | // I: IO Pin Service 72 | // L: LED Service 73 | // M: Magnetometer Service 74 | // T: Temperature Service 75 | // U: UART Service 76 | // 77 | // PAIRING CONFIG 78 | // Note that switching pairing on or off is achieved by setting "open" in config.json to 1 or 0 respectively 79 | 80 | // P: PASSKEY 81 | // J: Just Works 82 | // N: No Pairing Required 83 | // 84 | // TX Power Level 85 | // 0-7 taken from tx_power in config.json 86 | 87 | 88 | // Services/Pairing Config/Power Level 89 | uBit.display.scroll("BLE ABDILMT/P/0"); 90 | 91 | uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected); 92 | uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected); 93 | 94 | new MicroBitAccelerometerService(*uBit.ble, uBit.accelerometer); 95 | new MicroBitButtonService(*uBit.ble); 96 | new MicroBitIOPinService(*uBit.ble, uBit.io); 97 | new MicroBitLEDService(*uBit.ble, uBit.display); 98 | new MicroBitMagnetometerService(*uBit.ble, uBit.compass); 99 | new MicroBitTemperatureService(*uBit.ble, uBit.thermometer); 100 | 101 | // If main exits, there may still be other fibers running or registered event handlers etc. 102 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then 103 | // sit in the idle task forever, in a power efficient sleep. 104 | release_fiber(); 105 | } 106 | -------------------------------------------------------------------------------- /source/examples/bluetooth-uart/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal": { 3 | "bluetooth": { 4 | "enabled": 1, 5 | "pairing_mode": 1, 6 | "private_addressing": 0, 7 | "open": 0, 8 | "whitelist": 1, 9 | "advertising_timeout": 0, 10 | "tx_power": 0, 11 | "dfu_service": 1, 12 | "event_service": 0, 13 | "device_info_service": 1, 14 | "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" 15 | }, 16 | "gatt_table_size": "0x600" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /source/examples/bluetooth-uart/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | // Works with the Animal Vegetable Mineral guessing game in the Android 'micro:bit Blue' app which is obtainable from 27 | // https://play.google.com/store/apps/details?id=com.bluetooth.mwoolley.microbitbledemo 28 | 29 | #include "MicroBit.h" 30 | #include "MicroBitUARTService.h" 31 | 32 | MicroBit uBit; 33 | MicroBitUARTService *uart; 34 | 35 | int connected = 0; 36 | 37 | void onConnected(MicroBitEvent) 38 | { 39 | 40 | uBit.display.scroll("C"); 41 | 42 | connected = 1; 43 | 44 | // mobile app will send ASCII strings terminated with the colon character 45 | ManagedString eom(":"); 46 | 47 | while(connected == 1) { 48 | ManagedString msg = uart->readUntil(eom); 49 | uBit.display.scroll(msg); 50 | } 51 | 52 | } 53 | 54 | void onDisconnected(MicroBitEvent) 55 | { 56 | uBit.display.scroll("D"); 57 | connected = 0; 58 | } 59 | 60 | void onButtonA(MicroBitEvent) 61 | { 62 | if (connected == 0) { 63 | return; 64 | } 65 | uart->send(ManagedString("YES")); 66 | uBit.display.scroll("Y"); 67 | } 68 | 69 | void onButtonB(MicroBitEvent) 70 | { 71 | if (connected == 0) { 72 | return; 73 | } 74 | uart->send(ManagedString("NO")); 75 | uBit.display.scroll("N"); 76 | } 77 | 78 | void onButtonAB(MicroBitEvent) 79 | { 80 | if (connected == 0) { 81 | return; 82 | } 83 | uart->send(ManagedString("GOT IT!!")); 84 | uBit.display.scroll("!"); 85 | } 86 | 87 | int main() 88 | { 89 | // Initialise the micro:bit runtime. 90 | uBit.init(); 91 | 92 | uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_CONNECTED, onConnected); 93 | uBit.messageBus.listen(MICROBIT_ID_BLE, MICROBIT_BLE_EVT_DISCONNECTED, onDisconnected); 94 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA); 95 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB); 96 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB); 97 | 98 | 99 | // Note GATT table size increased from default in MicroBitConfig.h 100 | // #define MICROBIT_SD_GATT_TABLE_SIZE 0x500 101 | uart = new MicroBitUARTService(*uBit.ble, 32, 32); 102 | uBit.display.scroll("UART ready"); 103 | 104 | // If main exits, there may still be other fibers running or registered event handlers etc. 105 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then 106 | // sit in the idle task forever, in a power efficient sleep. 107 | release_fiber(); 108 | } 109 | -------------------------------------------------------------------------------- /source/examples/button-events/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | // 31 | // Print details of all events received to the serial port. 32 | // Default settings are 115200 baud, 8N1 over the USB interface. 33 | // 34 | void onButton(MicroBitEvent e) 35 | { 36 | if (e.source == MICROBIT_ID_BUTTON_A) 37 | uBit.serial.printf("BUTTON A: "); 38 | 39 | if (e.source == MICROBIT_ID_BUTTON_B) 40 | uBit.serial.printf("BUTTON B: "); 41 | 42 | if (e.source == MICROBIT_ID_BUTTON_AB) 43 | uBit.serial.printf("BUTTON A+B: "); 44 | 45 | if (e.source == MICROBIT_ID_IO_P0) 46 | uBit.serial.printf("TOUCH P0: "); 47 | 48 | if (e.source == MICROBIT_ID_IO_P1) 49 | uBit.serial.printf("TOUCH P1: "); 50 | 51 | if (e.source == MICROBIT_ID_IO_P2) 52 | uBit.serial.printf("TOUCH P2: "); 53 | 54 | if (e.value == MICROBIT_BUTTON_EVT_DOWN) 55 | uBit.serial.printf("DOWN"); 56 | 57 | if (e.value == MICROBIT_BUTTON_EVT_UP) 58 | uBit.serial.printf("UP"); 59 | 60 | if (e.value == MICROBIT_BUTTON_EVT_CLICK) 61 | uBit.serial.printf("CLICK"); 62 | 63 | if (e.value == MICROBIT_BUTTON_EVT_LONG_CLICK) 64 | uBit.serial.printf("LONG_CLICK"); 65 | 66 | if (e.value == MICROBIT_BUTTON_EVT_HOLD) 67 | uBit.serial.printf("HOLD"); 68 | 69 | if (e.value == MICROBIT_BUTTON_EVT_DOUBLE_CLICK) 70 | uBit.serial.printf("DOUBLE_CLICK"); 71 | 72 | uBit.serial.printf("\r\n"); 73 | } 74 | 75 | 76 | int main() 77 | { 78 | // Initialise the micro:bit runtime. 79 | uBit.init(); 80 | 81 | // Register to receive events when any buttons are clicked, including the A+B virtual button (both buttons at once). 82 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButton); 83 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButton); 84 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_EVT_ANY, onButton); 85 | 86 | // Also register for touch events on P0, P1 and P2. 87 | uBit.messageBus.listen(MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, onButton); 88 | uBit.messageBus.listen(MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, onButton); 89 | uBit.messageBus.listen(MICROBIT_ID_IO_P2, MICROBIT_EVT_ANY, onButton); 90 | 91 | // Put the P0, P1 and P2 pins into touch sense mode. 92 | uBit.io.P0.isTouched(); 93 | uBit.io.P1.isTouched(); 94 | uBit.io.P2.isTouched(); 95 | 96 | // We're done, so just enter a power efficient sleep while we wait for an event. 97 | while (1) 98 | uBit.sleep(10000); 99 | } 100 | 101 | -------------------------------------------------------------------------------- /source/examples/greyscale/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | int main() 31 | { 32 | // Initialise the micro:bit runtime. 33 | uBit.init(); 34 | 35 | // Enable per pixel rendering, with 256 level of brightness per pixel. 36 | uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE); 37 | 38 | // Draw a rainbow brightness effect across the display 39 | int value = 1; 40 | 41 | for(int j = 0; j < 5; j++) 42 | { 43 | for(int i = 0; i < 5; i++) 44 | { 45 | uBit.display.image.setPixelValue(i,j,value); 46 | value += 10; 47 | } 48 | } 49 | 50 | // Nothing else to do, so enter a power efficient sleep. 51 | while(1) 52 | uBit.sleep(10000); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /source/examples/hello-world/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | int main() 31 | { 32 | // Initialise the micro:bit runtime. 33 | uBit.init(); 34 | 35 | // Insert your code here! 36 | uBit.display.scroll("HELLO WORLD! :)"); 37 | 38 | // If main exits, there may still be other fibers running or registered event handlers etc. 39 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then 40 | // sit in the idle task forever, in a power efficient sleep. 41 | release_fiber(); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /source/examples/invaders/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 Lancaster University. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a 7 | copy of this software and associated documentation files (the "Software"), 8 | to deal in the Software without restriction, including without limitation 9 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | and/or sell copies of the Software, and to permit persons to whom the 11 | Software is furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | 26 | // 27 | // 28 | // A simple game of Space Invaders for the BBC micro:bit, using the 29 | // accelerometer and buttons to control the player's ship. 30 | // 31 | // As well as illustrating the use of sensors, the display and events, 32 | // this demonstration also provides a highly elegant example of 33 | // how fibers can be used to create safe and elegant programs... Note the 34 | // use of event handlers when the player fires, and the indepenent fibers 35 | // used to control the players ship, aliens, bullets and screen refresh... 36 | // 37 | // 38 | 39 | #include "MicroBit.h" 40 | 41 | #define GAME_ON 0 42 | #define GAME_OVER 1 43 | 44 | struct Point 45 | { 46 | int x; 47 | int y; 48 | }; 49 | 50 | MicroBit uBit; 51 | MicroBitImage invaders(5,5); 52 | int score; 53 | int game_over; 54 | int level; 55 | int INVADER_SPEED = 750; 56 | int PLAYER_SPEED = 150; 57 | int BULLET_SPEED = 50; 58 | Point player; 59 | Point bullet; 60 | 61 | /** 62 | * Add a new row of space invaders to the game. 63 | */ 64 | int 65 | addRow() 66 | { 67 | // If we're adding a row of invaders, but we're out of space, it's game over!! 68 | for (int x=0; x<5; x++) 69 | if (invaders.getPixelValue(x,4)) 70 | return GAME_OVER; 71 | 72 | // Otherwise, move down the invaders, and add a new role at the top. 73 | invaders.shiftDown(1); 74 | 75 | for (int x=1; x<4; x++) 76 | invaders.setPixelValue(x,0,255); 77 | 78 | return GAME_ON; 79 | } 80 | 81 | /* 82 | * Display Game Over and show the player's score. 83 | */ 84 | void 85 | gameOver() 86 | { 87 | uBit.display.clear(); 88 | 89 | uBit.display.scroll("GAME OVER! SCORE:"); 90 | uBit.display.scroll(score); 91 | } 92 | 93 | /* 94 | * Calculate the speed of an invaders movement, based on the game level 95 | */ 96 | int 97 | invaderSpeed() 98 | { 99 | return max(INVADER_SPEED - level*50, 50); 100 | } 101 | 102 | /* 103 | * Determine if the are any space invaders in the given column 104 | */ 105 | bool 106 | invadersInColumn(int x) 107 | { 108 | for (int y = 0; y < 5; y++) 109 | if (invaders.getPixelValue(x,y)) 110 | return true; 111 | 112 | return false; 113 | } 114 | 115 | /* 116 | * Determine the number of space invaders currently on screen 117 | */ 118 | bool 119 | invaderCount() 120 | { 121 | int count = 0; 122 | 123 | for (int x=0; x<5; x++) 124 | for (int y=0; y<5; y++) 125 | if (invaders.getPixelValue(x,y)) 126 | count++; 127 | 128 | return count; 129 | } 130 | 131 | /* 132 | * Move space invaders on the screen. 133 | */ 134 | void 135 | invaderUpdate() 136 | { 137 | bool movingRight = true; 138 | 139 | while(!game_over) 140 | { 141 | // Wait for next update; 142 | uBit.sleep(invaderSpeed()); 143 | 144 | if (movingRight) 145 | { 146 | if(invadersInColumn(4)) 147 | { 148 | movingRight = false; 149 | if (addRow() == GAME_OVER) 150 | { 151 | game_over = true; 152 | return; 153 | } 154 | } 155 | else 156 | { 157 | invaders.shiftRight(1); 158 | } 159 | } 160 | else 161 | { 162 | if(invadersInColumn(0)) 163 | { 164 | movingRight = true; 165 | if (addRow() == GAME_OVER) 166 | { 167 | game_over = true; 168 | return; 169 | } 170 | } 171 | else 172 | { 173 | invaders.shiftLeft(1); 174 | } 175 | } 176 | 177 | if (invaderCount() == 0) 178 | { 179 | level++; 180 | addRow(); 181 | } 182 | } 183 | } 184 | 185 | /* 186 | * Move the bullet up the screen 187 | */ 188 | void 189 | bulletUpdate() 190 | { 191 | while (!game_over) 192 | { 193 | uBit.sleep(BULLET_SPEED); 194 | if (bullet.y != -1) 195 | bullet.y--; 196 | 197 | if (invaders.getPixelValue(bullet.x, bullet.y) > 0) 198 | { 199 | score++; 200 | invaders.setPixelValue(bullet.x, bullet.y, 0); 201 | bullet.x = -1; 202 | bullet.y = -1; 203 | } 204 | } 205 | } 206 | 207 | /* 208 | * Move the player across the screen. 209 | */ 210 | void 211 | playerUpdate() 212 | { 213 | while (!game_over) 214 | { 215 | uBit.sleep(PLAYER_SPEED); 216 | 217 | if(uBit.accelerometer.getX() < -300 && player.x > 0) 218 | player.x--; 219 | 220 | if(uBit.accelerometer.getX() > 300 && player.x < 4) 221 | player.x++; 222 | } 223 | } 224 | 225 | /* 226 | * Fire a new missile from the player 227 | */ 228 | void 229 | fire(MicroBitEvent) 230 | { 231 | if (bullet.y == -1) 232 | { 233 | bullet.y = 4; 234 | bullet.x = player.x; 235 | } 236 | } 237 | 238 | /* 239 | * A simple game of space invaders 240 | */ 241 | void 242 | spaceInvaders() 243 | { 244 | // Reset all game state. 245 | game_over = 0; 246 | level = 0; 247 | score = 0; 248 | player.x = 2; 249 | player.y = 4; 250 | 251 | bullet.x = -1; 252 | bullet.y = -1; 253 | 254 | // Add a single row of invaders at the start.. cannon fodder! 255 | invaders.clear(); 256 | addRow(); 257 | 258 | // Spawn independent fibers to handle the movement of each player 259 | create_fiber(invaderUpdate); 260 | create_fiber(bulletUpdate); 261 | create_fiber(playerUpdate); 262 | 263 | // Register event handlers for button presses (either button fires!) 264 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, fire); 265 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, fire); 266 | 267 | // Now just keep the screen refreshed. 268 | while (!game_over) 269 | { 270 | uBit.sleep(10); 271 | uBit.display.image.paste(invaders); 272 | uBit.display.image.setPixelValue(player.x, player.y, 255); 273 | uBit.display.image.setPixelValue(bullet.x, bullet.y, 255); 274 | } 275 | 276 | // Display GAME OVER and score 277 | gameOver(); 278 | } 279 | 280 | int main() 281 | { 282 | // Initialise the micro:bit runtime. 283 | uBit.init(); 284 | 285 | // Welcome message 286 | uBit.display.scroll("INVADERS!"); 287 | 288 | // Keep playing forever 289 | while(1) 290 | spaceInvaders(); 291 | } 292 | 293 | -------------------------------------------------------------------------------- /source/examples/logic-gates/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | #define LOGIC_MODE_NOT 1 29 | #define LOGIC_MODE_AND 2 30 | #define LOGIC_MODE_OR 3 31 | #define LOGIC_MODE_OUTPUT 4 32 | 33 | #define LOGIC_MODE_MIN 1 34 | #define LOGIC_MODE_MAX 4 35 | 36 | #define TOOL_SELECT_DELAY 1000 37 | 38 | MicroBit uBit; 39 | 40 | MicroBitImage NOT("\ 41 | 0 0 1 0 0\n\ 42 | 0 0 1 1 0\n\ 43 | 1 1 1 1 1\n\ 44 | 0 0 1 1 0\n\ 45 | 0 0 1 0 0\n"); 46 | 47 | MicroBitImage AND("\ 48 | 0 0 1 1 0\n\ 49 | 1 1 1 1 1\n\ 50 | 0 0 1 1 1\n\ 51 | 1 1 1 1 1\n\ 52 | 0 0 1 1 0\n"); 53 | 54 | MicroBitImage OR("\ 55 | 0 0 0 1 0\n\ 56 | 1 1 1 1 1\n\ 57 | 0 0 0 1 1\n\ 58 | 1 1 1 1 1\n\ 59 | 0 0 0 1 0\n"); 60 | 61 | MicroBitImage OUTPUT_ON("\ 62 | 0 1 1 1 0\n\ 63 | 1 1 1 1 1\n\ 64 | 1 1 1 1 1\n\ 65 | 1 1 1 1 1\n\ 66 | 0 1 1 1 0\n"); 67 | 68 | MicroBitImage OUTPUT_OFF("\ 69 | 0 1 1 1 0\n\ 70 | 1 0 0 0 1\n\ 71 | 1 0 0 0 1\n\ 72 | 1 0 0 0 1\n\ 73 | 0 1 1 1 0\n"); 74 | 75 | int mode = LOGIC_MODE_NOT; 76 | 77 | void onShake(MicroBitEvent) 78 | { 79 | // The micro:bit has been shaken, so move on to the next logic gate. 80 | mode++; 81 | 82 | // Wrap back to the start if necessary. 83 | if (mode > LOGIC_MODE_MAX) 84 | mode = LOGIC_MODE_MIN; 85 | 86 | // Update the display to 87 | switch (mode) 88 | { 89 | case LOGIC_MODE_NOT: 90 | uBit.display.print(NOT); 91 | break; 92 | 93 | case LOGIC_MODE_AND: 94 | uBit.display.print(AND); 95 | break; 96 | 97 | case LOGIC_MODE_OR: 98 | uBit.display.print(OR); 99 | break; 100 | 101 | case LOGIC_MODE_OUTPUT: 102 | uBit.display.print(OUTPUT_OFF); 103 | break; 104 | } 105 | } 106 | 107 | int main() 108 | { 109 | // Initialise the micro:bit runtime. 110 | uBit.init(); 111 | 112 | // Register to receive events when the micro:bit is shaken. 113 | uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, onShake); 114 | 115 | // 116 | // Create a simple logic gate simulator, using the P0, P1 and P2 pins. 117 | // The micro:bit can then be configured as an NOT / AND / OR gate, by shaking the device. 118 | // 119 | int output = 0; 120 | 121 | // Our icons are drawn left to right, so rotate the display so the outputs point at the pins on the edge connector. :-) 122 | uBit.display.rotateTo(MICROBIT_DISPLAY_ROTATION_270); 123 | 124 | while (1) 125 | { 126 | // Check inputs and update outputs accordingly. 127 | switch (mode) 128 | { 129 | int o1; 130 | int o2; 131 | 132 | case LOGIC_MODE_NOT: 133 | output = uBit.buttonA.isPressed() ? 0 : !uBit.io.P0.getDigitalValue(); 134 | uBit.display.print(NOT); 135 | break; 136 | 137 | case LOGIC_MODE_AND: 138 | o1 = uBit.buttonA.isPressed() || uBit.io.P0.getDigitalValue(); 139 | o2 = uBit.buttonB.isPressed() || uBit.io.P1.getDigitalValue(); 140 | output = o1 && o2; 141 | break; 142 | 143 | case LOGIC_MODE_OR: 144 | output = uBit.buttonA.isPressed() || uBit.io.P0.getDigitalValue() || uBit.buttonB.isPressed() || uBit.io.P1.getDigitalValue(); 145 | break; 146 | 147 | case LOGIC_MODE_OUTPUT: 148 | if (uBit.io.P0.getDigitalValue()) 149 | uBit.display.print(OUTPUT_ON); 150 | else 151 | uBit.display.print(OUTPUT_OFF); 152 | 153 | output = 0; 154 | break; 155 | } 156 | 157 | // Update output pin value 158 | uBit.io.P2.setDigitalValue(output); 159 | 160 | // Perform a power efficient sleep for a little while. No need to run too quickly! 161 | uBit.sleep(1000); 162 | } 163 | } 164 | 165 | -------------------------------------------------------------------------------- /source/examples/out-of-box-experience/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal": { 3 | "bluetooth": { 4 | "enabled": 1, 5 | "private_addressing": 0, 6 | "advertising_timeout": 0, 7 | "tx_power": 6, 8 | "dfu_service": 1, 9 | "device_info_service": 1, 10 | "event_service": 1, 11 | "eddystone_url": 1, 12 | "eddystone_uid": 1, 13 | "open": 0, 14 | "pairing_mode": 1, 15 | "whitelist": 1, 16 | "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM", 17 | "partial_flashing": 0 18 | }, 19 | "gatt_table_size": "0x600" 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /source/examples/out-of-box-experience/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Technology Will Save Us and Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | #define OOB_SHAKE_OVERSAMPLING 5 29 | #define OOB_SHAKE_OVERSAMPLING_THRESHOLD 4 30 | #define OOB_SHAKE_THRESHOLD 1500 31 | 32 | MicroBit uBit; 33 | 34 | enum modes { 35 | WAKE = 0, 36 | INTRO, 37 | BUTTONA, 38 | BUTTONB, 39 | TURN, 40 | DOTCHASER, 41 | NEXT, 42 | SECRET 43 | }; 44 | 45 | int mode; 46 | int accelX, accelY; 47 | int targetX, targetY; 48 | bool flag = false; 49 | 50 | bool button_a_pressed = false; 51 | bool button_b_pressed = false; 52 | 53 | MicroBitImage currentFrame; 54 | 55 | 56 | //shake game 57 | int shakeCount; 58 | int xMin; 59 | int xMax; 60 | int yMin; 61 | int yMax; 62 | int prevX; 63 | int prevY; 64 | 65 | 66 | // Images and animations ----------------- 67 | 68 | const MicroBitImage dot("0,1,0,1,0\n1,1,1,1,1\n1,1,1,1,1\n0,1,1,1,0\n0,0,1,0,0\n"); 69 | 70 | const char *shake[] = { 71 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n", 72 | "0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,0,0,0,0\n0,0,0,0,0\n", 73 | "0,0,0,0,0\n0,1,0,1,0\n0,0,1,0,0\n0,1,0,1,0\n0,0,0,0,0\n", 74 | "0,0,1,0,0\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n0,0,1,0,0\n", 75 | "1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n", 76 | "1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n" 77 | }; 78 | 79 | const char *wakeAnim[] = { 80 | "0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,0,0,0,0\n0,0,0,0,0\n", 81 | "0,0,0,0,0\n0,1,1,1,0\n0,1,1,1,0\n0,1,1,1,0\n0,0,0,0,0\n", 82 | "1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n" 83 | }; 84 | 85 | const char *explosionTime[] = { 86 | "1,1,1,1,1\n1,0,0,0,1\n1,0,0,0,1\n1,0,0,0,1\n1,1,1,1,1\n", 87 | "1,1,1,1,1\n1,1,1,1,1\n1,1,0,1,1\n1,1,1,1,1\n1,1,1,1,1\n", 88 | "1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n1,1,1,1,1\n", 89 | "0,0,0,0,0\n0,1,1,1,0\n0,1,1,1,0\n0,1,1,1,0\n0,0,0,0,0\n", 90 | "0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,0,0,0,0\n0,0,0,0,0\n", 91 | "0,0,0,0,0\n0,1,0,1,0\n0,0,0,0,0\n0,1,0,1,0\n0,0,0,0,0\n", 92 | "1,0,0,0,1\n0,0,1,0,0\n0,1,1,1,0\n0,0,1,0,0\n1,0,0,0,1\n", 93 | "0,0,1,0,0\n0,1,0,1,0\n1,0,0,0,1\n0,1,0,1,0\n0,0,1,0,0\n", 94 | "1,0,0,0,1\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n1,0,0,0,1\n", 95 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n" 96 | }; 97 | 98 | const char *twistyTime[] = { 99 | "0,0,0,0,0\n0,0,0,0,0\n1,0,0,0,1\n0,0,0,0,0\n0,0,0,0,0\n", 100 | "0,0,0,0,0\n1,0,0,0,1\n1,1,0,1,1\n1,0,0,0,1\n0,0,0,0,0\n", 101 | "1,0,0,0,1\n1,1,0,1,1\n1,1,1,1,1\n1,1,0,1,1\n1,0,0,0,1\n", 102 | "0,0,0,1,1\n1,0,0,1,1\n1,1,1,1,1\n1,1,0,0,1\n1,1,0,0,0\n", 103 | "0,1,1,1,1\n0,0,1,1,1\n1,0,1,0,1\n1,1,1,0,0\n1,1,1,1,0\n", 104 | "1,1,1,1,1\n0,0,1,1,1\n0,0,1,0,0\n1,1,1,0,0\n1,1,1,1,1\n", 105 | "1,1,1,1,1\n0,1,1,1,0\n0,0,1,0,0\n0,1,1,1,0\n1,1,1,1,1\n", 106 | "0,1,1,1,0\n0,0,1,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,1,1,1,0\n", 107 | "0,0,1,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n", 108 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n" 109 | }; 110 | 111 | const char *heart[] = { 112 | "0,1,0,1,0\n1,1,1,1,1\n1,1,1,1,1\n0,1,1,1,0\n0,0,1,0,0\n" 113 | }; 114 | 115 | // Arrow images and animations. 116 | const MicroBitImage arrowUpTime("0,0,1,0,0\n0,1,1,1,0\n1,0,1,0,1\n0,0,1,0,0\n0,0,1,0,0\n"); 117 | 118 | const char *arrowDisintegrationTime[] = { 119 | "0,0,0,0,0\n0,0,1,0,0\n0,0,1,0,0\n1,0,1,0,1\n0,1,1,1,0\n", 120 | "0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,0,1,0,0\n1,0,1,0,1\n", 121 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n0,0,1,0,0\n", 122 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,1,0,0\n", 123 | "0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n0,0,0,0,0\n" 124 | }; 125 | 126 | // Bottom arrow from left to right 127 | const char *bottomArrow[] = { 128 | "0,0,1,0,0\n0,1,0,0,0\n1,1,1,1,1\n0,1,0,0,0\n0,0,1,0,0\n", 129 | "0,0,0,0,1\n1,0,0,1,0\n1,0,1,0,0\n1,1,0,0,0\n1,1,1,1,0\n", 130 | "0,0,1,0,0\n0,0,1,0,0\n1,0,1,0,1\n0,1,1,1,0\n0,0,1,0,0\n", 131 | "1,0,0,0,0\n0,1,0,0,1\n0,0,1,0,1\n0,0,0,1,1\n0,1,1,1,1\n", 132 | "0,0,1,0,0\n0,0,0,1,0\n1,1,1,1,1\n0,0,0,1,0\n0,0,1,0,0\n" 133 | }; 134 | 135 | const char *topArrow[] = { 136 | "0,0,1,0,0\n0,1,0,0,0\n1,1,1,1,1\n0,1,0,0,0\n0,0,1,0,0\n", 137 | "1,1,1,1,0\n1,1,0,0,0\n1,0,1,0,0\n1,0,0,1,0\n0,0,0,0,1\n", 138 | "0,0,1,0,0\n0,1,1,1,0\n1,0,1,0,1\n0,0,1,0,0\n0,0,1,0,0\n", 139 | "0,1,1,1,1\n0,0,0,1,1\n0,0,1,0,1\n0,1,0,0,1\n1,0,0,0,0\n", 140 | "0,0,1,0,0\n0,0,0,1,0\n1,1,1,1,1\n0,0,0,1,0\n0,0,1,0,0\n" 141 | }; 142 | 143 | // --------------------------- 144 | 145 | // Wake up the device 146 | void wake() 147 | { 148 | uBit.display.setBrightness(0); 149 | // Turn on all pixels. 150 | for(int y=0; y<5; y++) { 151 | for(int x=0; x<5; x++) { 152 | uBit.display.image.setPixelValue(x, y, 1); 153 | } 154 | } 155 | 156 | // Fade in all LEDs. 157 | for(int i=0; i<255; i++) { 158 | uBit.display.setBrightness(i); 159 | uBit.sleep(5); 160 | } 161 | // Fade out all LEDs. 162 | for(int i=255; i>0; i--) { 163 | uBit.display.setBrightness(i); 164 | uBit.sleep(5); 165 | } 166 | 167 | // Set brightness back to full and clear screen. 168 | uBit.display.image.clear(); 169 | uBit.display.setBrightness(255); 170 | 171 | // Pulsing animation. 172 | int animDelay = 50; 173 | for(int j=0; j<15; j++) { 174 | for(int i=0; i<3; i++) { 175 | currentFrame = MicroBitImage(wakeAnim[i]); 176 | uBit.display.print(currentFrame,0,0,0,animDelay); 177 | } 178 | for(int i=2; i>-1; i--) { 179 | currentFrame = MicroBitImage(wakeAnim[i]); 180 | uBit.display.print(currentFrame,0,0,0,animDelay); 181 | } 182 | animDelay -= 3; 183 | } 184 | 185 | // Fade out last dot. 186 | for(int i=255; i>=0; i--) { 187 | uBit.display.setBrightness(i); 188 | uBit.sleep(1); 189 | } 190 | 191 | // Clear display and set brightnes back to full. 192 | uBit.display.image.clear(); 193 | uBit.display.setBrightness(255); 194 | 195 | uBit.sleep(500); 196 | 197 | // Proceed to the next mode. 198 | mode++; 199 | } 200 | 201 | void intro() 202 | { 203 | // Introduce the micro:bit. 204 | uBit.display.image.clear(); 205 | uBit.display.scroll("HELLO."); 206 | 207 | // Proceed to the next mode. 208 | mode++; 209 | } 210 | 211 | void onButtonA(MicroBitEvent) 212 | { 213 | button_a_pressed = true; 214 | } 215 | 216 | void pressButtonA() 217 | { 218 | // Set up button A event listener 219 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA); 220 | 221 | 222 | // Wait for a button press. 223 | while(!button_a_pressed) { 224 | uBit.display.print("A ",100); 225 | uBit.sleep(1); 226 | uBit.display.print("A ",100); 227 | uBit.sleep(1); 228 | if(uBit.buttonA.isPressed()) break; 229 | 230 | currentFrame = MicroBitImage(topArrow[0]); 231 | uBit.display.print(currentFrame,0,0,0,100); 232 | uBit.sleep(100); 233 | if(uBit.buttonA.isPressed()) break; 234 | 235 | currentFrame = MicroBitImage(topArrow[0]); 236 | uBit.display.print(currentFrame,0,0,0,100); 237 | uBit.sleep(100); 238 | if(uBit.buttonA.isPressed()) break; 239 | } 240 | 241 | // SADHBH'S animation goes here. 242 | for(int i=0; i<10; i++) { 243 | currentFrame = MicroBitImage(explosionTime[i]); 244 | uBit.display.print(currentFrame,0,0,0,100); 245 | } 246 | 247 | uBit.display.stopAnimation(); 248 | uBit.sleep(1000); 249 | 250 | // Proceed to the next mode. 251 | 252 | mode++; 253 | } 254 | 255 | void onButtonB(MicroBitEvent) 256 | { 257 | button_b_pressed = true; 258 | } 259 | 260 | void pressButtonB() 261 | { 262 | // Set up button B event listener 263 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB); 264 | 265 | // Wait for a button press. 266 | while(!button_b_pressed) { 267 | uBit.display.print("B ",100); 268 | uBit.sleep(1); 269 | uBit.display.print("B ",100); 270 | uBit.sleep(1); 271 | if(uBit.buttonB.isPressed()) break; 272 | 273 | currentFrame = MicroBitImage(topArrow[4]); 274 | uBit.display.print(currentFrame,0,0,0,100); 275 | uBit.sleep(100); 276 | if(uBit.buttonB.isPressed())break; 277 | 278 | currentFrame = MicroBitImage(topArrow[4]); 279 | uBit.display.print(currentFrame,0,0,0,100); 280 | uBit.sleep(100); 281 | if(uBit.buttonB.isPressed())break; 282 | } 283 | 284 | // SADHBH'S animation goes here. 285 | for(int i=0; i<10; i++) { 286 | currentFrame = MicroBitImage(twistyTime[i]); 287 | uBit.display.print(currentFrame,0,0,0,100); 288 | } 289 | 290 | uBit.sleep(2000); 291 | 292 | // Proceed to the next mode. 293 | mode++; 294 | } 295 | 296 | void updateAccelPosition() 297 | { 298 | accelX = 0; 299 | accelY = 0; 300 | 301 | if (uBit.accelerometer.getX() > 600) 302 | accelX++; 303 | if (uBit.accelerometer.getX() > 250) 304 | accelX++; 305 | if (uBit.accelerometer.getX() > -250) 306 | accelX++; 307 | if (uBit.accelerometer.getX() > -600) 308 | accelX++; 309 | 310 | if (uBit.accelerometer.getY() > 600) 311 | accelY++; 312 | if (uBit.accelerometer.getY() > 250) 313 | accelY++; 314 | if (uBit.accelerometer.getY() > -250) 315 | accelY++; 316 | if (uBit.accelerometer.getY() > -600) 317 | accelY++; 318 | } 319 | 320 | void turn() 321 | { 322 | int timeout = 0; 323 | int samples_high; 324 | int x, y, z, magnitude; 325 | 326 | uBit.display.scroll("SHAKE!"); 327 | 328 | uBit.accelerometer.setRange(8); 329 | 330 | xMax = uBit.accelerometer.getX(); 331 | yMax = uBit.accelerometer.getY(); 332 | 333 | while(timeout < 10000) { 334 | samples_high = 0; 335 | for (int samples = 0; samples < OOB_SHAKE_OVERSAMPLING; samples++) 336 | { 337 | x = uBit.accelerometer.getX(); 338 | y = uBit.accelerometer.getY(); 339 | z = uBit.accelerometer.getZ(); 340 | magnitude = sqrt((x*x)+(y*y)+(z*z)); 341 | 342 | if (magnitude > OOB_SHAKE_THRESHOLD) 343 | samples_high++; 344 | } 345 | 346 | if (samples_high >= OOB_SHAKE_OVERSAMPLING_THRESHOLD) 347 | shakeCount++; 348 | else 349 | shakeCount--; 350 | 351 | // Clamp shakeCount within range 0..4 352 | shakeCount = min(shakeCount, 4); 353 | shakeCount = max(shakeCount, 0); 354 | 355 | // Display an image matching the shake intensity measured 356 | currentFrame = MicroBitImage(shake[shakeCount]); 357 | uBit.display.print(currentFrame); 358 | 359 | // Wait a while. 360 | uBit.sleep(150); 361 | timeout += 150; 362 | } 363 | 364 | uBit.accelerometer.setRange(2); 365 | uBit.display.image.clear(); 366 | uBit.sleep(1000); 367 | 368 | mode++; 369 | } 370 | 371 | void insertNewTarget() 372 | { 373 | targetX = uBit.random(4); 374 | targetY = uBit.random(4); 375 | if(targetX == 0 && targetY == 0) targetY++; 376 | else if(targetX == 0 && targetY == 4) targetY--; 377 | else if(targetX == 4 && targetY == 0) targetY++; 378 | else if(targetX == 4 && targetY == 4) targetY--; 379 | } 380 | 381 | void dotChaser() 382 | { 383 | uBit.display.scroll("CHASE THE DOT"); 384 | 385 | int score = 0; 386 | int toggle = 0; 387 | int toggleCount = 0; 388 | 389 | while(score < 6) { 390 | if(toggleCount % 5 == 0) toggle = 255-toggle; 391 | 392 | updateAccelPosition(); 393 | 394 | uBit.display.image.clear(); 395 | uBit.display.image.setPixelValue(accelX, accelY, 255); 396 | uBit.display.image.setPixelValue(targetX, targetY, toggle); 397 | 398 | if(targetX == accelX && targetY == accelY) { 399 | insertNewTarget(); 400 | score++; 401 | } 402 | 403 | uBit.sleep(100); 404 | 405 | toggleCount++; 406 | } 407 | 408 | // Fade out last dot. 409 | for(int i=255; i>=0; i--) { 410 | uBit.display.setBrightness(i); 411 | uBit.sleep(1); 412 | } 413 | 414 | // Clear display and set brightnes back to full. 415 | uBit.display.image.clear(); 416 | uBit.display.setBrightness(255); 417 | 418 | uBit.sleep(2000); 419 | 420 | mode++; 421 | } 422 | 423 | #define SNAKE_EMPTY 0 424 | #define SNAKE_UP 1 425 | #define SNAKE_LEFT 2 426 | #define SNAKE_RIGHT 3 427 | #define SNAKE_DOWN 4 428 | 429 | 430 | #define SNAKE_FRAME_DELAY 350 431 | 432 | struct Point 433 | { 434 | int x; 435 | int y; 436 | }; 437 | 438 | Point head; // Location of the head of our snake. 439 | Point tail; // Location of the tail of our snake. 440 | Point food; // Location of food. 441 | MicroBitImage map(5,5); 442 | 443 | 444 | void place_food() 445 | { 446 | int r = uBit.random(24); 447 | int x = 0; int y = 0; 448 | 449 | while (r > 0) 450 | { 451 | x = (x+1) % 5; 452 | if (x == 0) 453 | y = (y+1) % 5; 454 | 455 | if(map.getPixelValue(x,y) == SNAKE_EMPTY) 456 | r--; 457 | } 458 | 459 | food.x = x; 460 | food.y = y; 461 | } 462 | 463 | void snake() 464 | { 465 | Point newHead; // Calculated placement of new head position based on user input. 466 | int hdirection; // Head's direction of travel 467 | int tdirection; // Tail's direction of travel 468 | int snakeLength; // number of segments in the snake. 469 | int growing; // boolean state indicating if we've just eaten some food. 470 | 471 | // Start in the middle of the screen. 472 | tail.x = tail.y = 2; 473 | head.x = head.y = 2; 474 | snakeLength = 1; 475 | growing = 0; 476 | map.clear(); 477 | 478 | uBit.display.image.setPixelValue(head.x, head.y, 255); 479 | 480 | // Add some random food. 481 | place_food(); 482 | 483 | while (1) 484 | { 485 | // Flash the food is necessary; 486 | uBit.display.image.setPixelValue(food.x, food.y, uBit.systemTime() % 1000 < 500 ? 0 : 255); 487 | 488 | int dx = uBit.accelerometer.getX(); 489 | int dy = uBit.accelerometer.getY(); 490 | 491 | newHead.x = head.x; 492 | newHead.y = head.y; 493 | 494 | if (abs(dx) > abs(dy)) 495 | { 496 | if(dx < 0) 497 | { 498 | hdirection = SNAKE_LEFT; 499 | newHead.x = newHead.x == 0 ? 4 : newHead.x-1; 500 | } 501 | else 502 | { 503 | hdirection = SNAKE_RIGHT; 504 | newHead.x = newHead.x == 4 ? 0 : newHead.x+1; 505 | } 506 | } 507 | else 508 | { 509 | if(dy < 0) 510 | { 511 | hdirection = SNAKE_UP; 512 | newHead.y = newHead.y == 0 ? 4 : newHead.y-1; 513 | } 514 | else 515 | { 516 | hdirection = SNAKE_DOWN; 517 | newHead.y = newHead.y == 4 ? 0 : newHead.y+1; 518 | } 519 | } 520 | 521 | int status = map.getPixelValue(newHead.x, newHead.y); 522 | if (status == SNAKE_UP || status == SNAKE_DOWN || status == SNAKE_LEFT || status == SNAKE_RIGHT) 523 | { 524 | ManagedString s("GAME OVER! SCORE: "); 525 | ManagedString s2(snakeLength-1); 526 | 527 | uBit.display.scroll(s); 528 | uBit.display.scroll(s2); 529 | 530 | return; 531 | } 532 | 533 | // move the head. 534 | map.setPixelValue(head.x, head.y, hdirection); 535 | uBit.display.image.setPixelValue(newHead.x, newHead.y, 255); 536 | 537 | if (growing) 538 | { 539 | growing = 0; 540 | snakeLength++; 541 | } 542 | else 543 | { 544 | // move the tail. 545 | tdirection = map.getPixelValue(tail.x,tail.y); 546 | map.setPixelValue(tail.x, tail.y, SNAKE_EMPTY); 547 | uBit.display.image.setPixelValue(tail.x, tail.y, 0); 548 | 549 | // Move our record of the tail's location. 550 | if (snakeLength == 1) 551 | { 552 | tail.x = newHead.x; 553 | tail.y = newHead.y; 554 | } 555 | else 556 | { 557 | if (tdirection == SNAKE_UP) 558 | tail.y = tail.y == 0 ? 4 : tail.y-1; 559 | 560 | if (tdirection == SNAKE_DOWN) 561 | tail.y = tail.y == 4 ? 0 : tail.y+1; 562 | 563 | if (tdirection == SNAKE_LEFT) 564 | tail.x = tail.x == 0 ? 4 : tail.x-1; 565 | 566 | if (tdirection == SNAKE_RIGHT) 567 | tail.x = tail.x == 4 ? 0 : tail.x+1; 568 | } 569 | } 570 | 571 | // Update our record of the head location and away we go! 572 | head.x = newHead.x; 573 | head.y = newHead.y; 574 | 575 | // if we've eaten some food, replace the food and grow ourselves! 576 | if (head.x == food.x && head.y == food.y) 577 | { 578 | growing = 1; 579 | place_food(); 580 | } 581 | 582 | uBit.sleep(SNAKE_FRAME_DELAY); 583 | } 584 | } 585 | 586 | void next() 587 | { 588 | if(flag == false){ 589 | flag = true; 590 | uBit.display.scroll("GREAT! NOW GET CODING!"); 591 | } 592 | while(!uBit.buttonA.isPressed() && !uBit.buttonB.isPressed()){ 593 | for(int i=0; i<10; i++) { 594 | currentFrame = MicroBitImage(twistyTime[i]); 595 | uBit.display.print(currentFrame,0,0,0,100); 596 | if(uBit.buttonA.isPressed() && uBit.buttonB.isPressed()){ 597 | uBit.display.stopAnimation(); 598 | break; 599 | } 600 | } 601 | for(int i=0; i<10; i++) { 602 | currentFrame = MicroBitImage(explosionTime[i]); 603 | uBit.display.print(currentFrame,0,0,0,100); 604 | if(uBit.buttonA.isPressed() && uBit.buttonB.isPressed()){ 605 | uBit.display.stopAnimation(); 606 | break; 607 | } 608 | } 609 | currentFrame = MicroBitImage(heart[0]); 610 | uBit.display.print(currentFrame,0,0,0,400); 611 | uBit.sleep(100); 612 | if(uBit.buttonA.isPressed() && uBit.buttonB.isPressed()){ 613 | uBit.display.stopAnimation(); 614 | break; 615 | } 616 | } 617 | mode++; 618 | 619 | 620 | 621 | 622 | } 623 | 624 | int 625 | main() 626 | { 627 | uBit.init(); 628 | 629 | 630 | new MicroBitAccelerometerService(*uBit.ble, uBit.accelerometer); 631 | new MicroBitButtonService(*uBit.ble); 632 | new MicroBitLEDService(*uBit.ble, uBit.display); 633 | new MicroBitTemperatureService(*uBit.ble, uBit.thermometer); 634 | 635 | if(uBit.buttonA.isPressed()) mode = SECRET; 636 | while(1) 637 | { 638 | switch(mode) { 639 | 640 | case WAKE: 641 | wake(); 642 | break; 643 | 644 | case INTRO: 645 | intro(); 646 | break; 647 | 648 | case BUTTONA: 649 | pressButtonA(); 650 | break; 651 | 652 | case BUTTONB: 653 | pressButtonB(); 654 | break; 655 | 656 | case TURN: 657 | turn(); 658 | break; 659 | 660 | case DOTCHASER: 661 | dotChaser(); 662 | break; 663 | 664 | case NEXT: 665 | next(); 666 | break; 667 | 668 | case SECRET: 669 | snake(); 670 | break; 671 | } 672 | } 673 | } 674 | 675 | -------------------------------------------------------------------------------- /source/examples/proximity-heart/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal":{ 3 | "bluetooth":{ 4 | "enabled": 0 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /source/examples/proximity-heart/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | 27 | /* 28 | * This is a simple example that uses the micro:bit radio to show if another 29 | * micro:bit running the same code is nearby. 30 | * 31 | * Each micro:bit is periodically broadcasting a group name, and listening 32 | * to see if another micro:bit in that group is also in-range. 33 | * 34 | * When another micro:bit in the same group is detected, the display of the 35 | * detecting micro:bit will show a filled-in heart shape 36 | * 37 | * Otherwise, the display will show an empty heart shape 38 | * 39 | */ 40 | 41 | #include "MicroBit.h" 42 | 43 | #if MICROBIT_BLE_ENABLED 44 | #ifdef YOTTA_CFG 45 | #error "This example needs BLE to be disabled. Use the yotta config.json in the proximit-heart directory to do this" 46 | #else 47 | #error "This example needs BLE to be disabled in the microbit config file in the microbit-dal: MicroBitConfig.h" 48 | #endif 49 | #endif 50 | 51 | MicroBit uBit; 52 | 53 | // Have we seen a friend recently? 54 | uint8_t friend_seen = 0; 55 | 56 | // Are we currently sending out messages? 57 | uint8_t broadcast = 1; 58 | 59 | /* We have a group name, and if any micro:bit is in range and in the group 60 | * then the others will see it. 61 | */ 62 | const char group_name[] = "tiger"; 63 | 64 | const uint8_t empty_heart_arr[] { 65 | 0, 1, 0, 1, 0, 66 | 1, 0, 1, 0, 1, 67 | 1, 0, 0, 0, 1, 68 | 0, 1, 0, 1, 0, 69 | 0, 0, 1, 0, 0, }; 70 | 71 | const uint8_t full_heart_arr[] { 72 | 0, 1, 0, 1, 0, 73 | 1, 1, 1, 1, 1, 74 | 1, 1, 1, 1, 1, 75 | 0, 1, 1, 1, 0, 76 | 0, 0, 1, 0, 0, }; 77 | 78 | const uint8_t small_heart_arr[] { 79 | 0, 0, 0, 0, 0, 80 | 0, 1, 0, 1, 0, 81 | 0, 1, 1, 1, 0, 82 | 0, 1, 1, 0, 0, 83 | 0, 0, 0, 0, 0, }; 84 | 85 | MicroBitImage empty_heart(5,5,empty_heart_arr); 86 | MicroBitImage full_heart(5,5,full_heart_arr); 87 | MicroBitImage small_heart(5,5,small_heart_arr); 88 | 89 | /* We send messages when people press buttons 'A' and 'B'. 90 | * At the moment, all micro:bits listening for messages 91 | * will see these and can respond to them 92 | * Challenge: make only certain micro:bits respond to these 93 | */ 94 | void onButtonA(MicroBitEvent) 95 | { 96 | uBit.radio.datagram.send("1"); 97 | } 98 | 99 | void onButtonB(MicroBitEvent) 100 | { 101 | uBit.radio.datagram.send("2"); 102 | } 103 | 104 | /* We toggle broadcasting if both buttons are pressed together */ 105 | void onButtonAB(MicroBitEvent) 106 | { 107 | broadcast = !broadcast; 108 | uBit.display.print("!"); 109 | } 110 | 111 | 112 | void onData(MicroBitEvent) 113 | { 114 | ManagedString s = uBit.radio.datagram.recv(); 115 | int rssi = uBit.radio.getRSSI(); 116 | 117 | if (s == "1") 118 | uBit.display.print(full_heart); 119 | 120 | if (s == "2") 121 | uBit.display.print(small_heart); 122 | 123 | /* For detecting the presence of our friend, we require them to be sending 124 | * the same group name as we are in 125 | */ 126 | if (s == group_name && rssi < 70) { 127 | // We can make this larger to allow more missed packets 128 | friend_seen = 3; 129 | } 130 | } 131 | 132 | int main() 133 | { 134 | // Initialise the micro:bit runtime. 135 | uBit.init(); 136 | 137 | // Setup some button handlers to allow direct heartbeat control with buttons 138 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_EVT_ANY, onButtonA); 139 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_EVT_ANY, onButtonB); 140 | uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_EVT_ANY, onButtonAB); 141 | 142 | //Setup a hander to run when data is received 143 | uBit.messageBus.listen(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, onData); 144 | 145 | uBit.radio.enable(); 146 | 147 | while(1) { 148 | if (friend_seen) { 149 | uBit.display.print(full_heart); 150 | friend_seen -= 1; 151 | } else { 152 | uBit.display.print(empty_heart); 153 | } 154 | 155 | if (broadcast) 156 | uBit.radio.datagram.send(group_name); 157 | 158 | uBit.sleep(1000); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /source/examples/simple-animation/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | int main() 31 | { 32 | // Initialise the micro:bit runtime. 33 | uBit.init(); 34 | 35 | // Setup a simple triangular waveform. 36 | MicroBitImage img("1 0 0 0 0 0 0 0 0 1\n0 1 0 0 0 0 0 0 1 0\n0 0 1 0 0 0 0 1 0 0\n0 0 0 1 0 0 1 0 0 0\n0 0 0 0 1 1 0 0 0 0\n"); 37 | 38 | while(1) 39 | uBit.display.scroll(img, 80, -1); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /source/examples/simple-radio-rx/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal":{ 3 | "bluetooth":{ 4 | "enabled": 0 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /source/examples/simple-radio-rx/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | void onData(MicroBitEvent) 31 | { 32 | ManagedString s = uBit.radio.datagram.recv(); 33 | 34 | if (s == "1") 35 | uBit.display.print("A"); 36 | 37 | if (s == "2") 38 | uBit.display.print("B"); 39 | } 40 | 41 | int main() 42 | { 43 | // Initialise the micro:bit runtime. 44 | uBit.init(); 45 | 46 | uBit.messageBus.listen(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, onData); 47 | uBit.radio.enable(); 48 | 49 | while(1) 50 | uBit.sleep(1000); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /source/examples/simple-radio-tx/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "microbit-dal":{ 3 | "bluetooth":{ 4 | "enabled": 0 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /source/examples/simple-radio-tx/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | int main() 31 | { 32 | // Initialise the micro:bit runtime. 33 | uBit.init(); 34 | uBit.radio.enable(); 35 | 36 | while(1) 37 | { 38 | if (uBit.buttonA.isPressed()) 39 | uBit.radio.datagram.send("1"); 40 | 41 | else if (uBit.buttonB.isPressed()) 42 | uBit.radio.datagram.send("2"); 43 | 44 | uBit.sleep(100); 45 | } 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /source/examples/snake/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | #define SNAKE_EMPTY 0 29 | #define SNAKE_UP 1 30 | #define SNAKE_LEFT 2 31 | #define SNAKE_RIGHT 3 32 | #define SNAKE_DOWN 4 33 | 34 | #define SNAKE_FRAME_DELAY 350 35 | #define GROWTH_SPEED 3 36 | 37 | struct Point 38 | { 39 | int x; 40 | int y; 41 | }; 42 | 43 | MicroBit uBit; 44 | Point head; // Location of the head of our snake. 45 | Point tail; // Location of the tail of our snake. 46 | Point food; // Location of food. 47 | MicroBitImage map(5,5); 48 | 49 | void place_food() 50 | { 51 | int r = uBit.random(24); 52 | int x = 0; int y = 0; 53 | 54 | while (r > 0) 55 | { 56 | x = (x+1) % 5; 57 | if (x == 0) 58 | y = (y+1) % 5; 59 | 60 | if(map.getPixelValue(x,y) == SNAKE_EMPTY) 61 | r--; 62 | } 63 | 64 | food.x = x; 65 | food.y = y; 66 | } 67 | 68 | void snake() 69 | { 70 | Point newHead; // Calculated placement of new head position based on user input. 71 | int hdirection; // Head's direction of travel 72 | int tdirection; // Tail's direction of travel 73 | int snakeLength; // number of segments in the snake. 74 | int growing; // boolean state indicating if we've just eaten some food. 75 | int score; 76 | 77 | // Start in the middle of the screen. 78 | tail.x = tail.y = 2; 79 | head.x = head.y = 2; 80 | snakeLength = 1; 81 | growing = 0; 82 | score = 0; 83 | map.clear(); 84 | 85 | uBit.display.image.setPixelValue(head.x, head.y, 255); 86 | 87 | // Add some random food. 88 | place_food(); 89 | 90 | while (1) 91 | { 92 | // Flash the food is necessary; 93 | uBit.display.image.setPixelValue(food.x, food.y, uBit.systemTime() % 1000 < 500 ? 0 : 255); 94 | 95 | int dx = uBit.accelerometer.getX(); 96 | int dy = uBit.accelerometer.getY(); 97 | 98 | newHead.x = head.x; 99 | newHead.y = head.y; 100 | 101 | if (abs(dx) > abs(dy)) 102 | { 103 | if(dx < 0) 104 | { 105 | hdirection = SNAKE_LEFT; 106 | newHead.x = newHead.x == 0 ? 4 : newHead.x-1; 107 | } 108 | else 109 | { 110 | hdirection = SNAKE_RIGHT; 111 | newHead.x = newHead.x == 4 ? 0 : newHead.x+1; 112 | } 113 | } 114 | else 115 | { 116 | if(dy < 0) 117 | { 118 | hdirection = SNAKE_UP; 119 | newHead.y = newHead.y == 0 ? 4 : newHead.y-1; 120 | } 121 | else 122 | { 123 | hdirection = SNAKE_DOWN; 124 | newHead.y = newHead.y == 4 ? 0 : newHead.y+1; 125 | } 126 | } 127 | 128 | int status = map.getPixelValue(newHead.x, newHead.y); 129 | if (status == SNAKE_UP || status == SNAKE_DOWN || status == SNAKE_LEFT || status == SNAKE_RIGHT) 130 | { 131 | uBit.display.scroll("GAME OVER! SCORE: "); 132 | uBit.display.scroll(score); 133 | 134 | return; 135 | } 136 | 137 | // move the head. 138 | map.setPixelValue(head.x, head.y, hdirection); 139 | uBit.display.image.setPixelValue(newHead.x, newHead.y, 255); 140 | 141 | if (growing == GROWTH_SPEED) 142 | { 143 | growing = 0; 144 | snakeLength++; 145 | } 146 | else 147 | { 148 | // move the tail. 149 | tdirection = map.getPixelValue(tail.x,tail.y); 150 | map.setPixelValue(tail.x, tail.y, SNAKE_EMPTY); 151 | uBit.display.image.setPixelValue(tail.x, tail.y, 0); 152 | 153 | // Move our record of the tail's location. 154 | if (snakeLength == 1) 155 | { 156 | tail.x = newHead.x; 157 | tail.y = newHead.y; 158 | } 159 | else 160 | { 161 | if (tdirection == SNAKE_UP) 162 | tail.y = tail.y == 0 ? 4 : tail.y-1; 163 | 164 | if (tdirection == SNAKE_DOWN) 165 | tail.y = tail.y == 4 ? 0 : tail.y+1; 166 | 167 | if (tdirection == SNAKE_LEFT) 168 | tail.x = tail.x == 0 ? 4 : tail.x-1; 169 | 170 | if (tdirection == SNAKE_RIGHT) 171 | tail.x = tail.x == 4 ? 0 : tail.x+1; 172 | } 173 | } 174 | 175 | // Update our record of the head location and away we go! 176 | head.x = newHead.x; 177 | head.y = newHead.y; 178 | 179 | // if we've eaten some food, replace the food and grow ourselves! 180 | if (head.x == food.x && head.y == food.y) 181 | { 182 | growing++; 183 | score++; 184 | place_food(); 185 | } 186 | 187 | uBit.sleep(SNAKE_FRAME_DELAY); 188 | } 189 | } 190 | 191 | int main() 192 | { 193 | // Initialise the micro:bit runtime. 194 | uBit.init(); 195 | 196 | // Insert your code here! 197 | uBit.display.scroll("SNAKE v1.0"); 198 | 199 | while(1) 200 | snake(); 201 | } 202 | 203 | -------------------------------------------------------------------------------- /source/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2016 British Broadcasting Corporation. 5 | This software is provided by Lancaster University by arrangement with the BBC. 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a 8 | copy of this software and associated documentation files (the "Software"), 9 | to deal in the Software without restriction, including without limitation 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 | and/or sell copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | */ 25 | 26 | #include "MicroBit.h" 27 | 28 | MicroBit uBit; 29 | 30 | int main() 31 | { 32 | // Initialise the micro:bit runtime. 33 | uBit.init(); 34 | 35 | // Insert your code here! 36 | uBit.display.scroll("HELLO WORLD! :)"); 37 | 38 | // If main exits, there may still be other fibers running or registered event handlers etc. 39 | // Simply release this fiber, which will mean we enter the scheduler. Worse case, we then 40 | // sit in the idle task forever, in a power efficient sleep. 41 | release_fiber(); 42 | } 43 | 44 | --------------------------------------------------------------------------------