From 70db1dfa53ad0c1f9d09d70f0f92a6e4fd8a9f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lino?= Date: Fri, 14 Aug 2015 15:24:54 +0100 Subject: [PATCH] Piezo melody implemented and audible warnings done. --- Melody.cpp | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++ Melody.h | 118 ++++++++++++++++++++++++++++++ brew.ino | 34 ++++++--- 3 files changed, 351 insertions(+), 11 deletions(-) create mode 100644 Melody.cpp create mode 100644 Melody.h diff --git a/Melody.cpp b/Melody.cpp new file mode 100644 index 0000000..e12fac7 --- /dev/null +++ b/Melody.cpp @@ -0,0 +1,210 @@ +#include "Arduino.h" +#include "Melody.h" + +int simple_melody[] = { _C, _b, _g, _C, _b, _e, _R, _C, _c, _g, _a, _C }; +int simple_tempo[] = { 16, 16, 16, 8, 8, 16, 32, 16, 16, 16, 8, 8 }; + +int supermario_start_melody[] = { + NOTE_E7, NOTE_E7, 0, NOTE_E7, + 0, NOTE_C7, NOTE_E7, 0, + NOTE_G7, 0, 0, 0, + NOTE_G6, 0, 0, 0, + }; +int supermario_start_tempo[] = { + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, +}; + +int supermario_melody[] = { + NOTE_E7, NOTE_E7, 0, NOTE_E7, + 0, NOTE_C7, NOTE_E7, 0, + NOTE_G7, 0, 0, 0, + NOTE_G6, 0, 0, 0, + + NOTE_C7, 0, 0, NOTE_G6, + 0, 0, NOTE_E6, 0, + 0, NOTE_A6, 0, NOTE_B6, + 0, NOTE_AS6, NOTE_A6, 0, + + NOTE_G6, NOTE_E7, NOTE_G7, + NOTE_A7, 0, NOTE_F7, NOTE_G7, + 0, NOTE_E7, 0, NOTE_C7, + NOTE_D7, NOTE_B6, 0, 0, + + NOTE_C7, 0, 0, NOTE_G6, + 0, 0, NOTE_E6, 0, + 0, NOTE_A6, 0, NOTE_B6, + 0, NOTE_AS6, NOTE_A6, 0, + + NOTE_G6, NOTE_E7, NOTE_G7, + NOTE_A7, 0, NOTE_F7, NOTE_G7, + 0, NOTE_E7, 0, NOTE_C7, + NOTE_D7, NOTE_B6, 0, 0 +}; +//Mario main them tempo +int supermario_tempo[] = { + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + + 9, 9, 9, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, + + 9, 9, 9, + 12, 12, 12, 12, + 12, 12, 12, 12, + 12, 12, 12, 12, +}; + +//Underworld melody +int underworld_melody[] = { + NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, + NOTE_AS3, NOTE_AS4, 0, + 0, + NOTE_C4, NOTE_C5, NOTE_A3, NOTE_A4, + NOTE_AS3, NOTE_AS4, 0, + 0, + NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, + NOTE_DS3, NOTE_DS4, 0, + 0, + NOTE_F3, NOTE_F4, NOTE_D3, NOTE_D4, + NOTE_DS3, NOTE_DS4, 0, + 0, NOTE_DS4, NOTE_CS4, NOTE_D4, + NOTE_CS4, NOTE_DS4, + NOTE_DS4, NOTE_GS3, + NOTE_G3, NOTE_CS4, + NOTE_C4, NOTE_FS4, NOTE_F4, NOTE_E3, NOTE_AS4, NOTE_A4, + NOTE_GS4, NOTE_DS4, NOTE_B3, + NOTE_AS3, NOTE_A3, NOTE_GS3, + 0, 0, 0 +}; + +//Underwolrd tempo +int underworld_tempo[] = { + 12, 12, 12, 12, + 12, 12, 6, + 3, + 12, 12, 12, 12, + 12, 12, 6, + 3, + 12, 12, 12, 12, + 12, 12, 6, + 3, + 12, 12, 12, 12, + 12, 12, 6, + 6, 18, 18, 18, + 6, 6, + 6, 6, + 6, 6, + 18, 18, 18, 18, 18, 18, + 10, 10, 10, + 10, 10, 10, + 3, 3, 3 +}; + +int song = 0; + +void buzz(int targetPin, long frequency, long length) { + long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions + //// 1 second's worth of microseconds, divided by the frequency, then split in half since + //// there are two phases to each cycle + long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing + //// multiply frequency, which is really cycles per second, by the number of seconds to + //// get the total number of cycles to produce + for (long i = 0; i < numCycles; i++) { // for the calculated length of time... + digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram + delayMicroseconds(delayValue); // wait for the calculated delay value + digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram + delayMicroseconds(delayValue); // wait again or the calculated delay value + } +} + +void sing(int s, int pin) { + // iterate over the notes of the melody: + song = s; + + switch(song) { + case 1: { + int size = sizeof(supermario_melody) / sizeof(int); + for (int thisNote = 0; thisNote < size; thisNote++) { + + // to calculate the note duration, take one second + // divided by the note type. + //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. + int noteDuration = 1000 / supermario_tempo[thisNote]; + + buzz(pin, supermario_melody[thisNote], noteDuration); + + // to distinguish the notes, set a minimum time between them. + // the note's duration + 30% seems to work well: + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + + // stop the tone playing: + buzz(pin, 0, noteDuration); + + } + break; + } + case 2: { + int size = sizeof(underworld_melody) / sizeof(int); + for (int thisNote = 0; thisNote < size; thisNote++) { + + // to calculate the note duration, take one second + // divided by the note type. + //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. + int noteDuration = 1000 / underworld_tempo[thisNote]; + + buzz(pin, underworld_melody[thisNote], noteDuration); + + // to distinguish the notes, set a minimum time between them. + // the note's duration + 30% seems to work well: + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + + // stop the tone playing: + buzz(pin, 0, noteDuration); + + } + break; + } + case 3: { + int size = sizeof(supermario_start_melody) / sizeof(int); + for (int thisNote = 0; thisNote < size; thisNote++) { + + // to calculate the note duration, take one second + // divided by the note type. + //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. + int noteDuration = 1000 / supermario_start_tempo[thisNote]; + + buzz(pin, supermario_start_melody[thisNote], noteDuration); + + // to distinguish the notes, set a minimum time between them. + // the note's duration + 30% seems to work well: + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + + // stop the tone playing: + buzz(pin, 0, noteDuration); + + } + break; + } + + } +} \ No newline at end of file diff --git a/Melody.h b/Melody.h new file mode 100644 index 0000000..c0246a0 --- /dev/null +++ b/Melody.h @@ -0,0 +1,118 @@ +#ifndef MELODY_h +#define MELODY_h + +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#define NOTE_C3 131 +#define NOTE_CS3 139 +#define NOTE_D3 147 +#define NOTE_DS3 156 +#define NOTE_E3 165 +#define NOTE_F3 175 +#define NOTE_FS3 185 +#define NOTE_G3 196 +#define NOTE_GS3 208 +#define NOTE_A3 220 +#define NOTE_AS3 233 +#define NOTE_B3 247 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 + +// Start by defining the relationship between note, period, & frequency. +#define _c 3830 // 261 Hz +#define _d 3400 // 294 Hz +#define _e 3038 // 329 Hz +#define _f 2864 // 349 Hz +#define _g 2550 // 392 Hz +#define _a 2272 // 440 Hz +#define _b 2028 // 493 Hz +#define _C 1912 // 523 Hz +// Define a special note, 'R', to represent a rest +#define _R 0 + +#define MELODY_SUPER_MARIO 1 +#define MELODY_UNDERWORLD 2 +#define MELODY_SUPER_MARIO_START 3 + + +// melody[] is an array of notes, accompanied by beats[], +// which sets each note's relative length (higher #, longer note) + + +void buzz(int targetPin, long frequency, long length); +void sing(int s, int pin); + +#endif \ No newline at end of file diff --git a/brew.ino b/brew.ino index a1fe896..298dd64 100644 --- a/brew.ino +++ b/brew.ino @@ -42,6 +42,10 @@ //#define MIXER_PIN 12 //#define MIXER_MAX_POSITION 255 +// ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++ +#include "Melody.h" +#define PIEZO_PIN 25 + // ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++ #define PUMP_PIN 6 #define PUMP_SPEED_STOP 0 @@ -191,15 +195,6 @@ PT100 upPT100(PT100_UP_OUTPUT_PIN, PT100_UP_INPUT_PIN, PT100_U PT100 downPT100(PT100_DOWN_OUTPUT_PIN, PT100_DOWN_INPUT_PIN, PT100_DOWN_TIME_BETWEEN_READINGS, PT100_DOWN_DEFAULT_ADC_VMAX, PT100_DOWN_DEFAULT_VS, PT100_DOWN_DEFAULT_R1_RESISTENCE, PT100_DOWN_DEFAULT_LINE_RESISTENCE, PT100_DOWN_DEFAULT_OPERATION_RESISTENCE); // ######################### INTERRUPTS ######################### -void xSetupRotaryEncoder( eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep ) { - if( newMode >= 0 ) rotaryEncoderMode = newMode; - if( newPosition >= 0 ) rotaryEncoderVirtualPosition = newPosition; - if( newMaxPosition >= 0 ) rotaryEncoderMaxPosition = newMaxPosition; - if( newMinPosition >= 0 ) rotaryEncoderMinPosition = newMinPosition; - if( newSingleStep >= 0 ) rotaryEncoderSingleStep = newSingleStep; - if( newMultiStep >= 0 ) rotaryEncoderMultiStep = newMultiStep; -} - void isr () { // Interrupt service routine is executed when a HIGH to LOW transition is detected on CLK unsigned long interruptTime = millis(); unsigned long diff = interruptTime - lastInterruptTime; @@ -287,6 +282,15 @@ void isr () { // Interrupt service routine is executed when a HIGH to LOW tr refresh = true; } +void xSetupRotaryEncoder( eRotaryEncoderMode newMode, int newPosition, int newMaxPosition, int newMinPosition, int newSingleStep, int newMultiStep ) { + if( newMode >= 0 ) rotaryEncoderMode = newMode; + if( newPosition >= 0 ) rotaryEncoderVirtualPosition = newPosition; + if( newMaxPosition >= 0 ) rotaryEncoderMaxPosition = newMaxPosition; + if( newMinPosition >= 0 ) rotaryEncoderMinPosition = newMinPosition; + if( newSingleStep >= 0 ) rotaryEncoderSingleStep = newSingleStep; + if( newMultiStep >= 0 ) rotaryEncoderMultiStep = newMultiStep; +} + // ######################### START ######################### void xSafeHardwarePowerOff() { // analogWrite(MIXER_PIN, 0); // Turn mixer OFF for safety @@ -298,6 +302,9 @@ void xSafeHardwarePowerOff() { void displayWelcome() { lcdPrint(" Let's start", " Brewing!"); // Write welcome + // Play Melody; + sing(MELODY_SUPER_MARIO_START, PIEZO_PIN); + //termometerCalibration(); delay(SETTING_WELCOME_TIMEOUT); // pause for effect } @@ -324,6 +331,9 @@ void setup() { iPumpSpeed = PUMP_SPEED_STOP; // Time frame to operate in analogWrite(PUMP_PIN, iPumpSpeed); // analogWrite values from 0 to 255 + // ++++++++++++++++++++++++ Pump ++++++++++++++++++++++++ + pinMode(PIEZO_PIN, OUTPUT); + // ++++++++++++++++++++++++ Temperature Sensor PT100 ++++++++++++++++++++++++ //basePT100.setup(); /* @@ -406,7 +416,7 @@ void setup() { xSetupRotaryEncoder ( eRotaryEncoderMode_Menu, eMainMenu_GO, MENU_SIZE_MAIN_MENU - 1, 0, 1, 0 ); } -// ######################### START ######################### +// ######################### MAIN LOOP ######################### void loop() { unsigned long inactivityTime = millis() - lastInterruptTime; @@ -425,6 +435,8 @@ void loop() { operateMachine(); } +// ######################### FUNCTIONS ######################## + void xPaintStatusTemplate() { // Clear LCD lcd.clear(); @@ -1019,7 +1031,7 @@ bool xRegulatePumpSpeed() { } void xWarnClockEnded() { - /// TODO + sing(MELODY_SUPER_MARIO_START, PIEZO_PIN); } void xStageFirstRun( int stageTime, int stageTemperature, int stagePumpSpeed ) { -- 2.24.1