/* * EEL4746C - AVR Piano - Speaker Section * speaker is connected to PD2 and ground * 15 buttons are connected to PD3-7, PC0-4, PB0-4 * the LCD Arduino UNO is connected to TX/RX (PD0/1) */ #include #include #define F_CPU 16e6 #include #define T1_PRESCALAR 8 #define FREQ(f) (16e6 / f / T1_PRESCALAR / 2) #define HIGH(sn) ((sn >> 8) & 0xff) #define LOW(sn) (sn & 0xff) #define P_RX 0 #define P_TX 1 #define P_SPKR 2 #define MARIO 50 unsigned short freqs[] = { // PD3-7 100, 200, 250, 300, 350, // PB0-4 400, 450, // middle c 500, 600, 700, // PC0-4 750, 800, 850, 900, 950, // notes [MARIO] = 131, // C3 262, // C4 110, // A2 220, // A3 117, // Bb2 233, // Bb3 87, 175, 73, 147, 78, 156, 156, 147, 139, 131, 156, 147, 104, 98, 139, 156, 185, 175, 165, 233, 220, 208, 156, 123, 123, 110, 104, ['"'] = 16000, [255] = 0 // used as a 'silent' note }; unsigned short t_freqs[] = { // PD3-7 FREQ(100), FREQ(200), FREQ(250), FREQ(300), FREQ(350), // PB0-4 FREQ(400), FREQ(450), // middle c FREQ(500), FREQ(600), FREQ(700), // PC0-4 FREQ(750), FREQ(800), FREQ(850), FREQ(900), FREQ(950), // notes [MARIO] = FREQ(131), // C3 FREQ(262), // C4 FREQ(110), // A2 FREQ(220), // A3 FREQ(117), // Bb2 FREQ(233), // Bb3 FREQ(87), FREQ(175), FREQ(73), FREQ(147), FREQ(78), FREQ(156), FREQ(156), FREQ(147), FREQ(139), FREQ(131), FREQ(156), FREQ(147), FREQ(104), FREQ(98), FREQ(139), FREQ(156), FREQ(185), FREQ(175), FREQ(165), FREQ(233), FREQ(220), FREQ(208), FREQ(156), FREQ(123), FREQ(123), FREQ(110), FREQ(104), ['"'] = FREQ(16000), [255] = 0 // used as a 'silent' note }; unsigned char note = 0; // 0 = normal/piano mode // 1 = recording mode // 2 = mario demo unsigned char mode = '0'; ISR (PCINT0_vect) { // check if any button in the whole port is pressed for (unsigned char i = 0; i <= 5; i++) { if (PINB & (1 << i)) { note = i + 5; break; } } } ISR (PCINT1_vect) { // check if any button in the whole port is pressed for (unsigned char i = 0; i <= 5; i++) { if (PINC & (1 << i)) { note = i + 10; break; } } } ISR (PCINT2_vect) { // check if any button in the whole port is pressed for (unsigned char i = 3; i <= 7; i++) { if (PIND & (1 << i)) { note = i - 3; break; } } } void usart_init(void) { // 9600 bps, TX enabled UBRR0 = 103; UCSR0B = 1 << TXEN0; UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); } void usart_send(unsigned char c) { while (!(UCSR0A & (1 << UDRE0))); UDR0 = c; } void usart_send_str(const char *c) { for (unsigned char i = 0; c[i] != '\0'; i++) usart_send(c[i]); } unsigned char usart_read(void) { while (!(UCSR0A & (1 << RXC0))); return UDR0; } void playtone(void) { // Prepare Timer/Counter TCNT1 = 1; OCR1A = t_freqs[note]; TCCR1B |= 1 << CS11; // Monitor OutPut Compare Flag while ((TIFR1 & (1 << OCF1A)) == 0); // Toggles port For Speaker PORTD ^= 1 << P_SPKR; TIFR1 |= 1 << OCF1A; TCCR1B &= ~(1 << CS11); } void play_note(unsigned char _note, unsigned short _cycles) { note = _note; usart_send(note); for (unsigned short i = 0; i < _cycles; i++) playtone(); _delay_ms(25); } int main(void) { // Data Direction for Buttons, UART, Speaker DDRB = 0x00; DDRC = 0x00; DDRD = (1 << P_TX) | (1 << P_SPKR); // Enabling Pin Change Interrupt for All Buttons PCMSK0 = 0b00011111; PCMSK1 = 0b00011111; PCMSK2 = 0b11111000; PCICR = (1 << PCIE0) | (1 << PCIE1) | (1 << PCIE2); TCCR1A = 0x00; // use timer1 CTC mode TCCR1B = 1 << WGM12; // already prescaled by 8 in table sei(); usart_init(); // Sends Square wave to the Speaker When a Button is Pressed unsigned short cycles = 0; unsigned char tmp = 0; for (unsigned char n = 0;; n = (n + 1) % 2) { if (PINC & _BV(5)) mode = '2'; else if (PINB & _BV(5)) mode = '3'; else mode = '0'; // check if any buttons are pressed, otherwise don't play a note if (mode == '0' && ((PINB & PCMSK0) | (PINC & PCMSK1) | (PIND & PCMSK2)) == 0) { // if a button was released, then send note and cycles played if (cycles > 0) { usart_send(tmp); cycles = 0; } continue; } if (mode == '0') { tmp = note; playtone(); cycles = (cycles + 1) % 0xffff; } else if (mode == '1') { } else if (mode == '3') { for (unsigned char i = 0; i < 2; i++) { for (unsigned char j = 0; j <= 5; j++) play_note(MARIO + j, freqs[MARIO + j] * 0.3); _delay_ms(1800); } for (unsigned char i = 0; i < 2; i++) { for (unsigned char j = 6; j <= 11; j++) play_note(MARIO + j, freqs[MARIO + j] * 0.3); _delay_ms(1800); } for (unsigned char i = 12; i <= 14; i++) play_note(MARIO + i, freqs[MARIO + i] * 0.3); for (unsigned char i = 15; i <= 20; i++) play_note(MARIO + i, freqs[MARIO + i] * 0.6); for (unsigned char i = 21; i <= 26; i++) play_note(MARIO + i, freqs[MARIO + i] * 0.3); for (unsigned char i = 27; i <= 32; i++) play_note(MARIO + i, freqs[MARIO + i] * 0.6); } } }