Ethercard library and Processing 3

Hi everyone! I am using Arduino Nano with the Ethernet shield ENC28J60. With this program Arduino is successfully sending data, I can see it in Wireshark:

#include <EtherCard.h>

static byte mymac[] = { 0x1A,0x2B,0x3C,0x4D,0x5E,0x6F };
byte Ethernet::buffer[700];
static uint32_t timer;

#define STATIC 1  // set to 1 to disable DHCP (adjust myip/gwip values below)

#if STATIC
static byte myip[] = { 192,168,1,50 };
static byte gwip[] = { 192,168,1,1 };
static byte dnsip[] = { 192,168,1,1 };
#endif

static byte dip[] = { 192,168,1,40 };
const int dstPort PROGMEM = 44000;
const int srcPort PROGMEM = 44000;

void setup () {
  Serial.begin(9600);

  
  // Change 'SS' to your Slave Select pin, if you arn't using the default pin
  if (ether.begin(sizeof Ethernet::buffer, mymac, SS) == 0)
    Serial.println( "Failed to access Ethernet controller");

#if STATIC
  ether.staticSetup(myip, gwip, dnsip);
#else
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");
#endif

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);
  ether.printIp("SRV: ", ether.hisip);
}

char textToSend[] = "abc";

void loop () {
    if (millis() > timer) {
      timer = millis() + 5000;
     //static void sendUdp (char *data,uint8_t len,uint16_t sport, uint8_t *dip, uint16_t dport);
     ether.sendUdp(textToSend, sizeof(textToSend), srcPort, dip, dstPort );
  }
}

However, for days I have been trying to set up a UDP client in Processing by using different examples from the Web, but no luck so far. Here is one:

import hypermedia.net.*;  // import the UDP library

UDP udp;    // define the UDP object

void setup(){
  size(400, 400);
  udp = new UDP (this, 44000);    // create a new datagram connection on port 44000
  udp.listen (true);      // and wait for incoming message
}


void draw(){
}


void receive (byte[] data){
  // print the incoming data bytes as ASCII characters
  for (int i=0; i<data.length; i++) {
    print (char (data[i]));
  }
  println();
}

This one above doesn't print out anything, but there is no error message either. Another one:

import processing.net.*; 

Client myClient; 
int dataIn; 
 
void setup() { 
  size(400, 400); 
  // Connect to the local machine at port 44000.
  // This example will not run if you haven't
  // previously started a server on this port.
  myClient = new Client(this, "192.168.1.50", 44000); 
} 
 
void draw() { 
  if (myClient.available() > 0) { 
    dataIn = myClient.read();
  } 
  print(char(dataIn));
}

This one gives a message after 15-20 seconds:

java.net.ConnectException: Connection timed out: connect
	at java.net.DualStackPlainSocketImpl.connect0(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at java.net.Socket.connect(Socket.java:538)
	at java.net.Socket.<init>(Socket.java:434)
	at java.net.Socket.<init>(Socket.java:211)
	at processing.net.Client.<init>(Unknown Source)
	at sketch_200307b.setup(sketch_200307b.java:30)
	at processing.core.PApplet.handleDraw(PApplet.java:2432)
	at processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1547)
	at processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)

It seems that these sketches work for many people, as far as I could see on different message boards. What am I doing wrong?

I am working with LAN8720 (10/100) and STM32F407, I have already tried the ENC28J60 (10), but I always use a terminal program that makes life a lot easier, after everything is working on one side, whether on Arduino or PC, so I let the two talk.

https://www.hw-group.com/software/hercules-setup-utility

I tried Hercules as you suggested. This is the 4th application of this kind which I am using, but the problem is still the same: whatever the method I use the Processing sketch doesn't seem to receive or recognize the incoming packets. And I am trying on 3 different OS's: Windows, Ubuntu, Raspbian - no luck. I use Processing because I want to make a GUI and it's pretty easy with it. I have no problems receiving data through USB/serial but LAN is proving to be a real stinker. :frowning:

I found this code below.

Tested on Processing 3 and Smartphone Android and App TCP/UDP Test Tool - animod, from PlayStore, it looks like Hercules will only work on another machine other than the one running Processing, but Hercules worked with the Smartphone.

Please use the Processing forum for any queries about Processing code:

I posted this code here, because I also found the examples found on the internet confusing.

Processing 3 code:

//import ui library for buttons
import controlP5.*; // (need install: Sketch(menu)/Import library.../Add library...)
ControlP5 cp5;

//import udp library
import hypermedia.net.*;
UDP udpRX,udpTX;

//variables for udp
String ip="192.168.1.59"; // Local (PC running Processing)
String ipTX="192.168.1.100"; // Target (Smartphone Android with App TCP/UDP Test Tool - animod)
int portRX=51000;
int portTX=50000;
int rx_buffer_size=100;
String rx_string="Waiting for Data";
byte[] rx_byte=new byte[rx_buffer_size];
int rx_byte_count=0;

//set strings for sending on udp
String s0="Zero";
String s1="One";
String s2="Two";

void setup(){

  //set window dimensions
  size(700,300);
  
  //disables drawing outlines
  noStroke();
  
  //create new cp5 object for this user
  cp5=new ControlP5(this);
  
  //create 3 buttons 
  for (int i=0;i<3;i++){
    cp5.addBang("Send"+i)
       .setPosition(400+i*80,200)
       .setSize(60,40)
       .setColorForeground(140)
       .setId(i)
       ; 
  }//end of for loop 

  //create new object for transmitting
  udpTX=new UDP(this,portTX,ip);
  udpTX.log(true);
  udpTX.setBuffer(5);
  udpTX.loopback(true);
  
  //create new object for receiving 
  udpRX=new UDP(this,portRX,ip);
  udpRX.log(true);
  udpRX.listen(true);

  
  //confirm if tx is multicast and loopback is disabled
  println("Is TX mulitcast: "+udpTX.isMulticast());
  println("Has TX joined multicast: "+udpTX.isJoined());
  println("Is loopback enabled on TX: "+udpTX.isLoopback());
  
  //confirm if rx is multicast 
  println("Is RX mulitcast: "+udpRX.isMulticast());
  println("Has RX joined multicast: "+udpRX.isJoined());



//stop looping setup  
noLoop();

}//end of setup()


void draw(){
  
  //set background color, also clears the screen
  background(0);
  
  
  //misc
  int off_x=200;
  
  //main title 
  fill(255);
  textSize(25);
  text("UDP Tool",20,30);
  
  fill(200);
  
  //IP address
  textSize(20);
  text("IP Address:",20,30+25);
  fill(252,10,55);
  text(ip,130,30+25);
  
  fill(200);
  
  //UDP ports
  text("Port(Local):",20,30+25+20);
  fill(252,10,55);
  text(portRX,155,30+25+20);
  
  fill(200);
  
  text("Port(Target):",20,30+25+40);
  fill(252,10,55);
  text(portTX,170,30+25+40);
  
  fill(200);
  
  text("Last Packet Received:",20,30+25+120);
  fill(252,10,55);
  text(rx_string,230,30+25+120);
  
  fill(200);
  text("Total Bytes Recieved:",20,30+25+140);
  fill(252,10,55);
  text(rx_byte_count,230,30+25+140);
  //start looping draw
  loop();
  
}//end of draw()


//event handling 
public void controlEvent(ControlEvent theEvent) {

    if(theEvent.getController().getId()==0){
    println("String Sent: "+s0);
    udpTX.send(s0,ipTX,portTX);
    }
    
    if(theEvent.getController().getId()==1){
    println("String Sent: "+s1);
    udpTX.send(s1,ipTX,portTX);
    }
    
    if(theEvent.getController().getId()==2){
    println("String Sent: "+s2);
    udpTX.send(s2,ipTX,portTX);
    }
   
    
}//end of event


//udp receive handling
void receive(byte[] data, String ip, int portRX){
  
String value=new String(data);
println(value);
rx_byte_count+=data.length;

//clear receive byte array
for(int j=0;j<rx_byte.length;j++)
{
  rx_byte[j]=0;
}

//copy received bytes to rx_byte array
arrayCopy(data,rx_byte);

//copy bytes to a string and trim string to remove nulls
rx_string=new String(rx_byte);
rx_string=trim(rx_string);

//is called to update the received string
redraw();
}

Source: UDP Library Example - Processing Forum

Thanks for your effort rtek1000. I didn't use your code, but I finally got it right. I will put below some of my remarks which will hopefully be useful to others. On Arduino side I use the library UIPEthernet and the sketches called UdpServer and UdpClient that come with the library. I used the software PacketSender to test the connection and to send / receive packets, in my opinion it is very simple to use.

Later on I moved to Processing, as was my intention from the start. This Processing code worked when Arduino was the server:

import hypermedia.net.*;  // import the UDP library

UDP udp;    // define the UDP object

void setup(){
  udp = new UDP (this, 24000);    // create a new datagram connection on port 24000
  udp.listen (true);      // and wait for incoming message
}


void draw(){
}

void keyPressed(){
  int destPort = 10000;
  String ip = "192.168.1.123";      // broadcast message
  udp.send ("Hello World", ip, destPort);    // the message to send
}


void receive (byte[] data){
  // print the incoming data bytes as ASCII characters
  for (int i=0; i<data.length; i++) {
    print (char (data[i]));
  }
  println();
}

Important to note, in the UdpServer sketch the IP and port of Arduino were changed to 192.168.1.23 and 10000.

Now to the case where Arduino was the client:

import hypermedia.net.*;  // import the UDP library

UDP udp;    // define the UDP object

void setup(){
  udp = new UDP (this, 20000);    // create a new datagram connection on port 20000
  udp.listen (true);      // and wait for incoming message
}


void draw(){
}


void receive (byte[] data){
  // print the incoming data bytes as ASCII characters
  for (int i=0; i<data.length; i++) {
    print (char (data[i]));
  }
  println();
}

In the UdpClient sketch the first IP address is for Arduino, but the second one is of the device (computer in my case) to which Arduino is sending packets. The port must be set to the same value in Arduino and Processing code. Btw. I set static IP addresses to all devices.

Let me also note that this was tried with two variants of Ethernet shields ENC28J60. One had 10 pins and works on 3.3V, the other 12 pins and 5V. Both server and client Arduino applications communicate fine with a Windows 10 computer, while with a Linux Ubuntu computer only the server works fine, but the client doesn't since i don't see any incoming packets. For now I don't know why, but that's not a big issue now for me.