Print a message to a custom LED matrix and play a song on a piezo buzzer.
Dependencies: Adafruit_32x8matrix
main.cpp
- Committer:
- maclobdell
- Date:
- 2021-11-03
- Revision:
- 9:d70273b3133b
- Parent:
- 8:5f5ceafa826d
- Child:
- 10:aa7764fae417
File content as of revision 9:d70273b3133b:
/*
* Copyright (c) 2016 ARM Limited. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed.h" // this tells us to load mbed related functions
#include "tones.h" // list of all the tones and their frequencies
#include "Adafruit_32x8matrix.h"
#define I2C_ADDR1 0x70
#define I2C_ADDR2 0x71
#define ROTATION1 0
#define ROTATION2 2
#define BRIGHTNESS 1
I2C i2c(D14, D15);
Adafruit_32x8matrix matrix(&i2c, I2C_ADDR1, I2C_ADDR2, ROTATION1, ROTATION2, BRIGHTNESS);
Thread displayThread;
PwmOut buzzer(D3); // our buzzer is a PWM output (pulse-width modulation)
static int BPM = 80;
static void silence() {
buzzer.write(0.0f); // silence!
}
// this is our function that plays a tone.
// Takes in a tone frequency, and after duration (in ms.) we stop playing again
static void play_tone(int tone) {
buzzer.period_us(1000000/(tone));
buzzer.write(0.10f); // 10% duty cycle, otherwise it's too loud
}
static void play_song(int notes_left, int* melody, int* duration) {
// melody and duration are pointers, they point to the array of tones and durations we declared earlier
// every time we play a note we up these pointers (move one element forward)
// so the current tone is always the first element of melody (same for duration)
int length;
while(notes_left > 0)
{
int tone = melody[0];
// BPM is quarter notes per minute, so length in milliseconds is:
length = static_cast<int>(static_cast<float>(1000 / duration[0]) * (60000.0f / static_cast<float>(BPM * 1000)));
play_tone(tone);
// after half the length of this tone, we silence
wait_ms(length / 2);
silence();
//after the full length of this tone, call next note
wait_ms(length);
// after the full length of this tone, we up the melody, and down the notes_left
notes_left--;
melody++;
duration++;
}
// we're done! just finish this note and silence
wait_ms(length / 2);
silence();
}
void display_thread()
{
char buffer [50];
snprintf(buffer, 50, "GO TIGERS!\0"); //pass in max chars to prevent overflow
for (int i = 0; i< 3; i++) {
matrix.playText(buffer,strlen(buffer), 1);
Thread::wait(250);
}
}
int main() {
// declare a melody
int melody[] = {
NOTE_G4, NOTE_C5, NOTE_E5, NOTE_G5, NOTE_E5, NOTE_G5
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
// the rapid succession of 16th notes produces a twill effect
int duration[] = {
8, 8, 8, 4, 8, 2
};
// melody & duration are on the heap, need to get them on the stack
int *m = new int[sizeof(melody) / sizeof(int)];
memcpy(m, melody, sizeof(melody));
int *d = new int[sizeof(duration) / sizeof(int)];
memcpy(d, duration, sizeof(duration));
if (sizeof(melody) != sizeof(duration)) {
printf("Melody and duration do not have same number of elements! Aborting!\r\n");
return 1;
}
for (int i = 0; i< 3; i++)
{
displayThread.start(display_thread);
play_song(sizeof(melody) / sizeof(int), m, d);
Thread::wait(100);
}
return 0;
}