ENC28J60 Ethernet LAN

:cold_sweat: buenas, he adquirido el ENC28J60 Ethernet LAN
y estoy tratando de hacerlo funcionar con el Processing.

hasta ahora he podido que el arduino sirva de servidor y
el Processing de cliente. funciona.

el problema es ahora que quiero que el arduino sea el cliente
y el Processing servidor. pero no se que puede estar mal. Alguna sugerencia ???
estoy usando la libreria que propicia el vendedor para la placa Aqui: http://www.geeetech.com/Documents/ENC28J60%20library.rar, tiene unos ejemplos donde se puede poner en modo clinte el arduino.

deben eliminar la libreria Ethernet, que traee por defecto el arduino, sino se crea un complito con esta libreria.

#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 42, 42 };
byte server[] = { 192, 168, 42, 1 };

Client client(server,1234);

void setup() {
  Ethernet.begin(mac, ip);
  Serial.begin(9600);
  
  delay(1000);
  Serial.println("connecting...");
  
  if (client.connect()) {
    Serial.println("connected");
    client.println("GET /search?q=arduino HTTP/1.0");
    client.println();
  }
  else {
    Serial.println("connection failed");
  }
}

void loop() {
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }
  
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    for(;;)
      ;
  }
}

en cuento al Processing. estoy usando los ejemplos que traee por defecto para network;

/**
 * Chat Server 
 * by Tom Igoe. 
 * 
 * Press the mouse to stop the server.
 */
 

import processing.net.*;

int port = 1234;
boolean myServerRunning = true;
int bgColor = 0;
int direction = 1;
int textLine = 60;

Server myServer;

void setup()
{
  size(400, 400);
  textFont(createFont("SanSerif", 16));
  myServer = new Server(this, port); // Starts a myServer on port 10002
  background(0);
}

void mousePressed()
{
  // If the mouse clicked the myServer stops
  myServer.stop();
  myServerRunning = false;
}

void draw()
{
  if (myServerRunning == true)
  {
    text("server", 15, 45);
    Client thisClient = myServer.available();
    if (thisClient != null) {
      if (thisClient.available() > 0) {
        text("mesage from: " + thisClient.ip() + " : " + thisClient.readString(), 15, textLine);
        textLine = textLine + 35;
      }
    }
  } 
  else 
  {
    text("server", 15, 45);
    text("stopped", 15, 65);
  }
}

En Processing apenas he visto algo. Lo siento.

buenas, he tenido que dar uno pasos a tras.
he observado que tanto la libreria que dispone por defaut arduino y la libreria
que uso para esta placa ENC28J60 Ethernet LAN, en cuento
a la programacion son iguales, es decir la estructura y la funciones son =.

en el ejemplo de arduino ,

Servidor Chat

Un simple servidor que distribuye cualquier mensaje entrante a todos los clientes conectados. Para usarlo realizar un telnet al 10.0.0.177 y escribir. Cualquier mensaje será enviado a todos los clientes conectados (incluyendo al que está escribiendo)

Circuito

Una placa Arduino con Arduino Ethernet Shield. El shield debería estar conectado a la red con un cable ethernet. Necesitarás cambiar la configuración de la red con el programa que corresponda para tu red.

Código

#include <Ethernet.h>

// Configuración de la red. El Gateway y subred son opcionales
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };
byte gateway[] = { 10, 0, 0, 1 };
byte subnet[] = { 255, 255, 0, 0 };

// telnet al puerto por defecto 23
Server server(23);

void setup()
{
  // inicializa el dispositivo ethernet
  Ethernet.begin(mac, ip, gateway, subnet);

  // inicia la escucha de los clientes
  server.begin();
}

void loop()
{
  Client client = server.available();
  if (client) {
    server.write(client.read());
  }
}

he utilizado el programa putty para el tenet.
resulta que supestamente me deberia devolver lo mismo que le envio,
pero nada. luego me sale un error como este.

alguna idea ??

No tengo idea de estas shields pero veo algo un poco raro para una red domestica el primer eje,plo lo tienes en 192.168.42 mientras el segundo en una 10.0.0. Usas puertos un poco raros 1234. Y luego la masxcarw de red 255.255.0.0 . DYo revisaría firewalls y hasta antivirus...

si los firewalls, estan bien, de hecho he probado el ejemplo
del serverwed y me tira bien con el programa putty-
pero el otro ejemplo nada.

Perdon, lo tengo configurado al arduino como server.

la libreria ethernet, tiene un periodo en que se cierra automaticamente la comunicacion?

poque por ejemplo envio desde el Processing, un paquete de datos, y los resibe bien, pero cuando termina
el envio luego le envio otro dato y me da error, como se cerraria la comunicacion.

java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
at processing.net.Client.write(Unknown Source)
at processing.net.Client.write(Unknown Source)
at HTTPClient.EN(HTTPClient.java:60)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)

COde Arduino

/*
 * Chat Server
 *
 * A simple server that distributes any incoming messages to all
 * connected clients.  To use telnet to 10.0.0.177 and type!
 */

#include <Ethernet.h>

// network configuration.  gateway and subnet are optional.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 0, 0, 177 };


// telnet defaults to port 23
Server server(1234);

void setup()
{
  // initialize the ethernet device
  Ethernet.begin(mac, ip);
  
  // start listening for clients
  server.begin();
 Serial.begin(9600);
}

void loop()
{
  Client client = server.available();
  if (client) {
   char c = client.read();
   Serial.println(c);
  }
}
 * HTTP Client. 
 * 
 * Starts a network client that connects to a server on port 80,
 * sends an HTTP 1.0 GET request, and prints the results. 
 *
 * Note that this code is not necessary for simple HTTP GET request:
 * Simply calling loadStrings("http://www.processing.org") would do
 * the same thing as (and more efficiently than) this example.
 * This example is for people who might want to do something more 
 * complicated later.
 */
 

import processing.net.*;

Client c;
String data;
import controlP5.*;

ControlP5 controlP5;
void setup() {
  size(200, 200);
  background(50);
  fill(200);
  controlP5 = new ControlP5(this);
  c = new Client(this, "10.0.0.177", 1234); // Connect to server on port 80
  c.write("GET / HTTP/1.0\r\n"); // Use the HTTP "GET" command to ask for a Web page
  controlP5.addButton("EN",0,100,100,80,19);
}

void draw() {
  
}

public void EN(int theValue) {
  println("a button event from buttonA: "+theValue);
  c.write("GET"); 
  
  
}

COMO PUEDO CONFIGURARLO COMO UN PUERTO SERIAL??
solo quiero enviar y recivir datos

Con Proccesing? No tengo ni idea, nunca lo he usado.

haber si me pueden ayudar.

he usado la libreria http://blog.thiseldo.co.uk/wp-filez/EtherShield_1.6.zip, en unos de los ejemplos
hace referencia el envio y recesion de paquetes UDP.

lo he conectado con el processing y parece prometedor con lo que desea hacer.
el problema es que no se bien como se envia datos desde el arduino.
usa una codificacion que poco y nada entiendo.
si alguien mas idoneo me puede explicar o simplificarlo.

en segundo termino, simpre que se quiere enviar , se debe parar "la comunicaion"., algo asi como la
funcion Client.stop(). como puedo enviar de forma continua ??

/*
  Processing sketch to run with this example
 =====================================================
 
 // Processing UDP example to send and receive string data from Arduino
 // press any key to send the "Hello Arduino" message
 
 
 import hypermedia.net.*;
 
 UDP udp;  // define the UDP object
 
 
 void setup() {
 udp = new UDP( this, 6000 );  // 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       = "192.168.1.177"; // the remote IP address
 int port        = 8888;        // the destination port
 
 udp.send("Hello World", 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();  
 }
 */
/*
 * Arduino ENC28J60 Ethernet shield UDP broadcast client
 */
#include "EtherShield.h"

// Note: This software implements a web server and a web browser.
// The web server is at "myip" 
// 
// Please modify the following lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
static uint8_t mymac[6] = {
  0x54,0x55,0x58,0x10,0x00,0x25};

static uint8_t myip[4] = {
  192,168,1,25};

static uint8_t broadcastip[4] = {
  192,168,1,255};

// Port 52240
#define DEST_PORT_L  0x10
#define DEST_PORT_H  0xCC

const char iphdr[] PROGMEM ={
  0x45,0,0,0x82,0,0,0x40,0,0x20}; // 0x82 is the total

struct UDPPayload {
  uint32_t time;            // Time
  uint16_t temperature;     // Temp in 1/10 degree
  uint16_t data[10];        //watts data
  uint16_t errorCount;      // count of errors in the XML.
  uint16_t timeout_count;   // count of all protocol lockups
};

UDPPayload udpPayload;
uint8_t  srcport = 11023;

// Packet buffer, must be big enough to packet and payload
#define BUFFER_SIZE 150
static uint8_t buf[BUFFER_SIZE+1];

EtherShield es=EtherShield();
uint32_t lastUpdate = 0;

void setup(){

  // Initialise data in the payload structure
  for( int i=0; i<10; i++ ) {
    udpPayload.data[i] = i;
  }
  udpPayload.time = millis();
  udpPayload.temperature = 0;

  /*initialize enc28j60*/
  es.ES_enc28j60Init(mymac);

  //init the ethernet/ip layer:
  es.ES_init_ip_arp_udp_tcp(mymac,myip, 80);

  lastUpdate = millis();

  delay(10000);
}

void loop(){
  uint16_t dat_p;

  while(1){
    // handle ping and wait for a tcp packet
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));

    if( lastUpdate < (millis() - 10000) ) {
      // time to send broadcast
      // Update the data to make it different each time
      udpPayload.time = millis();
      udpPayload.temperature++;
      for( int i=0; i<10; i++ ) {
        udpPayload.data[i]++;
      }
      broadcastData() ;
      lastUpdate = millis();
    }
  }
}

// Broadcast the data in the udpPayload structure
void broadcastData( void ) {
  uint8_t i=0;
  uint16_t ck;
  // Setup the MAC addresses for ethernet header
  while(i<6){
    buf[ETH_DST_MAC +i]= 0xff; // Broadcsat address
    buf[ETH_SRC_MAC +i]=mymac[i];
    i++;
  }
  buf[ETH_TYPE_H_P] = ETHTYPE_IP_H_V;
  buf[ETH_TYPE_L_P] = ETHTYPE_IP_L_V;
  es.ES_fill_buf_p(&buf[IP_P],9,iphdr);

  // IP Header
  buf[IP_TOTLEN_L_P]=28+sizeof(UDPPayload);
  buf[IP_PROTO_P]=IP_PROTO_UDP_V;
  i=0;
  while(i<4){
    buf[IP_DST_P+i]=broadcastip[i];
    buf[IP_SRC_P+i]=myip[i];
    i++;
  }
  es.ES_fill_ip_hdr_checksum(buf);
  buf[UDP_DST_PORT_H_P]=DEST_PORT_H;
  buf[UDP_DST_PORT_L_P]=DEST_PORT_L;
  buf[UDP_SRC_PORT_H_P]=10;
  buf[UDP_SRC_PORT_L_P]=srcport; // lower 8 bit of src port
  buf[UDP_LEN_H_P]=0;
  buf[UDP_LEN_L_P]=8+sizeof(UDPPayload); // fixed len
  // zero the checksum
  buf[UDP_CHECKSUM_H_P]=0;
  buf[UDP_CHECKSUM_L_P]=0;
  // copy the data:
  i=0;
  // most fields are zero, here we zero everything and fill later
  uint8_t* b = (uint8_t*)&udpPayload;
  while(i< sizeof( UDPPayload ) ){ 
    buf[UDP_DATA_P+i]=*b++;
    i++;
  }
  // Create correct checksum
  ck=es.ES_checksum(&buf[IP_SRC_P], 16 + sizeof( UDPPayload ),1);
  buf[UDP_CHECKSUM_H_P]=ck>>8;
  buf[UDP_CHECKSUM_L_P]=ck& 0xff;
  es.ES_enc28j60PacketSend(42 + sizeof( UDPPayload ), buf);
}

// End