Select between multiple EthernetUDP instances

Status
Not open for further replies.

crustn

Member
Hi all,

I've written a sketch with two EthernetUDP instances to control two computers on the network. When I press one of the pbuttons, the function HUIbutton sends out UDP packets.


The selectButton will define which computer (or which multicast port) will receive the packets.


Please see the following code:

Code:
#include <Bounce2.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


#define PRESS HIGH
#define RELEASE LOW
#define HUI_SWITCH 0xB0
#define HUI_RX_ZONE_SEL 0x0F
#define HUI_RX_PORT_SEL 0x2F

#define Z_TRANSPORT 0x0E

#define P_STOP 0x03
#define P_PLAY 0x04
#define P_REC 0x05


//-----------------------------------------------------------------------------------------------------------------
//ETHERNET CONFIG
//-----------------------------------------------------------------------------------------------------------------

#define UDP_TX_PACKET_MAX_SIZE 1500
/* in Ethernet.h, #define UDP_TX_PACKET_MAX_SIZE is only 24 bytes and too short for the incoming packages.
  This will freeze the Teensy. see explanation at http://forum.arduino.cc/index.php?topic=103502.0
  you can ignore the compiling warnings*/

// Enter the MAC and IP address for your controller below.
byte mac[] = {0x04, 0xE9, 0xE5, 0x03, 0x22, 0x4F};

IPAddress ip(192, 168, 0, 55);    // local IP of the microcontroller 
//unsigned int localPort = 8888;  // local port to listen on (not needed for multicast)

IPAddress ipMulti(225, 0, 0, 37); // ipMidi Multicast address
unsigned int portMulti = 21928;  // common ipMidi Mutlicast port for UDP.beginPacket(), doesn't matter which one is used
unsigned int portMulti1 = 21928;  // ipMidi Mutlicast port 1, only important for beginMulticast() in setup()
unsigned int portMulti2 = 21929;  // ipMidi Mutlicast port 2, only important for beginMulticast() in setup()
unsigned int portMulti3 = 21930;  // ipMidi Mutlicast port 3, only important for beginMulticast() in setup()
unsigned int portMulti4 = 21931;  // ipMidi Mutlicast port 4, only important for beginMulticast() in setup()

byte packetBuffer[UDP_TX_PACKET_MAX_SIZE];      // buffer to hold incoming packet

// Two EthernetUDP instances for two multicast ports to send and receive packets over UDP
EthernetUDP computer1;
EthernetUDP computer2;


Bounce selectButton = Bounce();
Bounce pbutton[3] = Bounce();
int selectButtonPin = 6;
int buttonPin[] = {7, 8, 9};
byte pArr[] = {P_STOP, P_PLAY, P_REC};





void setup() {


  Serial.begin(9600);

pinMode(selectButtonPin, INPUT_PULLUP);
    selectButton.attach(selectButtonPin);
    selectButton.interval(10);


for (int i = 0; i < 3; i++) {
    pinMode(buttonPin[i], INPUT_PULLUP);
    pbutton[i].attach(buttonPin[i]);
    pbutton[i].interval(10);
  }
  


  Ethernet.begin(mac, ip);
  computer1.beginMulticast(ipMulti, portMulti3);
  computer2.beginMulticast(ipMulti, portMulti4);

}

void loop () {

  selectButton.update();

  if (selectButton.fallingEdge()) {
    for (int i = 0; i < 3; i++) {
      pbutton[i].update();

      if (pbutton[1].fallingEdge()) {
        HUIbutton(computer1, Z_TRANSPORT, pArr[i], PRESS);
      }

      if (pbutton[1].risingEdge()) {
        HUIbutton(computer1, Z_TRANSPORT, pArr[i], RELEASE);
      }
    }
  }

if (selectButton.risingEdge()) {
    for (int i = 0; i < 3; i++) {
      pbutton[i].update();

      if (pbutton[1].fallingEdge()) {
        HUIbutton(computer2, Z_TRANSPORT, pArr[i], PRESS);
      }

      if (pbutton[1].risingEdge()) {
        HUIbutton(computer2, Z_TRANSPORT, pArr[i], RELEASE);
      }
    }
  }
}


void HUIbutton(EthernetUDP &UDP, byte zone, byte port, bool state) {

  if (state) {
    port += 0x40;
  }

  UDP.beginPacket(ipMulti, portMulti);
  UDP.write(HUI_SWITCH);
  UDP.write(HUI_RX_ZONE_SEL);
  UDP.write(zone);
  UDP.write(HUI_SWITCH);
  UDP.write(HUI_RX_PORT_SEL);
  UDP.write(port);
  UDP.endPacket();
}


As you see in the main loop, I've written the same code in both if conditions with the exception of the EthernetUDP instance name (computer1 or computer2). Is there a simpler way to accomplish that? Is there a way to treat the EthernetUDP instance name like a variable?

This is only an example sketch. My project has over 60 push buttons and it would be very painful and ugly to solve this with if comparisons...

Any help would be much appreciated.

Thanks,
Stefan
 
I SOLVED IT!!! Basically what i was doing with "void HUIbutton(EthernetUDP &UDP, byte zone, byte port, bool state)" is passing an object by reference to a function. If I want to select which object reference to be passed, I need another function with the type EthernetUDP which is returning an object reference. I hope that my explanation and terminology is correct. Please correct me if I'm wrong!


In my case the function looks like this:
Code:
EthernetUDP &compSel() {

  if (selectButton.fallingEdge()) {
    return computer2;
  }
  return computer1;
}

Now I only need to change the parameter of the other function:
Code:
HUIbutton(compSel(), Z_TRANSPORT, pArr[i], PRESS);



This is the entire code:
Code:
#include <Bounce2.h>
#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>


#define PRESS HIGH
#define RELEASE LOW
#define HUI_SWITCH 0xB0
#define HUI_RX_ZONE_SEL 0x0F
#define HUI_RX_PORT_SEL 0x2F

#define Z_TRANSPORT 0x0E

#define P_STOP 0x03
#define P_PLAY 0x04
#define P_REC 0x05


//-----------------------------------------------------------------------------------------------------------------
//ETHERNET CONFIG
//-----------------------------------------------------------------------------------------------------------------

#define UDP_TX_PACKET_MAX_SIZE 1500
/* in Ethernet.h, #define UDP_TX_PACKET_MAX_SIZE is only 24 bytes and too short for the incoming packages.
  This will freeze the Teensy. see explanation at http://forum.arduino.cc/index.php?topic=103502.0
  you can ignore the compiling warnings*/

// Enter the MAC and IP address for your controller below.
byte mac[] = {0x04, 0xE9, 0xE5, 0x03, 0x22, 0x4F};

IPAddress ip(192, 168, 0, 55);    // local IP of the microcontroller
//unsigned int localPort = 8888;  // local port to listen on (not needed for multicast)

IPAddress ipMulti(225, 0, 0, 37); // ipMidi Multicast address
unsigned int portMulti = 21928;  // common ipMidi Mutlicast port for UDP.beginPacket(), doesn't matter which one is used
unsigned int portMulti1 = 21928;  // ipMidi Mutlicast port 1, only important for beginMulticast() in setup()
unsigned int portMulti2 = 21929;  // ipMidi Mutlicast port 2, only important for beginMulticast() in setup()
unsigned int portMulti3 = 21930;  // ipMidi Mutlicast port 3, only important for beginMulticast() in setup()
unsigned int portMulti4 = 21931;  // ipMidi Mutlicast port 4, only important for beginMulticast() in setup()

byte packetBuffer[UDP_TX_PACKET_MAX_SIZE];      // buffer to hold incoming packet

// Two EthernetUDP instances for two multicast ports to send and receive packets over UDP
EthernetUDP computer1;
EthernetUDP computer2;


Bounce selectButton = Bounce();
Bounce pbutton[3] = Bounce();
int selectButtonPin = 6;
int buttonPin[] = {7, 8, 9};
byte pArr[] = {P_STOP, P_PLAY, P_REC};





void setup() {


  Serial.begin(9600);

  pinMode(selectButtonPin, INPUT_PULLUP);
  selectButton.attach(selectButtonPin);
  selectButton.interval(10);


  for (int i = 0; i < 3; i++) {
    pinMode(buttonPin[i], INPUT_PULLUP);
    pbutton[i].attach(buttonPin[i]);
    pbutton[i].interval(10);
  }



  Ethernet.begin(mac, ip);
  computer1.beginMulticast(ipMulti, portMulti3);
  computer2.beginMulticast(ipMulti, portMulti4);

}

void loop () {

  selectButton.update();


  for (int i = 0; i < 3; i++) {
    pbutton[i].update();

    if (pbutton[1].fallingEdge()) {
      HUIbutton(compSel(), Z_TRANSPORT, pArr[i], PRESS);
    }

    if (pbutton[1].risingEdge()) {
      HUIbutton(compSel(), Z_TRANSPORT, pArr[i], RELEASE);
    }
  }
}


void HUIbutton(EthernetUDP &UDP, byte zone, byte port, bool state) {

  if (state) {
    port += 0x40;
  }

  UDP.beginPacket(ipMulti, portMulti);
  UDP.write(HUI_SWITCH);
  UDP.write(HUI_RX_ZONE_SEL);
  UDP.write(zone);
  UDP.write(HUI_SWITCH);
  UDP.write(HUI_RX_PORT_SEL);
  UDP.write(port);
  UDP.endPacket();
}


EthernetUDP &compSel() {

  if (selectButton.read()) {
    return computer2;
  }
  return computer1;
}

So simple when you know the answer.

The code is now compiling, working and is much easier to handle instead of endless if statements.

cheers,
Stefan
 
Last edited:
Status
Not open for further replies.
Back
Top