int pin_gate = 2;//gate输入
int pin_out = 8;//方波输出
int bpm = 60;
int beatUp = 4;//拍号分母
int pin_root = A0;
int pin_bpm = A1;
int pin_apply = 1;
#include <TimerOne.h>
#include <math.h>
int duration = 0;
bool gate = false;
int arps[] = {0,1,2,3};
int arpPos = 0;
int root = 59;
void noteOn(){
arpPos = 0;
gate = true;
}
void noteOff(){
gate = false;
}
void onChange(){
if(gate){
noteOff();
return;
}
noteOn();
}
void updateP(){
bpm = map(analogRead(pin_bpm),0,1023,20,999);
Timer1.initialize(60000000/bpm/beatUp);
}
void arpLoop(){
if(!gate) return;
int note = arps[arpPos] + root;
auto fre = 1.f*powf(2.f,(note-59)/12.f);
duration = int(1000000.f/fre);
duration = duration < 0?0:duration ;
duration = duration > 65535?65535:duration;
digitalWrite(7,arpPos&0x2);
digitalWrite(6,arpPos&0x1);
++arpPos;
arpPos &= 3;
}
void setup() {
Serial.begin(9600);
// put your setup code here, to run once:
pinMode(pin_gate, INPUT);
pinMode(pin_out, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(pin_bpm, INPUT);//bpm在这个定时器用不了
pinMode(pin_root, INPUT);
pinMode(pin_apply, INPUT);
attachInterrupt(digitalPinToInterrupt(pin_gate), onChange,CHANGE );
attachInterrupt(digitalPinToInterrupt(pin_apply), updateP ,CHANGE );
Timer1.initialize(60000000/bpm/beatUp);
Timer1.attachInterrupt(arpLoop);
}
void loop() {
// put your main code here, to run repeatedly:
root = map(analogRead(pin_root),0,1023,0,100);
if(!gate) return;
digitalWrite(pin_out, HIGH);
delayMicroseconds(duration);
digitalWrite(pin_out, LOW);
delayMicroseconds(duration);
}