Ethernet and UDP?

Hello people,

I am new here and to Arduino and have some questions about setting up Ethernet and UDP.

I want to send data from an analog pin down an Ethernet cable to my computer. I will then use this data in Max/MSP using the "UDP receive" object.

I am using the official Arduino Ethernet shield (W5100). Am I correct in assuming that I don't need to be connected to the internet to set up network in this way?

I have been looking through example code and have got so far but all of the projects I have found so far are about publishing data to web pages. Al of this extra code for the web page stuff is confusing me. I know it's missing a lot but I have this so far

#include <SPI.h>
#include <Ethernet.h>
#define LAZER 2           //LAZER connected to digital pin 2
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
byte mac[] = { 0x90, 0xA2, 0XDA, 0X00, 0X4B, 0X9F}; //mac address of my ethernet shield
byte ip[] = { 188, 28, 134, 164}; //ip address of my computer
Server server(80);

void setup(void) 
{
  Ethernet.begin(mac, ip);
  pinMode(LAZER, OUTPUT);
  Serial.begin(9600);
    
}
 
void loop(void) {
  digitalWrite(LAZER, HIGH);
  photocellReading = analogRead(photocellPin);  
 
  Serial.print("Analog reading = ");
  Serial.println(photocellReading);     // the raw analog reading
 
 
  delay(100);
}

I have tried the code below from the UDP tutorial but get this error when compiling:
sketch_may25a:23: error: 'UDP' does not name a type

Can anyone help me send the analog pin data via Ethernet into Max/MSP?

#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008


// 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 };
byte ip[] = { 
  192,168,1,177 };

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

// the next two variables are set when a packet is received
byte remoteIp[4];        // holds received packet's originating IP
unsigned int remotePort; // holds received packet's originating port

// 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

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

void setup() {
  // start the Ethernet and UDP:
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.available(); // note that this includes the UDP header
  if(packetSize)
  {
    packetSize = packetSize - 8;      // subtract the 8 byte header
    Serial.print("Received packet of size ");
    Serial.println(packetSize);

    // read the packet into packetBufffer and get the senders IP addr and port number
    Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, remotePort);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    Udp.sendPacket( ReplyBuffer, remoteIp, remotePort);
  }
  delay(10);
}

The Arduino side of the current UDPSendReceiveString example does not have a line that says "UDP Udp;". I think it is a singleton: an object of which there is only one instance. Try starting with the example again.

Thanks for the quick response John,

do yo mean for me to remove the ine that says "UDP Udp;" and then compile the sketch?

TomSlater:
do yo mean for me to remove the ine that says "UDP Udp;" and then compile the sketch?

Yes, since that seems to be the only difference between what you have and what came with Arduino0022.

OK John I see now.

The difference occurred because I pasted the code from this online tutorial http://arduino.cc/en/Tutorial/UDPSendReceiveString

I didn't realise that this example was included with the Arduino software, a silly mistake.

Does this mean that there is an error in the online tutorial?

Thanks very much for your help.

It looks like the online example is out of date, possibly based on an older library.

OK gettng there! So this is what I have now. The data from the photocell is appearing in the serial monitor. Do you know how I get that same photocell data down my Ethernet cable? I'm sure I'm just missing one or two lines of code here...

#define LAZER 2           //LAZER connected to digital pin 2
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
#include <SPI.h>         
#include <Ethernet.h>
#include <Udp.h>         


byte mac[] = {  
  0x90, 0xA2, 0xDA, 0x00, 0x4B, 0x9F };  //MAC address of my Ethernet shield
byte ip[] = { 
  188,28,134,164 };  //ip address of my computer

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

// the next two variables are set when a packet is received
byte remoteIp[4];        // holds received packet's originating IP
unsigned int remotePort; // holds received packet's originating port

// 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


void setup() {
  
  pinMode(LAZER, OUTPUT);
  Ethernet.begin(mac,ip);
  Serial.begin(9600);
  Udp.begin(localPort);  // start the Ethernet and UDP:

  Serial.begin(9600);
}

void loop() {
  digitalWrite(LAZER, HIGH);  //turn on LAZER
  photocellReading = analogRead(photocellPin);
   Serial.print("Analog reading = ");
  Serial.println(photocellReading);  
  
  // if there's data available, read a packet
  int packetSize = Udp.available(); // note that this includes the UDP header
  if(packetSize)
  {
    packetSize = packetSize - 8;      // subtract the 8 byte header
    Serial.print("Received packet of size ");
    Serial.println(packetSize);

    // read the packet into packetBufffer and get the senders IP addr and port number
    Udp.readPacket(packetBuffer,UDP_TX_PACKET_MAX_SIZE, remoteIp, remotePort);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    Udp.sendPacket( ReplyBuffer, remoteIp, remotePort);
  }
  delay(10);
}

It looks like the Open Sound Control protocol would be appropriate for your use:

That covers the MaxMSP side. You just have to figure out the format of an appropriate OSC packet.

Or you could use an existing OSC library to format and send the UDP packet:
http://recotana.com/recotanablog/closet

According to the comments in your code, it appears you are setting the Arduino's IP address to the same as your computer's. That will create problems on your network. Your Arduino's IP address should be one that is not being used by another device on your subnet. Same goes for the MAC but it probably is unique enough already.

Thanks,

I think I need to initialise remotePort and remoteIp with the ip address and port number on my computer, I'm confused how to do this. Also do I have the "photocell reading" in the right place to send to the computer?

#define LAZER 2           //LAZER connected to digital pin 2
int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider
#include <SPI.h>         
#include <Ethernet.h>
#include <Udp.h> 
Server server(80);



byte mac[] = {  
  0x90, 0xA2, 0xDA, 0x00, 0x4B, 0x9F };  //MAC address of my Ethernet shield
byte ip[] = { 
  188,28,134,164 };  //ip address of my computer

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

// the next two variables are set when a packet is received
byte remoteIp[4];        // holds received packet's originating IP
unsigned int remotePort; // holds received packet's originating port

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


void setup() {
  

  pinMode(LAZER, OUTPUT);
  Ethernet.begin(mac,ip);
  server.begin();
  Serial.begin(9600);
  Udp.begin(localPort);  // start the Ethernet and UDP:

  Serial.begin(9600);
}

void loop() {
  digitalWrite(LAZER, HIGH);  //turn on LAZER
  photocellReading = analogRead(photocellPin);
  
  
  {
    

    Udp.sendPacket( ReplyBuffer, remoteIp, remotePort);
  }
  delay(10);
}

Correct, remoteIP and remotePort should be set to your computer's IP and the port that your computer is listening on but

byte ip[] = { 
  188,28,134,164 };  //ip address of my computer
Ethernet.begin(mac,ip);

requires a unique IP for your subnet, not your computer's IP.

I'm even more confused now. If I run the ifconfig command in terminal it tells me my ip address is one thing and if I look in system pref>network have another 2 different ip addresses: One for my air port and another for my built in ethernet as well as a subnet mask

I want to send data down the Ethernet cable not wireless, so do I need to use the "self assigned" ip address and subnet mask that is displayed in my system pref>network> window?

I've switch to this example it seems simpler

#include <SPI.h>
#include <Ethernet.h> // version IDE 0022

#include <Z_OSC.h>

byte myMac[] = { 0x90, 0xA2, 0xDA, 0x00, 0x4B, 0x9F };//This is the Mac address of my ethernet sheild
byte myIp[]  = { 192, 168, 0, 255 };//how do I find the unique IP for my subnet?

byte destIp[] =  { 169, 254, 139, 32 };//This this the ip address of my computer's builtin ethernet?
int  destPort = 10000;



char oscAdr[] = "/z-osc/test/123";
char oscAdr2[] = "/z-osc/test2/abc";

int      iCount  = 0;     
long int liCount = 0;      
float    fCount  = 0.0;    
char     str[]   = "abcd"; 

Z_OSCClient client;

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

  Ethernet.begin(myMac ,myIp);  
  
}

void loop(){
  
  sendProcess();
  
  Z_OSCMessage mes;  
  
  mes.setAddress(destIp,destPort);
  mes.setZ_OSCMessage(oscAdr2 ,"s" ,"test test");
  
  client.send(&mes);
  
  mes.flush();  
  
  delay(100);
}


void sendProcess(){
  
   
  long int tmp=(long int)iCount; 
  
  Z_OSCMessage message;  
  
  message.setAddress(destIp,destPort);
  message.setZ_OSCMessage(oscAdr ,"iifs" ,&tmp ,&liCount ,&fCount ,str);
  
  client.send(&message);


  if(iCount++  > 1000)  iCount =0;
  if(liCount++ > 1000)  liCount=0;
  fCount += 0.1;
  if(fCount  > 100.0) fCount =0.0;
  
}

Read over Ethernet - Arduino Reference.

Your Airport IP is most likely your gateway, DHCP & DNS IP. In your code, destIp should be your computer's builtin ethernet IP, myIp should be an IP address that is not in use by any other device on your network. I have no idea what your network looks like so I can't say what IP will be unused. Try using the ping command in terminal to see if you get any replies before using a random IP for myIp.

On most home networks, your subnet is 255.255.255.0. That means all the devices on your network will share the same first 3 octets, only the last octet in the IP address will change. For example, if the router/gateway IP address is 192.168.0.1, then your computer IP should be 192.168.0.x, and your Arduino's IP should be 192.168.0.x (different than the computer, where 'x' means a number from 2 - 254, 255 is reserved for broadcast msgs). I can't guarantee that your network is like I just described. Run ifconfig, you probably have a connection named eth0, note what it's inet addr and mask are. That is your computer's IP address and your network's subnet mask. Usually, all devices on the same network have the same subnet mask.

If the IP addresses in your code are the actually addresses you are trying to use, you will have problems. destIp looks like a randomly selected IP due to a lack of a DHCP server, usually also with a 255.255.0.0 subnet. With those IPs, your arduino and computer will not be able to communicate.

I want to send data from an analog pin down an Ethernet cable to my computer.

If you are connecing directly to your computer are you using an ethernet crossover cable?

If you are connecing directly to your computer are you using an ethernet crossover cable?

That's a new one on me!! As far as I know its a standard cable, do I need a cross over cable?

Maybe you should describe what your network looks like. Router? Switch? Cabling? How is it all connected?

That's a new one on me!! As far as I know its a standard cable, do I need a cross over cable?

How would I know without knowing how you are trying to connect the arduino to your pc. :roll_eyes:

How would I know without knowing how you are trying to connect the arduino to your pc. smiley-roll-blue

Sorry...I am trying to connect directly to my Mac :blush:

Maybe you should describe what your network looks like. Router? Switch? Cabling? How is it all connected?

It's a basic domestic set up....

I have a wireless o2 router,
I am connected to that via the air port on my mac
and I am plugging the Arduino directly into the ethernet socket on my Mac

My airport settings tell me that "AirPort is connected to Mash up and has the IP address 192.168.1.64."

When I plug the Arduino into the ethernet socket my ethernet setting tell me "Ethernet has a self-assigned IP address and will not be able to connect to the Internet". an the ip address is 169.254.139.32.

And finally when I go to a site called http://www.ip-adress.com/ it tells me my ip address is 188.222.96.25

Not familiar with how macs work. If you have a router, plug the arduino into the router and things may be easier to use.