Work 6 (Музыкальная пищалка)

Описание

Проигрыватель мелодий, где мелодия выбирается с помощью потенциометра.
Музыка из Интернета https://github.com/hibit-dev/buzzer/tree/master/src/movies
Название мелодии или номерация нот отображаются на ЖК-экране.

Использованые компоненты

1x 16×2 LCD экран
2x потенциометр
21x стандартные одиночные провода «папа-папа»
1x 330 Ω резистор
1x Piezo пищалка

Код программы

#include <LiquidCrystal.h>

#define SONG_CAST(x) do { \
	size = sizeof(durations_ ## x) / sizeof(int); \
	memcpy(frequences, frequences_ ## x, sizeof(frequences_ ## x)); \
	memcpy(durations, durations_ ## x, sizeof(durations_ ## x)); \
} while (false)

const int PMETR_PIN = 0;
const int BUZZER_PIN = 11;

const char * song_names[5] = { "Star Wars", "Home Alone", "Pink Panther", "", "" };
uint8_t cur_song = 0;

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Star Wars

uint16_t frequences_SW[] = {
	 466,  466,  466,  698, 1047, 932, 880,  784, 1397, 1047,
	 932,  880,  784, 1397, 1047, 932, 880,  932,  784,  523,
	 523,  523,  698, 1047,  932, 880, 784, 1397, 1047,  932,
	 880,  784, 1397, 1047,  932, 880, 932,  784,  523,  523,
	 587,  587,  932,  880,  784, 698, 698,  784,  880,  784,
	 587,  659,  523,  523,  587, 587, 932,  880,  784,  698,
	1047,  784,  784,    0,  523, 587, 587,  932,  880,  784,
	 698,  698,  784,  880,  784, 587, 659, 1047, 1047, 1397,
	1245, 1109, 1047,  932,  831, 784, 698, 1047
};

uint8_t durations_SW[] = {
	8,  8, 8,  2, 2, 8, 8, 8,  2,  4,
	8,  8, 8,  2, 4, 8, 8, 8,  2,  8,
	8,  8, 2,  2, 8, 8, 8, 2,  4,  8,
	8,  8, 2,  4, 8, 8, 8, 2,  8, 16,
	4,  8, 8,  8, 8, 8, 8, 8,  8,  4,
	8,  4, 8, 16, 4, 8, 8, 8,  8,  8,
	8, 16, 2,  8, 8, 4, 8, 8,  8,  8,
	8,  8, 8,  8, 4, 8, 4, 8, 16,  4,
	8,  4, 8,  4, 8, 4, 8, 1
};

// Home Alone

uint16_t frequences_HA[] = {
	330, 523, 494, 494, 523, 494, 349, 392, 392, 330,
	392, 330, 523, 392, 294, 440, 392, 262, 349, 330,
	294, 392, 330, 392, 330, 523, 392, 440, 523, 349,
	330, 392, 262, 330, 294,   0, 330, 262, 349, 294,
	  0, 370, 294, 440, 392,   0, 831, 330, 494, 440,
	349, 523, 440, 494, 392, 330, 392, 330, 523, 392,
	294, 440, 392, 262, 349, 330, 294, 392, 330, 392,
	330, 523, 392,   0, 440, 494, 523, 392, 330,   0,
	440, 494, 523, 392, 330,   0, 440, 494, 523, 392,
	330, 262, 523, 494, 587, 330, 392, 330, 523, 392,
	523
};

uint8_t durations_HA[] = {
	 4,  8, 8, 2,  8,  8,  4,  4, 4, 4,
	 4,  4, 2, 2,  4,  4,  4,  8, 8, 2,
	 2,  4, 4, 4,  4,  2,  2,  8, 8, 4,
	 8,  8, 4, 2,  2,  4,  8,  8, 4, 4,
	 4,  8, 8, 4,  4,  4,  8,  8, 4, 4,
	 4,  8, 8, 2,  4,  4,  4,  4, 2, 2,
	 4,  4, 4, 8,  8,  2,  2,  4, 4, 4,
	 4,  2, 2, 4, 16, 16,  8,  4, 4, 4,
	16, 16, 8, 4,  4,  4, 16, 16, 8, 4,
	 4,  4, 2, 4,  4,  4,  4,  4, 2, 2,
	 1
};

// Pink Panther

uint16_t frequences_PP[] = {
	  0,    0,   0, 311, 330,   0, 370, 392,   0, 311,
	330,  370, 392, 523, 494, 330, 392, 494, 466, 440,
	392,  330, 294, 330,   0,   0, 311, 330,   0, 370,
	392,    0, 311, 330, 370, 392, 523, 494, 392, 494,
	659, 1245, 587,   0,   0, 311, 330,   0, 370, 392,
	  0,  311, 330, 370, 392, 523, 494, 330, 392, 494,
	466,  440, 392, 330, 294, 330,   0,   0, 659, 587,
	494,  440, 392, 330, 466, 440, 466, 440, 466, 440,
	466,  440, 392, 330, 294, 330, 330, 330
};

uint8_t durations_PP[] = {
	 2,  4,  8,  8,  4,  8,  8, 4,  8,  8,
	 8,  8,  8,  8,  8,  8,  8, 8,  2, 16,
	16, 16, 16,  2,  4,  8,  4, 4,  8,  8,
	 4,  8,  8,  8,  8,  8,  8, 8,  8,  8,
	 8,  1,  2,  4,  8,  8,  4, 8,  8,  4,
	 8,  8,  8,  8,  8,  8,  8, 8,  8,  8,   
	 2, 16, 16, 16, 16,  4,  4, 4,  8,  8,
	 8,  8,  8,  8, 16,  8, 16, 8, 16,  8,
	16,  8, 16, 16, 16, 16, 16, 2
};

void setup()
{
	pinMode(BUZZER_PIN, OUTPUT);
	pinMode(PMETR_PIN, INPUT);
	lcd.begin(16, 2);
}

void play_song(uint8_t song)
{
	lcd.setCursor(0, 1);
	lcd.print("S: ");
	lcd.setCursor(3, 1);
	lcd.print(song_names[song - 1]);

	uint8_t size = 0, durations[255];
	uint16_t frequences[255];

	memset(&durations, 0, sizeof(durations));
	memset(&frequences, 0, sizeof(frequences));

	switch (song) {
		case 1:
			SONG_CAST(SW);
			break;
		case 2:
			SONG_CAST(HA);
			break;
		case 3:
			SONG_CAST(PP);
			break;
		default:
			return;
	}

	for (int note = 0; note < size; note++) {
		uint16_t duration = 1000 / durations[note];
		cur_song = map(analogRead(PMETR_PIN), 0, 1023, 0, 5);

		if (cur_song != song) {
			lcd.clear();
			break;
		}

		lcd.setCursor(0, 0);
		lcd.print("Note: ");
		lcd.setCursor(6, 0);
		lcd.print(note);
		lcd.print(' ');

		tone(BUZZER_PIN, frequences[note], duration);
		delay(duration * 1.3);
		noTone(BUZZER_PIN);
	}
}

void loop()
{
	cur_song = map(analogRead(PMETR_PIN), 0, 1023, 0, 5);

	if (cur_song > 0) {
		//fork(); -- HELPME: not works in arduino, sad [Nurkz]
		play_song(cur_song);
	}
}

Видеоотчет