Print a message to a custom LED matrix and play a song on a piezo buzzer.

Dependencies:   Adafruit_32x8matrix

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?

UserRevisionLine numberNew 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 }