I'm trying to sync a servo to sweep 0-180-0 deg. and loop, controlled and synced to a MIDI signal from Ableton Live
For now I can start the sweep with midi and get it to stay in a set tempo with turning the servo 1 deg. at a time with a delay
this code:
// Midi controlled servo sweep
// eptheca 2012
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0; // variable to store the servo position
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
void setup() {
Serial.begin(31250); // midi baud rate
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0);
}
void loop() {
if(Serial.available() > 0) {
data = Serial.read();
//Serial.print(data, BYTE);
if(data == midi_start || data == midi_continue) {
play_flag = 1;
}
while(play_flag = 1)
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(11.11); // waits 15ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(11.11); // waits 15ms for the servo to reach the position
}
}
else if(data == midi_stop) {
play_flag = 0;
myservo.write(0);
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
void Sync() {
// do something for every MIDI Clock pulse when the sequencer is running
}
This doesn't really work as the delay makes it not listen to other incoming MIDI messages, and it's not accurate.
MIDI sync messages sends 24 ticks per. 1/4 note, so in a 4/4 beat it would be 96 ticks per bar.
I would like the servo to move from 0 to 180 deg. in that tempo, and wonder if anybody has a suggestion for how to scale the 180 deg. to the 96 ticks?
For now I have tried this:
// Midi controlled servo sweep
// eptheca 2012
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created
int pos = 0;// variable to store the servo position
int counter = 0;
byte midi_start = 0xfa;
byte midi_stop = 0xfc;
byte midi_clock = 0xf8;
byte midi_continue = 0xfb;
int play_flag = 0;
byte data;
void setup() {
Serial.begin(31250); // midi baud rate
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0);
}
void loop() {
if(Serial.available() > 0) {
data = Serial.read();
//Serial.print(data, BYTE);
if(data == midi_start || data == midi_continue) {
play_flag = 1;
}
else if(data == midi_stop) {
play_flag = 0;
counter = 0;
myservo.write(0);
}
else if((data == midi_clock) && (play_flag == 1)) {
Sync();
}
}
}
void Sync(){ // do something for every MIDI Clock pulse when the sequencer is running
if(counter < 192) {
counter = counter + 1;
else if(counter <= 96){
if(pos == 0);
pos +=1;
myservo.write(pos);
}
else if(counter >= 96) {
if(pos == 180);
pos -=1;
myservo.write(pos);
}
else{
counter = 0;
}
}
}
I am not sure about the counting
Does it make sense?
My idea was to get it to count the ticks, up to 192, then reset count to 0 and loop that
For every tick it should move 1 deg. until 180 deg. then 1 deg. until 0 and loop that
With this code it works once, up to 180 deg. then it stops, and starting and stopping midi messages does not help
Also 1 deg per tick is not what I'm after, I would like it to move 180 deg. in 96 ticks, which is 1.875 deg per tick
Anybody have an idea on how to do that?
Grateful for any suggestions
Cheers