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-08
Revision:
10:aa7764fae417
Parent:
9:d70273b3133b

File content as of revision 10:aa7764fae417:

/*
 * 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 t1;
Thread t2;
InterruptIn sw(D4);
EventQueue queue1(32 * EVENTS_EVENT_SIZE);
EventQueue queue2(32 * EVENTS_EVENT_SIZE);

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 start_song()
{
    // 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");
    }
   
    for (int i = 0; i< 3; i++)
    {  
        play_song(sizeof(melody) / sizeof(int), m, d);                        
        Thread::wait(100);
    }
    
}
    
void start_display()
{
    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);
    }
}

void switch_handler(void)
{
    queue1.call(start_song);
    queue2.call(start_display);
    
} 

int main() {
    
    // Start the event queues
    t1.start(callback(&queue1, &EventQueue::dispatch_forever));
    t2.start(callback(&queue2, &EventQueue::dispatch_forever));
    
    // Call handler when the switch is pressed
    sw.fall(switch_handler);
        
    while(1)
    {//chill
    }
 
    return 0;
 
}