MIDI signal on Arduino UNO Databyte2 is not changing my motorized Fader

Hello, i wanted to control a motorized Fader with an input of my midi software, so that the value in my software is represented on my fader, i can set my fader to a position i like but the Serial Input of my Arduino does not resolve the values of my MIDI software accordingly.

I also use the Hairless MIDI bridge to recieve and send the MIDI signals over Serial.
The sending works fine, so this is not a problem.

This is my Schematic:

And this is my Code:


int statusByte;
int dataByte1;
int dataByte2;


int motorUp = 2;
int motorDown = 3;

int Fader = A0;

void setFader(int value){
  int value1 = map(value, 0,127, 0, 1023);
  int current = analogRead(Fader);
  if(current != value1){
      if(current < value){
        while(current != value1){
           current = analogRead(Fader);
          digitalWrite(motorUp, HIGH);
          //Serial.println(analogRead(A0));
        }
        digitalWrite(motorUp, LOW);
      }else{
        while(current != value1){
          current = analogRead(Fader);
          digitalWrite(motorDown, HIGH);
          //Serial.println(analogRead(A0));
        }
        digitalWrite(motorDown, LOW);
      }
  }
}


void setup() {
  // put your setup code here, to run once:
  pinMode(motorUp, OUTPUT);
  pinMode(motorDown, OUTPUT);

  

  Serial.begin(115200);


  Serial.write(176);
  Serial.write(22);
  Serial.write(0);

}

void loop() {
  // put your main code here, to run repeatedly:
  delay(1);
  do{
    if(Serial.available()){
      statusByte = Serial.read();
      dataByte1 = (Serial.read(), DEC);
      dataByte2 = (Serial.read(), DEC);
      
      if(statusByte >= 176 ){
        setFader(dataByte2);
      }
      
    }
    
  }
  while(Serial.available() > 2);

}

The problem is that my setFader(dataByte2) is not working, the values i get from dataByte2 must not be normal, because my fader is always moving between two points, like fidgeting.

Can someone help me?

      dataByte1 = Serial.read();
      dataByte2 = Serial.read();

@maximusnolte @kolaha points out your error.

You probably copied the pattern from Serial.print(), where the comma separates the optional parameter DEC that is the base you want the value to be printed in.

Your use was the comma operator which has low precedence and is left-associative, which in this case means in the statement

  dataByte = (Serial.read(), DEC);

which is the same as

  dataByte = Serial.read(), DEC;

the serial read is performed and whatever it returns is discarded, and the value of DEC is what ends up being assigned to the dataByte.

@kolaha good eye! It is unusual to see the comma operator in this circumstance.I don't see it much at all, and looked past it here several times.

a7

You start reading when there is something in the serial read buffer, This is ok, but you should not start reading 3 bytes that may or may not be there. Also you should use the MIDI format to make sure that the byte you are receiving first is actually a status byte by checking bit 7. Then you check if the status byte should be followed by 1 or 2 data bytes (or by none) or if you are just after cc commands, you can check for that and discard any bytes that aren't what you want. Seninding is always easier than receiving.
But mainly, don't start reading bytes that may not be there.

That also doesnt work, if i do this the fader is still only moving up

How can i check the bytes if they are really a status byte?

I dont have much experience with Serial, but i understand the MIDI format slightly

do you mean it acting same way without changes proposed by me?

good, what is

?

Yes, after your changes the fader is still behaving the same way

well, try this

      dataByte1 = (Serial.read(), DEC);
      dataByte2 = (Serial.read(), DEC);
      Serial.print(dataByte1, DEC);
      Serial.print('\t');
      Serial.println(dataByte2, DEC);

can you see serial monitor?

I cant access it because if i use the Hairless Serial/Midi bridge i cant open it, however currently im trying to display it on my lcd

Any status byte will have bit 7 set, and any data bytes will have bit 7 cleared.

so something like

if(Serial.available()){
      byte incomingByte = Serial.read();
      if (incomingByte & 1 << 7) { // it's a status byte
      }
      else {  // it's a dat byte
      }

You will anyway have to do error checking, there is no guarantee that the first byte coming in is actually the status byte, or even that it is always followed by 2 data bytes (this depends on the type of status byte received) You can look all possible MIDI commands up.
The possibility exists that the stream starts out with a dummy byte somewhere or by a set of 3 bytes from which 1 or to bytes at the start are missing.

You can prevent all of these issues by simply using the builtin library MIDI.h which willtake care of all of this stuff for you. Or you can re-invent the wheel. The half implementation that you have now is not going to yield much reliable results.

But you could built yourself a state machine to receive 1 byte at a time,
set a flag depending on what you receive to receive what you expect next and discard when that is not correct.

If you are waiting for input, you need to first wait for the status byte, then depending on the type you need to wait for data bytes, if you receive a status byte before you have received the expected data bytes, you can start over and accept the new status byte as the start of the midi command you are receiving.

Huh, while hairless midi is running you want debug messages in the Serial monitor, how will that work ?

Anyway, i think you should switch to using MIDI.h to do the parsing of the incoming messages, and do the outgoing messages throigh there as well. you will need to set the baudrate to 115200 in 'SerialMIDI.h'

struct DefaultSerialSettings
{
    /*! Override the default MIDI baudrate to transmit over USB serial, to
    a decoding program such as Hairless MIDI (set baudrate to 115200)\n
    http://projectgus.github.io/hairless-midiserial/
    */
    static const long BaudRate = 31250;
};

which you should be able to find in the src folder next to MIDI.h & MIDI.cpp

1 Like

Ok, i will try the midi.h libary

idk, may be software have console or something

But what are the commands for sending/recieving, do you have a documentation?

You may find GitHub - tttapa/Control-Surface-Motor-Fader: Arduino motorized fader controller, and example code for integration with the Control Surface library. useful.

Specifically, see chapter 6. Configuration options and common use cases in the documentation:

Direct MIDI control

Although the ATmega328P doesn't have native USB support, it does support MIDI over Serial. After changing the WITH_MIDI macro to 1 and setting serial_control = false, you can send MIDI Pitch Bend messages to the serial port of the motor controller to change the setpoints of the controllers. Fader touch changes are reported back using MIDI Note On/Off messages, and while touched, the fader positions are sent as MIDI Pitch Bend messages.

[...]

If you plan to use a software Serial-to-MIDI bridge, you'll have to select an appropriate baud rate as well. For example, for Hairless MIDI, set midi_baud_rate = 115200.

You'll need to edit these lines:
Motor-Controller/main.cpp#L92-L93
Motor-Controller/main.cpp#L111-L112
Motor-Controller/main.cpp#L118-L122

But how do i can i use the libary?

Which library are you referring to? Most libraries will have links to the documentation, installation instructions, and example code in their README on GitHub.

The one you send me: GitHub - tttapa/Control-Surface-Motor-Fader: Arduino motorized fader controller, and example code for integration with the Control Surface library.

It's not a library, but two Arduino sketches you can modify and upload. You can find instructions at the bottom of the README, and more detailed information about what the code actually does under the hood can be found in the documentation.

You will have to install the Control Surface library, there's a link to the installation instructions in the README.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.