UDP commands triggered by button press

Greetings,

I am attempting what I thought would be a simple task. Create an interactive element to my christmas lights.

My Lighting controller will respond to UDP commands and I have integrated this function many times on professional installs.

I am trying to make a small interactive stand using various forms of contact closure inputs. each button would send a different string to the controller, and its programmed to respond in kind. controlling the lights and media.

I have tries to take the UDPsendRecievestring, and State Change detection examples and bring them together. Both work independently, but not together. So far here are my troubleshooting steps.

Verifiy independant functionality:
-UDP TX/RX sketch - Tested and works as expected with processing sketch.
-State change detection on same arduino - works as expected Serial monitor shows Off, On, and counter
-Verifyied Controller and Processing sketch will trade UDP strings - Adjusted IP and Port settings to match, Communication is good.

So i have now added the state change detection into the UDP TX/RX code, and adjusted what I thought I needed to for them to work, and for the button state change to fire off a UDP string. With this code, the Arduino will still respond to the processing sketch, but nothing happens when the button is pressed. I thought Id atleast see the serial lines "startbutton on"

Once I get this part working, Ill want to receive UDP commands so I can have lights on my interactive panel light up based on lighting controller status.

Im sure im missing something obvious, but apparently not to me.

Heres Code:

#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(2, 0, 0, 20);

unsigned int localPort = 3141;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged";        // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

//controller address:
unsigned int pharos = (2, 0, 0, 201);
unsigned int pharosport = (3141);

//define pins for interactive elements

const int startbutton = 13 ;

//variables for I/O States
int startbuttonstatus = 0 ;

//LAST statuses vari's for change detection
int laststartbuttonstatus = 0 ;


//define udp strings


void setup() {
  // I/O Pin settings
  pinMode(startbutton , INPUT_PULLUP);


  // Set Output pins to start positions


  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // start the Ethernet
  Ethernet.begin(mac, ip);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start UDP
  Udp.begin(localPort);
}

void loop() {
  startbuttonstatus = digitalRead(startbutton) ; // check button status, set variable
  udpcheck();
  buttoncheck() ;
  delay (50);
}

 void udpcheck(){
  //From UDPsendrecievestring:
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
 }

void buttoncheck() {
  //send UDP command upon button state change.
  // compare the buttonState to its previous state
  if (startbuttonstatus != laststartbuttonstatus) {
    // if the state has changed, increment the counter
    if (startbuttonstatus == LOW) {
      // if the current state is HIGH then the button went from off to on:

      Serial.print("Startbutton");
      Serial.println("on");

      Udp.beginPacket(pharos, pharosport);
      Udp.write("starttimeline1");
      Udp.endPacket();
      Serial.println("sent start command");
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
  }
  // Delay a little bit to avoid bouncing


  // save the current state as the last state, for next time through the loop
  laststartbuttonstatus = startbuttonstatus;
  delay(50);
}

I haven't used the Ethernet on the Arduino but I'm wondering if the code is blocking somewhere. Perhaps you could put a print statement at the end of setup() and at the entry and exit of each function to see if the code is blocking.

ToddL1962,

The first function,"udpcheck" always works, It continues to respond to the Programmer sketch and prints the contents of packets, but I have not been able to get the second function "buttoncheck" to work when combined.
I dont see the button presses on the serial monitor, and definitely dont see any UDP strings coming from the Arduino. So I do agree, It seems like its looping and not running the second part of code.

I'm new to this, so its possible im missing a basic programming / structure concept somewhere.
Cheers!

Update,
I stripped out the state change test,
and made this a basic "push button, send string"

Its somewhat working but not really.
When I run the processing sketch included with the UDPsendrecieve string, everything behaves normally. I hut a keyboard button, and "acknowledged" comes back almost instantly.
When I press the button The arduino hangs, and then sends garbage before the "sent string"

I am using an Uno, but have checked this on a Mega with the same result.

Furthermore, the button press wont do anything until the Processing sketch has sent something and the arduino replied.

Processing sketch log:
acknowledged
acknowledged
acknowledged
acknowledgedstartshow1
º?startshow1

the actual characters wont even show on here.
Im quite baffled. Any help is appreciated.

Here is my code:

#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(2, 0, 0, 20);
//controller address


unsigned int localPort = 3141;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged";        // a string to send back
char startshow[] = "startshow1";  // string to send when button is pressed
// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

//controller address:


//define pins for interactive elements

const int startbutton = 2 ;

//variables for I/O States
int startbuttonstatus = 0 ;

//LAST statuses vari's for change detection
int laststartbuttonstatus = 0 ;


//define udp strings


void setup() {
  // I/O Pin settings
  pinMode(startbutton, INPUT_PULLUP);


  // Set Output pins to start positions


  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // start the Ethernet
  Ethernet.begin(mac, ip);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start UDP
  Udp.begin(localPort);
}

void loop() {
  startbuttonstatus = digitalRead(startbutton) ; // check button status, set variable
  udpcheck();
  buttoncheck() ;
  delay (50);
}

 void udpcheck(){
  //From UDPsendrecievestring:
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i = 0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
 }

void buttoncheck() {
  //send UDP command upon button state change.
  // compare the buttonState to its previous state
 
    // if the state has changed, increment the counter
    if (startbuttonstatus == LOW) {
      // if the current state is HIGH then the button went from off to on:

      Serial.println("Startbutton");
      Serial.println("on");
      Udp.beginPacket("2,0,0,1", 3141);
      Udp.write(startshow);
      Udp.endPacket();
      Serial.println("sent start command");
    } 
    delay (100);
    }

Processing sketch:

import hypermedia.net.*;

 UDP udp;  // define the UDP object


 void setup() {
 udp = new UDP( this, 3141 );  // create a new datagram connection on port 6000
 //udp.log( true );     // <-- printout the connection activity
 udp.listen( true );           // and wait for incoming message
 }

 void draw()
 {
 }

 void keyPressed() {
 String ip       = "2.0.0.20";  // the remote IP address
 int port        = 3141;    // the destination port

 udp.send("starttimeline1", ip, port );   // the message to send

 }

 void receive( byte[] data ) {       // <-- default handler
 //void receive( byte[] data, String ip, int port ) {  // <-- extended handler

 for(int i=0; i < data.length; i++)
 print(char(data[i]));
 println();
 }
1 Like