Go Down

Topic: [SOLVED] - LED IN MIDI IN/OUT MESSAGES PROBLEM (Read 388 times) previous topic - next topic

stecciu

Jan 22, 2019, 11:10 am Last Edit: Feb 13, 2019, 11:41 am by stecciu
Hi to everyone!
I'm building a guitar pedal, it would send and receive midi message. It does it.
The problem is that I would like to put a simple pulsing led just to know the power status (and aesthetic reasons) and when I put some strings of code the midi system going crazy.

I think this is a simple programming issue..

This led is on a PWM pin (3).

This is the code (LEDCONTROLLO is just a simple led for debugging, the pulse led is LED1):

Code: [Select]

#include <MIDI.h>
#include "Controller.h"

// Define labels for the AMP's pins
#define RELAY1  4  // LEAD                        
#define RELAY2  5  // CLEAN                    
#define RELAY3  6  // REVERB                    
#define RELAY4  7  // BOOST

//Define LED's pin
const int LED1 = 3;
const int LEDCONTROLLO = 13;

//Create an instance of the library with default name, serial port and settings
MIDI_CREATE_DEFAULT_INSTANCE();

// Define labels for the POT & FOOTSWITCHES's pin
byte NUMBER_BUTTONS = 1;
byte NUMBER_POTS = 1;

//Pot (Pin Number, Command, CC Control, Channel Number)
Pot PO1(A0, 0, 24, 13);
Pot *POTS[] {&PO1};

//***DEFINE DIRECTLY CONNECTED BUTTONS*******************************
//Button (Pin Number, Command, Note Number, Channel, Debounce Time)
//** Command parameter 0=NOTE  1=CC  2=Toggle CC **

Button BU1(8, 2, 25, 13, 5 );
Button BU2(9, 2, 26, 13, 5 );
Button BU3(10, 2, 27, 13, 5 );
Button BU4(11, 2, 28, 13, 5 );
Button BU5(12, 2, 29, 13, 5 );
Button *BUTTONS[] {&BU1, &BU2, &BU3, &BU4, &BU5};

void setup() {
  pinMode(RELAY1, OUTPUT); //PIN in uscita LEAD      
  pinMode(RELAY2, OUTPUT); //PIN in uscita CLEAN
  pinMode(RELAY3, OUTPUT); //PIN in uscita REVERB
  pinMode(RELAY4, OUTPUT); //PIN in uscita BOOST
  pinMode (LED1, OUTPUT); //PIN in uscita LED
  pinMode (LEDCONTROLLO, OUTPUT); //PIN in uscita LED CONTROLLO
  
  MIDI.begin(13);
  //MIDI.begin(MIDI_CHANNEL_OMNI); // Initialize the Midi Library.
  // OMNI sets it to listen to all channels.. MIDI.begin(2) would set it
  // to respond to notes on channel 2 only.
  MIDI.setHandleControlChange(MyCCFunction); // This command tells the MIDI Library
  // the function you want to call when a Continuous Controller command
  // is received. In this case it's "MyCCFunction".

  //Pulsing led function call
  LampeggioLed();
 
}

void loop() { // Main loop
  
  if (NUMBER_BUTTONS != 0) updateButtons();
  if (NUMBER_POTS != 0) updatePots();

  MIDI.read(); // Continuously check if Midi data has been received.
  
}


//*****************Functions******************

//Pulsing led function
void LampeggioLed() {
  float in, out;
  for (in = 0; in < 6.283; in = in + 0.001)
  {
    out = sin(in) * 127.5 + 127.5;
    analogWrite(LED1,out);
  delay(1);
  }
}


// MyCCFunction is the function that will be called by the Midi Library
// when a Continuous Controller message is received.
// It will be passed bytes for Channel, Controller Number, and Value
// It checks if the controller number is within the 22 to 27 range
// If it is, light up the corresponding LED with the PWM brightness equal to the Value byte
void MyCCFunction(byte channel, byte number, byte value) {
  switch (number) {
    case 20:
      if (value > 0)
    {
      digitalWrite(RELAY1,HIGH);
    }
    else
    {
      digitalWrite(RELAY1,LOW);
    }
      break;
  case 21:
      if (value > 0)
    {
      digitalWrite(RELAY2,HIGH);
    }
    else
    {
      digitalWrite(RELAY2,LOW);
    }
      break;
  case 22:
      if (value > 0)
    {
      digitalWrite(RELAY3,HIGH);
    }
    else
    {
      digitalWrite(RELAY3,LOW);
    }
      break;
    case 23:
      if (value > 0)
    {
      digitalWrite(RELAY4,HIGH);
    }
    else
    {
      digitalWrite(RELAY4,LOW);
    }
      break;
  }
}

//**********************BUTTONS*************************
void updateButtons() {

  // Cycle through Button array
  for (int i = 0; i < NUMBER_BUTTONS; i = i + 1) {
    byte message = BUTTONS[i]->getValue();

    //  Button is pressed
    if (message == 0) {
      switch (BUTTONS[i]->Bcommand) {
        case 0: //Note
          MIDI.sendNoteOn(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 1: //CC
          MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
          break;
        case 2: //Toggle
          if (BUTTONS[i]->Btoggle == 0) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 127, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 1;
          }
          else if (BUTTONS[i]->Btoggle == 1) {
            MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
            BUTTONS[i]->Btoggle = 0;
          }
          break;
      }
    }

    //  Button is not pressed
    if (message == 1) {
      switch (BUTTONS[i]->Bcommand) {
        case 0:
          MIDI.sendNoteOff(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
          break;
        case 1:
          MIDI.sendControlChange(BUTTONS[i]->Bvalue, 0, BUTTONS[i]->Bchannel);
          break;
      }
    }
  }
}

//***********************POTS*****************************
void updatePots() {
  for (int i = 0; i < NUMBER_POTS; i = i + 1) {
    byte potmessage = POTS[i]->getValue();
    if (potmessage != 255) MIDI.sendControlChange(POTS[i]->Pcontrol, potmessage, POTS[i]->Pchannel);
  }
}


If I put the LampeggioLed() function in the loop Arduino doesn't send and receive correct messages, if I put this function in the setup() it just stay switched on.
I don't know where to put this to have a working midi system:

Code: [Select]

float in, out;
  for (in = 0; in < 6.283; in = in + 0.001)
  {
    out = sin(in) * 127.5 + 127.5;
    analogWrite(LED1,out);
  delay(1);
  }

Sorry guys for my english....
Thank you in advance!


Grumpy_Mike

That function takes far to long to run. You should write it as a state machine and remove the for loop and delay. Call it each time the loop is run.

On entry the contents that was in the for loop is run only once and your loop variable is updated and checked for the end. Using the sin function also takes a long time, just use a simple ramp.

stecciu

Thank you Grumpy_Mike for the help.

What do you mea for ramp? Could you help me to write the code?

I also found this code in the arduino tutorial

Code: [Select]
int led = 9;           // the PWM pin the LED is attached to
int brightness = 0;    // how bright the LED is
int fadeAmount = 5;    // how many points to fade the LED by

// the setup routine runs once when you press reset:
void setup() {
  // declare pin 9 to be an output:
  pinMode(led, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  // set the brightness of pin 9:
  analogWrite(led, brightness);

  // change the brightness for next time through the loop:
  brightness = brightness + fadeAmount;

  // reverse the direction of the fading at the ends of the fade:
  if (brightness <= 0 || brightness >= 255) {
    fadeAmount = -fadeAmount;
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}


What do you think, could it work?

Grumpy_Mike

Quote
What do you think, could it work?
No, it still has most of the problems as your first code, although that is what is meant by a ramp, a simple increase or decrease in the brightness value that changes each step.

Stop trying to find code that does what you want because you don't seem to know what you are looking for. Look at my reply again and try and figure out what I asked you to do. If there is something specific about what I told you to do that you do not understand then ask specifically about that.

stecciu

#4
Jan 24, 2019, 04:39 pm Last Edit: Jan 24, 2019, 04:43 pm by stecciu
Hi Grumpy_Mike!
Ok maybe I understand your message... you'll be my guru!

I tried 2 solutions but I don't feel so sure the second one is a state machine. The first one I tried is not so beautiful.. so I tried the second one.

At the moment I can't try the led in the sketch with the midi loop but if I understand your reasoning I think it would be ok.

At the moment I can pulse up the led but I need to implement the pulse down function.

1° SKETCH

Code: [Select]

int LEDstate = 0;
int tempo = 8;  // Do this every second or 1000 milliseconds
long int tempoVia;

void setup(){
pinMode(3,OUTPUT);
tempoVia = millis();
}

void loop(){
if(millis() >= tempoVia) pulseUP();
}

void pulseUP(){

switch(LEDstate) {
  case 0:
    analogWrite(3, 16);
    LEDstate = 16;
   break;

  case 16:
    analogWrite(3, 32);
    LEDstate = 32;
   break;

  case 32:
    analogWrite(3, 48);
    LEDstate = 48;
   break;

  case 48:
    analogWrite(3, 64);
    LEDstate = 64;
   break;

  case 64:
    analogWrite(3, 80);
    LEDstate = 80;
   break;

  case 80:
    analogWrite(3, 96);
    LEDstate = 96;
   break;

  case 96:
    analogWrite(3, 112);
    LEDstate = 112;
   break;

  case 112:
    analogWrite(3, 128);
    LEDstate = 128;
   break;

  case 128:
    analogWrite(3, 144);
    LEDstate = 144;
   break;

  case 144:
    analogWrite(3, 160);
    LEDstate = 160;
   break;

  case 160:
    analogWrite(3, 176);
    LEDstate = 176;
   break;

  case 176:
    analogWrite(3, 191);
    LEDstate = 191;
   break;

  case 191:
    analogWrite(3, 207);
    LEDstate = 207;
   break;

  case 207:
    analogWrite(3, 223);
    LEDstate = 223;
   break;

  case 223:
    analogWrite(3, 239);
    LEDstate = 239;
   break;

  case 239:
    analogWrite(3, 255);
    LEDstate = 255;
   break;

  case 255:
    analogWrite(3, 0);
    LEDstate = 0;
   break;
  }

tempoVia = millis() + tempo;

}


2nd SKETCH

Code: [Select]

int LEDstate = 0;
int tempo = 8;  // Do this every second or 1000 milliseconds
long int tempoVia;
int valore;

void setup(){
pinMode(3,OUTPUT);
tempoVia = millis();
}

void loop(){
if(millis() >= tempoVia) pulseUP();
}

void pulseUP(){

if (LEDstate <= 254) {
  analogWrite(3, valore);
  LEDstate++;
  valore++;
}
else {
  analogWrite(3, 0);
  LEDstate = 0;
  valore = 0;
}

tempoVia = millis() + tempo;

}


Hope I centered the question....!

Grumpy_Mike

Sorry both not much good,
In the second it was the closest but the valore variable was never given a value so it defaults to zero hence it never changes the value you write to the LED
something like this:-
Code: [Select]


int valore = 4;
boolean direction= true;
LEDstate = 0;

void pulseUP(){
if(direction) LEDstate += valore; else LEDstate -=valore;

if( (LEDstate >= 250) || (LEDstate < 5) {
   direction = !direction; // invert direction
}

  analogWrite(3, LEDstate);
 
tempoVia = millis() + tempo;

Not compiled or tested but is a lot closer to what you want.

stecciu

#6
Jan 27, 2019, 10:31 am Last Edit: Jan 27, 2019, 10:32 am by stecciu
Hi Grumpy_Mike!
Ok, I wasn't so far...
I corrected your sketch and tested it.
The final working result is this:

Code: [Select]

int LEDstate = 0;
int tempo = 60;  // Do this every 60 milliseconds
long int tempoVia;
int valore = 4;
boolean direction = true;

void setup(){
pinMode(3,OUTPUT);
tempoVia = millis();
}

void loop(){
if(millis() >= tempoVia) pulseUP();
}

void pulseUP(){

if(direction) LEDstate += valore; else LEDstate -=valore;

if ((LEDstate >= 250) || (LEDstate < 4)) {
   direction = !direction; // invert direction
}

  analogWrite(3, LEDstate);
 
tempoVia = millis() + tempo;

}


When I'll can try this with the midi loop I'll give you an answer about its operation.
In the meantime, thank you a lot!

stecciu

Hi Grumpy_Mike!
It works!
Really thank you for your help!!!
Thanks again!!!


Go Up