Print a message to a custom LED matrix and play a song on a piezo buzzer.
Dependencies: Adafruit_32x8matrix
main.cpp@10:aa7764fae417, 2021-11-08 (annotated)
- Committer:
- maclobdell
- Date:
- Mon Nov 08 22:45:16 2021 +0000
- Revision:
- 10:aa7764fae417
- Parent:
- 9:d70273b3133b
uses switch to trigger start.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
maclobdell | 8:5f5ceafa826d | 1 | /* |
maclobdell | 8:5f5ceafa826d | 2 | * Copyright (c) 2016 ARM Limited. All rights reserved. |
maclobdell | 8:5f5ceafa826d | 3 | * SPDX-License-Identifier: Apache-2.0 |
maclobdell | 8:5f5ceafa826d | 4 | * Licensed under the Apache License, Version 2.0 (the License); you may |
maclobdell | 8:5f5ceafa826d | 5 | * not use this file except in compliance with the License. |
maclobdell | 8:5f5ceafa826d | 6 | * You may obtain a copy of the License at |
maclobdell | 8:5f5ceafa826d | 7 | * |
maclobdell | 8:5f5ceafa826d | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
maclobdell | 8:5f5ceafa826d | 9 | * |
maclobdell | 8:5f5ceafa826d | 10 | * Unless required by applicable law or agreed to in writing, software |
maclobdell | 8:5f5ceafa826d | 11 | * distributed under the License is distributed on an AS IS BASIS, WITHOUT |
maclobdell | 8:5f5ceafa826d | 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
maclobdell | 8:5f5ceafa826d | 13 | * See the License for the specific language governing permissions and |
maclobdell | 8:5f5ceafa826d | 14 | * limitations under the License. |
maclobdell | 8:5f5ceafa826d | 15 | */ |
maclobdell | 8:5f5ceafa826d | 16 | |
maclobdell | 9:d70273b3133b | 17 | #include "mbed.h" // this tells us to load mbed related functions |
maclobdell | 9:d70273b3133b | 18 | #include "tones.h" // list of all the tones and their frequencies |
maclobdell | 0:2eec8a9428ea | 19 | |
maclobdell | 6:8d2eb79a4baf | 20 | #include "Adafruit_32x8matrix.h" |
maclobdell | 8:5f5ceafa826d | 21 | |
maclobdell | 6:8d2eb79a4baf | 22 | #define I2C_ADDR1 0x70 |
maclobdell | 6:8d2eb79a4baf | 23 | #define I2C_ADDR2 0x71 |
maclobdell | 6:8d2eb79a4baf | 24 | #define ROTATION1 0 |
maclobdell | 6:8d2eb79a4baf | 25 | #define ROTATION2 2 |
maclobdell | 6:8d2eb79a4baf | 26 | #define BRIGHTNESS 1 |
maclobdell | 8:5f5ceafa826d | 27 | |
maclobdell | 0:2eec8a9428ea | 28 | I2C i2c(D14, D15); |
maclobdell | 8:5f5ceafa826d | 29 | |
maclobdell | 6:8d2eb79a4baf | 30 | Adafruit_32x8matrix matrix(&i2c, I2C_ADDR1, I2C_ADDR2, ROTATION1, ROTATION2, BRIGHTNESS); |
maclobdell | 10:aa7764fae417 | 31 | Thread t1; |
maclobdell | 10:aa7764fae417 | 32 | Thread t2; |
maclobdell | 10:aa7764fae417 | 33 | InterruptIn sw(D4); |
maclobdell | 10:aa7764fae417 | 34 | EventQueue queue1(32 * EVENTS_EVENT_SIZE); |
maclobdell | 10:aa7764fae417 | 35 | EventQueue queue2(32 * EVENTS_EVENT_SIZE); |
maclobdell | 9:d70273b3133b | 36 | |
maclobdell | 9:d70273b3133b | 37 | PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation) |
maclobdell | 9:d70273b3133b | 38 | |
maclobdell | 9:d70273b3133b | 39 | static int BPM = 80; |
maclobdell | 9:d70273b3133b | 40 | |
maclobdell | 9:d70273b3133b | 41 | static void silence() { |
maclobdell | 9:d70273b3133b | 42 | buzzer.write(0.0f); // silence! |
maclobdell | 9:d70273b3133b | 43 | } |
maclobdell | 9:d70273b3133b | 44 | |
maclobdell | 9:d70273b3133b | 45 | // this is our function that plays a tone. |
maclobdell | 9:d70273b3133b | 46 | // Takes in a tone frequency, and after duration (in ms.) we stop playing again |
maclobdell | 9:d70273b3133b | 47 | static void play_tone(int tone) { |
maclobdell | 9:d70273b3133b | 48 | buzzer.period_us(1000000/(tone)); |
maclobdell | 9:d70273b3133b | 49 | buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud |
maclobdell | 9:d70273b3133b | 50 | } |
maclobdell | 9:d70273b3133b | 51 | |
maclobdell | 9:d70273b3133b | 52 | static void play_song(int notes_left, int* melody, int* duration) { |
maclobdell | 9:d70273b3133b | 53 | |
maclobdell | 9:d70273b3133b | 54 | // melody and duration are pointers, they point to the array of tones and durations we declared earlier |
maclobdell | 9:d70273b3133b | 55 | // every time we play a note we up these pointers (move one element forward) |
maclobdell | 9:d70273b3133b | 56 | // so the current tone is always the first element of melody (same for duration) |
maclobdell | 9:d70273b3133b | 57 | |
maclobdell | 9:d70273b3133b | 58 | int length; |
maclobdell | 9:d70273b3133b | 59 | |
maclobdell | 9:d70273b3133b | 60 | while(notes_left > 0) |
maclobdell | 9:d70273b3133b | 61 | { |
maclobdell | 9:d70273b3133b | 62 | |
maclobdell | 9:d70273b3133b | 63 | int tone = melody[0]; |
maclobdell | 9:d70273b3133b | 64 | // BPM is quarter notes per minute, so length in milliseconds is: |
maclobdell | 9:d70273b3133b | 65 | length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000))); |
maclobdell | 9:d70273b3133b | 66 | |
maclobdell | 9:d70273b3133b | 67 | play_tone(tone); |
maclobdell | 9:d70273b3133b | 68 | |
maclobdell | 9:d70273b3133b | 69 | // after half the length of this tone, we silence |
maclobdell | 9:d70273b3133b | 70 | wait_ms(length / 2); |
maclobdell | 9:d70273b3133b | 71 | silence(); |
maclobdell | 9:d70273b3133b | 72 | |
maclobdell | 9:d70273b3133b | 73 | //after the full length of this tone, call next note |
maclobdell | 9:d70273b3133b | 74 | wait_ms(length); |
maclobdell | 9:d70273b3133b | 75 | |
maclobdell | 9:d70273b3133b | 76 | // after the full length of this tone, we up the melody, and down the notes_left |
maclobdell | 9:d70273b3133b | 77 | |
maclobdell | 9:d70273b3133b | 78 | notes_left--; |
maclobdell | 9:d70273b3133b | 79 | melody++; |
maclobdell | 9:d70273b3133b | 80 | duration++; |
maclobdell | 9:d70273b3133b | 81 | |
maclobdell | 9:d70273b3133b | 82 | } |
maclobdell | 9:d70273b3133b | 83 | |
maclobdell | 9:d70273b3133b | 84 | // we're done! just finish this note and silence |
maclobdell | 9:d70273b3133b | 85 | wait_ms(length / 2); |
maclobdell | 9:d70273b3133b | 86 | silence(); |
maclobdell | 9:d70273b3133b | 87 | } |
maclobdell | 9:d70273b3133b | 88 | |
maclobdell | 10:aa7764fae417 | 89 | void start_song() |
maclobdell | 9:d70273b3133b | 90 | { |
maclobdell | 9:d70273b3133b | 91 | // declare a melody |
maclobdell | 10:aa7764fae417 | 92 | int melody[] = { |
maclobdell | 9:d70273b3133b | 93 | NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_E5, NOTE_G5 |
maclobdell | 9:d70273b3133b | 94 | }; |
maclobdell | 9:d70273b3133b | 95 | |
maclobdell | 9:d70273b3133b | 96 | // note durations: 4 = quarter note, 8 = eighth note, etc.: |
maclobdell | 9:d70273b3133b | 97 | // the rapid succession of 16th notes produces a twill effect |
maclobdell | 9:d70273b3133b | 98 | int duration[] = { |
maclobdell | 9:d70273b3133b | 99 | 8, 8, 8, 4, 8, 2 |
maclobdell | 9:d70273b3133b | 100 | }; |
maclobdell | 9:d70273b3133b | 101 | |
maclobdell | 9:d70273b3133b | 102 | // melody & duration are on the heap, need to get them on the stack |
maclobdell | 9:d70273b3133b | 103 | int *m = new int[sizeof(melody) / sizeof(int)]; |
maclobdell | 9:d70273b3133b | 104 | memcpy(m, melody, sizeof(melody)); |
maclobdell | 9:d70273b3133b | 105 | int *d = new int[sizeof(duration) / sizeof(int)]; |
maclobdell | 9:d70273b3133b | 106 | memcpy(d, duration, sizeof(duration)); |
maclobdell | 9:d70273b3133b | 107 | |
maclobdell | 9:d70273b3133b | 108 | |
maclobdell | 9:d70273b3133b | 109 | if (sizeof(melody) != sizeof(duration)) { |
maclobdell | 9:d70273b3133b | 110 | printf("Melody and duration do not have same number of elements! Aborting!\r\n"); |
maclobdell | 4:8641e4da6744 | 111 | } |
maclobdell | 9:d70273b3133b | 112 | |
maclobdell | 9:d70273b3133b | 113 | for (int i = 0; i< 3; i++) |
maclobdell | 10:aa7764fae417 | 114 | { |
maclobdell | 10:aa7764fae417 | 115 | play_song(sizeof(melody) / sizeof(int), m, d); |
maclobdell | 9:d70273b3133b | 116 | Thread::wait(100); |
maclobdell | 9:d70273b3133b | 117 | } |
maclobdell | 10:aa7764fae417 | 118 | |
maclobdell | 10:aa7764fae417 | 119 | } |
maclobdell | 10:aa7764fae417 | 120 | |
maclobdell | 10:aa7764fae417 | 121 | void start_display() |
maclobdell | 10:aa7764fae417 | 122 | { |
maclobdell | 10:aa7764fae417 | 123 | char buffer [50]; |
maclobdell | 10:aa7764fae417 | 124 | snprintf(buffer, 50, "GO TIGERS!\0"); //pass in max chars to prevent overflow |
maclobdell | 10:aa7764fae417 | 125 | |
maclobdell | 10:aa7764fae417 | 126 | for (int i = 0; i< 3; i++) { |
maclobdell | 10:aa7764fae417 | 127 | matrix.playText(buffer,strlen(buffer), 1); |
maclobdell | 10:aa7764fae417 | 128 | Thread::wait(250); |
maclobdell | 10:aa7764fae417 | 129 | } |
maclobdell | 10:aa7764fae417 | 130 | } |
maclobdell | 10:aa7764fae417 | 131 | |
maclobdell | 10:aa7764fae417 | 132 | void switch_handler(void) |
maclobdell | 10:aa7764fae417 | 133 | { |
maclobdell | 10:aa7764fae417 | 134 | queue1.call(start_song); |
maclobdell | 10:aa7764fae417 | 135 | queue2.call(start_display); |
maclobdell | 10:aa7764fae417 | 136 | |
maclobdell | 10:aa7764fae417 | 137 | } |
maclobdell | 10:aa7764fae417 | 138 | |
maclobdell | 10:aa7764fae417 | 139 | int main() { |
maclobdell | 10:aa7764fae417 | 140 | |
maclobdell | 10:aa7764fae417 | 141 | // Start the event queues |
maclobdell | 10:aa7764fae417 | 142 | t1.start(callback(&queue1, &EventQueue::dispatch_forever)); |
maclobdell | 10:aa7764fae417 | 143 | t2.start(callback(&queue2, &EventQueue::dispatch_forever)); |
maclobdell | 10:aa7764fae417 | 144 | |
maclobdell | 10:aa7764fae417 | 145 | // Call handler when the switch is pressed |
maclobdell | 10:aa7764fae417 | 146 | sw.fall(switch_handler); |
maclobdell | 10:aa7764fae417 | 147 | |
maclobdell | 10:aa7764fae417 | 148 | while(1) |
maclobdell | 10:aa7764fae417 | 149 | {//chill |
maclobdell | 10:aa7764fae417 | 150 | } |
maclobdell | 10:aa7764fae417 | 151 | |
maclobdell | 9:d70273b3133b | 152 | return 0; |
maclobdell | 8:5f5ceafa826d | 153 | |
maclobdell | 1:dd1d1b64b9a5 | 154 | } |