Knowledgebase
emscom > emscom Help Desk > Knowledgebase

Search help:


Arduino Processing Sketch to receive UDP Device Control Block

Solution

Processing sketch demonstrating receive of a UDP packet containing a device control block.  

The application could be useful as a real-time Arduino monitor.

Processing sketch

/*  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);
}


Arduino Sketch to transmit a matching DCB
 #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);
}

 

 
Was this article helpful? yes / no
Article details
Article ID: 54
Category: Arduino
Date added: 03-01-2014 07:22:48
Views: 2100
Rating (Votes): Article rated 3.4/5.0 (10)

 
« Go back

 
Powered by Help Desk Software HESK, in partnership with SysAid Technologies