/**************************************************************/ /* template.c: provides a menued interface to the Handyboard, */ /* allowing you to test motors, sensors, etc... */ /* while your program is loaded */ /* */ /* Usage: Turn the User Knob to select a menu option. */ /* Use the Start and Stop buttons to make selections */ /* */ /* Ben "Max" Davis, 2/99, for MIT ESG Robotics Seminar SP.285 */ /* some code used from menu.c by Anne Wright */ /* */ /* v1.1, 2/00, minor modifications, motor power is now 100% */ /* v1.2, 3/00, ?? switch debounce, analog joystick control */ /* */ /**************************************************************/ /* music.c */ /* hacked up by randy sargent 1/91 */ /* randy apologizes for the annoying syntax of the music as he tries to re-read the earlier songs 6/94 */ /* songs work like this: */ /* a note is */ /* how many "beats" the note gets. if you make 1 an eighth note, then 2=quarter note, 4=half note, 8=whole note, 3=dotted quarter, 6=dotted half, etc. If you have a dotted eighth, you'd need to make eighth equal 2, etc. */ /* optional # or & means make the next note sharp or flat */ /* a-g means which note. the octave for the note is automatically chosen to make the note as close as possible to the last note. you can override this with U or D in between notes to force a shift up or down. just enter all the notes without the U and D's, listen to the song, and it will become clear where the U's and D's need to go*/ /* note that you can add spaces anywhere you want, to make your song (somewhat) more legible. for debugging you might want to put spaces at each measure, for example */ /* use start_process to play your favorite song while your robot robots :) */ char pp_song[]= "1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 7r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3b1g3b1e 28&e D3r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 12r U3e1d3b1a3g1#f 1&b3a1&b3a1&b3a1&b3a 2g2e2d20e"; char w_song[]="1c2f1f2f1g2a1a2a1f2g1g2g1e4f1r 1f2a1a2a1&b2c1c2c1c2d1c2&b1a4g1r 1gU2d1d2d1c2d1e2f1d2c1d2c1&b4a1r D1c2f1f2f1g2a1a2a1f2g1g2f1e5f"; char classics_song[]="4g2c2d4c4g4a2g2f2e2c2d2e2f2g2a2b10c2r 4c4b4c2d2b2c2d2e2#f4g2#f2e4d2g2#f4g4d4e2d2c2b2g2a2b2c2b2c2d2e2d2e2#f12g"; char charge_song[]="1c1e1g2c1r1g4c"; char looney_tune_song[]= "U3e1d2c2d2e2d2e2c2d2d2d6d2r 3d1c2b2c2d2#c2d2b2c2c2c6c"; /* randy. "pink panther" */ void pp() { play(pp_song); } /* added to by karsten ulland 10/92 */ void wate() { play(w_song); } void classics() { play(classics_song); } /* more from karsten 1/93 */ void charge() { play(charge_song); } /* randy 4/94 */ void looney_tune() { play(looney_tune_song); } char benny_song[] ="1c1d1cU2f2f1d1c1#g1a2c2d1c1a1#g1g2f1f1f1a1c2d5c1c1d1c2f2f1d1c1#g1a2c2d1c1a1#g1g2c1c1c1e1g2e5c1c1d1c2f2f2f2f2f2f1d1c1g1a2#a2#a2#a2#a1d1#a1d1#aU1f3g1a1#g1a1#g1a3c1a1#g1#a5f1a1#f1#d1cU1#g1f1d1b4f"; /* Matt Southall 7th June 1996 */ /* "Recognisably supposed to be the Benny Hill Theme" ;) */ void benny() { play(benny_song); } /* The MUSIC BOX song -- transcribed by James Hu (jxh@cs.wustl.edu) */ char mb_song1[] = "2c2e2g2eU2c2g2e2gD2c2e2g2eU2c2g2e 2c2c2g2c2e2c2e2gD2cU2c2b2a7g1r 2g2g2f2d2b2g2b2d2f2e2cU2a7g1r D2c2c2g2c2e2c2e2gD2cU2c2b2a7g1r 2g2g2f2d2b2g2b2d2b2c2gU2e4c 2c2e2g2c2a2f2c2a2c2f2a2gD2cU2a4g D2g2b2d2g2f2d2b2g2b2d2f2e2cU2a4g D2c2e2g2c2a2f2c2a2c2f2a2gD2cU2a4g D2g2b2d2g2f2d2b2g2b2d2b2c2gU2e7c"; char mb_song2[] = "2c2e2g2eU2c2g2e2gD2c2e2g2eU2c2g2e 2c2c2g2c2e2c2e2gD2cU2c2b2a7g1r U2g2g2f2d2b2g2b2d2f2e2cU2a7g1r DD2c2c2g2c2e2c2e2gD2cU2c2b2a7g1r U2g2g2f2d2b2g2b2d2b2c2gU2e4c 2c2e2g2c2a2f2c2a2c2f2a2gD2cU2a4g D2g2b2d2g2f2d2b2g2b2d2f2e2cU2a4g DD2c2e2g2c2a2f2c2a2c2f2a2gD2cU2a4g U2g2b2d2g2f2d2b2g2b2d2b2c2gU2e7c"; void musicbox() { play(mb_song1); play(mb_song2); } /**********************************************************************/ /* music player Randy Sargent */ /* # of milliseconds per 16th note, divided by 8 */ int tempo= 12; long time, newtime; /* command letter to motor control */ int music_current_command= 'o'; /* Example using play: Songs should be GLOBALS so they can be longer - MD 7/93 char song[]= "1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 7r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3b1g3b1e 28&e D3r1#d 4e3r1#f4g3r1#d 3e1#f3g1c3bD1e3g1b 8&b2b2a2g2e2d10e 12r U3e1d3b1a3g1#f 1&b3a1&b3a1&b3a1&b3a 2g2e2d2e18e 8r 2g2e2d2e18e 8r 2g2e2d2e18e"; void pp() { play(song); } Also see tequila.c for an example of music interspersed with commands Also see tunes.c for other fun tunes. */ int music_next_command= 0; void play(char song[]) { int i, duration, accidental, delta, note, rest; int notes[]= {0,2,3,5,7,8,10}; int old_note= 30; play_reset(); i= 0; while (song[i] && !stop_button()) { while (1) { while (song[i] == ' ') ++i; if (song[i] == 'X') {++i; music_next_command= song[i]; ++i;} else break; } if (!song[i]) break; while (song[i] == 'D') { old_note -= 12; ++i; } while (song[i] == 'U') { old_note += 12; ++i; } if ('0' <= song[i] && song[i] <= '9') { duration= 0; while ('0' <= song[i] && song[i] <= '9') { duration = duration * 10 + song[i]-'0'; ++i; } } if (song[i] == '#') { accidental= 1; ++i; } else if (song[i] == '&') { accidental= -1; ++i; } else { accidental= 0; } /* printf("dur %d a %d i %d\n", duration, accidental, i);*/ /* wait();*/ if (song[i] == 'r') rest= 1; else { if (song[i] < 'a' || song[i] > 'g') { printf("\nBad note:%c\n", song[i]); beep(); beep(); beep(); sleep(5.0); return; } note= notes[song[i]-'a'] + accidental; rest= 0; } i++; if (rest) { play_note(0, duration); } else { delta= note - (old_note % 12); old_note += delta; if (delta > 5) old_note -= 12; if (delta < -5) old_note += 12; play_note(old_note, duration); } } play_note(0, 1); music_command('o'); } void music_command(int c) { music_current_command= c; } void play_reset() { time= mseconds(); newtime= time+100L; } void play_note(int note, int duration) { play_note_2(note, duration*7); play_note_2(0, duration); } void play_note_2(int note, int duration) { float freq; int period; if (note) { freq= 55.0 * (2. ^ (((float) note) / 12.)); } while (mseconds() < newtime); if (note) { set_beeper_pitch(freq); beeper_on(); } else { beeper_off(); } if (music_next_command && music_current_command != music_next_command){ music_command(music_next_command); music_next_command= 0; } newtime += (long)(duration * tempo); } void randmusic() { int x; while (!stop_button()) { tempo = random(10) + 10 * 128 / 256; x = random(8); if (x == 0) play(pp_song); if (x == 1) play(w_song); if (x == 2) play(classics_song); if (x == 3) play(charge_song); if (x == 4) play(looney_tune_song); if (x == 5) play(benny_song); if (x == 6) play(mb_song1); if (x == 7) play(mb_song2); } } /* place your #defines and global variable declarations here */ void program() { randmusic(); } /* put your functions and subroutines here */ /*********************************************************************/ /********* FROM HERE ON ARE MENU ROUTINES: LEAVE AS IS ***************/ /*********************************************************************/ void main() { printf("template.c v1.2 updated 3/1/00\n"); sleep(1.5); while (1==1) { ao(); menu(); ao(); program(); ao(); sleep(1.0); } } char menu_choices[7][32] = {"Any button = run user program","MOTOR: Start=FWD 0 : Stop=RVS","MOTOR: Start=FWD 1 : Stop=RVS","MOTOR: Start=FWD 2 : Stop=RVS","MOTOR: Start=FWD 3 : Stop=RVS","Any button = Show Analogs","Any button = Show Digitals"}; int menu_motorstate = 0; int menu_choice = 9; int menu_motorpower = 100; void menu() { while (1) { while (stop_button() || start_button()) {} sleep(0.05); while (stop_button() || start_button()) {} sleep(0.05); while (stop_button() || start_button()) {} sleep(0.05); while (stop_button() || start_button()) {} menu_choice = select_string(menu_choices, 7); if ((menu_choice == -1) || (menu_choice == 0)) { printf("\n\n"); return; } else { if (menu_choice == 1) { motor(0, menu_motorpower); } if (menu_choice == 2) { motor(0, -menu_motorpower); } if (menu_choice == 3) { motor(1, menu_motorpower); } if (menu_choice == 4) { motor(1, -menu_motorpower); } if (menu_choice == 5) { motor(2, menu_motorpower); } if (menu_choice == 6) { motor(2, -menu_motorpower); } if (menu_choice == 7) { motor(3, menu_motorpower); } if (menu_choice == 8) { motor(3, -menu_motorpower); } if (menu_choice == 9) { while (start_button() || stop_button()) {} display_analogs(); } if (menu_choice == 10) { while (start_button() || stop_button()) {} display_analogs(); } if (menu_choice == 11) { while (start_button() || stop_button()) {} display_digitals(); } if (menu_choice == 12) { while (start_button() || stop_button()) {} display_digitals(); } while (stop_button() || start_button()) {} ao(); } } } void display_digitals() { int i, a; while (!start_button() && !stop_button()) { printf("digitals 7->15: "); for(i=7; i<=15; i++) { a = digital(i); printf("%d",a); } printf("\n"); sleep(0.1); } } void display_analogs() { int i, a; while (!start_button() && !stop_button()) { for(i=0; i<=6; i++) { a = analog(i); if (a < 10) { printf(" "); } if (a < 100) { printf(" "); } printf("%d ",a); } printf("\n"); sleep(0.1); } } int select_string(char choices[][],int n) { int selection,last_selection=-1,coarseness; if(n>_array_size(choices)) n=_array_size(choices); coarseness=255/(n-1); while(!(stop_button() || start_button())) { selection=(knob())/coarseness; if(selection!=last_selection) { printf("%s\n",choices[selection]); sleep(0.1); last_selection=selection; } } if (start_button()) { return selection * 2 - 1; } else { return selection * 2; } }