DIY可編程Guitar效果器Loop Switcher(Arduino含程式碼)

        多年前燕子剛開始在接觸效果器DIY的時候,那時候台灣有在自製效果器的人還不多,燕子會手工山寨一些效果器放在網拍上賺一些零用錢。生意不算好也不算壞,但提供燕子可以繼續研究的資金。當年有個網友找到了燕子表示希望可以幫他製作可記憶音色的Loop Switcher, 燕子上網查了資料發現需要使用單晶片並編寫程式燕子就果斷放棄委託。當年單晶片的開發門檻很高,更別提燕子只有在學校用8051跑過LED跑馬燈。


        燕子已經很多年不在網拍上賣效果器了,但是可編程Guitar效果器Loop switcher這個委託案子卻讓燕子一直記在心裡。近年來隨著Arduino開發平台的活躍,擁有的資源越來越豐富,使的單晶片的開發門檻也越來越低。憑藉著Google跟Arduino的加持下燕子打算對多年前這個委託案挑戰看看,算是對多年身為DIY Player的小總結。



        到底什麼是Loop Switcher?說穿了就是效果器迴路切換選擇器。對於擁有許多單顆效果器的樂手來說,最害怕的事就是在表演時得像在玩跳舞機一樣得到處踩效果器。Loop Switcher方便讓樂手整合自己的效果器,讓優秀音色的Pedalboard有綜效的方便性有些效果器Bypass電路不僅會像黑洞一樣吞噬高頻,還會消除整體訊號和輸出電平並注入令人討厭的噪聲,造成音色嚴重破壞,也以透過Loop Switcher解決這個問題。使用Loop Switcher還有一個好處是效果器的擺放位置可以不用受限於串接的順序,在擺盤上會輕鬆許多。更多的細節可至《樂手巢 YSOLIFE》Loop Switcher解析:讓你輕鬆切換音色的秘密武


不可儲存預設(Unprogrammable)Loop Switcher
  
   不可儲存預設(Unprogrammable)Loop Switcher單純是用腳踏開關控制對應到的效果迴路開啟關閉(一踏一開)也就是串起來的True Bypass系統

可儲存預設(Programmable)Loop Switcher


     可儲存預設(Programmable)Loop Switcher可以直接設定好每一組預設分別要開啟哪些迴路,在切換預設時就可以同時切換多種效果(一踏多開)。

電路說明
整個電路分為三個區塊,按鈕控制區塊、七段顯示器顯示當前狀態、跟LED陣列表示各個迴路的開啟跟關閉狀態。其中按鈕控制區塊使用3*2矩陣鍵盤(Keypad)概念製作,6個按鍵只需要用到5支腳位並且不需要處裡上拉電阻跟機械彈跳問題,使用起來相當方便。

(Programmable)Loop Switcher電路配線









   









驗器材
Arduino UNO 開發板
麵包板 2個
共陽極七段顯示器 1個
LED 6個
220 Ω 的電阻 13個
杜邦線n條

可編程Guitar效果器Loop switcher的原理
控制各個迴路(以LED替代)腳位開啟跟關閉並在EEPROM儲存各腳位狀態以便下次呼叫。

動作項目
呼叫設定1~0共10頁,每頁有A、B、C三個呼叫鍵總共可設定30組。
Guitar效果器(Programmable) Loop switcher動作展示
設定1-C鍵6個迴路狀態並儲存成預設。
Guitar效果器(Programmable) Loop switcher儲存預設
最後將LED換成光耦合器繼電器模塊就可以實現效果器迴路切換
4 通道光耦合器隔離繼電器模塊觸發器
Arduino程式碼
#include <Keypad.h>    // 引用Keypad程式庫
#include <EEPROM.h>
#define KEY_ROWS 2 // 按鍵模組的列數
#define KEY_COLS 3 // 按鍵模組的行數
 
// 依照行、列排列的按鍵字元(二維陣列)
char keymap[KEY_ROWS][KEY_COLS] = {
  {'A', 'C', 'D'},
  {'B', 'X', 'U'}
};
 
byte colPins[KEY_COLS] = {9, 10, 11};     // 按鍵模組,行接腳。
byte rowPins[KEY_ROWS] = {12, 13}; // 按鍵模組,列接腳。 
 
// 初始化Keypad物件
Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);
int ledPin[6] = {19,18,17,16,15,14};//6ch LED&繼電器
// 共陽極七段顯示器
// Pin Map
// a  b  c  d  e  f  g  
// 2  3  4  5  6  7  8  
int Map_Table [12][7] = {  
  {1, 0, 0, 1, 1, 1, 1},   // 1
  {0, 0, 1, 0, 0, 1, 0},   // 2
  {0, 0, 0, 0, 1, 1, 0},   // 3
  {1, 0, 0, 1, 1, 0, 0},   // 4
  {0, 1, 0, 0, 1, 0, 0},   // 5
  {0, 1, 0, 0, 0, 0, 0},   // 6
  {0, 0, 0, 1, 1, 1, 1},   // 7
  {0, 0, 0, 0, 0, 0, 0},   // 8
  {0, 0, 0, 0, 1, 0, 0},   // 9
  {0, 0, 0, 0, 0, 0, 1},   // 0
  {1, 1, 1, 0, 0, 0, 1},   // L
  {1, 0, 0, 1, 0, 0, 0}};  // H

int count =0;
int Preset;
void setup(){
  Serial.begin(9600);
  Display(0);
  readPreset(1);
  for(int y=0; y<6; y++) /* setup test phase */
  {
    pinMode(ledPin[y], OUTPUT);
  }
  for (byte i = 2; i <8; i++) {    
    pinMode(i, OUTPUT);
  }
}
void readPreset(int addr){ //讀取EEPROM
  for(int i=0; i<6; i++)
    digitalWrite(ledPin[i], EEPROM.read((addr)+i));
 }
void Display(int led) { //七段顯示器
  for (byte i = 0; i <6; i++)
        if (Map_Table[led][i] == LOW)
      digitalWrite(i+2, LOW);      
     else
      digitalWrite(i+2, HIGH);      
}

void loop(){
   // 透過Keypad物件的getKey()方法讀取按鍵的字元
  char key = myKeypad.getKey();
  if (key)  {
    
   switch (key)
      {  
        case 'A': 
    Preset = count*50+1;
    
      readPreset(Preset);
      break;
    case 'B': 
    Preset = count*50+11;
    
      readPreset(Preset);
      break;  
    case 'C': 
    Preset = count*50+21;
    
      readPreset(Preset);
      break;  
    case 'U':  // up 0-9 
      count++;
      if (count > 9)
        count = 0;
  
      Display(count);
      break; 
    case 'D': //dOWN 9-0
      count--;
      if (count < 0)
        count = 9;
  
      Display(count);
      break;
     
    case 'X':    // 設定Loop預設   
       Display(10);
     boolean quit = false;
     byte z = 0;
      while (!quit) {
        key = myKeypad.getKey();
        if(key) {
          if(key == 'U') {
            Display(11);
            z=3;            
          }else  if(key == 'D') {
            Display(10);
            z=0;
            }else  if(key == 'A') {
            digitalWrite(ledPin[0+z], !digitalRead(ledPin[0+z]));
            }else  if(key == 'B') {
            digitalWrite(ledPin[1+z], !digitalRead(ledPin[1+z]));
            }else  if(key == 'C') {
            digitalWrite(ledPin[2+z], !digitalRead(ledPin[2+z]));
            }else  if(key == 'X') {
              for(int i=0; i<6; i++){
              EEPROM.write((Preset) + i, digitalRead(ledPin[i]));
              }
             quit = true;
             }
           }
        } 
        Display(count);
        break;
      }
    Serial.println(key);  // 顯示按鍵的字元
     }
  }

        因為Arduino UNO腳位數量的限制最終規劃成6 Channel Loop Switcher,如果需要更多的迴路可以使用Arduino MEGA2560。目前找不到燕子心中理想的外殼,整個案子到這裡先告一個段落。回想全部過程順利的超乎想像,令燕子信心大增。這要歸功於Arduino的方便跟網路上資源的豐富,我們身處在Maker的黃金年代。

參考資料:
《樂手巢 YSOLIFE》Loop Switcher解析:讓你輕鬆切換音色的秘密武器
臺灣高空 - 效果器迴路與迴路切換器
instructables circuits Arduino Programable 5 Pedal Switcher

留言

這個網誌中的熱門文章

一次搞懂Treble Bleed高頻補血電路

~各種效果器Bypass切換線路分析~

隧道型重低音喇叭改裝mp3解碼板