Print a message to a custom LED matrix and play a song on a piezo buzzer.
Dependencies: Adafruit_32x8matrix
main.cpp@9:d70273b3133b, 2021-11-03 (annotated)
- Committer:
- maclobdell
- Date:
- Wed Nov 03 19:49:24 2021 +0000
- Revision:
- 9:d70273b3133b
- Parent:
- 8:5f5ceafa826d
- Child:
- 10:aa7764fae417
initial version
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 | 9:d70273b3133b | 31 | Thread displayThread; |
maclobdell | 9:d70273b3133b | 32 | |
maclobdell | 9:d70273b3133b | 33 | PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation) |
maclobdell | 9:d70273b3133b | 34 | |
maclobdell | 9:d70273b3133b | 35 | static int BPM = 80; |
maclobdell | 9:d70273b3133b | 36 | |
maclobdell | 9:d70273b3133b | 37 | static void silence() { |
maclobdell | 9:d70273b3133b | 38 | buzzer.write(0.0f); // silence! |
maclobdell | 9:d70273b3133b | 39 | } |
maclobdell | 9:d70273b3133b | 40 | |
maclobdell | 9:d70273b3133b | 41 | // this is our function that plays a tone. |
maclobdell | 9:d70273b3133b | 42 | // Takes in a tone frequency, and after duration (in ms.) we stop playing again |
maclobdell | 9:d70273b3133b | 43 | static void play_tone(int tone) { |
maclobdell | 9:d70273b3133b | 44 | buzzer.period_us(1000000/(tone)); |
maclobdell | 9:d70273b3133b | 45 | buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud |
maclobdell | 9:d70273b3133b | 46 | } |
maclobdell | 9:d70273b3133b | 47 | |
maclobdell | 9:d70273b3133b | 48 | static void play_song(int notes_left, int* melody, int* duration) { |
maclobdell | 9:d70273b3133b | 49 | |
maclobdell | 9:d70273b3133b | 50 | // melody and duration are pointers, they point to the array of tones and durations we declared earlier |
maclobdell | 9:d70273b3133b | 51 | // every time we play a note we up these pointers (move one element forward) |
maclobdell | 9:d70273b3133b | 52 | // so the current tone is always the first element of melody (same for duration) |
maclobdell | 9:d70273b3133b | 53 | |
maclobdell | 9:d70273b3133b | 54 | int length; |
maclobdell | 9:d70273b3133b | 55 | |
maclobdell | 9:d70273b3133b | 56 | while(notes_left > 0) |
maclobdell | 9:d70273b3133b | 57 | { |
maclobdell | 9:d70273b3133b | 58 | |
maclobdell | 9:d70273b3133b | 59 | int tone = melody[0]; |
maclobdell | 9:d70273b3133b | 60 | // BPM is quarter notes per minute, so length in milliseconds is: |
maclobdell | 9:d70273b3133b | 61 | length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000))); |
maclobdell | 9:d70273b3133b | 62 | |
maclobdell | 9:d70273b3133b | 63 | play_tone(tone); |
maclobdell | 9:d70273b3133b | 64 | |
maclobdell | 9:d70273b3133b | 65 | // after half the length of this tone, we silence |
maclobdell | 9:d70273b3133b | 66 | wait_ms(length / 2); |
maclobdell | 9:d70273b3133b | 67 | silence(); |
maclobdell | 9:d70273b3133b | 68 | |
maclobdell | 9:d70273b3133b | 69 | //after the full length of this tone, call next note |
maclobdell | 9:d70273b3133b | 70 | wait_ms(length); |
maclobdell | 9:d70273b3133b | 71 | |
maclobdell | 9:d70273b3133b | 72 | // after the full length of this tone, we up the melody, and down the notes_left |
maclobdell | 9:d70273b3133b | 73 | |
maclobdell | 9:d70273b3133b | 74 | notes_left--; |
maclobdell | 9:d70273b3133b | 75 | melody++; |
maclobdell | 9:d70273b3133b | 76 | duration++; |
maclobdell | 9:d70273b3133b | 77 | |
maclobdell | 9:d70273b3133b | 78 | } |
maclobdell | 9:d70273b3133b | 79 | |
maclobdell | 9:d70273b3133b | 80 | // we're done! just finish this note and silence |
maclobdell | 9:d70273b3133b | 81 | wait_ms(length / 2); |
maclobdell | 9:d70273b3133b | 82 | silence(); |
maclobdell | 9:d70273b3133b | 83 | } |
maclobdell | 9:d70273b3133b | 84 | |
maclobdell | 9:d70273b3133b | 85 | void display_thread() |
maclobdell | 9:d70273b3133b | 86 | { |
maclobdell | 9:d70273b3133b | 87 | char buffer [50]; |
maclobdell | 9:d70273b3133b | 88 | snprintf(buffer, 50, "GO TIGERS!\0"); //pass in max chars to prevent overflow |
maclobdell | 9:d70273b3133b | 89 | |
maclobdell | 9:d70273b3133b | 90 | for (int i = 0; i< 3; i++) { |
maclobdell | 9:d70273b3133b | 91 | matrix.playText(buffer,strlen(buffer), 1); |
maclobdell | 9:d70273b3133b | 92 | Thread::wait(250); |
maclobdell | 9:d70273b3133b | 93 | } |
maclobdell | 9:d70273b3133b | 94 | } |
maclobdell | 8:5f5ceafa826d | 95 | |
maclobdell | 0:2eec8a9428ea | 96 | int main() { |
maclobdell | 9:d70273b3133b | 97 | |
maclobdell | 9:d70273b3133b | 98 | |
maclobdell | 9:d70273b3133b | 99 | // declare a melody |
maclobdell | 9:d70273b3133b | 100 | int melody[] = { |
maclobdell | 9:d70273b3133b | 101 | NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_E5, NOTE_G5 |
maclobdell | 9:d70273b3133b | 102 | }; |
maclobdell | 9:d70273b3133b | 103 | |
maclobdell | 9:d70273b3133b | 104 | // note durations: 4 = quarter note, 8 = eighth note, etc.: |
maclobdell | 9:d70273b3133b | 105 | // the rapid succession of 16th notes produces a twill effect |
maclobdell | 9:d70273b3133b | 106 | int duration[] = { |
maclobdell | 9:d70273b3133b | 107 | 8, 8, 8, 4, 8, 2 |
maclobdell | 9:d70273b3133b | 108 | }; |
maclobdell | 9:d70273b3133b | 109 | |
maclobdell | 9:d70273b3133b | 110 | |
maclobdell | 9:d70273b3133b | 111 | // melody & duration are on the heap, need to get them on the stack |
maclobdell | 9:d70273b3133b | 112 | int *m = new int[sizeof(melody) / sizeof(int)]; |
maclobdell | 9:d70273b3133b | 113 | memcpy(m, melody, sizeof(melody)); |
maclobdell | 9:d70273b3133b | 114 | int *d = new int[sizeof(duration) / sizeof(int)]; |
maclobdell | 9:d70273b3133b | 115 | memcpy(d, duration, sizeof(duration)); |
maclobdell | 9:d70273b3133b | 116 | |
maclobdell | 9:d70273b3133b | 117 | |
maclobdell | 9:d70273b3133b | 118 | if (sizeof(melody) != sizeof(duration)) { |
maclobdell | 9:d70273b3133b | 119 | printf("Melody and duration do not have same number of elements! Aborting!\r\n"); |
maclobdell | 9:d70273b3133b | 120 | return 1; |
maclobdell | 4:8641e4da6744 | 121 | } |
maclobdell | 9:d70273b3133b | 122 | |
maclobdell | 9:d70273b3133b | 123 | for (int i = 0; i< 3; i++) |
maclobdell | 9:d70273b3133b | 124 | { |
maclobdell | 9:d70273b3133b | 125 | displayThread.start(display_thread); |
maclobdell | 9:d70273b3133b | 126 | |
maclobdell | 9:d70273b3133b | 127 | play_song(sizeof(melody) / sizeof(int), m, d); |
maclobdell | 9:d70273b3133b | 128 | |
maclobdell | 9:d70273b3133b | 129 | Thread::wait(100); |
maclobdell | 9:d70273b3133b | 130 | } |
maclobdell | 9:d70273b3133b | 131 | return 0; |
maclobdell | 8:5f5ceafa826d | 132 | |
maclobdell | 1:dd1d1b64b9a5 | 133 | } |