Guest User

Pitch to MIDI Tracker

a guest
Apr 14th, 2012
243
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 38.61 KB | None | 0 0
  1. -----------------------------------
  2. Arduino Based Theremin/MIDI Tracker
  3. Version 1.0
  4. January 2011
  5. -----------------------------------
  6.  
  7. This folder contains the following:
  8.  
  9.  
  10. /Arduino Sketches
  11.  
  12. Contains all the test code and libraries needed to program the ATMEL328P microprocessor
  13.  
  14. ---
  15.  
  16. /Eagle CAD Files
  17.  
  18. Contains the CAD files for both the schematic and board.
  19. Eagle can be downloaded for free from http://www.cadsoft.de/freeware.htm
  20.  
  21. ---
  22.  
  23. /Images
  24.  
  25. The board and schematic as high resolution PNG image files (600 DPI)
  26.  
  27. ---
  28.  
  29. EtchMask600DPI.tif
  30.  
  31. A high resolution monochrome etch mask - used to make your own PCB if required
  32.  
  33. ---
  34.  
  35. ThereminTracker_Assembly.pdf
  36.  
  37. Complete guide to etching a PCB, building and programming the board and using the
  38. Theremin Tracker.
  39.  
  40. ---
  41.  
  42. With thanks to
  43.  
  44. www.cadsoft.de
  45. www.adafruit.com
  46. little-scale.blogspot.com
  47. www.arduino.cc
  48.  
  49. //==========================
  50. // Readme
  51. //==========================
  52.  
  53. The AFSoftSerial library needs to be installed in the
  54. Arduino /libraries folder before trying to compile the
  55. THEREMIN_MIDI_2011 sketch.
  56.  
  57. //==========================
  58. // AFSoftSerial.cpp
  59. //==========================
  60. /*
  61.   SoftwareSerial.cpp - Software serial library
  62.   Copyright (c) 2006 David A. Mellis.  All right reserved. - hacked by ladyada
  63.  
  64.   This library is free software; you can redistribute it and/or
  65.   modify it under the terms of the GNU Lesser General Public
  66.   License as published by the Free Software Foundation; either
  67.   version 2.1 of the License, or (at your option) any later version.
  68.  
  69.   This library is distributed in the hope that it will be useful,
  70.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  71.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  72.   Lesser General Public License for more details.
  73.  
  74.   You should have received a copy of the GNU Lesser General Public
  75.   License along with this library; if not, write to the Free Software
  76.   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  77. */
  78.  
  79. /******************************************************************************
  80.  * Includes
  81.  ******************************************************************************/
  82. #include <avr/interrupt.h>
  83. #include "WConstants.h"
  84. #include "AFSoftSerial.h"
  85.  
  86. /******************************************************************************
  87.  * Definitions
  88.  ******************************************************************************/
  89.  
  90. #define AFSS_MAX_RX_BUFF 64
  91.  
  92. /******************************************************************************
  93.  * Statics
  94.  ******************************************************************************/
  95. static uint8_t _receivePin;
  96. static uint8_t _transmitPin;
  97. static int _bitDelay;
  98.  
  99. static char _receive_buffer[AFSS_MAX_RX_BUFF];
  100. static uint8_t _receive_buffer_index;
  101.  
  102. #if (F_CPU == 16000000)
  103. void whackDelay(uint16_t delay) {
  104.   uint8_t tmp=0;
  105.  
  106.   asm volatile("sbiw    %0, 0x01 \n\t"
  107.            "ldi %1, 0xFF \n\t"
  108.            "cpi %A0, 0xFF \n\t"
  109.            "cpc %B0, %1 \n\t"
  110.            "brne .-10 \n\t"
  111.            : "+r" (delay), "+a" (tmp)
  112.            : "0" (delay)
  113.            );
  114. }
  115. #endif
  116.  
  117. /******************************************************************************
  118.  * Interrupts
  119.  ******************************************************************************/
  120.  
  121. SIGNAL(SIG_PIN_CHANGE0) {
  122.   if ((_receivePin >=8) && (_receivePin <= 13)) {
  123.     recv();
  124.   }
  125. }
  126. SIGNAL(SIG_PIN_CHANGE2)
  127. {
  128.   if (_receivePin <8) {
  129.     recv();
  130.   }
  131. }
  132.  
  133.  
  134. void recv(void) {
  135.   /*char i, d = 0;
  136.   if (digitalRead(_receivePin))
  137.     return;       // not ready!
  138.   whackDelay(_bitDelay - 8);
  139.   for (i=0; i<8; i++) {
  140.     //PORTB |= _BV(5);
  141.     whackDelay(_bitDelay*2 - 6);  // digitalread takes some time
  142.     //PORTB &= ~_BV(5);
  143.     if (digitalRead(_receivePin))
  144.       d |= (1 << i);
  145.    }
  146.   whackDelay(_bitDelay*2);
  147.   if (_receive_buffer_index >=  AFSS_MAX_RX_BUFF)
  148.     return;
  149.   _receive_buffer[_receive_buffer_index] = d; // save data
  150.   _receive_buffer_index++;  // got a byte
  151. */  
  152. }
  153.  
  154.  
  155.  
  156. /******************************************************************************
  157.  * Constructors
  158.  ******************************************************************************/
  159.  
  160. AFSoftSerial::AFSoftSerial(uint8_t transmitPin)
  161. {
  162.   //_receivePin = receivePin;
  163.   _transmitPin = transmitPin;
  164.   _baudRate = 0;
  165. }
  166.  
  167. void AFSoftSerial::setTX(uint8_t tx) {
  168.   _transmitPin = tx;
  169. }
  170. void AFSoftSerial::setRX(uint8_t rx) {
  171.   //_receivePin = rx;
  172. }
  173.  
  174. /******************************************************************************
  175.  * User API
  176.  ******************************************************************************/
  177.  
  178. void AFSoftSerial::begin(long speed)
  179. {
  180.   pinMode(_transmitPin, OUTPUT);
  181.   digitalWrite(_transmitPin, HIGH);
  182.  
  183.   //pinMode(_receivePin, INPUT);
  184.   //digitalWrite(_receivePin, HIGH);  // pullup!
  185.  
  186.   _baudRate = speed;
  187.   switch (_baudRate) {
  188.   case 115200: // For xmit -only-!
  189.     _bitDelay = 4; break;
  190.   case 57600:
  191.     _bitDelay = 14; break;
  192.   case 38400:
  193.     _bitDelay = 24; break;
  194.   case 31250:
  195.     _bitDelay = 31; break;
  196.   case 19200:
  197.     _bitDelay = 54; break;
  198.   case 9600:
  199.     _bitDelay = 113; break;
  200.   case 4800:
  201.     _bitDelay = 232; break;
  202.   case 2400:
  203.     _bitDelay = 470; break;
  204.   default:
  205.     _bitDelay = 0;
  206.   }    
  207.  
  208.   /* if (_receivePin < 8) {
  209.      // a PIND pin, PCINT16-23
  210.      PCMSK2 |= _BV(_receivePin);
  211.      PCICR |= _BV(2);
  212.   } else if (_receivePin <= 13) {
  213.     // a PINB pin, PCINT0-5
  214.     PCICR |= _BV(0);    
  215.     PCMSK0 |= _BV(_receivePin-8);
  216.   } */
  217.  
  218.   whackDelay(_bitDelay*2); // if we were low this establishes the end
  219. }
  220.  
  221. int AFSoftSerial::read(void)
  222. {
  223.   /*uint8_t d,i;
  224.  
  225.   if (! _receive_buffer_index)
  226.     return -1;
  227.  
  228.   d = _receive_buffer[0]; // grab first byte
  229.   // if we were awesome we would do some nifty queue action
  230.   // sadly, i dont care
  231.   for (i=0; i<_receive_buffer_index; i++) {
  232.     _receive_buffer[i] = _receive_buffer[i+1];
  233.   }
  234.   _receive_buffer_index--;
  235.   return d;*/
  236.   return 0;
  237. }
  238.  
  239. uint8_t AFSoftSerial::available(void)
  240. {
  241.   return 0; //_receive_buffer_index;
  242. }
  243.  
  244. void AFSoftSerial::print(uint8_t b)
  245. {
  246.   if (_baudRate == 0)
  247.     return;
  248.   byte mask;
  249.  
  250.   cli();  // turn off interrupts for a clean txmit
  251.  
  252.   digitalWrite(_transmitPin, LOW);  // startbit
  253.   whackDelay(_bitDelay*2);
  254.  
  255.   for (mask = 0x01; mask; mask <<= 1) {
  256.     if (b & mask){ // choose bit
  257.       digitalWrite(_transmitPin,HIGH); // send 1
  258.     }
  259.     else{
  260.       digitalWrite(_transmitPin,LOW); // send 1
  261.     }
  262.     whackDelay(_bitDelay*2);
  263.   }
  264.  
  265.   digitalWrite(_transmitPin, HIGH);
  266.   sei();  // turn interrupts back on. hooray!
  267.   whackDelay(_bitDelay*2);
  268. }
  269.  
  270. void AFSoftSerial::print(const char *s)
  271. {
  272.   while (*s)
  273.     print(*s++);
  274. }
  275.  
  276. void AFSoftSerial::print(char c)
  277. {
  278.   print((uint8_t) c);
  279. }
  280.  
  281. void AFSoftSerial::print(int n)
  282. {
  283.   print((long) n);
  284. }
  285.  
  286. void AFSoftSerial::print(unsigned int n)
  287. {
  288.   print((unsigned long) n);
  289. }
  290.  
  291. void AFSoftSerial::print(long n)
  292. {
  293.   if (n < 0) {
  294.     print('-');
  295.     n = -n;
  296.   }
  297.   printNumber(n, 10);
  298. }
  299.  
  300. void AFSoftSerial::print(unsigned long n)
  301. {
  302.   printNumber(n, 10);
  303. }
  304.  
  305. void AFSoftSerial::print(long n, int base)
  306. {
  307.   if (base == 0)
  308.     print((char) n);
  309.   else if (base == 10)
  310.     print(n);
  311.   else
  312.     printNumber(n, base);
  313. }
  314.  
  315. void AFSoftSerial::println(void)
  316. {
  317.   print('\r');
  318.   print('\n');  
  319. }
  320.  
  321. void AFSoftSerial::println(char c)
  322. {
  323.   print(c);
  324.   println();  
  325. }
  326.  
  327. void AFSoftSerial::println(const char c[])
  328. {
  329.   print(c);
  330.   println();
  331. }
  332.  
  333. void AFSoftSerial::println(uint8_t b)
  334. {
  335.   print(b);
  336.   println();
  337. }
  338.  
  339. void AFSoftSerial::println(int n)
  340. {
  341.   print(n);
  342.   println();
  343. }
  344.  
  345. void AFSoftSerial::println(long n)
  346. {
  347.   print(n);
  348.   println();  
  349. }
  350.  
  351. void AFSoftSerial::println(unsigned long n)
  352. {
  353.   print(n);
  354.   println();  
  355. }
  356.  
  357. void AFSoftSerial::println(long n, int base)
  358. {
  359.   print(n, base);
  360.   println();
  361. }
  362.  
  363. // Private Methods /////////////////////////////////////////////////////////////
  364.  
  365. void AFSoftSerial::printNumber(unsigned long n, uint8_t base)
  366. {
  367.   unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  368.   unsigned long i = 0;
  369.  
  370.   if (n == 0) {
  371.     print('0');
  372.     return;
  373.   }
  374.  
  375.   while (n > 0) {
  376.     buf[i++] = n % base;
  377.     n /= base;
  378.   }
  379.  
  380.   for (; i > 0; i--)
  381.     print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
  382. }
  383.  
  384. //==========================
  385. // AFSoftSerial.h
  386. //==========================
  387. /*
  388.   SoftwareSerial.h - Software serial library
  389.   Copyright (c) 2006 David A. Mellis.  All right reserved.
  390.  
  391.   This library is free software; you can redistribute it and/or
  392.   modify it under the terms of the GNU Lesser General Public
  393.   License as published by the Free Software Foundation; either
  394.   version 2.1 of the License, or (at your option) any later version.
  395.  
  396.   This library is distributed in the hope that it will be useful,
  397.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  398.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  399.   Lesser General Public License for more details.
  400.  
  401.   You should have received a copy of the GNU Lesser General Public
  402.   License along with this library; if not, write to the Free Software
  403.   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  404. */
  405.  
  406. #ifndef AFSoftSerial_h
  407. #define AFSoftSerial_h
  408.  
  409. #include <inttypes.h>
  410.  
  411. uint16_t whackDelay2(uint16_t delay);
  412.  
  413. static void recv(void);
  414.  
  415. class AFSoftSerial
  416. {
  417.   private:
  418.     long _baudRate;
  419.     void printNumber(unsigned long, uint8_t);
  420.    
  421.   public:
  422.     AFSoftSerial(uint8_t);
  423.     void setTX(uint8_t tx);
  424.     void setRX(uint8_t rx);
  425.     void begin(long);
  426.     int read();
  427.     uint8_t available(void);
  428.     void print(char);
  429.     void print(const char[]);
  430.     void print(uint8_t);
  431.     void print(int);
  432.     void print(unsigned int);
  433.     void print(long);
  434.     void print(unsigned long);
  435.     void print(long, int);
  436.     void println(void);
  437.     void println(char);
  438.     void println(const char[]);
  439.     void println(uint8_t);
  440.     void println(int);
  441.     void println(long);
  442.     void println(unsigned long);
  443.     void println(long, int);
  444. };
  445.  
  446. #endif
  447.  
  448. //================
  449. //  keywords.txt
  450. //================
  451. #######################################
  452. # Syntax Coloring Map For Ultrasound
  453. #######################################
  454.  
  455. #######################################
  456. # Datatypes (KEYWORD1)
  457. #######################################
  458.  
  459. AFSoftSerial    KEYWORD1
  460.  
  461. #######################################
  462. # Methods and Functions (KEYWORD2)
  463. #######################################
  464.  
  465. #######################################
  466. # Constants (LITERAL1)
  467. #######################################
  468.  
  469. //===============
  470. //  Blink.pde
  471. //===============
  472. /*
  473.   Blink
  474.   Turns on an LED on for one second, then off for one second, repeatedly.
  475.  
  476.   This example code is in the public domain.
  477.  */
  478.  
  479. void setup() {                
  480.   // initialize the digital pin as an output.
  481.   // Pin 13 has an LED connected on most Arduino boards:
  482.   pinMode(13, OUTPUT);    
  483. }
  484.  
  485. void loop() {
  486.   digitalWrite(13, HIGH);   // set the LED on
  487.   delay(1000);              // wait for a second
  488.   digitalWrite(13, LOW);    // set the LED off
  489.   delay(1000);              // wait for a second
  490. }
  491.  
  492.  
  493. //====================
  494. //  Test_595.pde
  495. //====================
  496. //**************************************************************//
  497. //  Name    : shiftOutCode, Hello World                                
  498. //  Author  : Carlyn Maw,Tom Igoe, David A. Mellis
  499. //  Date    : 25 Oct, 2006    
  500. //  Modified: 23 Mar 2010                                
  501. //  Version : 2.0                                            
  502. //  Notes   : Code for using a 74HC595 Shift Register           //
  503. //          : to count from 0 to 255
  504. //
  505. //            http://arduino.cc/en/Tutorial/ShftOut11
  506. //
  507. //****************************************************************
  508.  
  509. //Pin connected to ST_CP of 74HC595
  510. int latchPin = 8;
  511. //Pin connected to SH_CP of 74HC595
  512. int clockPin = 12;
  513. ////Pin connected to DS of 74HC595
  514. int dataPin = 11;
  515.  
  516.  
  517.  
  518. void setup() {
  519.   //set pins to output so you can control the shift register
  520.   pinMode(latchPin, OUTPUT);
  521.   pinMode(clockPin, OUTPUT);
  522.   pinMode(dataPin, OUTPUT);
  523. }
  524.  
  525. void loop() {
  526.   // count from 0 to 255 and display the number
  527.   // on the LEDs
  528.   for (int numberToDisplay = 0; numberToDisplay < 256; numberToDisplay++) {
  529.     // take the latchPin low so
  530.     // the LEDs don't change while you're sending in bits:
  531.     digitalWrite(latchPin, LOW);
  532.     // shift out the bits:
  533.     shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  
  534.  
  535.     //take the latch pin high so the LEDs will light up:
  536.     digitalWrite(latchPin, HIGH);
  537.     // pause before next value:
  538.     delay(500);
  539.   }
  540. }
  541.  
  542. //==========================
  543. // THEREMIN_MIDI_2011.pde
  544. //==========================
  545. /////////////////////////////////////////////////////////////
  546. // General purpose theremin MIDI interface
  547. // 2011 S. Hobley
  548. // www.stephenhobley.com
  549. /////////////////////////////////////////////////////////////
  550. // Included to drive the LCD
  551. #include <AFSoftSerial.h>
  552.  
  553. // Include for PROGMEM
  554. #include <avr/pgmspace.h>
  555.  
  556. #define VERSION "1.0"
  557.  
  558. #define BUTTON1 15
  559. #define BUTTON2 16
  560.  
  561. #define MODE_PITCH    0    // 00
  562. #define MODE_CONTROL  2    // 01
  563. #define MODE_ARP_C    1    // 10
  564. #define MODE_ARP_F    3    // 11
  565.  
  566. #define NO_OF_SAMPLES 5
  567. #define BREATHCONTROL     0x02
  568. #define CONTROLLER        0xB0
  569. #define PITCHBEND         0xE0
  570. #define NOTEON            0x90
  571. #define CHANNEL_MODE
  572. #define VOLUME            0x07
  573. #define ALLNOTESOFF       0x7B
  574. #define MIDI_BAUD         31250
  575. #define VELOCITY          100
  576. #define DEBUG             0
  577. #define NO_NOTE 128
  578.  
  579. #define GEN_CONTROL_1     55
  580.  
  581. #define ARP_ROOT          48 // C
  582.  
  583. // Volatiles for interrupt handler
  584. volatile unsigned long samples[5];
  585. volatile int sample_counter = 0;
  586. volatile unsigned long _micros = 0;
  587.  
  588. //unsigned long temp_acc = 0;
  589.  
  590. byte iLastNote = NO_NOTE;
  591. byte iLastNoteArp = NO_NOTE;
  592.  
  593. byte old_detune_cent = NO_NOTE;
  594. int volume = NO_NOTE;
  595.  
  596. char cp_buffer[5];
  597. AFSoftSerial SSerial(9); // TX on 10
  598.  
  599. uint16_t lower_bound_period[]  = {
  600. /*22282,*/ 21052, 19869, 18748, 17696, 16706, 15768, 14880, 14046, 13259,
  601. 12515, 11814, 11152, 10525, 9931,  9374,  8849,  8351,  7882,  7442,
  602. 7024,  6631,  6260,  5908,  5577,  5264,  4968,  4689,  4426,  4177,
  603. 3943,  3722,  3513,  3316,  3130,  2955,  2789,  2632,  2485,  2346,
  604. 2214,  2090,  1972,  1862,  1757,  1658,  1565,  1478,  1395,  1317,
  605. 1244,  1174,  1107,  1045,  987,   932,   880,   830,   784,   740,
  606. 699,   659,   622,   588,   555,   524,   495,   467,   441,   421  
  607. };
  608.  
  609. int detune_values[]  = {
  610. /*123,*/ 118, 112, 105, 99, 94, 89, 83, 79, 75,
  611. 70,  66,  63,  60,  56, 53, 50, 47, 44, 42,
  612. 39,  37,  35,  33,  31, 30, 28, 26, 25, 24,
  613. 22,  21,  20,  19,  18, 17, 16, 15, 14, 13,
  614. 13,  12,  11,  11,  10, 9,  9,  8,  8,  7,
  615. 7,   7,   6,   6,   6,  5,  5,  5,  4,  4,
  616. 4,   4,   4,   3,   3,  3,  3,  3,  3, 3
  617. };
  618.  
  619. prog_char string_1[] PROGMEM   = "F#-3";  
  620. prog_char string_2[] PROGMEM   = "G -3";
  621. prog_char string_3[] PROGMEM   = "Ab-3";
  622. prog_char string_4[] PROGMEM   = "A -3";
  623. prog_char string_5[] PROGMEM   = "Bb-3";
  624. prog_char string_6[] PROGMEM   = "B -3";
  625. prog_char string_7[] PROGMEM   = "C -2";
  626. prog_char string_8[] PROGMEM   = "C#-2";
  627. prog_char string_9[] PROGMEM   = "D -2";
  628. prog_char string_10[] PROGMEM  = "Eb-2";
  629. prog_char string_11[] PROGMEM  = "E -2";
  630. prog_char string_12[] PROGMEM  = "F -2";
  631.  
  632. prog_char string_13[] PROGMEM  = "F#-2";  
  633. prog_char string_14[] PROGMEM  = "G -2";
  634. prog_char string_15[] PROGMEM  = "Ab-2";
  635. prog_char string_16[] PROGMEM  = "A -2";
  636. prog_char string_17[] PROGMEM  = "Bb-2";
  637. prog_char string_18[] PROGMEM  = "B -2";
  638. prog_char string_19[] PROGMEM  = "C -1";
  639. prog_char string_20[] PROGMEM  = "C#-1";
  640. prog_char string_21[] PROGMEM  = "D -1";
  641. prog_char string_22[] PROGMEM  = "Eb-1";
  642. prog_char string_23[] PROGMEM  = "E -1";
  643. prog_char string_24[] PROGMEM  = "F -1";
  644.  
  645. prog_char string_25[] PROGMEM  = "F#-1";  
  646. prog_char string_26[] PROGMEM  = "G -1";
  647. prog_char string_27[] PROGMEM  = "Ab-1";
  648. prog_char string_28[] PROGMEM  = "A -1";
  649. prog_char string_29[] PROGMEM  = "Bb-1";
  650. prog_char string_30[] PROGMEM  = "B -1";
  651. prog_char string_31[] PROGMEM  = "C  0";
  652. prog_char string_32[] PROGMEM  = "C# 0";
  653. prog_char string_33[] PROGMEM  = "D  0";
  654. prog_char string_34[] PROGMEM  = "Eb 0";
  655. prog_char string_35[] PROGMEM  = "E  0";
  656. prog_char string_36[] PROGMEM  = "F  0";
  657.  
  658. prog_char string_37[] PROGMEM  = "F# 0";  
  659. prog_char string_38[] PROGMEM  = "G  0";
  660. prog_char string_39[] PROGMEM  = "Ab 0";
  661. prog_char string_40[] PROGMEM  = "A  0";
  662. prog_char string_41[] PROGMEM  = "Bb 0";
  663. prog_char string_42[] PROGMEM  = "B  0";
  664. prog_char string_43[] PROGMEM  = "C  1";
  665. prog_char string_44[] PROGMEM  = "C# 1";
  666. prog_char string_45[] PROGMEM  = "D  1";
  667. prog_char string_46[] PROGMEM  = "Eb 1";
  668. prog_char string_47[] PROGMEM  = "E  1";
  669. prog_char string_48[] PROGMEM  = "F  1";
  670.  
  671. prog_char string_49[] PROGMEM  = "F# 1";  
  672. prog_char string_50[] PROGMEM  = "G  1";
  673. prog_char string_51[] PROGMEM  = "Ab 1";
  674. prog_char string_52[] PROGMEM  = "A  1";
  675. prog_char string_53[] PROGMEM  = "Bb 1";
  676. prog_char string_54[] PROGMEM  = "B  1";
  677. prog_char string_55[] PROGMEM  = "C  2";
  678. prog_char string_56[] PROGMEM  = "C# 2";
  679. prog_char string_57[] PROGMEM  = "D  2";
  680. prog_char string_58[] PROGMEM  = "Eb 2";
  681. prog_char string_59[] PROGMEM  = "E  2";
  682. prog_char string_60[] PROGMEM  = "F  2";
  683.  
  684. prog_char string_61[] PROGMEM  = "F# 2";
  685. prog_char string_62[] PROGMEM  = "G  2";
  686. prog_char string_63[] PROGMEM  = "Ab 2";
  687. prog_char string_64[] PROGMEM  = "A  2";
  688. prog_char string_65[] PROGMEM  = "Bb 2";
  689. prog_char string_66[] PROGMEM  = "B  2";
  690. prog_char string_67[] PROGMEM  = "C  3";
  691. prog_char string_68[] PROGMEM  = "Eb 3";
  692. prog_char string_69[] PROGMEM  = "D  3";
  693.  
  694. PROGMEM const char *note_name_table[] =      
  695. {  
  696.   string_1, string_2, string_3, string_4, string_5, string_6,
  697.   string_7, string_8, string_9, string_10, string_11, string_12,
  698.  
  699.   string_13, string_14, string_15, string_16, string_17, string_18,
  700.   string_19, string_20, string_21, string_22, string_23, string_24,
  701.  
  702.   string_25, string_26, string_27, string_28, string_29, string_30,
  703.   string_31, string_32, string_33, string_34, string_35, string_36,
  704.  
  705.   string_37, string_38, string_39, string_40, string_41, string_42,
  706.   string_43, string_44, string_45, string_46, string_47, string_48,
  707.  
  708.   string_49, string_50, string_51, string_52, string_53, string_54,
  709.   string_55, string_56, string_57, string_58, string_59, string_60,
  710.  
  711.   string_61, string_62, string_63, string_64, string_65, string_66,
  712.   string_67, string_68, string_69
  713.  
  714. };
  715.  
  716. // LEDs /////////////////////////////////////
  717. //Pin connected to ST_CP of 74HC595
  718. #define latchPin 8
  719. //Pin connected to SH_CP of 74HC595
  720. #define clockPin 12
  721. ////Pin connected to DS of 74HC595
  722. #define dataPin  11
  723.  
  724. // Local var for period analysis
  725. unsigned long accumulator = 0;
  726. unsigned long detune = 0;
  727. int detune_cent = 0;
  728.  
  729. byte button_state = 255;
  730.  
  731. byte arp2_added = 0;
  732.  
  733. // MIDI ////////////////////////////////////////
  734. byte data = 0;
  735. byte channel = 0;
  736. byte note = 0;
  737. byte value = 0;
  738. int  flag_previous = 0;
  739. int volInternalOld = 0;
  740.  
  741. byte output_channel = 0;  // To be made persistent
  742. byte input_channel = 0;   // To be made persistent
  743. byte pitchbendOld = 0;
  744.  
  745. /* flag_previous meanings:
  746.  -1 = note off status
  747.  -2 = note off pitch
  748.  0 = no action / waiting
  749.  1 = note on status
  750.  2 = pitch
  751.  3 = cc status
  752.  4 = cc number
  753.  */
  754.  
  755. // MIDI Arpeggiator
  756. byte notes[] = {NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE, NO_NOTE} ; // Store up to 12 notes
  757. byte intervals[] = {0,0,0,0}; // Store up to 4 intervals
  758. byte root = 128;  // root note
  759. char mod = '0';   // A/I/7/8 modifier Major, Minor, Seventh, Minor Seventh
  760. byte modroot = 0;
  761. bool checkrunstatus_off = false;
  762. bool checkrunstatus_on = false;
  763.  
  764. ///////////////////////////////////////////////////////////////////////////////////////////////
  765. void setup()
  766. {
  767.   Serial.begin(MIDI_BAUD);
  768.   SSerial.begin(9600);
  769.  
  770.   pinMode(BUTTON1, INPUT);
  771.   pinMode(BUTTON2, INPUT);
  772.  
  773.   digitalWrite(BUTTON1, HIGH);
  774.   digitalWrite(BUTTON2, HIGH);
  775.  
  776.   SSerial.print("?f");
  777.   SSerial.print("?a");
  778.   SSerial.print("MIDI Theremin");
  779.   SSerial.print("?x00?y1");
  780.   SSerial.print("Tracker ");
  781.   SSerial.print(VERSION);
  782.   delay(1000);
  783.  
  784.   // reset the MIDI In state machine
  785.   flag_previous = 0;
  786.   pinMode(latchPin, OUTPUT);
  787.  
  788.   attachInterrupt(0, sample_freq, RISING);
  789.   for(int i = 0; i < 10; i++)
  790.   {
  791.     SetLEDS(i,0);
  792.     delay(100);
  793.   }
  794.   for(int i = 9; i >= 0; i--)
  795.   {
  796.     SetLEDS(i,0);
  797.     delay(100);
  798.   }
  799.  
  800.   SetLEDS(0,0);
  801.  
  802.   SSerial.print("?f");
  803.   SSerial.print("?a");
  804.   SSerial.print("?x07?y1");
  805.   SSerial.print("[01][01][055]");
  806.   SSerial.print("?x00?y3");
  807.   SSerial.print("--");
  808.  
  809. }
  810. ///////////////////////////////////////////////////////////////////////////////////////////////
  811. void loop()
  812. {
  813.   ProcessMIDIIn();
  814.   ProcessButtons();
  815.  
  816.   // We have captured enough samples, time to process...
  817.   if (sample_counter == NO_OF_SAMPLES)
  818.   {
  819.     ProcessSamples();
  820.  
  821.     // Start sampling again
  822.     sample_counter = 0;
  823.   }
  824. }
  825. ///////////////////////////////////////////////////////////////////////////////////////////////
  826. void ProcessButtons()
  827. {
  828.   byte temp = button_state;
  829.   button_state = 0;
  830.  
  831.   if (digitalRead(BUTTON1) == LOW)
  832.   {
  833.     button_state |= 1;
  834.   }
  835.  
  836.   if (digitalRead(BUTTON2) == LOW)
  837.   {
  838.     button_state |= 2;
  839.   }
  840.  
  841.   if (button_state == temp)
  842.     return;
  843.  
  844.   // All Note Off
  845.   ProcessMIDIOut(CONTROLLER, ALLNOTESOFF, 0);
  846.   // Clear Table
  847.   for (int i=0; i < 12; i++)
  848.     notes[i] = NO_NOTE;
  849.    
  850.   for (int i=0; i < 4; i++)
  851.     intervals[i] = 0;
  852.    
  853.   SSerial.print("?x00?y3");
  854.   SSerial.print("             ");
  855.  
  856.   SSerial.print("?x00?y1");
  857.   switch(button_state)
  858.   {
  859.     case MODE_PITCH:
  860.       SSerial.print("[PITCH]");
  861.     break;
  862.     case MODE_CONTROL:
  863.       SSerial.print("[CNTRL]");
  864.     break;
  865.     case MODE_ARP_C:
  866.       SSerial.print("[ARP 1]");
  867.     break;
  868.     case MODE_ARP_F:
  869.       SSerial.print("[ARP 2]");
  870.     break;
  871.   }    
  872.   SSerial.print(button_state);
  873.  
  874.   // Short debounce
  875.   delay(100);
  876.  
  877.   //bit = number & (1 << x);  bit = t/f
  878. }
  879. ///////////////////////////////////////////////////////////////////////////////////////////////
  880. void ProcessMIDIOut(byte cmdtype, byte val1, byte val2)
  881. {
  882.   if (cmdtype == PITCHBEND)
  883.   {
  884.     Serial.print(0xE0 | (channel & 0xf), BYTE);            //  control change command
  885.     Serial.print(val1 & 0x7f, BYTE);                       //  pb MSB 0-127
  886.     Serial.print(val2, BYTE);                              //  pb LSB 0-15 - TODO
  887.   }
  888.   else // All standard note and cc messages
  889.   {
  890.     Serial.print(cmdtype | (output_channel & 0xf), BYTE);  //  control change command
  891.     Serial.print(val1, BYTE);                           //  command
  892.     Serial.print(val2 & 0x7f, BYTE);                       //  val1 0-127
  893.   }
  894. }
  895.  
  896. ///////////////////////////////////////////////////////////////////////////////////////////////
  897. // To be called once per loop
  898. void ProcessMIDIIn()
  899. {
  900.  
  901.   if(Serial.available() > 0)
  902.   {
  903.     data = Serial.read();
  904.    
  905.     // Ignore the active sense message
  906.     if (data == 0xfe)
  907.     {
  908.       return;
  909.     }
  910.    
  911.     // deal with note off data
  912.     if((data >= 0x80) && (data < 0x90) && (flag_previous == 0)) //NOTE OFF Step 1
  913.     {
  914.       channel = data & B00001111;
  915.       if (channel == input_channel)
  916.       {
  917.         flag_previous = -2; // Move on to get note
  918.       }
  919.     }
  920.     else if((data < 0x80) && ((flag_previous == -2)||(checkrunstatus_off))) // NOTE OFF Step 2
  921.     {
  922.       note = data;
  923.       checkrunstatus_off = false;
  924.       flag_previous = -1;
  925.     }
  926.     else if((data < 0x80) && (flag_previous == -1)) // NOTE OFF Step 3
  927.     {
  928.       value = data;
  929.       checkrunstatus_off = true;
  930.       checkrunstatus_on = false;
  931.       doNoteOff(note);
  932.       flag_previous = 0;
  933.     }
  934.     else if((data >= 0x90) && (data < 0xA0) && (flag_previous == 0)) //NOTE ON Step 1
  935.     {
  936.       channel = data & B00001111;
  937.       if (channel == input_channel)
  938.       {
  939.         flag_previous = 2; // Move on to get note
  940.       }
  941.     }
  942.     else if((data < 0x80) && ((flag_previous == 2)||(checkrunstatus_on))) // NOTE ON Step 2
  943.     {
  944.       note = data;
  945.       checkrunstatus_on = false;
  946.       flag_previous = 1;
  947.     }
  948.     else if((data < 0x80) && (flag_previous == 1)) // NOTE ON Step 3
  949.     {
  950.       value = data;
  951.      
  952.       if (value == 0)
  953.       {
  954.         //SSerial.print("-");
  955.         doNoteOff(note);
  956.       }
  957.       else
  958.       {
  959.         //SSerial.print("+");
  960.         doNoteOn(note, value);
  961.       }
  962.       checkrunstatus_off = false;
  963.       checkrunstatus_on = true;
  964.      
  965.       flag_previous = 0;
  966.     }
  967.     else
  968.       flag_previous = 0;
  969.     // done with note data
  970.   }
  971. }
  972.  
  973. ///////////////////////////////////////////////////////////////////////////////////////////////
  974. void doNoteOn(byte note, byte value)
  975. {
  976.  
  977.   // mod;   // 0/A/I/7/8 modifier Nothing, Major, Minor, Seventh, Minor Seventh
  978.   switch (button_state)
  979.   {
  980.     case MODE_PITCH :
  981.     case MODE_CONTROL:
  982.        return;
  983.     break;
  984.    
  985.     case MODE_ARP_C :
  986.       // Removing a note
  987.       if (value == 0)
  988.       {
  989.         // Removing
  990.         for (int i=0; i < 4; i++)
  991.         {
  992.           if (notes[i] == note)
  993.           {
  994.             if (note == root)
  995.             {
  996.               root = NO_NOTE;
  997.             }
  998.          
  999.             notes[i] = NO_NOTE;
  1000.           }
  1001.         }
  1002.         ProcessArpSeq();
  1003.       }
  1004.       else
  1005.       {
  1006.         // Adding a note
  1007.         bool added = false;
  1008.        
  1009.         for (int i=0; i < 4; i++)
  1010.         {
  1011.           if (notes[i] == NO_NOTE)
  1012.           {
  1013.             notes[i] = note;
  1014.             added = true;
  1015.             break;
  1016.           }
  1017.         }
  1018.        
  1019.         if (added) ProcessArpSeq();
  1020.       }
  1021.       break;
  1022.  
  1023.       case MODE_ARP_F:
  1024.       // Removing a note
  1025.  
  1026.       note = note % 12;
  1027.  
  1028.       if (value == 0)
  1029.       {
  1030.         // Removing
  1031.         for (int i=0; i < 12; i++)
  1032.         {
  1033.           if (notes[i] == note)
  1034.           {
  1035.             notes[i] = NO_NOTE;
  1036.            
  1037.             SSerial.print("?x");
  1038.             if (i < 10) SSerial.print("0");
  1039.             SSerial.print(i);
  1040.             SSerial.print("?y3");
  1041.             SSerial.print(" ");
  1042.  
  1043.          
  1044.             if (arp2_added > 0)
  1045.               arp2_added--;
  1046.            
  1047.             SSerial.print("?x15?y3");
  1048.             SSerial.print(arp2_added,DEC);
  1049.            
  1050.             // Clear anything else that might be stuck
  1051.             if (arp2_added == 0)
  1052.               ProcessMIDIOut(CONTROLLER, ALLNOTESOFF, 0);
  1053.            
  1054.             break;
  1055.           }
  1056.         }
  1057.       }
  1058.       else
  1059.       {
  1060.         // Adding a note
  1061.         bool added = false;
  1062.        
  1063.         for (int i=0; i < 12; i++)
  1064.         {
  1065.           if (notes[i] == NO_NOTE)
  1066.           {
  1067.             notes[i] = note;
  1068.             added = true;
  1069.  
  1070.             SSerial.print("?x");
  1071.             if (i < 10) SSerial.print("0");
  1072.             SSerial.print(i);
  1073.             SSerial.print("?y3");
  1074.             SSerial.print("+");
  1075.  
  1076.             arp2_added++;
  1077.  
  1078.             SSerial.print("?x15?y3");
  1079.             SSerial.print(arp2_added,DEC);
  1080.  
  1081.             break;
  1082.           }
  1083.         }
  1084.       }
  1085.       break;
  1086.   }
  1087. }
  1088. ////////////////////////////////////////////////////////////////////////////////
  1089. void ProcessArpSeq()
  1090. {
  1091.   // Scan the table and find the lowest note
  1092.   byte note_count = 0;
  1093.  
  1094.   for (int i=0; i < 4; i++)
  1095.   {
  1096.     if (notes[i] != NO_NOTE)
  1097.       note_count++;
  1098.  
  1099.     if (root > notes[i])
  1100.     {
  1101.       root = notes[i];
  1102.       modroot = root % 12;
  1103.     }
  1104.   }
  1105.  
  1106.   SSerial.print("?x00?y3");  // Goto bottom left
  1107.  
  1108.  
  1109.   switch(modroot)
  1110.   {
  1111.     case 0 :
  1112.      SSerial.print("C ");
  1113.     break;
  1114.     case 1 :
  1115.      SSerial.print("C# ");
  1116.     break;
  1117.     case 2 :
  1118.      SSerial.print("D ");
  1119.     break;
  1120.     case 3 :
  1121.      SSerial.print("Eb ");
  1122.     break;
  1123.     case 4 :
  1124.      SSerial.print("E ");
  1125.     break;
  1126.     case 5 :
  1127.      SSerial.print("F ");
  1128.     break;
  1129.     case 6 :
  1130.      SSerial.print("F# ");
  1131.     break;
  1132.     case 7 :
  1133.      SSerial.print("G ");
  1134.     break;
  1135.     case 8 :
  1136.      SSerial.print("Ab ");
  1137.     break;
  1138.     case 9 :
  1139.      SSerial.print("A ");
  1140.     break;
  1141.     case 10 :
  1142.      SSerial.print("Bb ");
  1143.     break;
  1144.     case 11 :
  1145.      SSerial.print("B ");
  1146.     break;
  1147.   }
  1148.  
  1149.   switch(note_count)
  1150.   {
  1151.     case 0:
  1152.       mod = '0'; // Nothing
  1153.       SSerial.print("?x00?y3");
  1154.       SSerial.print("--               ");
  1155.       intervals[0] = 0;
  1156.       intervals[1] = 0;
  1157.       intervals[2] = 0;
  1158.       intervals[3] = 0;
  1159.  
  1160.        // Silence whatever might be playing
  1161.       if (iLastNoteArp != NO_NOTE)
  1162.       {
  1163.         ProcessMIDIOut(NOTEON, iLastNoteArp, 0);
  1164.         iLastNoteArp = NO_NOTE;
  1165.       }
  1166.    
  1167.     break;
  1168.     case 1:
  1169.       mod = 'A'; // Major
  1170.       SSerial.print("Mj");
  1171.       intervals[0] = 4;
  1172.       intervals[1] = 3;
  1173.       intervals[2] = 5;
  1174.       intervals[3] = 0;  // Not used
  1175.       if (iLastNote != NO_NOTE)
  1176.       {
  1177.         ProcessMIDIOut(NOTEON, iLastNote, 0);
  1178.         iLastNote = NO_NOTE;
  1179.       }
  1180.     break;
  1181.     case 2:
  1182.       mod = 'I'; // Minor
  1183.       SSerial.print("Mn");
  1184.       intervals[0] = 3;
  1185.       intervals[1] = 4;
  1186.       intervals[2] = 5;
  1187.       intervals[3] = 0;  // Not used
  1188.       if (iLastNote != NO_NOTE)
  1189.       {
  1190.         ProcessMIDIOut(NOTEON, iLastNote, 0);
  1191.         iLastNote = NO_NOTE;
  1192.       }
  1193.     break;
  1194.     case 3:
  1195.       mod = '7'; // Seventh
  1196.       SSerial.print("b7");
  1197.       intervals[0] = 4;
  1198.       intervals[1] = 3;
  1199.       intervals[2] = 3;
  1200.       intervals[3] = 2;  
  1201.       if (iLastNote != NO_NOTE)
  1202.       {
  1203.         ProcessMIDIOut(NOTEON, iLastNote, 0);
  1204.         iLastNote = NO_NOTE;
  1205.       }
  1206.       break;
  1207.     case 4:
  1208.       mod = '8'; // Minor Seventh
  1209.       SSerial.print("M7");
  1210.       intervals[0] = 3;
  1211.       intervals[1] = 4;
  1212.       intervals[2] = 3;
  1213.       intervals[3] = 2;  
  1214.       if (iLastNote != NO_NOTE)
  1215.       {
  1216.         ProcessMIDIOut(NOTEON, iLastNote, 0);
  1217.         iLastNote = NO_NOTE;
  1218.       }
  1219.     break;
  1220.   }
  1221.  
  1222.   SSerial.println("      ");
  1223.  
  1224.   // Clear anything else that might be stuck
  1225.   ProcessMIDIOut(CONTROLLER, ALLNOTESOFF, 0);
  1226.  
  1227. }
  1228. ///////////////////////////////////////////////////////////////////////////////////////////////
  1229. void doNoteOff(byte note)
  1230. {
  1231.   doNoteOn(note, 0);
  1232.  
  1233. }
  1234.  
  1235. ///////////////////////////////////////////////////////////////////////////////////////////////
  1236. void PlayArpSequence(int note)
  1237. {
  1238.   byte acc = modroot;
  1239.   byte check = 0;
  1240.  
  1241.   int j = 0;  
  1242.  
  1243.   for(int i=0; i < note; i+=2 )  // less steps
  1244.   {
  1245.       check = acc+intervals[j];
  1246.      
  1247.       if (check > 100)
  1248.        break;
  1249.      
  1250.       acc = check;
  1251.      
  1252.       j++;
  1253.       if (j > 3)
  1254.         j = 0;
  1255.   }
  1256.   if (iLastNoteArp != acc)
  1257.   {
  1258.     ProcessMIDIOut(NOTEON, iLastNoteArp, 0);
  1259.     ProcessMIDIOut(NOTEON, acc, VELOCITY);
  1260.     iLastNoteArp = acc;  
  1261.   }
  1262. }
  1263. ///////////////////////////////////////////////////////////////////////////////////////////////
  1264. void PlayArp2Sequence(int note)
  1265. {
  1266.   if (arp2_added == 0)
  1267.     return;
  1268.  
  1269.     byte acc = 36;
  1270.   byte check = 0;
  1271.  
  1272.   byte oct = 0;
  1273.   byte j = -1;  
  1274.  
  1275.   int test = note+1;
  1276.  
  1277.   while(test > 0)
  1278.   {
  1279.       j++;
  1280.  
  1281.       if (j > 11)
  1282.       {
  1283.           j = 0;
  1284.           oct++;
  1285.       }
  1286.  
  1287.       if (notes[j] != 128)
  1288.           test--;
  1289.   }
  1290.  
  1291.   acc = 12 + (oct * 12) + notes[j];
  1292.  
  1293.   /*SSerial.print("?x00?y2");
  1294.   SSerial.print(acc,DEC);
  1295.   SSerial.print(":");
  1296.   SSerial.print(oct,DEC);
  1297.   SSerial.print(":");
  1298.   SSerial.print(j,DEC);
  1299.   SSerial.print("   ");
  1300.   */
  1301.   // Overflow check
  1302.   if (acc > 120)
  1303.   {
  1304.     ProcessMIDIOut(NOTEON, iLastNoteArp, 0);
  1305.     return;
  1306.   }
  1307.  
  1308.   if (iLastNoteArp != acc)
  1309.   {
  1310.     ProcessMIDIOut(NOTEON, iLastNoteArp, 0);
  1311.     ProcessMIDIOut(NOTEON, acc, VELOCITY);
  1312.     iLastNoteArp = acc;  
  1313.   }
  1314. }
  1315.  
  1316. ///////////////////////////////////////////////////////////////////////////////////////////////
  1317. unsigned long ProcessSamples()
  1318. {
  1319.     accumulator =  (samples[1] - samples[0]);
  1320.     accumulator += (samples[2] - samples[1]);
  1321.     accumulator += (samples[3] - samples[2]);
  1322.     accumulator += (samples[4] - samples[3]);
  1323.    
  1324.     accumulator = accumulator / 4;
  1325.    
  1326.     // Now scan up the interval table
  1327.     bool processed = false;
  1328.     byte realnote=0;
  1329.    
  1330.     for (int i = 0; i <69; i++)
  1331.     {
  1332.       if (accumulator > lower_bound_period[i])
  1333.       {
  1334.          processed = true;
  1335.          
  1336.         // Have we changed?
  1337.         if (i != iLastNote)
  1338.         {
  1339.           strcpy_P(cp_buffer, (char*)pgm_read_word(&(note_name_table[i])));
  1340.          
  1341.           switch (button_state)
  1342.           {
  1343.             case MODE_PITCH:
  1344.               //  UpdateMIDI
  1345.               if (iLastNote != NO_NOTE)
  1346.                  ProcessMIDIOut(NOTEON, iLastNote+30, 0);
  1347.               ProcessMIDIOut(NOTEON, i+30, VELOCITY); // For now
  1348.               iLastNote = i;
  1349.             break;
  1350.            
  1351.             case MODE_CONTROL:
  1352.               if (i > 63) i = 63;
  1353.               ProcessMIDIOut(CONTROLLER, GEN_CONTROL_1, i*2); // For now
  1354.             break;
  1355.            
  1356.             case MODE_ARP_C:
  1357.               if (root != NO_NOTE)
  1358.               {
  1359.                 PlayArpSequence(i);
  1360.               }
  1361.             break;
  1362.            
  1363.             case MODE_ARP_F:
  1364.                 PlayArp2Sequence(i);
  1365.             break;
  1366.           }
  1367.  
  1368.         }
  1369.        
  1370.         // Now we have to calculate the detune offset
  1371.         detune = accumulator - lower_bound_period[i];
  1372.         detune_cent = detune / detune_values[i];
  1373.    
  1374.         // Send pitchbend data
  1375.         ProcessMIDIOut(PITCHBEND, 0, (9-detune_cent) * 12);
  1376.  
  1377.        
  1378.         // Process Volume ////////////////////////////////
  1379.         volume = analogRead(0);
  1380.  
  1381.         // Sample volume
  1382.         byte volinternal = volume >> 3;
  1383.        
  1384.         volinternal*=2;
  1385.        
  1386.         if (volinternal > 127)
  1387.           volinternal = 127;
  1388.        
  1389.         if (volInternalOld != volinternal)
  1390.         {
  1391.           volInternalOld = volinternal;
  1392.           ProcessMIDIOut(CONTROLLER, VOLUME, volinternal);
  1393.         }    
  1394.         //////////////////////////////////////////////////
  1395.        
  1396.         UpdateLCD(cp_buffer, detune_cent, i, volume);
  1397.  
  1398.         delay(10); // Delay a little after each update - this could be moved to a timer interrupt
  1399.         break;  // From i loop
  1400.       }
  1401.     }
  1402.     if (!processed)
  1403.     {
  1404.        ProcessMIDIOut(NOTEON, iLastNote, 0);
  1405.        iLastNote = NO_NOTE;
  1406.        UpdateLCD("XXXX", 5, 0, volume);
  1407.     }
  1408.    
  1409.     //temp_acc = accumulator;
  1410.     accumulator = 0;
  1411.  
  1412.     return accumulator; //temp_acc;
  1413. }
  1414.  
  1415. ////////////////////////////////////////////////////////////////////////////
  1416. void shiftOut(int myDataPin, int myClockPin, byte myDataOut)
  1417. {
  1418.   // This shifts 8 bits out MSB first,
  1419.   //on the rising edge of the clock,
  1420.   //clock idles low
  1421.  
  1422. //internal function setup
  1423.   int i=0;
  1424.   int pinState;
  1425.   pinMode(myClockPin, OUTPUT);
  1426.   pinMode(myDataPin, OUTPUT);
  1427.  
  1428.  //clear everything out just in case to
  1429.  //prepare shift register for bit shifting
  1430.   digitalWrite(myDataPin, 0);
  1431.   digitalWrite(myClockPin, 0);
  1432.  
  1433.   //for each bit in the byte myDataOut…
  1434.   //NOTICE THAT WE ARE COUNTING DOWN in our for loop
  1435.   //This means that %00000001 or "1" will go through such
  1436.   //that it will be pin Q0 that lights.
  1437.   for (i=7; i>=0; i--)  {
  1438.     digitalWrite(myClockPin, 0);
  1439.  
  1440.     //if the value passed to myDataOut and a bitmask result
  1441.     // true then... so if we are at i=6 and our value is
  1442.     // %11010100 it would the code compares it to %01000000
  1443.     // and proceeds to set pinState to 1.
  1444.     if ( myDataOut & (1<<i) ) {
  1445.       pinState= 1;
  1446.     }
  1447.     else { 
  1448.       pinState= 0;
  1449.     }
  1450.  
  1451.     //Sets the pin to HIGH or LOW depending on pinState
  1452.     digitalWrite(myDataPin, pinState);
  1453.     //register shifts bits on upstroke of clock pin  
  1454.     digitalWrite(myClockPin, 1);
  1455.     //zero the data pin after shift to prevent bleed through
  1456.     digitalWrite(myDataPin, 0);
  1457.   }
  1458.  
  1459.   //stop shifting
  1460.   digitalWrite(myClockPin, 0);
  1461. }
  1462.  
  1463.  
  1464.  
  1465.  
  1466. ////////////////////////////////////////////////////////////////////////////////////
  1467. void SetLEDS(byte tune, int vol)
  1468. {
  1469.    
  1470.     digitalWrite(latchPin, 0);
  1471.     byte temp = 0;
  1472.    
  1473.     if (vol < 25)
  1474.       temp = 0;
  1475.     else if (vol < 100)
  1476.       temp = B00100000;
  1477.     else if (vol < 200)
  1478.       temp = B01100000;
  1479.     else
  1480.       temp = B11100000;
  1481.    
  1482.     switch(tune)
  1483.     {
  1484.       case 0:
  1485.         shiftOut(dataPin, clockPin, temp | 0);
  1486.       break;      
  1487.       case 1:
  1488.       case 2:
  1489.         shiftOut(dataPin, clockPin, temp | 16);
  1490.       break;
  1491.       case 3:
  1492.       case 4:
  1493.         shiftOut(dataPin, clockPin, temp | 8);
  1494.       break;
  1495.       case 5:
  1496.       case 6:
  1497.         shiftOut(dataPin, clockPin, temp | 4);
  1498.       break;
  1499.       case 7:
  1500.       case 8:
  1501.         shiftOut(dataPin, clockPin, temp | 2);
  1502.       break;
  1503.       case 9:
  1504.       case 10:
  1505.         shiftOut(dataPin, clockPin, temp | 1);
  1506.       break;
  1507.     }
  1508.     digitalWrite(latchPin, 1);
  1509.  
  1510. }
  1511.  
  1512. ///////////////////////////////////////////////////////////////////////////////////////////////
  1513. void UpdateLCD(char* buffer, int detune, int note, int volume)
  1514. {
  1515.       SSerial.print("?a"); // Home cursor    
  1516.  
  1517.       SSerial.print(buffer);
  1518.       SSerial.print(" [");
  1519.       SSerial.print(note);
  1520.       SSerial.print("]   Vol:");
  1521.       SSerial.print(volume);
  1522.       SSerial.print(" ");
  1523.      
  1524.       SetLEDS(detune, volume);
  1525.  
  1526.       //DrawDetune(detune);
  1527. }
  1528.  
  1529. ///////////////////////////////////////////////////////////////////////////////////////////////
  1530. void DrawDetune(int detune)
  1531. {
  1532.  
  1533.   if (detune < 0)
  1534.     detune = 0;
  1535.   if (detune > 9)
  1536.     detune = 9;
  1537.  
  1538.   int detune1 = 18 -(detune * 2);    
  1539.  
  1540.   if (old_detune_cent == detune1)
  1541.     return;
  1542.  
  1543.        
  1544.   SSerial.print("?y1?x"); // Home cursor    
  1545.   if (old_detune_cent < 10)
  1546.     SSerial.print("0");
  1547.   SSerial.print(old_detune_cent);
  1548.   SSerial.print("  ");
  1549.  
  1550.   SSerial.print("?y1?x"); // Home cursor    
  1551.   if (detune1 < 10)
  1552.     SSerial.print("0");
  1553.   SSerial.print(detune1);
  1554.  
  1555.   if (detune1 == 10)
  1556.     SSerial.print("[]");
  1557.   else
  1558.   {
  1559.     SSerial.print("?5?5");
  1560.   }
  1561.   old_detune_cent = detune1;
  1562. }
  1563.  
  1564. ///////////////////////////////////////////////////////////////////////////////////////////////
  1565. void sample_freq() // Interrupt handler function
  1566. {
  1567.   if (sample_counter == NO_OF_SAMPLES)
  1568.     return;
  1569.    
  1570.   if ((sample_counter > 0) && (micros() < samples[sample_counter-1]))
  1571.   {
  1572.     sample_counter = 0; // Reset and
  1573.     return;             // do nothing if we have overflowed.
  1574.   }
  1575.  
  1576.   samples[sample_counter] = micros();
  1577.   sample_counter++;
  1578. }
Advertisement
Add Comment
Please, Sign In to add comment