Assistance interfacing an IR Remote with Control Surface library to send MIDI CC

Good day all,
Newbie here :slight_smile:

I have been enjoying PieterP's Control Surface library. It really is fantastic and very powerful, thank you for your hard work on it!!

I have a question regarding it and wonder if anybody can help me?

I have an IR remote which I linked to my Arduino with an IR receiver module. Currently my script receives the signal from remote, decodes it and outputs which button was pressed to the serial monitor.
I want to turn each button into a "CCButtonLatched" (from the library), AKA a MIDI toggle button, however the constructor needs a digital pin to be specified as per the documentation at Control Surface: CCButtonLatched Class Reference.
This is the part where I am confused, becuse the digital pin will be same for all of the buttons on the IR remote, but I want each button to send a different midi CC message. So determining the MIDI CC message by what value has been returned on the digital pin, rather than whether the pin is just 'on'.

I am using an Arduino UNO by the way. It's the 32 rather than the 16, so I think the library can support it without custom firmware - is this correct?
(I do have a Arduino Leonoardo also but already using it with a previous Control Surface project :slight_smile: )

Here is my code so far:

Code: [Select]
#include "IRremote.h"
#include <Control_Surface.h>

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

/-----( Declare objects )-----/
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'

/* MIDI DEVICE */
USBMIDI_Interface midi;

/*
*
/
/
NEED TO SET UP THE TOGGLES HERE I THINK?
/*
*
*/

/-----( Function )-----/
void translateIR() // takes action based on IR code received

// describing Remote IR codes

{

switch(results.value)

{
case 0xFFA25D: Serial.println("POWER"); break;
case 0xFFE21D: Serial.println("FUNC/STOP"); break;
case 0xFF629D: Serial.println("VOL+"); break;
case 0xFF22DD: Serial.println("FAST BACK"); break;
case 0xFF02FD: Serial.println("PAUSE"); break;
case 0xFFC23D: Serial.println("FAST FORWARD"); break;
case 0xFFE01F: Serial.println("DOWN"); break;
case 0xFFA857: Serial.println("VOL-"); break;
case 0xFF906F: Serial.println("UP"); break;
case 0xFF9867: Serial.println("EQ"); break;
case 0xFFB04F: Serial.println("ST/REPT"); break;
case 0xFF6897: Serial.println("0"); break;
case 0xFF30CF: Serial.println("1"); break;
case 0xFF18E7: Serial.println("2"); break;
case 0xFF7A85: Serial.println("3"); break;
case 0xFF10EF: Serial.println("4"); break;
case 0xFF38C7: Serial.println("5"); break;
case 0xFF5AA5: Serial.println("6"); break;
case 0xFF42BD: Serial.println("7"); break;
case 0xFF4AB5: Serial.println("8"); break;
case 0xFF52AD: Serial.println("9"); break;
case 0xFFFFFFFF: Serial.println(" REPEAT");break;

default:
Serial.println(" other button ");

}// End Case

delay(500); // Do not get immediate repeat

} //END translateIR
void setup() /----( SETUP: RUNS ONCE )----/
{
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
irrecv.enableIRIn(); // Start the receiver
/SETUP CONTROL SURFACE /
Control_Surface.begin();
}/
--(end setup )---
/

void loop() /----( LOOP: RUNS CONSTANTLY )----/
{
/CONTROL SURFACE LOOP/
Control_Surface.loop();
/CONTINUE WITH IR SCRIPT/
if (irrecv.decode(&results)) // have we received an IR signal?

{
translateIR();
irrecv.resume(); // receive the next value
}
}/* --(end main loop )-- */

If anybody with experience of Control Surface Library has a spare moment to guide me on this, I would really appreciate it.

Many thanks & kind regards,
Josh

Good day,
Pieter kindly replied to me with the following:

The CCButtonLatched classes and the other *Button classes are designed to read input from physical buttons. If you want to use the input from the IR receiver to send MIDI messages, it's best to send the MIDI data yourself. You can replace the Serial.println(...) statements in your switch with Control_Surface.sendCC(address, value), for example. You'd probably need some additional logic to determine the right value, implementing the latching behavior.

Pieter also confirmed that the UNO doesn't have native USB support, so I am using my Leonardo instead, however I am now receiving the following error:

Arduino: 1.8.7 (Windows 10), Board: "Arduino Leonardo"

C:\Users\***\Documents\Arduino\libraries\Control-Surface-master\src\MIDI_Outputs\ManyAddresses\CCRotaryEncoder.cpp:1:21: fatal error: Encoder.h: No such file or directory

compilation terminated.

exit status 1
Error compiling for board Arduino Leonardo.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

My code is as follows (at the moment... Once I get round the error and get it working, I will add some further logic to do the latching behaviour etc):

#include "IRremote.h"
#include <Control_Surface.h>
USBMIDI_Interface midi;

int receiver = 11; // Signal Pin of IR receiver to Arduino Digital Pin 11

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

/*-----( Function )-----*/
void translateIR() // takes action based on IR code received

// describing Remote IR codes 

{

  switch(results.value)

  {
  case 0xFFA25D: 
  Serial.println("POWER"); 
  Control_Surface.sendCC(104,127);
  break; 
  case 0xFFE21D: Serial.println("FUNC/STOP"); break;
  case 0xFF629D: Serial.println("VOL+"); break;
  case 0xFF22DD: Serial.println("FAST BACK");    break;
  case 0xFF02FD: Serial.println("PAUSE");    break;
  case 0xFFC23D: Serial.println("FAST FORWARD");   break;
  case 0xFFE01F: Serial.println("DOWN");    break;
  case 0xFFA857: Serial.println("VOL-");    break;
  case 0xFF906F: Serial.println("UP");    break;
  case 0xFF9867: Serial.println("EQ");    break;
  case 0xFFB04F: Serial.println("ST/REPT");    break;
  case 0xFF6897: Serial.println("0");    break;
  case 0xFF30CF: Serial.println("1");    break;
  case 0xFF18E7: Serial.println("2");    break;
  case 0xFF7A85: Serial.println("3");    break;
  case 0xFF10EF: Serial.println("4");    break;
  case 0xFF38C7: Serial.println("5");    break;
  case 0xFF5AA5: Serial.println("6");    break;
  case 0xFF42BD: Serial.println("7");    break;
  case 0xFF4AB5: Serial.println("8");    break;
  case 0xFF52AD: Serial.println("9");    break;
  case 0xFFFFFFFF: Serial.println(" REPEAT");break;  

  default: 
    Serial.println(" other button   ");

  }// End Case

  delay(500); // Do not get immediate repeat


} //END translateIR
void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Control_Surface.begin();
  //Serial.begin(9600);
  Serial.println("IR Receiver Button Decode"); 
  irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  Control_Surface.loop();
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    translateIR(); 
    irrecv.resume(); // receive the next value
  }  
}/* --(end main loop )-- */

Is anybody able to assist in resolving this error?
Thanks & regards
Josh

fatal error: Encoder.h: No such file or directory

Is that error message that hard to understand? You are trying to use a library that you don't have. Get it installed.

Hi Paul,

As far as I could see, the Encoder library wasn't listed as a dependency to use Control Surface and I am a complete novice, so yes, the error message was hard for me to understand!

Having installed the Encoder library it appears to be working now.

Thanks for your patient advice......

Regards
Josh

The Encoder library is a dependency of Control Surface: Control Surface: Installation

However, it should only be included when needed. There was one file that included Encoder.h even when it wasn't used. That should be fixed now.

You can find some examples for sending MIDI here: Control Surface: Send-MIDI-Notes.ino

If you want to use CC instead of notes, just replace sendNoteOn and sendNoteOff by sendCC: Control Surface: MIDI_Sender< Derived > Class Template Reference

Pieter