NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » How to play user entered sound?
February 20, 2011 by missle3944 |
I all, I am confused on how I would have my microcontroller playback notes that the user entered. For my question to sound simpler you can watch my video I already have the printf and scanf working and I can type a key on my keyboard and have the micro controller play it. But what I am asking if the user entered 3 diffrent notes and if it could be stored in the program memory? Towards the end of the video I ask if I can store user entered variables and play them back into sound notes. |
---|---|
February 21, 2011 by hevans (NerdKits Staff) |
Hi missle3944, That is a pretty neat project you have going. There are definitely ways to store values in variables, you can just modify your user interface to temporarily store the notes in a variable or in an array. If you want to store them permanently that is a little a bit more difficult. You will need to look into using either the EEPROM or an outside storage element. Humberto |
February 21, 2011 by missle3944 |
Hi humberto I only need to store them temporarily but I am a little confused on how I would do this. I started modifying my code but I am stuck on how I would have the user enter a vairable and then have the MCU play it. Here is my code // musicbox1.c // for NerdKits with ATtiny26L // mrobbins@mit.edu // F_CPU defined for delay.c define F_CPU 14745600 // 8MHzinclude <avr/io.h>include <avr/interrupt.h>include <avr/pgmspace.h>include <util/delay.h>include <inttypes.h>include <stdlib.h>include "../libnerdkits/delay.h"include "../libnerdkits/lcd.h"include "../libnerdkits/delay.h"include "../libnerdkits/lcd.h"include "../libnerdkits/uart.h"// PIN DEFINITIONS: // // PA0 -- temperature sensor analog input // PB1 -- piezo buzzer // PD2 -- LCD RS (pin 4) // PA5 -- LCD E (pin 6) // PA7 -- button (pullup high) // PB3-6 -- LCD DB4-7 (pins 11-14) void play_tone(uint16_t delay, uint8_t duration) { // delay is half-period in microseconds // duration is in 10ms increments // example: 440Hz --> delay=1136 // duration = 2*delay * cycles (all in same units) // cycles = 10000 * duration / delay / 2 // cycles = 100 * duration / (delay/50) uint16_t tmp = 100 * duration; uint16_t delaysm = delay / 20; uint16_t cycles = tmp / delaysm; while (cycles > 0) { PORTB |= (1<<PB1); delay_us(delay); PORTB &= ~(1<<PB1); delay_us(delay); cycles--; } } // define some notes // Frequencies from http://www.phy.mtu.edu/~suits/notefreqs.html // converted to half-periods (us) by calculating // 1000000/2/frequency // where frequency is in Hz #define C1 166 #define D6 425 #define D5 851 #define E5 758 #define E6 379 #define F5 675 #define G5 637 #define A5 568 #define B5 506 #define C6 477 #define D6 425 #define G1 10204 #define DUR 20 int main() { // start up the LCD lcd_init(); FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE); lcd_write_string(PSTR("PIANO")); // init serial port uart_init(); FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW); stdin = stdout = &uart_stream; char tc; int x; // enable the piezo as output DDRB |= (1<<PB1); // fire up the LCD // loop forever! while(1) { // fire up the LCD tc = uart_read(); if(tc=='f') {play_tone(D5, DUR); lcd_write_string(PSTR("D5")); } if(tc=='d'){ play_tone(C6, DUR); lcd_write_string(PSTR("c6")); } if(tc=='a'){ play_tone(A5, DUR); lcd_write_string(PSTR("A5")); } if(tc=='s') play_tone(B5, DUR); if(tc=='g') play_tone(E5, DUR); if(tc=='h') play_tone(F5, DUR); if(tc=='j'){
// delay a bit delay_ms(500); } return 0; } |
February 21, 2011 by missle3944 |
|
February 21, 2011 by 6ofhalfdozen |
Hi missle3944, Since it sounds like you are just trying to temporarily store a couple notes that the user inputs, you will want to use either several variables or an array. I am not 100% sure, but from what I have seen so far of how the compiler works they would need to be marked "volatile" to prevent the compiler from making them fixed values. Here is what I would do. (using the code line numbers from your code only post above)
on line 95, put in some code to start saving the uart_read values to either an array or your variables to hold the notes. Once you have saved the uart values to variables you can create a loop holding the code in lines 98-127 and runs that code for each note input.
hopefully that gives you an idea of where to start. |
February 21, 2011 by missle3944 |
Hi 6ofhalfdozen, what sort of code would I use to have the user enter the values? I am sorta confused with it. I get the array part but I am just lost when it comes to having the user enter the variables into the array |
February 21, 2011 by missle3944 |
here is my modded code that has your array in it.
|
February 21, 2011 by 6ofhalfdozen |
Missle3944, first off, I forgot to add a "qq= qq + 1" inside of the brackets on line 15 of my pseudocode. Otherwise, it will play those 5 notes forever without looking for new input from the user. secondly, i highly doubt my pseudocode will compile as you plugged it into your code. array() might be a restricted name in C and you will most likely have to rename it something else. It also is not declared or initialized for size anywhere, which will cause big errors at compile time. you will need to properly code out my pseudocode for it to work. As for your question, I am not exactly sure what you are asking. the "tc =uart_read()" is all the code you need to read a character from the uart and put it into the variable tc. The code in lines 3-6 of my pseudocode, uses a loop to read from the uart and put the value directly into the array a total of 5 times. this loads the array ready for usage with no extra effort needed. If you are asking about the actual user input getting to the mcu, the user will need to type 5 characters in close succession into putty (or whichever terminal program you care to use) to be sent to the NK. The way you have the code setup, the mcu continually looks for input and loads 5 values, plays 5 notes, over and over again. I belive the code is setup so that if you don't type anything the mcu will not play any notes. But if you send it 5 keys and nothing for a while it might recycle and keep playing the 5 notes or totally freak out due to invalid /no input.. not sure, you would need to ask some of the C code gurus about that one.. so if you type 35 keys into putty for sending, the mcu "should" load and play 7 blocks of five notes. Obviously there will be some timing considerations and such. I don't know if that helps or just makes things muddier. |
February 21, 2011 by missle3944 |
6ofhalfdozen, you have just cleared my confusion up about user inputs. I'll have to look into the declaration of an array in c and I'll get back to you. Thanks -missle3944 |
Please log in to post a reply.
Did you know that a piezoelectric buzzer can be used in reverse as a microphone? Learn more...
|