MIDI Theremin Controller Project Advice

According to the page, it looks like pitchbend data is contained in 7 bits.

No it has 14 bits. After the pitch bend message then there are two bytes sent both with the most significant bit at zero.

since 8 bits seems more standard for any given MIDI message.

The message is the whole two or normally three bytes. The first is the message type and always has the most significant bit set, it is then followed by data which always has the least significant bit as zero.
So hairless is complaining that there is not enough data bytes being sent for the type of message it has received.

Thanks again for clearing that up. Still learning some of this stuff.

Also, I figured out the problem. I needed to install the MIDI library and call MIDI.begin(), and I also had to conform the baud rate to 115200, the same as Hairless.

Anyway, after an hour of tweaking and combining different sources of code, I've got it working!

Well, almost.

The data is really sporadic, so the pitch of the synth goes all over the place. I'm looking up some tutorials on smoothing data, so hopefully I can get this thing to actually be playable. I think I might have to mount the sensor differently too; right now it's connected directly to the ports of the Arduino, but I think it's pointing downwards a bit and sometimes senses the breadboard in front of it. Figures.

I also still have to set the values to a proper range, so that my hand doesn't have to go back six feet just to reach the bottom octaves. But it's definitely getting there. :smiley:

Before you add the sensors how about just reading a pot. In that way you will have known good quality solid data to test your software with.

Actually I've already implemented the smoothing bit. The pitch is definitely a bit more stable, but it still goes out of whack every few seconds, and tends to jump around if my hand is moving too fast. Heck, sometimes the pitch jumps around for a few seconds even if my hand is still.

I'm considering at some point just looking into a more traditional setup involving an antenna of some sort. I feel the distance sensor may not be the best way of approaching this project, as it's just too sporadic to use for something as precise as pitch.

Regardless, I'll try implementing the smoothing code with a simple potentiometer first and see how reliable the data is.

Again check with a print if your nut is unstable.

You might want to look at the Sharp IR distance sensors before going to RF.

I'm using ir sensors to input my data, I'm getting some very interesting sounds out of my device, I can play notes, pitch bend, but for the life of me I can't get the mod wheel working.

I have ir sensors connected to arduino, which is connected to my midi controller though the midi in cable, my controller then plays notes via a softsyth programme on my laptop.

Here is a link to a short video of my third night of work on the project, as you can see it's working but my goal was to have eight sensors driving cc values, but so far I can only get pitch wheel and note on working.

My question is can someone show me simple code to drive say 'main volume'? or Mod wheel, I've looked at a bunch fo charts showing the different possible values but none of them work?

I've looked at a bunch fo charts showing the different possible values but none of them work?

Yes they all work if you do the right thing with them. As you are not showing us what you have done with them then it is hard to say.
Have you read the how to use this forum thread?

managed to get my volume and cc controls working. My problems were sending the calls to midi needed to byte my vars before sending. Now i have prox sensors working but my problem is dealing with the changing maximum and minimum values. I have a function that takes the prox sensor and converts it to a value between 0-127 but I need to define the max and min possible inputs which over time change. Unlike a pot switch where the min and max values never change using a prox sensors min and max values change depending on ambient light. If anyone knows a way to deal with this please let me know.

I also wrote a simple function to correct the incoming notes to be in any given scale. You take the note coming from the sensor and divide it by 12, then take the remainder and compare it to an array that defines that scale, so for major scale you create an array
majorScale[] = {1,3,6,8,10}; if the incoming note is found within the array I then tell it to bump up the note to the next value. Worked great and resulted in my device sounding less chaotic .

Here is my code for my prox synth

#include <SoftwareSerial.h>

byte note = 0; // The MIDI note value to be played
////billy finger vars
int IRpin = A0;
int IRpin2 = A1;
int IRpin3 = A2;
int IRpin4 = A3;
int IRemitter = 5;
//int IRemitter2 = 9;

int ambientIR;
int obstacleIR;
int value[10];
int distance;

int fingers[] = {IRpin,IRpin2,IRpin3,IRpin4};
int lastNotes[] = {0,0,0,0};
int noteMax[] = {0,0,0,0};
int noteMin[] = {1000,1000,1000,1000};
int scaleMajor[] ={2,4,7,9,11};
int minorScale[] = {2,5,8};
///end of billy vars

int pitchbend = 224;
int modwheel = 176;
int lsb = 0;
int msb = 0;

//software serial
SoftwareSerial midiSerial(2, 3); // digital pins that we'll use for soft serial RX & TX

void setup() {
Serial.begin(9600);
midiSerial.begin(31250);
pinMode(IRemitter,OUTPUT);
digitalWrite(IRemitter,LOW);
}

void loop() {
for(int x=0;x<4;x++){//ren though the sensors
int tempVal = 0;
distance = readIR(6,x);
if(distance > noteMax[x]){noteMax[x] = distance;}
if(distance < noteMin[x]){noteMin[x] = distance;}

if((distance > noteMin[x]+1) && (distance < noteMax[x]-1)){
tempVal = ((distance * 127) / (noteMax[x]));
if(x==0){
int temptVal = (((distance - noteMin[x]) * 127) / (noteMax[x] - noteMin[x]));
int adjustVal = tempVal - (tempVal%12);
for(int z=0;z<5;z++){
if (adjustVal = scaleMajor[z]){
tempVal++;
}
}
if(lastNotes[x] != tempVal){
byte tempVal2 = 45;
noteOn(0x90, tempVal, tempVal2);
lastNotes[x] = tempVal;
}
}
if(x==1){
ccSend(19,tempVal);
}
if(x==2){
ccSend(20,tempVal);
}
if(x==3){
int tempVal3 = 127-tempVal;
ccSend(32,tempVal3);// volume!!!!
}

}

Serial.print(x);
Serial.print("(");
Serial.print(noteMax[x]);
Serial.print(":");
Serial.print(tempVal);
Serial.print(":");
Serial.print(noteMin[x]);
Serial.print(") ");
}
Serial.println();
}

void noteOn(byte cmd, byte data1, byte data2) {
midiSerial.write(cmd);
midiSerial.write(data1);
midiSerial.write(data2);
}

void ccSend(byte CCnumber, byte CCdata){
byte CCchannel = 0xB0;
midiSerial.write(CCchannel);
midiSerial.write(CCnumber);
midiSerial.write(CCdata);
}

int readIR(int times,int fingerNum){
for(int x=0;x<times;x++){
digitalWrite(IRemitter,LOW);
delay(1);
ambientIR = analogRead(fingers[fingerNum]);
digitalWrite(IRemitter,HIGH);
delay(1);
obstacleIR = analogRead(fingers[fingerNum]);
value[x] = ambientIR-obstacleIR;
}
distance = 0;
for(int x=0;x<times;x++){
distance +=value[x];
}
return(distance/times);
}

I have the volume working but for the life of me still can't get mod to work?

Read that code. See all the black squares? Did you put them there?
This is why we ask people to use code tags when posting code.
Please read the how to use this forum sticky post.

I copy pasted the code from my project to the form, I have a visual disability that makes it difficult to read.
I'm just trying to reach out to others doing similar creative things with arduino and midi, If anyone has some code examples to show how to send controls to the mod wheel would be much appreciated.

you're remarks are kind of like looking at a person in a wheelchair going up a ramp and commenting 'hey you know it would be faster to just use the stairs'.

No they are not.

They are like seeing a person in a wheelchair going up a ramp and commenting 'hey did you not read that big notice that says there is a lift ( elevator for the U.S. inclined ) '
It is intended to help both you and others.

The code you posted is unreadable, the forum mangled it, that is why we have code tags and that is why we explain them in the post I directed you to!

Thanks for all your help mike much appreciated.

If anyone has some code showing how to control midi mod wheel with arduino would be much appreciated. Once I have the unit fully working I'll post my code so others may benefit from what I have learned.

code showing how to control midi mod wheel with arduino

It is just like the other messages:-

void sendPB(int pb){ // send pitch bend message
  Serial.write( (byte)0xE0 | channel);
  Serial.write( pb & (byte)0x7f);
  Serial.write( (pb>>7) & (byte)0x7f);
}

Thanks for the sample code I will try it tonight. Here is where I am so far. Dealing with max and min values of the ir sensors has been the biggest challenge, it's most likely from touching the sensors and causing an abnormal spike in the voltage from the wires moving in the bread board, I'm sure once I solder it to a circuit board the sensors should be a little more predictable. (I've got all the code to handle max and min but every now and then I touch the sensor and makes the min or max way above what is the norm)

Thanks again mike, I was able to implement your code. Thanks for that.

I'm still having issues with max and min values coming in from the ir sensors,

As the values come in I then compare them to a max and min value if the incoming value is greater then the max I rewrite the max value to the new one, and then the same for the min value.

I then use the distance between the two to map it to 0-127 on my cc midi value.

But every now and again a greatly abnormal value comes in and redefines the max or min leaving me with the ability to turn the cc value say between 40-90% and never going back to zero, unless I get an abnormal value again?

I'm trying to implement a second level of logic to count the number of times a value comes in, if I get the same value too often I then consider the value as a realistic max or min and rewrite the max or min again.
Am I going about it the right way or does anyone have better way to self correct an ir input?

But every now and again a greatly abnormal value comes in and redefines the max or min leaving me with the ability to turn the cc value say between 40-90% and never going back to zero, unless I get an abnormal value again?

You can tackle this in two ways:-

  1. Do some tests and fix the max and min values in code.
  2. Use averaging rather than a single value to set your extremes.

Thanks Mike, I'm sure it has to do with my finger touching the sensor and making the connections in the breadboard cause a small spike. I'm sure once I get them soldiered in they should be more consistent. But on the whole as a user input these sensors need alot more attention then say a regulated input like a joy stick. I'm looking into averaging and mean. In the end it will mean collecting data into an array and constantly comparing it, which I'd rather not due seeing how c has so little array operators such as push and pop. But the syth is working great, just need to get the sensor code nailed down, thanks Mike. I'll post a video once it's a bit further along.

How have this turned out.