Hexi_Acceleromagnetic_Synth: Michael Yarnell, Alec Pierce, 2017 The program turns an NXP Hexiwear, its development board, and a Click buzzer collectively into an 'acceleromagnetic' synthesizer. That is to say that the synthesizer is controlled primarily via the on-board accelerometer and magnetometer units.
Dependencies: FXOS8700 Hexi_KW40Z NeatGUI PWM_6_Tone_Library
main.cpp
- Committer:
- MTYarnell
- Date:
- 2017-04-18
- Revision:
- 0:bec3a12e79e7
File content as of revision 0:bec3a12e79e7:
/* Hexi_Acceleromagnetic_Synth 2017 Michael Yarnell, Alec Pierce Class Project: ECE49500 SP17 (MEMS/NEMS/IoT/Wearables) IUPUI - Purdue School of Engineering and Technology The following program turns an NXP Hexiwear, its development board, and a Click buzzer collectively into an 'acceleromagnetic' synthesizer. That is to say that the synthsizer is controlled primarily via the onboard accelerometer and magnetometer units. Once the appropriate initializations have been made, the program plays a short, preprogrammed tune. If, at any time, the left or right screen buttons are pressed, they each emit unique "drumbeat" note sequences. The accelerometer and magnetometer are read. The accelerometer x and y (pitch and roll, respectively) control note selection. The magnetometer value RMS is calculated, and if the magnetic field RMS is greater than 250uT, the instrument will emit corresponding notes. Adapted from examples: "Hexi_Magneto-v2_Example" https://developer.mbed.org/teams/Hexiwear/code/Hexi_Magneto-v2_Example/ "Hexi_Accelero-v2_Example" https://developer.mbed.org/teams/Hexiwear/code/Hexi_Accelero-v2_Example/ "Hexi_Click_Buzzer-v2_Example" https://developer.mbed.org/teams/Hexiwear/code/Hexi_Click_Buzzer-v2_Example/ "Hexi_Bubble_Game" https://developer.mbed.org/teams/Hexiwear/code/Hexi_Bubble_Game/ */ // TYPEDEFS typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed long long int int64_t; typedef unsigned long long int uint64_t; // LIBRARIES // Note that pwm_6_tone.h has been modified from the default library header. #include "mbed.h" #include <pwm_6_tone.h> #include "Hexi_KW40Z.h" #include "FXOS8700.h" #include "string.h" // PIN CONNECTIONS // Define the Buzzer Pinout (PWM Out) PwmOut Buzzer(PTA10); // Instantiate the Hexi KW40Z Driver (UART TX, UART RX) KW40Z kw40z_device(PTE24, PTE25); // Accelerometer and Magnetometer instantiation FXOS8700 mag(PTC11, PTC10); FXOS8700 accel(PTC11, PTC10); // Initialize Face LED DigitalOut led1(LED_GREEN); // Initialize Serial port //Serial pc(USBTX, USBRX); // Include to debug modified sensor values // or enter a practice mode. // VARIABLES float accel_data[3]; // Storage for the data from the sensor float mag_data[3]; // Storage for the data from the sensor float mag_rms=0.0; // RMS value to be computed from sensor input // From Bubble int xposg = 0; // The roll position of the unit int yposg = 0; // The pitch position of the unit // New Variables // Note is a floating-point value that bears a number to send to the // Tune function. float Note = 0.0; // This table holds the values determined to play the appropriate notes // as reverse-engineered from the values in // "Hexi_Click_Buzzer-v2_Example" to widen range to nearly six octaves. float C_1 = 1000000/Do1, Cs_1 = 1000000/Do1s, D_1 = 1000000/Re1, Ds_1 = 1000000/Re1s, E_1 = 1000000/Mi1, F_1 = 1000000/Fa1, Fs_1 = 1000000/Fa1s, G_1 = 1000000/So1, Gs_1 = 1000000/So1s, A_1 = 1000000/La1, As_1 = 1000000/La1s, B_1 = 1000000/Ti1, C_2 = 1000000/Do2, Cs_2 = 1000000/Do2s, D_2 = 1000000/Re2, Ds_2 = 1000000/Re2s, E_2 = 1000000/Mi2, F_2 = 1000000/Fa2, Fs_2 = 1000000/Fa2s, G_2 = 1000000/So2, Gs_2 = 1000000/So2s, A_2 = 1000000/La2, As_2 = 1000000/La2s, B_2 = 1000000/Ti2, C_3 = 1000000/Do3, Cs_3 = 1000000/Do3s, D_3 = 1000000/Re3, Ds_3 = 1000000/Re3s, E_3 = 1000000/Mi3, F_3 = 1000000/Fa3, Fs_3 = 1000000/Fa3s, G_3 = 1000000/So3, Gs_3 = 1000000/So3s, A_3 = 1000000/La3, As_3 = 1000000/La3s, B_3 = 1000000/Ti3, C_4 = 1000000/Do4, Cs_4 = 1000000/Do4s, D_4 = 1000000/Re4, Ds_4 = 1000000/Re4s, E_4 = 1000000/Mi4, F_4 = 1000000/Fa4, Fs_4 = 1000000/Fa4s, G_4 = 1000000/So4, Gs_4 = 1000000/So4s, A_4 = 1000000/La4, As_4 = 1000000/La4s, B_4 = 1000000/Ti4, C_5 = 1000000/Do5, Cs_5 = 1000000/Do5s, D_5 = 1000000/Re5, Ds_5 = 1000000/Re5s, E_5 = 1000000/Mi5, F_5 = 1000000/Fa5, Fs_5 = 1000000/Fa5s, G_5 = 1000000/So5, Gs_5 = 1000000/So5s, A_5 = 1000000/La5, As_5 = 1000000/La5s, B_5 = 1000000/Ti5, C_6 = 1000000/Do6, Cs_6 = 1000000/Do6s, D_6 = 1000000/Re6, Ds_6 = 1000000/Re6s, E_6 = 1000000/Mi6, F_6 = 1000000/Fa6, Fs_6 = 1000000/Fa6s, G_6 = 1000000/So6, Gs_6 = 1000000/So6s, A_6 = 1000000/La6, As_6 = 1000000/La6s, B_6 = 1000000/Ti6; //FUNCTIONS void ButtonLeft(void) { // "Beat" 1 Tune(Buzzer, C_5, 1); Tune(Buzzer, E_2, 1); Tune(Buzzer, C_5, 1); Tune(Buzzer, E_1, 1); } void ButtonRight(void) { // "Beat" 2 Tune(Buzzer, C_3, 1); Tune(Buzzer, E_2, 1); Tune(Buzzer, C_1, 1); Tune(Buzzer, E_1, 1); } int main() { // Instantiate Buttons kw40z_device.attach_buttonLeft(&ButtonLeft); kw40z_device.attach_buttonRight(&ButtonRight); // Configure Accelerometer, Magnetometer FXOS8700 accel.accel_config(); mag.mag_config(); // Startup tune tones Tune(Buzzer, D_6, 2); wait_ms(5); Tune(Buzzer, D_4, 2); wait_ms(5); Tune(Buzzer, C_5, 2); wait_ms(5); Tune(Buzzer, D_4, 4); wait_ms(5); Tune(Buzzer, D_2, 4); wait_ms(5); Tune(Buzzer, Cs_1, 2); wait_ms(10); Tune(Buzzer, C_1, 16); wait_ms(10); Tune(Buzzer, C_2, 8); wait_ms(25); Tune(Buzzer, C_3, 4); wait_ms(60); Tune(Buzzer, C_4, 2); wait_ms(40); Tune(Buzzer, C_5, 4); wait_ms(100); // This loop, modified from from the Bubble game example, locates the // x/y accelerometer information (within boundaries) to determine // the position of the user and thus the note to play. while(1) { // Get accelerometer data accel.acquire_accel_data_g(accel_data); xposg=(accel_data[1] * (-20.0)); if (xposg > 30) xposg = 30; // Notes: 12 per octave if (xposg < -30) xposg = -30; yposg=(accel_data[0] * (40.0)); if (yposg > 30) yposg = 30; // Octaves: 6 available if (yposg < -30) yposg = -30; // Find Note // Program first attempts to find Octave from accelerometer y values. // Then it further determines the and assigns the value of the note // from the x value. if (yposg > 29) { // Octave 1 if (xposg > 20) Note = C_1; // C if (xposg > 16) Note = Cs_1; // Cs if (xposg > 12) Note = D_1; // D if (xposg > 8) Note = Ds_1; // Ds if (xposg > 4) Note = E_1; // E if (xposg >= 0) Note = F_1; // F if (xposg > -4) Note = Fs_1; // Fs if (xposg > -8) Note = G_1; // G if (xposg > -12) Note = Gs_1; // Gs if (xposg > -16) Note = A_1; // A if (xposg > -20) Note = As_1; // As else Note = B_1; // B } else if (yposg > 15) { // Octave 2 if (xposg > 20) Note = C_2; // C if (xposg > 16) Note = Cs_2; // Cs if (xposg > 12) Note = D_2; // D if (xposg > 8) Note = Ds_2; // Ds if (xposg > 4) Note = E_2; // E if (xposg >= 0) Note = F_2; // F if (xposg > -4) Note = Fs_2; // Fs if (xposg > -8) Note = G_2; // G if (xposg > -12) Note = Gs_2; // Gs if (xposg > -16) Note = A_2; // A if (xposg > -20) Note = As_2; // As else Note = B_2; // B } else if (yposg >= 0) { // Octave 3 if (xposg > 20) Note = C_3; // C if (xposg > 16) Note = Cs_3; // Cs if (xposg > 12) Note = D_3; // D if (xposg > 8) Note = Ds_3; // Ds if (xposg > 4) Note = E_3; // E if (xposg >= 0) Note = F_3; // F if (xposg > -4) Note = Fs_3; // Fs if (xposg > -8) Note = G_3; // G if (xposg > -12) Note = Gs_3; // Gs if (xposg > -16) Note = A_3; // A if (xposg > -20) Note = As_3; // As else Note = B_3; // B } else if (yposg > -15) { // Octave 4 if (xposg > 20) Note = C_4; // C if (xposg > 16) Note = Cs_4; // Cs if (xposg > 12) Note = D_4; // D if (xposg > 8) Note = Ds_4; // Ds if (xposg > 4) Note = E_4; // E if (xposg >= 0) Note = F_4; // F if (xposg > -4) Note = Fs_4; // Fs if (xposg > -8) Note = G_4; // G if (xposg > -12) Note = Gs_4; // Gs if (xposg > -16) Note = A_4; // A if (xposg > -20) Note = As_4; // As else Note = B_4; // B } else if (yposg > -29) { // Octave 5 if (xposg > 20) Note = C_5; // C if (xposg > 16) Note = Cs_5; // Cs if (xposg > 12) Note = D_5; // D if (xposg > 8) Note = Ds_5; // Ds if (xposg > 4) Note = E_5; // E if (xposg >= 0) Note = F_5; // F if (xposg > -4) Note = Fs_5; // Fs if (xposg > -8) Note = G_5; // G if (xposg > -12) Note = Gs_5; // Gs if (xposg > -16) Note = A_5; // A if (xposg > -20) Note = As_5; // As else Note = B_5; // B } else { // Octave 6 if (xposg > 20) Note = C_6; // C if (xposg > 16) Note = Cs_6; // Cs if (xposg > 12) Note = D_6; // D if (xposg > 8) Note = Ds_6; // Ds if (xposg > 4) Note = E_6; // E if (xposg >= 0) Note = F_6; // F if (xposg > -4) Note = Fs_6; // Fs if (xposg > -8) Note = G_6; // G if (xposg > -12) Note = Gs_6; // Gs if (xposg > -16) Note = A_6; // A if (xposg > -20) Note = As_6; // As else Note = B_6; // B } // Get magnetometer data mag.acquire_mag_data_uT(mag_data); // Find RMS values of this 3-axis reading mag_rms = sqrt(((mag_data[0] * mag_data[0]) + (mag_data[1] * mag_data[1]) + (mag_data[2] * mag_data[2])) / 3); //printf("\tX: %i \tY: %i \tMAGRMS: %i", xposg, yposg, mag_rms); // Above line displays modified sensor results, useful for practice or // debugging. // If the magnetic field is strong enough, play a note. if (mag_rms > 150) { Tune(Buzzer, Note, 2); }// Timing is out of 16ths } }