Go Down

Topic: Ableton + Arduino + Servo (Read 324 times) previous topic - next topic

idioma

Oct 04, 2016, 09:34 am Last Edit: Oct 04, 2016, 10:51 pm by idioma
Hi,

I have a project to do. I want to control a servo motor hitting a drum with midi sequences with an Arduino though Ableton live. Exemple in c/c 0-1-0-1 . The 'hammer' of the servo hits the second time and the 4th. I use Hairless-midi with IAC bus to send the midi infos on the Arduino, this part is working. Now I want to make move the hammer each time (for exemple) the C1 note pass in the midi signal. Can you help me on this? Thanks!

The servo code

 
Code: [Select]


#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
}

void loop() {
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

PieterP

#1
Oct 04, 2016, 05:03 pm Last Edit: Oct 04, 2016, 05:04 pm by PieterP
I'd recommend to use a MIDI library, like this one, for example. You can attach callbacks to certain MIDI events, as demonstrated here. Just add a note on handler, and check  if the pitch equals 12 (C1).

Also, please read the first topic on this board, How to use this forum, and use [code][/code] tags (or use the </> button).

Pieter

idioma

Hi,

Thanks a lot that's very helpful!

I'll try it and keep you updated.

Best,
Florent

idioma

#3
Oct 08, 2016, 08:37 pm Last Edit: Oct 08, 2016, 08:55 pm by idioma
So now I have this

Code: [Select]

#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>

MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
MIDI.begin(3);
}

void loop() {
if (MIDI.read()) {
 digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
 delay(10);                       // wait for a second
 digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
 delay(10);
}
}


I wanted to make blink the builtin led and it works! Now  I'm wondering how could I do this :

When the C1 note is pressed > Make blink the led.

Do you have an idea?

Best,
Florent

PieterP

Take a look at the second link in my previous post. You may want to look at Blink without delay as well.

idioma

I'm quite new to Arduino and I can't find the function 'when this note is played' > 'do something' in this library.. If anyone can help! Thank you

PieterP

First you need to detect when a note is pressed, this is done in the example mentioned earlier (second link, first post). Then you have to check what note is being pressed. Add this to the handleNoteOn function:
Code: [Select]
if (pitch == 12) { // pitch 12 corresponds to note C1 (C = 0, and there's 12 halve tones in an octave)
  kickTheDrum();
}


Then create a kickTheDrum function as well:
Code: [Select]
void kickTheDrum() {
  // Whatever code you need to activate the servo
}


Pieter

Grumpy_Mike

Without the technique described in the blink without delay program you end up with blocking code, especially if you use the delay function. Blocking code means nothing else can happen. So if you blink the LED five times then while it is blinking it can not respond to anything else without this technique.

One simple way round this would be to turn on the LED with a note on MIDI message and turn it off with a note off message.

idioma

#8
Oct 10, 2016, 12:19 pm Last Edit: Oct 10, 2016, 05:50 pm by idioma
Something like that ?



Code: [Select]



#include <MIDI.h>
MIDI_CREATE_DEFAULT_INSTANCE();

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

// -----------------------------------------------------------------------------
// This function will be automatically called when a NoteOn is received.
// It must be a void-returning function with the correct parameters,
// see documentation here:
// http://arduinomidilib.fortyseveneffects.com/a00022.html
void handleNoteOn(byte channel, byte pitch, byte velocity)
{

if (pitch == 12) { // pitch 12 corresponds to note C1 (C = 0, and there's 12 halve tones in an octave)
  kickTheDrum();
}

}

void kickTheDrum() {
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

void handleNoteOff(byte channel, byte pitch, byte velocity)
{
    // Do something when the note is released.
    // Note that NoteOn messages with 0 velocity are interpreted as NoteOffs.
}
// -----------------------------------------------------------------------------
void setup()
{

    myservo.attach(9);  // attaches the servo on pin 9 to the servo object

    // Connect the handleNoteOn function to the library,
    // so it is called upon reception of a NoteOn.
    MIDI.setHandleNoteOn(handleNoteOn);  // Put only the name of the function
    // Do the same for NoteOffs
    MIDI.setHandleNoteOff(handleNoteOff);
    // Initiate MIDI communications, listen to all channels
    MIDI.begin(MIDI_CHANNEL_OMNI);
}
void loop()
{
    // Call MIDI.read the fastest you can for real-time performance.
    MIDI.read();
    // There is no need to check if there are messages incoming
    // if they are bound to a Callback function.
    // The attached method will be called automatically
    // when the corresponding message has been received.
}

 

Grumpy_Mike

Well no. That code while it is the right idea takes over 5 seconds to strike the drum. During that time nothing else can happen, no other thing can be hit.

Work it out strike the drum there is 15mS between steps from 0 to 180 so that is 180 * 15 = 2700mS or 2.7 seconds, and the same on the way back 2.7 + 2.7 = 5.4 seconds.

So you have two problems, the time of the strike and the blocking nature. I thought you wanted LEDs to flash as well, that is not in your code yet.

idioma

Hi Thanks,

The flashing light was just to test the midi messages. The final target is to make move the servo.


Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy