Midi To Servo

nicnut

Well-known member
Hi,

I am trying to control a servo using MIDI output from a computer.
Before I got to this part of my project, I tested out the Sweep example in the PWM library, and my servo worked with that.

Then I tried the Knob example in the PWM library, where a potentiomenter controls a servo, and that worked fine.

Then I tried to change the potentiometer data to MIDI input and nothing happened.

If any one wants to look at my code I would really appreciate it. I can't really see anything wrong. The only thing I can think of that might be bad is that there is no MIDI library included, but I did declare the USB type as Serial + MIDI, so hopefully that is how the Teensy knows to look for midi data.

Thank you any suggestions are greatly appreciated.

Nick





Code:
#include <PWMServo.h>
#include <Bounce.h>

const int channel = 5;
const int MIDIchannel = 5;  // this will only apply to midi channel 1
const int servo1 = 50;      // midi control change 50
int pos1; // position of servo1

PWMServo myservo;  // create servo object to control a servo


             // variable to read the value from the analog pin

void setup() {
  myservo.attach(SERVO_PIN_A);  // attaches the servo on pin 9 to the servo object
  //myservo.attach(SERVO_PIN_A, 1000, 2000); // some motors need min/max setting

  // Serial.begin(115200);
  delay(500);
  Serial.println("!!! READY !!!");


  usbMIDI.setHandleControlChange(myControlChange);
}

void loop() {
 
}

void myControlChange(byte channel, byte control, byte value)  // for LEDs, MIDI output

{


  if (channel == MIDIchannel
      && control == servo1);
     {
    value = map(value, 0, 1023, 0, 179);
    value = pos1;
    myservo.write(pos1);  // sets the servo position according to the scaled value
    delay(15);
  }
}
 
Hi I am just giving this post a bump. It seemed like I couldn't connect to the forum right after I posted this. If so maybe this post was overlooked. Any advice is appreciated.
thanks, Nick
 
Hi joepasquariello. I think I intended it, but it looks like I don't need it. I'll try the code without the semicolon and see if that works. If that's all that was wrong I will be super amazed. Thank you for pointing that out.
 
Hi everyone,

Thank you for looking at the code and offering suggestions. I removed the semicolon after the "if" statement, and I added usbMIDI.read(); into the loop.

I also changed the mapping of value to: map(value, 0, 127, 0, 179); , since MIDI is from 0 to 127

I am still not getting any action. But the very first time I uploaded the code the servo moved. Then I heard it buzzing like it was waiting to get instructions, but it never moved. I unplugged it and plugged it in again and it was silent.

I am also attatching a photo of the hardware. I think I have it all correct. I have an external power supply, connected to a Capacitor, to the vin and ground from the teensy, to the power and ground from the servo. And pin 9 from the teensy is connected to the signal of the servo.

In the Arduino software I have USB type set to : Serial + MIDI. Maybe I have the wrong serial speed? Is that something I need to specify in the code?

If anyone can see something I am overlooking please let me know.

Thank you.


Code:
#include <PWMServo.h>
#include <Bounce.h>

const int channel = 5;
const int MIDIchannel = 5;  // this will only apply to midi channel 1
const int servo1 = 50;      // midi control change 50
int pos1; // position of servo1

PWMServo myservo;  // create servo object to control a servo


             // variable to read the value from the analog pin

void setup() {
  myservo.attach(SERVO_PIN_A);  // attaches the servo on pin 9 to the servo object
  //myservo.attach(SERVO_PIN_A, 1000, 2000); // some motors need min/max setting

  // Serial.begin(115200);
  delay(500);
  Serial.println("!!! READY !!!");


  usbMIDI.setHandleControlChange(myControlChange);
}

void loop() {
  usbMIDI.read();
 
}

void myControlChange(byte channel, byte control, byte value)  // for LEDs, MIDI output

{


  if (channel == MIDIchannel
      && control == servo1)
     {
    value = map(value, 0, 127, 0, 179);
    value = pos1;
    myservo.write(pos1);  // sets the servo position according to the scaled value
    delay(15);
  }
}
 

Attachments

  • unnamed.jpg
    unnamed.jpg
    495.1 KB · Views: 30
But the very first time I uploaded the code the servo moved. Then I heard it buzzing like it was waiting to get instructions, but it never moved
That might be it hitting the end-stop and getting hot quickly... Most servos have a very limited range of angles, 120 degrees or so, try to move past the physical end-stop is likely to cook the servo quite quickly as it pulls full current.
 
I think you should change:

if (channel == MIDIchannel && control == servo1) { value = map(value, 0, 127, 0, 179); value = pos1; myservo.write(pos1); // sets the servo position according to the scaled value delay(15); }

to :

if (channel == MIDIchannel && control == servo1) { pos1 = map(value, 0, 127, 0, 179); myservo.write(pos1); // sets the servo position according to the scaled value delay(15); }
 
Hey @thebigg. Your solution worked!!!
I had a feeling it was something super simple like that. I would have never guessed that, but it totally makes sense to map the value to the position.

Thank you so much for spotting that.
 
Back
Top