Pages: 1 [2]   Go Down
Author Topic: about connecting to Arduino Server with Ethernet through Processing  (Read 861 times)
0 Members and 1 Guest are viewing this topic.
Emsworth, UK
Offline Offline
Full Member
***
Karma: 6
Posts: 181
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@MikeLou

I don't do Java and Processing but managed to teach myself enough of it in my lunch break today to knock out a simple interface.

So here is the Arduino sketch, throttled to drive the GUI at 25 FPS.

Code:
#include <Streaming.h>

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

//#define _DEBUG

byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 };
IPAddress ip(192, 168, 200, 64);
EthernetUDP udp;

void setup()
{
Serial.begin(9600);
Ethernet.begin(mac);
}

typedef struct DCB {
int pinA0;
int pinA1;
int pinA2;
int pinA3;
int pinA4;
int pinA5;
uint32_t timeStamp;
char stringData[32];
byte endData;
} DCB;

uint32_t period = 0L;
uint32_t periodStart = 0L;

void loop()
{
periodStart = millis();

DCB* dcbData = (DCB*) malloc(sizeof(DCB));

dcbData->pinA0 = analogRead(A0);
dcbData->pinA1 = analogRead(A1);
dcbData->pinA2 = analogRead(A2);
dcbData->pinA3 = analogRead(A3);
dcbData->pinA4 = analogRead(A4);
dcbData->pinA5 = analogRead(A5);
dcbData->timeStamp = millis();

strcpy(dcbData->stringData, "Matt's Uno\r\n\0");
dcbData->endData = 0;

period += millis() - periodStart;
if (period >= 40) {

udp.begin(2000);
udp.beginPacket(ip, 2000);
udp.write( (byte*) dcbData, sizeof(DCB) );
udp.endPacket();
udp.stop();

period = 0;
};
free(dcbData);
}

Processing sketch in the next post
« Last Edit: November 25, 2013, 01:00:15 pm by MattS-UK » Logged

Emsworth, UK
Offline Offline
Full Member
***
Karma: 6
Posts: 181
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The Processing 2 Sketch
Displays Arduino analog pin values, Voltages and a bar graph.

I got the hypermedia.net library from here
http://ubaa.net/shared/processing/udp/udp.zip

As you can see in the code, I had to do a bit of gymnastics to work around Java's signed data types and my Mac's little endianess.  It should work on Windows without modification but I have only tested on a Mac.

Code:
/*  Arduino Monitor 1
  Matt S 25/11/2013
  A first venture in Java and Processing
  Sketch to recieve Arduino DCB
  sent in UDP datagram.
*/
  
import hypermedia.net.*;
import java.nio.ByteOrder;

class DCB {
  int pinA0 =0;
  int pinA1 =0;
  int pinA2 =0;
  int pinA3 =0;
  int pinA4 =0;
  int pinA5 =0;
  long timeStamp =0;
  String stringData;
  byte endData;

 // convert Arduino 10 bit analog int to Java signed int
  private int dcbShortToInt(byte dcbData[], int offset, boolean littleEndian) {
    int rawPinValue = 0;
    if (littleEndian) {
      rawPinValue = dcbData[offset +1] << 8;
      rawPinValue += dcbData[offset] & 0x00FF;
    }
    else {
      rawPinValue = (short) dcbData[offset] & 0x3ff;
    }
    return rawPinValue;
  };
  
  //default to little Endian
  private int dcbShortToInt(byte dcbData[], int offset) {
    return dcbShortToInt(dcbData, offset, true);
  };
  
 // convert Arduino 32 bit unsigned long to Java 64 bit long
  private long dcbULongToLong(byte dcbData[], int offset, boolean littleEndian) {
    Integer rawValue =0;
    
    if (littleEndian) {
      rawValue = dcbData[12 +3] << 24;
      rawValue += (dcbData[12 +2] & 0x00FF) << 16;
      rawValue += (dcbData[12 +1] & 0x00FF) << 8;
      rawValue += dcbData[12] & 0x00FF;
    }
    else {
      rawValue = dcbData[12] << 24;
      rawValue += (dcbData[12 +1] & 0x00FF) << 16;
      rawValue += (dcbData[12 +2] & 0x00FF) << 8;
      rawValue += dcbData[12 +3] & 0x00FF;
    }
    
    return rawValue;
  };
  
  //default to little Endian
  private long dcbULongToLong(byte dcbData[], int offset) {
    return this.dcbULongToLong(dcbData, offset, true);
  }
 
 //constructor does the platform conversion  
  public DCB(byte[] data, boolean littleEndian)  {

    pinA0 = dcbShortToInt(data, 0, littleEndian);
    pinA1 = dcbShortToInt(data, 2, littleEndian);
    pinA2 = dcbShortToInt(data, 4, littleEndian);
    pinA3 = dcbShortToInt(data, 6, littleEndian);
    pinA4 = dcbShortToInt(data, 8, littleEndian);
    pinA5 = dcbShortToInt(data, 10, littleEndian);

    timeStamp = dcbULongToLong(data, 12, littleEndian);
    
    String cString = new String(data, 16, 32);
    stringData = new String(cString.substring(0, cString.indexOf('\0')));
    
    endData = data[16 + 32];
  };
};

/* GLOBALS */
//Arduino analog voltage conversion factor (5 / 1024);
static float vFac = .0048828;

//endianess of running platform
boolean sysLittleEndian;

// IP and port to bind to
String HOST_IP = null;   //listen on all network interfaces
int PORT_RX = 2000;      //Arduino must send to this destination Port.

String udpData;  //byte buffer for the raw datagram
DCB dcb;         // class to convert datagram to something more useful
UDP udp;         // UDP socket object

//initialise the application
void setup(){
  sysLittleEndian = ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
  
  //bind to UDP port  
  udp= new UDP(this, PORT_RX);
  udp.listen(true);

  //Window extents
  size (320, 200);
}

//draw the window
void draw(){
  float textTop = 20;
  float lineHeight = 15;
  float pinTextMargin = 20;
  float voltTextMargin = 100;
    
  float barMargin = 200;
  float barWidth = 100;
  float barHeight = lineHeight -5;
  float hFac = barWidth / (float) 1023;
  
  int lineNum = 0;
  background(51);

 if (dcb != null) {
  
   lineNum = 0;
   text("Name: " + dcb.stringData, pinTextMargin, textTop + (lineHeight * lineNum));
  
   lineNum = 1;
   text("Uptime: " + String.format("%.3f ms", (float) dcb.timeStamp / 1000), pinTextMargin, textTop + (lineHeight * lineNum));
  
   lineNum = 2;  
   text("A0 " + dcb.pinA0, pinTextMargin, textTop + (lineHeight * 2));
   text (String.format("%.2f Volts", (dcb.pinA0 * vFac)), voltTextMargin, textTop + (lineHeight *lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - (textAscent() * 0.75 ) , hFac * dcb.pinA0, barHeight);
  
   lineNum = 3;
   text("A1 " + dcb.pinA1, pinTextMargin, textTop + (lineHeight * lineNum));
   text (String.format("%.2f Volts", (dcb.pinA1 * vFac)), voltTextMargin, textTop + (lineHeight * lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - ( textAscent() * 0.75 ), hFac * dcb.pinA1, barHeight);
  
   lineNum = 4;
   text("A2 " + dcb.pinA2, pinTextMargin, textTop + (lineHeight *lineNum));
   text ( String.format("%.2f Volts", (dcb.pinA2 * vFac)), voltTextMargin, textTop + (lineHeight * lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - ( textAscent() * 0.75 ), hFac * dcb.pinA2, barHeight);
        
   lineNum = 5;
   text("A3 " + dcb.pinA3, pinTextMargin, textTop + (lineHeight *lineNum));
   text ( String.format("%.2f Volts", (dcb.pinA3 * vFac)), voltTextMargin, textTop + (lineHeight * lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - ( textAscent() * 0.75 ), hFac * dcb.pinA3, barHeight);
  
   lineNum = 6;
   text("A4 " + dcb.pinA4, pinTextMargin, textTop + (lineHeight *lineNum));
   text ( String.format("%.2f Volts", (dcb.pinA4 * vFac)), voltTextMargin, textTop + (lineHeight * lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - ( textAscent() * 0.75 ), hFac * dcb.pinA4, barHeight);
  
   lineNum = 7;
   text("A5 " + dcb.pinA5, pinTextMargin, textTop + (lineHeight *lineNum));
   text ( String.format("%.2f Volts", (dcb.pinA5 * vFac)), voltTextMargin, textTop + (lineHeight * lineNum));
   rect(barMargin, (textTop + (lineHeight *lineNum)) - ( textAscent() * 0.75 ), hFac * dcb.pinA5, barHeight);
 }
}

//callback for UDP DataAvailable event
void receive(byte[] data, String HOST_IP, int PORT_RX){
  dcb = new DCB(data, sysLittleEndian);
}

« Last Edit: November 25, 2013, 01:02:25 pm by MattS-UK » Logged

0
Offline Offline
Tesla Member
***
Karma: 115
Posts: 8932
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Which bit of,  "I would not say one is better than the other."  Did you not understand?

Then what was the point of the other rambling like "You are entitled to your opinion but I personally think HTTP is a rubbish protocol to use for swapping a few bytes with a micro-controller." ?  smiley-wink

Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Emsworth, UK
Offline Offline
Full Member
***
Karma: 6
Posts: 181
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote from: zoomkat
Then what was the point of the other rambling like "You are entitled to your opinion but I personally think HTTP is a rubbish protocol to use for swapping a few bytes with a micro-controller." ?  smiley-wink

The paragraphs which followed my assertion support the assertion.  I defined a cost/benefit of HTTP implementation and outlined some less costly alternatives.  Describing what I said as rambling is ad-hominem. A worthless attack on the person, rather than their argument.  Which leads me to think you did not try to understand what I said the first time and so, are unlikely to understand it a second time.

In view of it having taken me whole minutes to produce the MCU code to swap a few bytes, with negligible impact on SRAM and CPU, I think the onus is on you to explain how wrapping those bytes in HTTP would be anything but a rubbish way to meet a similar requirement.
Logged

0
Offline Offline
Tesla Member
***
Karma: 115
Posts: 8932
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The paragraphs which followed my assertion support the assertion.

Then you finally concluded:

Quote
"I would not say one is better than the other."/quote]

 smiley-cool
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Emsworth, UK
Offline Offline
Full Member
***
Karma: 6
Posts: 181
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The paragraphs which followed my assertion support the assertion.

Then you finally concluded:

Quote
"I would not say one is better than the other."

 smiley-cool


I concluded.

Quote from: matt-s
An appropriate choice, very much depends on the usage case and application requirements.

Logged

Pages: 1 [2]   Go Up
Jump to: