Go Down

Topic: Using Pitchbend with Ultrasonic Sensor? (Read 121 times) previous topic - next topic

ajraycakn

May 09, 2019, 05:51 pm Last Edit: May 09, 2019, 05:54 pm by ajraycakn
Hello,
I've currently got a MIDI project going, and I'm trying to use a SR04 sensor to control pitch bend.
Here's what I've got:

Code: [Select]

void loop() {

  a=sr04.Distance();         
  if (a <= 20){                          //If Distance is less than 20cm, start pitch bending.
  pitchBend = map(a,0,20,8191,-8192);     // Map 0-20cm to Pitch Bend Parameters (close is higher, further is lower pitch).
  if (pitchBend>8191){pitchBend=8191;};if (pitchBend<-8192){pitchBend=-8192;}   // Debug
  PitchWheelChange(pitchBend);     


void PitchWheelChange(int value) {          // Pitch Wheel Function taken from here: [url=https://forum.arduino.cc/index.php?topic=119790.0]https://forum.arduino.cc/index.php?topic=119790.0[/url]
    unsigned int change = 0x2000 + value;  //  0x2000 == No Change
    unsigned char low = change & 0x7F;  // Low 7 bits
    unsigned char high = (change >> 7) & 0x7F;  // High 7 bits
    midiMessage(0xE0, low, high);
   
}

void midiMessage(int commandByte, int data1Byte, int data2Byte) {   // Midi Output Function
    Serial.write(commandByte);
    Serial.write(data1Byte);
    Serial.write(data2Byte);
}



So essentially I've mapped 0-20cm distance to pitch bend midi parameters, which outputs to a MIDI Message Function.

The issue I'm having is that Hairless MIDI freaks out with its "Received a Status Byte when we were expecting 1 more data byte" message.   And my DAW (FL Studio) simply states that I'm sending pitch bend of 158/168 cents no matter what the distance is. I guess therefore, SOMETHING works, but there is obviously something wrong.

Any ideas on this? Perhaps my coding is wrong?  I also heard the default library for those ultrasonc modules are very temperamental. Maybe worth getting a new library?

Any help's appreciated,

MarkT

Well Hairless MIDI is reporting seeing a status byte before both data bytes, the question is where does that come from?

Without posting your entire sketch its going to be harder to figure anything out.

You should explain how everything is connected together.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Grumpy_Mike

This code emulates a Theremin using two Sharp IR distance sensors that produce an analogue input on analogue 0 & 1. I notice from your code that you never actually send a note on message. An unexpected status byte message is often produced by hairless if the baud rate is not set the same at both ends. If you want to use this code with Hairless then you will have to up the serial rate to match the Hairless default.
If you have no sharp IR sensors you can always replace them with pots for a test.

Code: [Select]
// Theremin  - Grumpy Mike
boolean playing = false;
const byte channel = 0;
const byte baseNote = 72;

void setup(){
  Serial.begin(31250); // MIDI baud rate
  analogReference(EXTERNAL);
  controlSend(0, 0); // set bank 0 MSB
  controlSend(32, 0); // set bank 0 LSB
  programChange(52); // send voice number
  // set up Pitch bend sensitivity
  controlSend(101, 0);
  controlSend(100, 0);
  controlSend(6,72); // set to 6 octaves
  controlSend(38, 0); // and zero cents
}

void loop(){
  int av1 = 1027 - analogRead(0);
  int av2 = 1027 - analogRead(1);
  if(av1 <870 && av2 < 870){
     if(!playing)noteOn();
     else {
          trackNote(av2,av1);
     }
  }
  else {
    if(playing) noteOff();
  }
}

void noteOff(){
  playing= false;
  // note off + sustain off
  noteSend(0x80,baseNote,127);
  controlSend(64, 0);
}
void noteOn(){
 // note on + sustain on
  noteSend(0x90,baseNote,127);
  controlSend(64, 127);
  playing = true;
}

int trackNote(int freq, int volume){
  int pb = 0x2000 - (435 - freq);
  sendPB(pb);
  int vel = volume>> 3;
   controlSend(7, vel);
}

 void noteSend(byte cmd, byte data1, byte data2) {
  cmd = cmd | channel;
  Serial.write(cmd);
  Serial.write(data1);
  Serial.write(data2);
}

void controlSend(byte CCnumber, byte CCdata) {
  byte CCchannel = channel | 0xB0; // convert to Controller message
  Serial.write(CCchannel);
  Serial.write(CCnumber);
  Serial.write(CCdata);
}

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

void programChange(byte voice){
  Serial.write((byte)0xC0 | channel);
  Serial.write(voice);
}

Go Up