SHARE
TWEET

SpinnyB Firmware v1.3

weaknetlabs Oct 14th, 2014 248 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.   SpinnyB - 2014 WeakNet Labs
  3.   GNU (c) 2014, WeakNetLabs@Gmail.com
  4.   Hardware: v1.0
  5.   Firmware: v0.1 -- (for Arduino Micro - update Tone.cpp)
  6.   Rotary dial code modified from original author: Guidomax, instructables.com
  7.     http://www.instructables.com/id/Interface-a-rotary-phone-dial-to-an-Arduino/
  8.   Hardware idea: Matthew Hesse
  9.   Hardware design and code: Douglas Berdeaux
  10.   Hardware donation: Victoria Weis
  11. */
  12. #include <Tone.h>
  13. boolean playTone = false;
  14. int count;
  15. int lastState = LOW;
  16. int trueState = LOW;
  17. long lastStateChangeTime = 0;
  18. boolean record = 0; // record mode, default - turned off
  19. boolean pdm = 0; // pulse dial mode!
  20. int prevDigit = 0; // keep track of previously pressed digit
  21. int stored[16] = { // store up to 16 digits
  22.   13,13,13,13,13,13,13,13,
  23.   13,13,13,13,13,13,13,13,
  24. };
  25. boolean storedDigits = false;
  26. /* Constants Below: */
  27. const int in = 7; // output for rotary device
  28. const int holdTime = 3000; // milliseconds long to consider KP as "HELD"
  29. const int spinDelay = 100; // Rotary spin delay (requires tuning)
  30. const int debounceDelay = 10;
  31. Tone pin[2]; /* 3 lines for the tone output pins:  */
  32. const int pin0 = 11;  // for low tone in MF
  33. const int pin1 = 12;  // for high tone in MF
  34. const int b2600 = 4; // 2600Hz button pin (INPUT)
  35. const int bkp = 5; // KP button pin (INPUT)
  36. const int bst = 6; // ST button pin (INPUT)
  37. const int mfDuration = 75; // tone duration for MF tones
  38. const int bb[16][2] = { // MF 0,1,2,3,4,5,6,7,8,9,kp,st,2400+2600,kp2,st2,ss4 super
  39.   {1300,1500},{700,900},{700,1100},      // 0,1,2
  40.   {900,1100},{700,1300},{900,1300},      // 3,4,5
  41.   {1100,1300},{700,1500},{900,1500},     // 6,7,8
  42.   {1100,1500},{1100,1700},{1500,1700},   // 9,kp,st
  43. };
  44.  
  45. void setup(){ // BEGIN{}
  46.   Serial.begin(9600); // DEBUG MODE ONLY REMOVE FOR PROD
  47.   pinMode(in, INPUT); // input for rotary device
  48.   pin[0].begin(pin0); // Initialize our first tone generator
  49.   pin[1].begin(pin1); // Initialize our second tone generator
  50.   pinMode(b2600, INPUT); // 2600 button
  51.   pinMode(bst, INPUT); // 2600 button
  52.   pinMode(bkp, INPUT); // 2600 button
  53.   startUp(); // play startup tones
  54.   return;
  55. }
  56.  
  57. void loop(){ /* Event driven listen functions, etc */
  58.   buttons(); // Handle buttons first
  59.   rotary(); // process teh rotary dial mechanism
  60.   return;
  61. }
  62.  
  63. void rotary(void){
  64.   int reading = digitalRead(in);  
  65.   if ((millis() - lastStateChangeTime) > spinDelay){
  66.     if (playTone){
  67.       if(count==10) count=0;
  68.       prevDigitCheck(count); // was a special button pressed twice?
  69.       if(pdm){
  70.         if(count==0){ count=10; }
  71.         pulse(count);  
  72.       }else{
  73.         mf(count);
  74.       }
  75.       playTone = false;
  76.       count = 0;
  77.     }
  78.   }
  79.   if (reading != lastState){
  80.     lastStateChangeTime = millis(); // grab the time to check against later
  81.   }
  82.   if ((millis() - lastStateChangeTime) > debounceDelay){
  83.     // debounce - this happens once it's stablized
  84.     if (reading != trueState){
  85.       // this means that the switch has either just gone from closed->open or vice versa.
  86.       trueState = reading;
  87.       if (trueState == HIGH){
  88.         // increment the count of pulses if it's gone high.
  89.         count++;
  90.         playTone = true;
  91.       }
  92.     }
  93.   }
  94.   lastState = reading;
  95.   return;
  96. }
  97.  
  98. void prevDigitCheck(int newDigit){ // called by buttons AND rotary :)
  99.   if(record){
  100.     Serial.print("caught digit: ");
  101.     Serial.println(newDigit);
  102.     if(newDigit==10&&prevDigit==0){ // ONLY store the first KP
  103.       storeDigit(newDigit);
  104.     }else if(newDigit != 10){ // store 0-9,ST
  105.       storeDigit(newDigit);
  106.     }
  107.   }
  108.   if(prevDigit==newDigit&&prevDigit==10){ // KP x2 in a row
  109.     if(record){
  110.       record = false;
  111.       prevDigit = 0; // reset this
  112.       notify(0); // notify off
  113.       Serial.println("record mode is now off");
  114.       if(stored[1]==13){
  115.         resetStored(); // reset, nothing was recorded
  116.         storedDigits = false;
  117.       }else{
  118.         storedDigits = true;
  119.       }
  120.       return;
  121.     }else{
  122.       resetStored(); // truncate the stored digits
  123.       record = true; //   to make room for the new
  124.       prevDigit = 0; // reset this
  125.       notify(1);
  126.       Serial.println("record mode is now on");
  127.       return;
  128.     }
  129.     return; // don't overwrite the prevDigit again
  130.   }else if(prevDigit==newDigit&&prevDigit==11){ // ST twice
  131.     //pdm ? pdm = false : pdm = true;
  132.     if(pdm){ // turn PDM off, it's on:
  133.       pdm = false;
  134.       prevDigit = 0; // reset this
  135.       notify(0);
  136.     }else{
  137.       pdm = true;
  138.       notify(1);
  139.     }
  140.     return; // don't overwrite the prevDigit again
  141.   }
  142.   prevDigit = newDigit;
  143. }
  144.  
  145. void buttons(void){ // process any pushed buttons
  146.   if(digitalRead(b2600)){ // 2600 pressed
  147.     sf(2600,1000);
  148.     delay(300);
  149.     if(storedDigits){
  150.       for(int i=0;i<16;i++){
  151.         if(stored[i]==13){
  152.           return;
  153.         }else{
  154.           mf(stored[i]);
  155.         }
  156.       }
  157.     }
  158.   }else if(digitalRead(bkp)){ // KP Pressed
  159.     prevDigitCheck(10);
  160.     if(prevDigit==0){ // should never have a 0 then a KP
  161.       return;
  162.     }else{
  163.       mf(10);
  164.     }
  165.     delay(300);
  166.   }else if(digitalRead(bst)){ // ST pressed
  167.     prevDigitCheck(11);
  168.     mf(11);
  169.     delay(300);
  170.   }
  171.   return;
  172. }
  173.  
  174. void pulse(int digit){ // pulse out 2600 chirps (and flash LED)
  175.   for(int i=0;i<digit;i++){
  176.     sf(2600,66);
  177.     delay(34);
  178.   }
  179.   return;
  180. }
  181.  
  182. void mf(int digit){ /* simply play MF tones */
  183.   pin[0].play(bb[digit][0],mfDuration);
  184.   pin[1].play(bb[digit][1],mfDuration);
  185.   delay(mfDuration + 100);
  186.   return;  
  187. }
  188.  
  189. void startUp(){ // play the startup tones
  190.   for(int i=0;i<=4;i++){
  191.     sf(2600,33);
  192.     delay(66);
  193.   }
  194.   return;
  195. }
  196.  
  197. void resetStored(){ // Reset the stored digits
  198.   for(int i=0;i<16;i++){
  199.     stored[i]=13;
  200.   }
  201.   return;
  202. }
  203.  
  204. void sf(int freq,int dur){ // send me the frequency and duration
  205.   pin[1].play(freq,dur);
  206.   delay(dur);
  207.   return;
  208. }
  209.  
  210. void notify(int mode){ // 1 == on or 0 == off
  211.   if(mode){ // start record mode notification:
  212.     pin[0].play(1700,100);
  213.     delay(100);
  214.     pin[0].play(2200,500);
  215.     delay(700);
  216.   }else{
  217.     pin[0].play(2200,100);
  218.     delay(100);
  219.     pin[0].play(1700,500);
  220.     delay(700);
  221.   }
  222.   return;
  223. }
  224.  
  225. void storeDigit(int digit){
  226.  for(int i=0;i<16;i++){
  227.    if(stored[i]==13){
  228.      stored[i]=digit;
  229.      return;
  230.    }
  231.  }
  232. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top