Advertisement
Guest User

synthdriver source

a guest
Dec 5th, 2010
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.38 KB | None | 0 0
  1. #include <Wire.h>
  2.  
  3. #define PI  3.14159265358979323846
  4. #define ACCEL (0x53)    //ADXL345 device address
  5. #define TO_READ (6)        //num of bytes we are going to read each time (two bytes for each axis)
  6. #define g0 9.812865328
  7. #define ACCELEROMETER_GAIN (0.004 * g0)
  8. //MIDI Presets
  9. #define CC = 176
  10. #define DEFAULT_CHANNEL = 12
  11.  
  12. //Accelerometer
  13. #define R_INT_ENABLE = 46
  14. #define R_INT_MAP = 47
  15. #define R_THRESH_TAP = 29
  16. #define R_DUR = 33
  17. #define R_TAP_AXES 42
  18.  
  19. // Gyroscope ITG3200
  20. #define GYRO (0x68) // gyro address, binary = 11101001 when AD0 is connected to Vcc (see schematics of your breakout board)
  21. #define G_SMPLRT_DIV 0x15
  22. #define G_DLPF_FS 0x16
  23. #define G_INT_CFG 0x17
  24. #define G_PWR_MGM 0x3E
  25. #define G_TO_READ 8 // 2 bytes for each axis x, y, z
  26. #define G_X_OFFSET 14
  27. #define G_Y_OFFSET 47
  28. #define G_Z_OFFSET 10
  29.  
  30. char str[512]; //string buffer to transform data before sending it to the serial port
  31.  
  32. int CALIBRATION_SAMPLES = 128;
  33. int reads = 0;
  34. int x, y, z;
  35.  
  36. volatile double a_x, a_y, a_z;
  37. double a_xBias, a_yBias, a_zBias;
  38.  
  39. volatile double a_x_stack = 0;
  40. volatile double a_y_stack = 0;
  41. volatile double a_z_stack = 0;
  42.  
  43. volatile double g_x, g_y, g_z;
  44.  
  45. volatile double turn;
  46. volatile double prev_turn = 64;
  47. volatile double prev_a_z = 0;
  48.  
  49. volatile int last_pitch = 0;
  50. volatile int last_roll = 0;
  51. volatile int last_rotation = 0;
  52.  
  53. boolean noteon = false;
  54. int last_note = 36;
  55. int BASE_NOTE = 36;
  56. int TRIGGER_CHANNEL = 13;
  57. int SHAKE_TOLERANCE = 0;
  58. int notes[7] = {0,2,4,5,7,9,11}; //1-octave scale
  59. int last_pan = 0;
  60. boolean toggle = false;
  61.  
  62. void setup()
  63. {
  64.   Wire.begin();        // join i2c bus (address optional for master)
  65.   Serial.begin(115200);  // start serial for output
  66.  
  67.   initAccel();
  68.   initGyro();
  69.  
  70.   delay(22);
  71. }
  72.  
  73. void loop()
  74. {
  75.  
  76.   getAccelGyro();
  77.  
  78.   /* Flat chip orientation
  79.   double roll  = atan2(a_y, sqrt( a_x * a_x + a_z * a_z));
  80.   double pitch = atan2(a_x, sqrt( a_y * a_y + a_z * a_z));
  81.   */
  82.  
  83.   //Wheel orientation - Calculate the angle in RADs to the ground
  84.   double pitch  = atan2(a_z, sqrt( a_y * a_y + a_x * a_x));
  85.   double roll = atan2(a_y, sqrt( a_z * a_z + a_x * a_x));
  86.  
  87.   //Map the resulting values to a 7bit range  
  88.   int pitch_range = (int)map(constrain(pitch * 180/PI, -90, 90), -90, 90, 0, 127);
  89.   int roll_range = (int)map(constrain(roll * 180/PI, -90, 90), -90, 90, 0, 127);
  90.   int leftPot = map(constrain(analogRead(3), 490, 1023),490,1023,0,6);
  91.   int rightPot = map(constrain(analogRead(2), 515, 1017), 515,1017,0,127);
  92.  
  93.   //Lock the gyro turn to 90degrees in each direction
  94.   turn = constrain(turn,-90,90);
  95.   //Map the turn value to 7bit range
  96.   int rotation_range = map((int)constrain(turn,-90,90),-90,90,0,127);
  97.  
  98.   //Add the selected note to middle C
  99.   int this_note = BASE_NOTE + notes[leftPot];
  100.  
  101.   //If there is contact on the leftPot engage the note
  102.   if ((analogRead(3) > 0)) {
  103.     if ((this_note != last_note) || (this_note == last_note && !noteon)) {
  104.       sendMIDI(144, last_note, 0);
  105.       sendMIDI(144, this_note, 127);
  106.     }
  107.     noteon = true;
  108.     last_note = this_note;
  109.   } //Turn notes off if there is no contact
  110.   else if ((analogRead(3) == 0) && noteon) {
  111.     sendMIDI(144, last_note, 0);
  112.     noteon=false;
  113.   }
  114.  
  115.   /* Some gesture detection
  116.   if ((prev_a_z < -10.0) && (a_z > 0.0)) {
  117.     sendMIDI(144, last_note, 0);
  118.     noteon = false;
  119.   }
  120.  
  121.   prev_a_z = a_z;
  122.   */
  123.  
  124.   //When the change in values per cycle is greater than 0 (in this case) send the new midi command
  125.   if (abs(pitch_range - last_pitch) > SHAKE_TOLERANCE){
  126.     sendMIDI(176, 10, pitch_range);
  127.   }
  128.  
  129.   if (abs(roll_range - last_roll) > SHAKE_TOLERANCE){
  130.     sendMIDI(176, 11, roll_range);
  131.   }
  132.  
  133.   if (abs(rotation_range - last_rotation) > SHAKE_TOLERANCE) {
  134.     sendMIDI(176, 12, rotation_range);
  135.   }
  136.  
  137.   if (leftPot != 0) {
  138.     //sendMIDI(176, 13, leftPot);
  139.   }
  140.  
  141.   //Control the pan with right pot
  142.   if (rightPot != last_pan && rightPot != 0) {
  143.       sendMIDI(176, 13, rightPot);
  144.       last_pan = rightPot;
  145.     } //Return to middle if no contact
  146.   else if (rightPot != last_pan && rightPot == 0) {
  147.       sendMIDI(176, 13, 64);
  148.       last_pan = rightPot;
  149.   }
  150.  
  151.   last_pitch = pitch_range;
  152.   last_roll = roll_range;
  153.   last_rotation = rotation_range;
  154.  
  155. }
  156.  
  157.  
  158. void initAccel(){
  159.     //Turning on the ADXL345
  160.   writeTo(ACCEL, 0x2D, 0);
  161.   writeTo(ACCEL, 0x2D, 16);
  162.  
  163.   writeTo(ACCEL, 0x2C, 0x0C); // Set BW 200hz
  164.   writeTo(ACCEL, 0x31, 0x0B); // Set BW 200hz
  165.  
  166.   //TODO:TAP DETECTION
  167.   /*
  168.   writeTo(ACCEL, R_INT_MAP, 0); // send all interrupts to ADXL345's INT1 pin
  169.   writeTo(ACCEL, R_DUR, 0x1F); // 625us/LSB
  170.   writeTo(ACCEL, R_THRESH_TAP, 48); // 62.5mg/LSB  <==> 3000mg/62.5mg = 48 LSB as datasheet suggestion
  171.   writeTo(ACCEL, R_TAP_AXES, 6); // enable tap detection on x,y,z axes
  172.   writeTo(ACCEL, R_INT_ENABLE, 96); // enable signle and double tap, activity, inactivity and free fall detection
  173.   */
  174.  
  175.   writeTo(ACCEL, 0x2D, 8); //set power mode
  176. }
  177.  
  178. void initGyro()
  179. {
  180.   /*****************************************
  181.   * ITG 3200
  182.   * power management set to:
  183.   * clock select = internal oscillator
  184.   *     no reset, no sleep mode
  185.   *   no standby mode
  186.   * sample rate to = 125Hz
  187.   * parameter to +/- 2000 degrees/sec
  188.   * low pass filter = 5Hz
  189.   * no interrupt
  190.   ******************************************/
  191.   writeTo(GYRO, G_PWR_MGM, 0x00);
  192.   writeTo(GYRO, G_SMPLRT_DIV, 0x07); // EB, 50, 80, 7F, DE, 23, 20, FF
  193.   writeTo(GYRO, G_DLPF_FS, 0x1E); // +/- 2000 dgrs/sec, 1KHz, 1E, 19
  194.   writeTo(GYRO, G_INT_CFG, 0x00);
  195. }
  196.  
  197. //Read the accelerometer and gyro values to buffer
  198. void getAccelGyro(){
  199.   int gyroRegAddress = 0x1B;
  200.   byte gyroBuff[G_TO_READ];
  201.   int accelRegAddress = 0x32;
  202.   byte accelBuff[TO_READ] ;
  203.   int samples = 10;
  204.   double LSB = 14.375;
  205.   int sample_rate = 125;
  206.   //Smoothing loop for accel, and sampling loop for gyro
  207.   for(int i = 0; i < 10; i++){
  208.     readFrom(ACCEL, accelRegAddress, TO_READ, accelBuff); //read the acceleration data from the ADXL345
  209.    
  210.     //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  211.     //thus we are converting both bytes in to one int
  212.     a_x_stack += (((int)accelBuff[1]) << 8) | accelBuff[0];  
  213.     a_y_stack += (((int)accelBuff[3])<< 8) | accelBuff[2];
  214.     a_z_stack += (((int)accelBuff[5]) << 8) | accelBuff[4];
  215.      
  216.     readFrom(GYRO, gyroRegAddress, G_TO_READ, gyroBuff); //read the gyro data from the ITG3200
  217.  
  218.     g_x = ((int)(gyroBuff[2] << 8) | gyroBuff[3]) - G_X_OFFSET;
  219.     g_y = ((int)(gyroBuff[4] << 8) | gyroBuff[5]) - G_Y_OFFSET;
  220.     g_z = ((int)(gyroBuff[6] << 8) | gyroBuff[7]) - G_Z_OFFSET;
  221.    
  222.     turn += g_x / LSB / sample_rate; //Integrate the turn value assuming 1 sample every 8ms
  223.     delay(5); //stretch the sampling interval so that we're at about 8ms
  224.   }
  225.  
  226.   //Calculate the smoothed acceleration data into m/s/s
  227.   a_x = ((a_x_stack / samples) - a_xBias) * ACCELEROMETER_GAIN;
  228.   a_y = ((a_y_stack / samples) - a_yBias) * ACCELEROMETER_GAIN;
  229.   a_z = ((a_z_stack / samples) - a_zBias) * ACCELEROMETER_GAIN;
  230.  
  231.   a_x_stack = 0;
  232.   a_y_stack = 0;
  233.   a_z_stack = 0;
  234. }
  235.  
  236. //Method to calibrate accelerometer offset
  237. void calibrateAccelerometer(void) {
  238.     int regAddress = 0x32;
  239.     byte buff[TO_READ] ;    //6 bytes buffer for saving data read from the device
  240.     a_x_stack = 0;
  241.     a_y_stack = 0;
  242.     a_z_stack = 0;
  243.    
  244.     //Take a number of readings and average them
  245.     //to calculate the zero g offset.
  246.     for (int i = 0; i < CALIBRATION_SAMPLES; i++) {
  247.  
  248.       readFrom(ACCEL, regAddress, TO_READ, buff); //read the acceleration data from the ADXL345
  249.    
  250.      //each axis reading comes in 10 bit resolution, ie 2 bytes.  Least Significat Byte first!!
  251.      //thus we are converting both bytes in to one int
  252.       a_x_stack += (((int)buff[1]) << 8) | buff[0];  
  253.       a_y_stack += (((int)buff[3])<< 8) | buff[2];
  254.       a_z_stack += (((int)buff[5]) << 8) | buff[4];
  255.      
  256.       delay(5);
  257.  
  258.     }
  259.  
  260.     a_x_stack /= CALIBRATION_SAMPLES;
  261.     a_y_stack /= CALIBRATION_SAMPLES;
  262.     a_z_stack /= CALIBRATION_SAMPLES;
  263.  
  264.     //At 4mg/LSB, 250 LSBs is 1g.
  265.     a_xBias = (a_x_stack - 250);
  266.     a_yBias = a_y_stack;
  267.     a_zBias = a_z_stack;
  268.  
  269.     a_x_stack = 0;
  270.     a_y_stack = 0;
  271.     a_z_stack = 0;
  272.  
  273. }
  274.  
  275. //Writes val to address register on device
  276. void writeTo(int device, byte address, byte val) {
  277.    Wire.beginTransmission(device); //start transmission to device
  278.    Wire.send(address);        // send register address
  279.    Wire.send(val);        // send value to write
  280.    Wire.endTransmission(); //end transmission
  281. }
  282.  
  283. //reads num bytes starting from address register on device in to buff array
  284. void readFrom(int device, byte address, int num, byte buff[]) {
  285.   Wire.beginTransmission(device); //start transmission to device
  286.   Wire.send(address);        //sends address to read from
  287.   Wire.endTransmission(); //end transmission
  288.  
  289.   Wire.beginTransmission(device); //start transmission to device
  290.   Wire.requestFrom(device, num);    // request 6 bytes from device
  291.  
  292.   int i = 0;
  293.   while(Wire.available())    //device may send less than requested (abnormal)
  294.   {
  295.     buff[i] = Wire.receive(); // receive a byte
  296.     i++;
  297.   }
  298.   Wire.endTransmission(); //end transmission
  299. }
  300.  
  301. void sendMIDI(unsigned char MESSAGE, unsigned char CONTROL, unsigned char VALUE) //pass values out through standard Midi Command
  302. {
  303.    Serial.print(MESSAGE);
  304.    Serial.print(CONTROL);
  305.    Serial.print(VALUE);
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement