Added functions the bicycle control main file for playing sound, and updating so that songs can be played in 'parallel' with other processes. Also added Pitches.h to store all the pitch values.
This commit is contained in:
parent
ed98e9728d
commit
b2e597c309
|
@ -1,7 +1,7 @@
|
|||
#include <U8x8lib.h>
|
||||
#include <Arduino.h>
|
||||
#include <U8g2lib.h>
|
||||
#include "Musical.h"
|
||||
#include "Pitches.h"
|
||||
#ifdef U8X8_HAVE_HW_I2C
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
|
@ -57,129 +57,128 @@ unsigned long blinkerLeftLastUpdate = 0;
|
|||
char mode = 0;
|
||||
bool modePressed = 0;
|
||||
unsigned long modePressedTime = 0;
|
||||
//Left option button.
|
||||
bool leftPressed = 0;
|
||||
unsigned long leftPressedTime = 0;
|
||||
//Right option button.
|
||||
bool rightPressed = 0;
|
||||
unsigned long rightPressedTime = 0;
|
||||
bool leftPressed, rightPressed = 0;
|
||||
unsigned long leftPressedTime, rightPressedTime = 0;
|
||||
//Music variables.
|
||||
short BPM, noteDuration;
|
||||
short* currentSequence;
|
||||
bool isPlaying = false;
|
||||
int currentNoteIndex;
|
||||
unsigned long noteEndTime;
|
||||
|
||||
/*
|
||||
* Song file: bpm, followed by notes and a byte representing what division of a note it is.
|
||||
*/
|
||||
short mySong[] = {
|
||||
120,
|
||||
NOTE_D5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_F5, Q + E,
|
||||
NOTE_F5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_G5, E,
|
||||
NOTE_A5, Q + E,
|
||||
NOTE_A5, E,
|
||||
NOTE_A5, E,
|
||||
NOTE_C5, E,//10
|
||||
NOTE_G5, Q + E,
|
||||
NOTE_G5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_D5, Q + E,
|
||||
NOTE_D5, E,
|
||||
NOTE_D5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_F5, Q + E,
|
||||
NOTE_F5, E,//20
|
||||
NOTE_F5, E,
|
||||
NOTE_G5, E,
|
||||
NOTE_A5, Q + E,
|
||||
NOTE_A5, E,
|
||||
NOTE_A5, E,
|
||||
NOTE_C5, E,
|
||||
NOTE_D5, Q + E,
|
||||
NOTE_D5, E,
|
||||
NOTE_C5, E,
|
||||
NOTE_E5, E,//30
|
||||
NOTE_D5, Q + E,
|
||||
NOTE_D5, E,
|
||||
NOTE_D5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_F5, Q,
|
||||
NOTE_E5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_C5, Q,
|
||||
NOTE_B5, E,//40
|
||||
NOTE_B5, E,
|
||||
NOTE_A5, Q,
|
||||
NOTE_G5, Q + E,
|
||||
NOTE_G5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_A5, E,
|
||||
NOTE_G5, Q + E,
|
||||
NOTE_G5, Q,
|
||||
NOTE_F5, S,
|
||||
NOTE_E5, S,//50
|
||||
NOTE_F5, Q,
|
||||
NOTE_F5, S,
|
||||
NOTE_E5, S,
|
||||
NOTE_F5, Q,
|
||||
NOTE_F5, S,
|
||||
NOTE_E5, S,
|
||||
NOTE_G5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_D5, Q,//60
|
||||
NOTE_D5, S,
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, Q,
|
||||
NOTE_D5, S,
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, Q,
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, S,
|
||||
NOTE_E5, E,
|
||||
NOTE_F5, E,//70
|
||||
NOTE_C5, E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_D5, S,
|
||||
NOTE_E5, S,
|
||||
NOTE_F5, Q,
|
||||
NOTE_F5, S,
|
||||
NOTE_G5, S,
|
||||
NOTE_A5, Q,
|
||||
NOTE_E5, S,
|
||||
NOTE_F5, S,//80
|
||||
NOTE_G5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_E5, E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_D5, S,
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, Q,
|
||||
NOTE_D5, S,
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, Q,//90
|
||||
NOTE_C5, S,
|
||||
NOTE_D5, S,
|
||||
NOTE_E5, E,
|
||||
NOTE_F5, E,
|
||||
NOTE_C5, E,
|
||||
NOTE_D5, Q + E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_REST, E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_REST, E,//100
|
||||
NOTE_D5, Q,
|
||||
NOTE_REST, E,
|
||||
NOTE_D5, Q,
|
||||
NOTE_REST, E
|
||||
short beep1[] = {
|
||||
3, 100,
|
||||
NOTE_A4, 4,
|
||||
NOTE_E7, 4,
|
||||
NOTE_C2, 4
|
||||
};
|
||||
|
||||
const short beep1[] = {
|
||||
100,
|
||||
NOTE_A4, Q,
|
||||
NOTE_E7, Q,
|
||||
NOTE_C2, Q
|
||||
short skyrim[] = {
|
||||
104, 120,
|
||||
NOTE_D5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_F5, 8 / 3,
|
||||
NOTE_F5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_G5, 8,
|
||||
NOTE_A5, 8 / 3,
|
||||
NOTE_A5, 8,
|
||||
NOTE_A5, 8,
|
||||
NOTE_C5, 8,//10
|
||||
NOTE_G5, 8 / 3,
|
||||
NOTE_G5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_D5, 8 / 3,
|
||||
NOTE_D5, 8,
|
||||
NOTE_D5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_F5, 8 / 3,
|
||||
NOTE_F5, 8,//20
|
||||
NOTE_F5, 8,
|
||||
NOTE_G5, 8,
|
||||
NOTE_A5, 8 / 3,
|
||||
NOTE_A5, 8,
|
||||
NOTE_A5, 8,
|
||||
NOTE_C5, 8,
|
||||
NOTE_D5, 8 / 3,
|
||||
NOTE_D5, 8,
|
||||
NOTE_C5, 8,
|
||||
NOTE_E5, 8,//30
|
||||
NOTE_D5, 8 / 3,
|
||||
NOTE_D5, 8,
|
||||
NOTE_D5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_F5, 4,
|
||||
NOTE_E5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_D5, 4,
|
||||
NOTE_C5, 4,
|
||||
NOTE_B5, 8,//40
|
||||
NOTE_B5, 8,
|
||||
NOTE_A5, 4,
|
||||
NOTE_G5, 8 / 3,
|
||||
NOTE_G5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_A5, 8,
|
||||
NOTE_G5, 8 / 3,
|
||||
NOTE_G5, 4,
|
||||
NOTE_F5, 16,
|
||||
NOTE_E5, 16,//50
|
||||
NOTE_F5, 4,
|
||||
NOTE_F5, 16,
|
||||
NOTE_E5, 16,
|
||||
NOTE_F5, 4,
|
||||
NOTE_F5, 16,
|
||||
NOTE_E5, 16,
|
||||
NOTE_G5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_D5, 4,//60
|
||||
NOTE_D5, 16,
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 4,
|
||||
NOTE_D5, 16,
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 4,
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 16,
|
||||
NOTE_E5, 8,
|
||||
NOTE_F5, 8,//70
|
||||
NOTE_C5, 8,
|
||||
NOTE_D5, 4,
|
||||
NOTE_D5, 16,
|
||||
NOTE_E5, 16,
|
||||
NOTE_F5, 4,
|
||||
NOTE_F5, 16,
|
||||
NOTE_G5, 16,
|
||||
NOTE_A5, 4,
|
||||
NOTE_E5, 16,
|
||||
NOTE_F5, 16,//80
|
||||
NOTE_G5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_E5, 8,
|
||||
NOTE_D5, 4,
|
||||
NOTE_D5, 16,
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 4,
|
||||
NOTE_D5, 16,
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 4,//90
|
||||
NOTE_C5, 16,
|
||||
NOTE_D5, 16,
|
||||
NOTE_E5, 8,
|
||||
NOTE_F5, 8,
|
||||
NOTE_C5, 8,
|
||||
NOTE_D5, 8 / 3,
|
||||
NOTE_D5, 4,
|
||||
NOTE_REST, 8,
|
||||
NOTE_D5, 4,
|
||||
NOTE_REST, 8,//100
|
||||
NOTE_D5, 4,
|
||||
NOTE_REST, 8,
|
||||
NOTE_D5, 4,
|
||||
NOTE_REST, 8
|
||||
};
|
||||
|
||||
//-------------------|
|
||||
|
@ -383,10 +382,26 @@ void updateInputs() {
|
|||
}
|
||||
}
|
||||
|
||||
//Updates the music player, and potentially quits the music.
|
||||
void updateSoundPlay() {
|
||||
if (isPlaying && (noteEndTime < millis()) && currentNoteIndex < currentSequence[0]) {
|
||||
//It is necessary to play the next note.
|
||||
int realNoteIndex = currentNoteIndex * 2 + 2;
|
||||
int realDuration = noteDuration / currentSequence[currentNoteIndex * 2 + 3];
|
||||
tone(BUZZER, currentSequence[realNoteIndex], realDuration);
|
||||
noteEndTime = millis() + realDuration;
|
||||
currentNoteIndex++;
|
||||
}
|
||||
if (currentNoteIndex == currentSequence[0]) {
|
||||
isPlaying = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Updates all modules.
|
||||
void updateAll() {
|
||||
updateBlinkerStatus();
|
||||
updateInputs();
|
||||
updateSoundPlay();
|
||||
}
|
||||
|
||||
//-------------------|
|
||||
|
@ -451,6 +466,24 @@ void setIndicatorColor(byte red, byte green, byte blue) {
|
|||
analogWrite(LED_indicatorBlue, blue);
|
||||
}
|
||||
|
||||
//-------------------|
|
||||
//MUSIC FUNCTIONS: |
|
||||
//-------------------|
|
||||
|
||||
void setBPM(short newBPM) {
|
||||
BPM = newBPM;
|
||||
noteDuration = 15000 / BPM;
|
||||
}
|
||||
|
||||
//Begins playing a new sequence of the form: {Length, BPM, note 1, time 1, note 2, time 2, ...}
|
||||
void playSequence(short* sequence) {
|
||||
currentSequence = sequence;
|
||||
setBPM(sequence[1]);
|
||||
currentNoteIndex = 0;
|
||||
noteEndTime = 0;
|
||||
isPlaying = true;
|
||||
}
|
||||
|
||||
//-------------------|
|
||||
//ERROR CHECKING: |
|
||||
//-------------------|
|
||||
|
@ -489,13 +522,12 @@ void setup() {
|
|||
startupScreen();
|
||||
drawMainScreen();
|
||||
updateAll();
|
||||
Musical::setBuzzerPin(BUZZER);
|
||||
Musical::playSequence(mySong, 104);
|
||||
playSequence(skyrim);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
updateBlinkerStatus();
|
||||
updateInputs();
|
||||
Musical::update();
|
||||
updateSoundPlay();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>C:\Users\AndrewComputer\Documents\Arduino\libraries\U8g2\src;C:\Users\AndrewComputer\Documents\Arduino\libraries\U8g2\src\utility;D:\Arduino\hardware\arduino\avr\libraries\Wire\src;D:\Arduino\hardware\arduino\avr\libraries\Wire\src\utility;D:\Arduino\libraries;D:\Arduino\hardware\arduino\avr\libraries;C:\Users\AndrewComputer\Documents\Arduino\libraries;D:\Arduino\hardware\arduino\avr\cores\arduino;D:\Arduino\hardware\arduino\avr\variants\eightanaloginputs;C:\Users\AndrewComputer\Documents\Arduino\BicycleControl;D:\Arduino\hardware\tools\avr/avr/include/;D:\Arduino\hardware\tools\avr//avr/include/avr/;D:\Arduino\hardware\tools\avr/lib\gcc\avr\4.8.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>C:\Users\AndrewComputer\Documents\Arduino\libraries\U8g2\src;D:\Arduino\hardware\arduino\avr\libraries\SPI\src;D:\Arduino\hardware\arduino\avr\libraries\Wire\src;D:\Arduino\hardware\arduino\avr\libraries\SPI\src\utility;C:\Users\AndrewComputer\Documents\Arduino\libraries\U8g2\src\utility;D:\Arduino\hardware\arduino\avr\libraries\Wire\src\utility;D:\Arduino\libraries;D:\Arduino\hardware\arduino\avr\libraries;C:\Users\AndrewComputer\Documents\Arduino\libraries;D:\Arduino\hardware\arduino\avr\cores\arduino;D:\Arduino\hardware\arduino\avr\variants\eightanaloginputs;C:\Users\AndrewComputer\Documents\Arduino\BicycleControl;D:\Arduino\hardware\arduino\avr\cores\arduino;D:\Arduino\hardware\arduino\avr\variants\eightanaloginputs;C:\Users\AndrewComputer\Documents\Arduino\libraries\U8g2\src;D:\Arduino\hardware\arduino\avr\libraries\SPI\src;D:\Arduino\hardware\arduino\avr\libraries\Wire\src;D:\Arduino\libraries;D:\Arduino\hardware\arduino\avr\libraries;D:\VisualStudio\Common7\IDE\Extensions\g5m1xwby.5un\Micro Platforms\default\debuggers;C:\Users\AndrewComputer\Documents\Arduino\libraries;D:\Arduino\hardware\tools\avr/avr/include/;D:\Arduino\hardware\tools\avr//avr/include/avr/;D:\Arduino\hardware\tools\avr/lib\gcc\avr\4.8.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ForcedIncludeFiles>C:\Users\AndrewComputer\Documents\Arduino\BicycleControl\__vm\.BicycleControl.vsarduino.h;%(ForcedIncludeFiles)</ForcedIncludeFiles>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<PreprocessorDefinitions>__AVR_ATmega328p__;__AVR_ATmega328P__;F_CPU=16000000L;ARDUINO=106012;ARDUINO_AVR_NANO;ARDUINO_ARCH_AVR;__cplusplus=201103L;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
|
@ -79,12 +79,9 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Musical.h" />
|
||||
<ClInclude Include="Pitches.h" />
|
||||
<ClInclude Include="__vm\.BicycleControl.vsarduino.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Musical.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<DebuggerFlavor>VisualMicroDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -21,13 +21,8 @@
|
|||
<ClInclude Include="__vm\.BicycleControl.vsarduino.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Musical.h">
|
||||
<ClInclude Include="Pitches.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Musical.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
57
Musical.cpp
57
Musical.cpp
|
@ -1,57 +0,0 @@
|
|||
#include "Musical.h"
|
||||
|
||||
|
||||
|
||||
Musical::Musical()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Musical::~Musical()
|
||||
{
|
||||
}
|
||||
|
||||
void Musical::setBPM(short newBPM)
|
||||
{
|
||||
BPM = newBPM;
|
||||
Q = 60000 / BPM;
|
||||
H = Q * 2;
|
||||
E = Q / 2;
|
||||
S = Q / 4;
|
||||
W = Q * 4;
|
||||
}
|
||||
|
||||
void Musical::setBuzzerPin(short pinNumber)
|
||||
{
|
||||
pin = pinNumber;
|
||||
}
|
||||
|
||||
void Musical::playNote(int note, int duration)
|
||||
{
|
||||
tone(pin, note, duration);
|
||||
}
|
||||
|
||||
//Plays an array as a musical sequence. Array is: {bpm, note1, time1, note2, time2, ...} Length is the number of notes.
|
||||
void Musical::playSequence(short * sequence, int length)
|
||||
{
|
||||
setBPM(sequence[0]);
|
||||
currentSong = sequence;
|
||||
songLength = length;
|
||||
currentNote = 0;
|
||||
lastNoteTime = 0;
|
||||
isPlaying = true;
|
||||
}
|
||||
|
||||
//Updates the playing song to allow multitasking.
|
||||
void Musical::update()
|
||||
{
|
||||
if (isPlaying && lastNoteTime > millis() && currentNote < songLength) {
|
||||
//It is necessary to play the next note.
|
||||
playNote(currentSong[currentNote * 2 + 1], currentSong[currentNote * 2 + 2]);
|
||||
lastNoteTime = millis() + currentSong[currentNote * 2 + 2];
|
||||
currentNote++;
|
||||
}
|
||||
if (currentNote == songLength) {
|
||||
isPlaying = false;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
//Musical notes:
|
||||
#define NOTE_B0 31
|
||||
#define NOTE_C1 33
|
||||
#define NOTE_CS1 35
|
||||
|
@ -90,24 +88,4 @@
|
|||
#define NOTE_CS8 4435
|
||||
#define NOTE_D8 4699
|
||||
#define NOTE_DS8 4978
|
||||
#define NOTE_REST 0
|
||||
|
||||
class Musical
|
||||
{
|
||||
public:
|
||||
Musical();
|
||||
~Musical();
|
||||
static void setBPM(short newBPM);
|
||||
static void setBuzzerPin(short pinNumber);
|
||||
static void playNote(int note, int duration);
|
||||
static void playSequence(short* sequence, int length);
|
||||
static void update();
|
||||
private:
|
||||
static short BPM, Q, H, E, S, W, pin;
|
||||
static short* currentSong;
|
||||
static int songLength;
|
||||
static bool isPlaying;
|
||||
static int currentNote;
|
||||
static unsigned long lastNoteTime;
|
||||
};
|
||||
|
||||
#define NOTE_REST 0
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue