Categories
Projects

Controlling a Monoprice 4×4 True Matrix HDMI switch using IR, ESP8266 and OSC

I used a Lolin D1 Mini and their IR shield.

D1 Mini

Details: https://www.wemos.cc/en/latest/d1/d1_mini.html

To buy: https://www.aliexpress.com/item/32529101036.html

D1 Mini IR Controller Shield

Details: https://www.wemos.cc/en/latest/d1_mini_shiled/ir.html

To buy: https://www.aliexpress.com/item/32891173618.html

You’ll need the ESP8266 specific version of the IRRemote library:

https://github.com/crankyoldgit/IRremoteESP8266

And I use the CNMAT OSC library:

https://github.com/CNMAT/OSC

/*------------------------------------------------------

	OSC to IR interface for 
	Monoprice Blackbird 4K Pro 4X4 True Matrix HDMI Powered Switch with EDID and RS232 Control

	/matrix   first integer variable is input channel, second is output channel
	/led  sets onboard LED (0 = off, 1 = on)
	
----------------------------------------------------- */

#ifdef ESP8266
#include <ESP8266WiFi.h>
#else
#include <WiFi.h>
#endif
#include <WiFiUdp.h>
#include <OSCMessage.h>
#include <OSCBundle.h>
#include <OSCData.h>

#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

const uint16_t kIrLed = 0;  // ESP8266 GPIO pin to use. Recommended: 4 (D2).

IRsend irsend(kIrLed);  // Set the GPIO to be used to sending the message.

char ssid[] = "**network**";          			// your network SSID (name)
char pass[] = "**password**";     					// your network password

// A UDP instance to let us send and receive packets over UDP
WiFiUDP Udp;
const IPAddress outIp(10,40,10,105);        // remote IP (not needed for receive)
const unsigned int outPort = 9999;          // remote port (not needed for receive)
const unsigned int localPort = 8888;        // local port to listen for UDP packets (here's where we send the packets)


OSCErrorCode error;
unsigned int ledState = LOW;              	// LOW means led is *on*
unsigned int inChannel = 0;
unsigned int outChannel = 0;

#ifndef BUILTIN_LED
#ifdef LED_BUILTIN
#define BUILTIN_LED LED_BUILTIN
#else
#define BUILTIN_LED 13
#endif
#endif

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);
  digitalWrite(BUILTIN_LED, ledState);    // turn *on* led

  irsend.begin();

  Serial.begin(115200);

  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, pass);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  Serial.println("Starting UDP");
  Udp.begin(localPort);
  Serial.print("Local port: ");
#ifdef ESP32
  Serial.println(localPort);
#else
  Serial.println(Udp.localPort());
#endif

}


void led(OSCMessage &msg) {
  ledState = msg.getInt(0);
  digitalWrite(BUILTIN_LED, ledState);
  Serial.print("/led: ");
  Serial.println(ledState);
}

void switchmatrix(OSCMessage &msg) {
  inChannel = msg.getInt(0);
  outChannel = msg.getInt(1);
  
  // this bit is just for debugging
  // it prints the command neatly to the serial monitor
  
  Serial.print("/matrix/");
  Serial.print(inChannel);
  Serial.print("/");
  Serial.println(outChannel);
  
  switch (inChannel) {
  case 1:
    switch (outChannel) {
      case 1:
        irsend.sendNEC(0xFF906F);
        break;
      case 2:
        irsend.sendNEC(0xFFB847);
        break;
      case 3:
        irsend.sendNEC(0xFFF807);
        break;
      case 4:
        irsend.sendNEC(0xFFB04F);
        break;
      default:
        break;
      }
    break;
  case 2:
    switch (outChannel) {
      case 1:
        irsend.sendNEC(0xFFE817);
        break;
      case 2:
        irsend.sendNEC(0xFF48B7);
        break;
      case 3:
        irsend.sendNEC(0xFF9A65);
        break;
      case 4:
        irsend.sendNEC(0xFF10EF);
        break;
      default:
        break;
      }
    break;
  case 3:
    switch (outChannel) {
      case 1:
        irsend.sendNEC(0xFFE817);
        break;
      case 2:
        irsend.sendNEC(0xFFB847);
        break;
      case 3:
        irsend.sendNEC(0xFFF807);
        break;
      case 4:
        irsend.sendNEC(0xFFB04F);
        break;
      default:
        break;
      }
    break;
  case 4:
    switch (outChannel) {
      case 1:
        irsend.sendNEC(0xFFE817);
        break;
      case 2:
        irsend.sendNEC(0xFFB847);
        break;
      case 3:
        irsend.sendNEC(0xFFF807);
        break;
      case 4:
        irsend.sendNEC(0xFFB04F);
        break;
      default:
        break;
      }
    break;
  default:
    break;
  }
}

void loop() {
  // Serial.println("loop");
  OSCMessage msg;
  int size = Udp.parsePacket();

  if (size > 0) {
    while (size--) {
      msg.fill(Udp.read());
    }
    if (!msg.hasError()) {
      //Serial.println("msg received");
      msg.dispatch("/led", led);
      msg.dispatch("/matrix", switchmatrix);

    } else {
      error = msg.getError();
      Serial.print("error: ");
      Serial.println(error);
    }
  }
}