0

I've recently bought an Arduo Due to create some sort of a Midi controller together with the MIDIUSB library.

I have create a simple a test program with 1 potentiometer (without the use of a class) to test the MIDIUSB library and everything works fine, so I decided to expanded my program to make it work with more than 1 potentiometer (with the use of a class).

However my pc stopped recognizing my Arduino as a MIDI device with my updated code. When I upload my previous example code it all works fine. I get no compile errors or whatsoever. I don't understand what I'm doing wrong. If anybody could explain me what I'm doing wrong or could give me a solution you would be a hero since I can't really work further if this issue doesn't get resolved. Thanks!

Here is my code for Custom_MIDI_controller_V2.ino:

#include "MIDIUSB.h"
#include "Class.h"
#define TOLERANCE 8

byte NUMBER_POTS = 5;

Pot PO0(A0, 1, 14);
Pot PO1(A1, 1, 15);
Pot PO2(A2, 1, 16);
Pot PO3(A3, 1, 17);
Pot PO4(A4, 1, 18);

Pot *POTS[] = {&PO0, &PO1, &PO2, &PO3, &PO4};

void setup() {

}

void loop() {
  for (int i = 0; i < NUMBER_POTS; i++) {
    int potValue = POTS[i]->getValue();
      if(potValue != 255) {
        controlChange(POTS[i]->_channel, POTS[i]->_control, potValue);
        MidiUSB.flush();
      }
   }
}

void controlChange(byte channel, byte control, byte value) {
  midiEventPacket_t event = {0x0B, 0xB0 | channel, control, value};
  MidiUSB.sendMIDI(event);
}

Here is my Class.cpp code:

#include "Arduino.h"
#include "Class.h"

#define TOLERANCE 8

Pot::Pot(int pin, int channel, int control) {
  _pin = pin;
  _channel = channel;
  _control = control;
  _value = analogRead(_pin);
  _oldValue = _value - 10;
}

int Pot::getValue() {
  int diff = abs(_value - _oldValue);
  if(diff > TOLERANCE)
  {
    _oldValue = _value;
    return map(_value, 0, 1023, 127, 0);
  } else {
    return 255;
  }
}

And this is my header Class.h code:

#ifndef Class_h
#define Class_h
#include "Arduino.h"

class Pot
{
  public:
    Pot(int pin, int channel, int control);
    int getValue();
    int _pin;
    int _channel;
    int _control;
    int _value;
    int _oldValue;
};

#endif
  • Unrelated error: analogRead() is called only once, in the constructor. – CL. Dec 18 '19 at 13:55
  • Please show the test program that worked. – CL. Dec 18 '19 at 13:57
  • @CL unrelated? That may well be the root cause - the constructor get called before main() which is where things like analogRead()` may be pre-configured. So it may never get past that point of the program. – Majenko Dec 18 '19 at 15:38
  • What is the point of creating an array of pointers? Just create an array of objects as shown here, for example. – tttapa Dec 18 '19 at 23:35
0

You need to take care with constructors in C++. They get called during the global variable initialisation phase of the execution, which happens before main() gets called.

main() calls the routines that initialise and configure the peripherals and such in the chip, and by having analogRead() in your constructor (which is itself another error I will mention below) there is a good chance (I don't know the full initialisation sequence of that chip though) that it will never complete, and thus your program hangs at that point.

Your analogRead() doesn't want to be in the constructor, anyway, since that will only execute once when the object is constructed. Instead you want to have analogRead() called at the point you need to get the analog value. In your code that would be at the start of int Pot::getValue().

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.