tag:blogger.com,1999:blog-54347663421847506622024-03-13T10:50:44.137-07:00Matthew DollMatthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.comBlogger103125tag:blogger.com,1999:blog-5434766342184750662.post-21244347519110643112011-03-17T08:53:00.001-07:002011-03-17T08:53:38.276-07:00New HomeNet BlogI've started a new blog dedicated to HomeNet over at <a href="http://homenetme.blogspot.com/">http://homenetme.blogspot.com/</a>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-45619642624404046792011-02-03T10:32:00.000-08:002011-02-03T10:38:05.157-08:00The Virtual HomeEverything these days is being virtualized so that we can interact with them through our electronic devices. We have virtualized the art of letter writing into email and opening an encyclopedia into searching Wikipedia. We have virtualized ourselves on Facebook, creating a digital representation of ourselves on the internet. We post what we like and dislike about our lives. We list our attributes, what we do, where we live and where we go to school. It's a database of our friends and a history of our lives. In video games we create 3d Avatars that represent our selves as we interact in the virtual world.<br />
<br />
It's only logical to think that one day architecture is going to be virtualized into an electronic form. What will this look like? How do we interact with our home virtually? Who is going to design it?<br />
<br />
These are questions I've been trying to answer over the last few weeks as I start working on building the user interface for HomeNet. Currently, I'm taking the Facebook approach, building a website that allows you to create a virtual profile of your home. The HomeNet website will allow you to create a detailed profile of your home listing all of it's rooms and properties and allow you to view and control all of the smart HomeNet devices you have. You will be able to personalize each page with photos of your house creating a unique personal link to your home. <br />
<br />
I think that the future architect needs to not only design how one physically interacts with the building but also how one interacts with all the electronics and technology the future home will contain. The virtual world is currently dominated by Engineers and Graphic Designers. I think that architects need to get involved so that people have the same quality experience in the virtual building as the do in the physical building. I'm not sure if it's the architects role to design the virtual building but I think that the architect needs to represent the owners interests in it's construction the same way an architect works with a contractor to build a physical building.Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-29561108322036418702011-01-18T10:55:00.000-08:002011-01-18T10:55:41.723-08:00Arduino: The DocumentaryThis is a great video on the history of the Arduino project. <br />
<br />
<iframe src="http://player.vimeo.com/video/18539129?title=0&byline=0&portrait=0" width="400" height="225" frameborder="0"></iframe><p><a href="http://vimeo.com/18539129">Arduino The Documentary (2010) English HD</a> from <a href="http://vimeo.com/gnd">gnd</a> on <a href="http://vimeo.com">Vimeo</a>.</p><br />
It's hard to believe that arduino didn't exist yet when I graduated high school and now it's the key piece I'm using in my Master's ProjectMatthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-76361666721167452102010-12-17T10:16:00.000-08:002010-12-17T10:16:43.627-08:00Half wayWell my thesis has officially reach the half way point with the end of Master Project 1. I presented my work to the school and had a great presentation. I had 11 demo's up and running, 8 based on JeeNode hardware and additional 3 running on Arduino (because I ran out of JeeNodes). In the coming days I'll work on posting photos, details and code demos.<br />
<br />
Currently I'm spending a week relaxing after some stressful finals and working on fixing some minor issues. This week I added better support of interrupts and started experimenting with implementing a sleep cycle to conserve battery. Next up comes rewriting the processing script to match the updated modular Arduino code.Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-7122674498793238152010-11-30T05:29:00.000-08:002010-11-30T05:59:23.282-08:00Google Code SetupWell I finally made the jump and got and my code setup on Google code to start sharing my HomeNet Code. You can also find some documentation on how it all works 1800 lines of code and growing...<br />
<br />
<a href="http://code.google.com/p/homenet/">Google Code: HomeNet</a>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-50183759152062789552010-11-23T02:51:00.000-08:002010-11-23T02:51:36.129-08:00Even More ModularMy last code post simplified things, but many things were hard coded in. These weekend I modularized things so you can choose which network adapters you needs as well as what devices are connected.<br />
<pre>#include <ports.><span style="color: #cc6600;">h</span>>
<span style="color: #7e7e7e;">//#include <portslcd.h></portslcd.h></span>
#include <rf12.><span style="color: #cc6600;">h</span>>
#include <homenet.><span style="color: #cc6600;">h</span>>
<span style="color: #7e7e7e;">//#include <homenetdevices.h></homenetdevices.h></span>
#include <homenetdevicelcd.><span style="color: #cc6600;">h</span>>
<span style="color: #7e7e7e;">//Start HomeNet Packet Stack</span>
HomeNet stack(0x04);<span style="color: #7e7e7e;">//0x01 is RF12 base station //0xFF is PC uplink</span>
<span style="color: #7e7e7e;">//Setup Network Adapters</span>
<span style="color: #7e7e7e;">//HomeNetPortSerial portSerial(PORT_SERIAL, stack); //PORT_SERIAL tells the adpater which serial serial port to use (for future support of the arduino mega)</span>
HomeNetPortRF12 portRF12(stack);
<span style="color: #7e7e7e;">//Setup attached devices</span>
HomeNetDeviceStatusLights statusLights(stack);
<span style="color: #7e7e7e;">//HomeNetDeviceTMP37 tmp37(stack);</span>
<span style="color: #7e7e7e;">//HomeNetDeviceLight light(stack);</span>
HomeNetDeviceLCD lcd(stack);
<span style="color: #7e7e7e;">//package the setup info in a nice neat arrays</span>
HomeNetPort* ports[] = {&portRF12};<span style="color: #7e7e7e;">//,&portSerial}; </span>
HomeNetDevice* devices[] = {&statusLights, &lcd};<span style="color: #7e7e7e;">// &light , &tmp37};</span>
MilliTimer sendTimer;
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>() {
<span style="color: #7e7e7e;">//initize home net with the setup info</span>
stack.init(ports, 1, devices, 2);
stack.registerStatusLights(statusLights); <span style="color: #7e7e7e;">//setup status lights</span>
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>loop</b></span>() {
<span style="color: #7e7e7e;">//receive incoming packets</span>
stack.<span style="color: #cc6600;">receive</span>();
<span style="color: #cc6600;">if</span> (sendTimer.poll(10000)){
<span style="color: #7e7e7e;">// PayloadBuffer buffer;</span>
<span style="color: #7e7e7e;">// buffer.print("TEST NODE 3");</span>
<span style="color: #7e7e7e;">// stack.addUdpPacket(0, 2, 0, CMD_STRING, buffer.payload());</span>
<span style="color: #7e7e7e;">//stack.schedule(2,255,0); //type, toNode, toDevice</span>
}
<span style="color: #7e7e7e;">//process packets in the stack- send packets that ready</span>
stack.process();
<span style="color: #cc6600;">delay</span>(1);
}
</homenetdevicelcd.></homenet.></rf12.></ports.></pre>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-49761808172128396852010-11-18T17:52:00.000-08:002010-11-18T19:46:31.718-08:00More CodeSo the code finally reached a tipping it's time to package the code up into a library. I'm calling it HomeNet because it describes its perfectly it's a new home net work and amazingly enough, there isn't anything going by the name yet.<br />
<br />
Compared to the long mess of code posted before, Moving most of the code to a library really simplified things:<br />
<br />
<pre>#include <<span style="color: #cc6600;">ports.h</span>>
#include <<span style="color: #cc6600;">rf12.h</span>>
#include <<span style="color: #cc6600;">homenet.h</span>>
HomeNet stack(0x04);<span style="color: #7e7e7e;">//start stack with a node id</span>
MilliTimer sendTimer;
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>() {
<span style="color: #7e7e7e;">// put your setup code here, to run once:</span>
stack.init();
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>loop</b></span>() {
<span style="color: #7e7e7e;">// put your main code here, to run repeatedly: </span>
stack.<span style="color: #cc6600;">receive</span>();
<span style="color: #cc6600;">if</span> (sendTimer.poll(2000)){
PayloadBuffer buffer;
buffer.<span style="color: #cc6600;">print</span>(123,<span style="color: #006699;">DEC</span>);
stack.addUdpPacket(0, 255, 2, CMD_BYTE, buffer.payload());
}
stack.process();
}
</pre><br />
and the processing sketch using the library<br />
<pre>import processing.serial.*;
import xmlrpclib.*;
import org.apache.commons.codec.binary.Base64; <span style="color: #7e7e7e;">//part of the xmlrpclib</span>
XmlrpcClient homeNetXmlrpcClient = <span style="color: #cc6600;">new</span> XmlrpcClient(<span style="color: #006699;">"http://matthew.sgcs.usf.edu/mcdportal/public/xmlrpc.php?api_key=dfgdfgdgdgd"</span>);
XmlrpcServer homeNetXmlrpcServer = <span style="color: #cc6600;">new</span> XmlrpcServer(8081);
final <span style="color: #cc6600;">int</span> NODE_ID = 255;
final <span style="color: #cc6600;">int</span> PACKET_TIMEOUT = 150;
PacketStack stack = <span style="color: #cc6600;">new</span> PacketStack(NODE_ID);
<span style="color: #cc6600;"><b>Serial</b></span> myPort; <span style="color: #7e7e7e;">// The serial port</span>
XMLElement xmlConfig;
XMLElement commands[];
XMLElement devices[];
<span style="color: #cc6600;">String</span> findXMLid(XMLElement[] xml , <span style="color: #cc6600;">int</span> value, <span style="color: #cc6600;">String</span> rAttribute){
<span style="color: #cc6600;">String</span> rValue = <span style="color: #006699;">""</span>;
<span style="color: #cc6600;">for</span>(<span style="color: #cc6600;">int</span> a = 0; a<commands.length;a++){ =""><span style="color: #cc6600;">if</span>(unhex(commands[a].getAttribute(<span style="color: #006699;">"id"</span>)) == value){
<span style="color: #cc6600;">return</span> commands[a].getAttribute(rAttribute);
}
}
<span style="color: #cc6600;">return</span> rValue;
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>() {
size(600, 400); <span style="color: #7e7e7e;">// Stage size</span>
<span style="color: #7e7e7e;">//noStroke(); // No border on the next thing drawn</span>
homeNetXmlrpcServer.add(<span style="color: #006699;">"testserver"</span>, <span style="color: #cc6600;">this</span>); <span style="color: #7e7e7e;">//setup server</span>
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"HomeNet XML-RPC Server started at "</span> + homeNetXmlrpcServer.ip()+<span style="color: #006699;">":8081/RPC2"</span>); <span style="color: #7e7e7e;">// Note that /RPC2 is hard-coded to URI in the Apache Library.</span>
textFont(createFont(<span style="color: #006699;">"Consolas"</span>, 14));
<span style="color: #7e7e7e;">//fixedFont);</span>
xmlConfig = <span style="color: #cc6600;">new</span> XMLElement(<span style="color: #cc6600;">this</span>, <span style="color: #006699;">"config.txt"</span>);
devices = xmlConfig.getChildren(<span style="color: #006699;">"devices/device"</span>);
commands = xmlConfig.getChildren(<span style="color: #006699;">"commands/command"</span>);
<span style="color: #7e7e7e;">//load the above as hash table from my sevrer.</span>
<span style="color: #7e7e7e;">// Print a list of the serial ports, for debugging purposes:</span>
<span style="color: #7e7e7e;">//println(Serial.list());</span>
<span style="color: #cc6600;">String</span> portName = <span style="color: #cc6600;"><b>Serial</b></span>.list()[1];
myPort = <span style="color: #cc6600;">new</span> <span style="color: #cc6600;"><b>Serial</b></span>(<span style="color: #cc6600;">this</span>, portName, 115200);
}
<span style="color: #cc6600;">boolean</span> arduinoBoot = <span style="color: #cc6600;">false</span>;
<span style="color: #cc6600;">int</span> count = 0;
<span style="color: #cc6600;">long</span> sendTimer;
<span style="color: #cc6600;">void</span> draw() {
<span style="color: #cc6600;">if</span>(arduinoBoot == <span style="color: #cc6600;">false</span>){
<span style="color: #cc6600;">delay</span>(2500);
sendTimer = <span style="color: #cc6600;">millis</span>();
arduinoBoot = <span style="color: #cc6600;">true</span>;;
}
<span style="color: #cc6600;">if</span>((<span style="color: #cc6600;">millis</span>() - sendTimer) > 2000){
<span style="color: #7e7e7e;">//DataPacket packet = build_udp_packet(NODE_ID,0,3,2,CMD_STRING,str_to_payload("Hello "+count));</span>
<span style="color: #7e7e7e;">//packet.status = STATUS_READY;</span>
sendTimer=<span style="color: #cc6600;">millis</span>();
count++;
}
stack.process();
stack.tempSerialCheck(myPort); <span style="color: #7e7e7e;">//this is temp until I add support for multiple serial ports, and pass a list of ports to the packetStack</span>
}
<span style="color: #cc6600;">void</span> packetEvent(DataPacket packet){
packet.<span style="color: #cc6600;">status</span> = STATUS_CLEAR;
Hashtable <span style="color: #cc6600;">send</span> = <span style="color: #cc6600;">new</span> Hashtable();
<span style="color: #cc6600;">String</span> packetBase64 = <span style="color: #cc6600;">new</span> <span style="color: #cc6600;">String</span>(Base64.encodeBase64(packet.payload));
<span style="color: #cc6600;">send</span>.put(<span style="color: #006699;">"received"</span>,packet.received);
<span style="color: #cc6600;">send</span>.put(<span style="color: #006699;">"packet"</span>, packetBase64);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"Server Reply: "</span>+homeNetXmlrpcClient.execute(<span style="color: #006699;">"HomeNet.addPacket"</span>, <span style="color: #cc6600;">send</span>));
}
<span style="color: #cc6600;">void</span> serialEvent(<span style="color: #cc6600;"><b>Serial</b></span> port) {
stack.buildSerialPacket(port);
}
</commands.length;a++){></pre>Much easier to use now!Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-2639725989378106852010-11-12T13:11:00.000-08:002010-11-30T16:05:14.473-08:00First TestsI finally completed enough of the packet code that I finally test to see if it actually works! and Amazingly enough ti works. Packets can now be sent from a remote wireless node to a receiver and passed to the computer. It also works the other way, data from the computer can be sent to a remote node. I recorded a video but I don't have it up yet.<br />
<br />
Code after the jump<br />
<a name='more'></a><br />
<br />
Arduino Code<br />
packet.h<br />
<pre>#define CMD_ERROR 0x00
#define CMD_VERSION 0x01
#define CMD_BATTERYLEVEL 0x03
#define CMD_PING 0x3E
#define CMD_PONG 0xE3
#define CMD_ACK 0x11
#define CMD_SETNODEID 0x21
#define CMD_GETNODEID 0x21
#define CMD_SETNODEID 0x22
#define CMD_GETPLUG 0x23
#define CMD_SETPLUG 0x24
#define CMD_AUTOSENDSTART 0xC1
#define CMD_AUTOSENDSTOP 0xC2
#define CMD_GETVALUE 0xD0
#define CMD_SETVALUE 0xD1
#define CMD_ON 0xE0
#define CMD_OFF 0xE1
#define CMD_LEVEL 0xE2
#define CMD_BYTE 0xF0
#define CMD_STRING 0xF1
#define CMD_INT 0xF2
#define CMD_FLOAT 0xF3
#define CMD_LONG 0xF4
#define DVC_TMP37 0x01
#define DVC_LIGHT 0x02
#define DVC_SHT21 0x03
#define DVC_DOORCONTACT 0x04
#define DVC_WINDOWCONTACT 0x05
#define DVC_MOTION 0x06
#define DVC_2LINEDISPLAY 0x07
#define DVC_POWER30 0x08
#define DVC_POWER100 0x09
#define DVC_SMARTOUTLET 0x10
#define DVC_RGBLIGHT 0x11
#define DVC_SOUND 0x12
#define DVC_SWITCH 0x13
#define DVC_STATUSLED 0x14
#define DVC_BUZZER 0x15
<span style="color: #7E7E7E;">//decoded packet struct</span>
typedef struct {
uint8_t command;
<span style="color: #7E7E7E;">//if 255 = ready to send // 0 = resend last</span>
uint8_t length;
uint8_t <span style="color: #CC6600;">status</span>;
uint8_t settings; <span style="color: #7E7E7E;">//01010101 //version //type direct or broadcast //ack //ttl //priority //multi</span>
uint8_t type; <span style="color: #7E7E7E;">//1 single tcp, 2 single udp, 3 multipacket tcp</span>
uint16_t fromNode;
uint8_t fromPlug;
uint16_t toNode; <span style="color: #7E7E7E;">//00 is base //xffff is broadcast</span>
uint8_t toPlug;
uint8_t id;
uint8_t ttl;
uint8_t from;
uint8_t payload[48];
uint16_t checksum;
uint8_t ptr;
} DataPacketDecoded;
<span style="color: #7E7E7E;">//simple data packet</span>
typedef struct {
uint8_t ptr;
uint8_t from;
uint8_t <span style="color: #CC6600;">status</span>;
uint8_t payload[56];
uint16_t checksum;
} DataPacket;
<span style="color: #7E7E7E;">//payload type</span>
typedef struct {
uint8_t length;
uint8_t data[56];
} Payload;
<span style="color: #7E7E7E;">//not used yet</span>
typedef struct {
<span style="color: #CC6600;">long</span> start;
uint8_t waiting;
uint8_t ptr;
} ACKStatus;
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;">typedef struct {</span>
<span style="color: #7E7E7E;"> uint8_t type;</span>
<span style="color: #7E7E7E;"> uint8_t status;</span>
<span style="color: #7E7E7E;">} Port;*/</span>
<span style="color: #7E7E7E;">//shortcuts to important bytes</span>
<span style="color: #7E7E7E;">//keeps from having to decode the whole thing to check simple parts</span>
#define PACKET_LENGTH 0
#define PACKET_SETTINGS 1
#define PACKET_FROM 2
#define PACKET_TO 4
#define PACKET_TTL 4
#define PACKET_ID 6
#define PACKET_COMMAND 7
#define PACKET_PAYLOAD 8
<span style="color: #7E7E7E;">//an enum might be better here</span>
#define STATUS_CLEAR 0
#define STATUS_RECEVING 1
#define STATUS_RECEIVED 2
#define STATUS_WAITING 3
#define STATUS_READY 4
#define STATUS_SENDING 5
#define STATUS_SENT 6
#define STATUS_ACK 7
#define STATUS_SUCCESS 8
#define OFFSET_PACKET 10
#define OFFSET_HEADER 8
#define OFFSET_FOOTER 2
</pre>node.pde<br />
<pre>#include <util/crc16.<span style="color: #CC6600;">h</span>> <span style="color: #7E7E7E;">//checksum functions</span>
#include <span style="color: #006699;">"protocol.h"</span>
#include <RF12.<span style="color: #CC6600;">h</span>>
#include <Ports.<span style="color: #CC6600;">h</span>>
<span style="color: #7E7E7E;">//#include <PortsLCD.h></span>
<span style="color: #7E7E7E;">//PortI2C myI2C (2);</span>
<span style="color: #7E7E7E;">//LiquidCrystalI2C lcd (myI2C);</span>
#define NODE_ID 0x04
Port leds (1);
Port light (2);
MilliTimer sendTimer;
#define PLUG_1 DVC_STATUSLED
#define PLUG_2 DVC_2LINEDISPLAY
#define PLUG_3 0
#define PLUG_4 0
#define PACKET_BUFFER 16 <span style="color: #7E7E7E;">//can be adujsted based on available space</span>
#define PACKET_TIMEOUT 150
#define PORT_RF12 1
#define PORT_SERIAL 2
#define PORT_SERIAL1 3
#define PORT_SERIAL2 4
#define PORT_SERIAL3 5
#define PORT_COUNT 2
#define PORT_0 PORTTYPE_SERIAL
#define PORT_1 PORTTYPE_RF12
<span style="color: #7E7E7E;">//#define DEBUG 1</span>
<span style="color: #7E7E7E;">//#define ENABLE_SERIAL 1</span>
#define ENABLE_RF12 1
<span style="color: #7E7E7E;">//#define ENABLE_SERIAL123 </span>
#define PACKET_TCP 1
#define PACKET_UDP 2
#define PACKET_BROADCAST 3
<span style="color: #7E7E7E;">//types</span>
<span style="color: #7E7E7E;">//ACK</span>
<span style="color: #7E7E7E;">//Single TCp //requires 2byte packet ID</span>
<span style="color: #7E7E7E;">//Single UDP</span>
<span style="color: #7E7E7E;">//Multi TCP //requires 2byte total ID, 2 byte Packet ID + byte current packet + byte total packets</span>
<span style="color: #7E7E7E;">//multi packet</span>
<span style="color: #7E7E7E;">//packet id</span>
<span style="color: #7E7E7E;">//current packets</span>
<span style="color: #7E7E7E;">//total packets</span>
<span style="color: #7E7E7E;">//</span>
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;">Port ports[] = {{PORTTYPE_SERIAL,STATUS_CLEAR},</span>
<span style="color: #7E7E7E;"> {PORTTYPE_RF12,STATUS_CLEAR}};</span>
<span style="color: #7E7E7E;">*/</span>
<span style="color: #7E7E7E;">//list attached ports</span>
<span style="color: #7E7E7E;">//1 2 3 4 //rf12</span>
#define COLLECT 0x20 <span style="color: #7E7E7E;">// collect mode, i.e. pass incoming without sending acks</span>
DataPacket data[PACKET_BUFFER];
uint16_t checksum;
<span style="color: #CC6600;">byte</span> uniqueId = 0;
<span style="color: #CC6600;">byte</span> i;
DataPacket incomingPacket; <span style="color: #7E7E7E;">//current incoming packet</span>
DataPacket *sendingPacket;
<span style="color: #7E7E7E;">//probably should break this out by type</span>
<span style="color: #CC6600;">boolean</span> sending = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">boolean</span> receiving = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">long</span> packetTimer;;
DataPacket *getNewPacket() {
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
<span style="color: #CC6600;">if</span>(data[i].<span style="color: #CC6600;">status</span> == STATUS_CLEAR){
data[i].from = 0;
<span style="color: #CC6600;">return</span> &data[i];
}
}
<span style="color: #7E7E7E;">//Serial.println("all full");</span>
<span style="color: #CC6600;">return</span> 0;
}
uint8_t getId()
{
<span style="color: #CC6600;">return</span> uniqueId++; <span style="color: #7E7E7E;">//loops when it overflows</span>
}
uint16_t compressAddress(uint16_t node, uint8_t port)
{
<span style="color: #CC6600;">return</span> (node << 4) | (port & 0x0F);
}
<span style="color: #7E7E7E;">//byte m = 1;</span>
#ifdef ENABLE_SERIAL
<span style="color: #CC6600;">void</span> send_packet_serial(DataPacket *packet)
{
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING PACKET SERIAL"</span>);
#endif
uint16_t dataChecksum = 0;
<span style="color: #CC6600;">for</span>(i=0; i < (packet->payload[PACKET_LENGTH]-OFFSET_FOOTER); i++){
dataChecksum = _crc16_update(dataChecksum, packet->payload[i]);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(packet->payload[i],<span style="color: #006699;">BYTE</span>);
}
packet->checksum = dataChecksum;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">highByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);
<span style="color: #7E7E7E;">// Serial.print(",");</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">lowByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);
packet-><span style="color: #CC6600;">status</span> = STATUS_SENT;
<span style="color: #7E7E7E;">//Serial.println("");</span>
}
#endif
#ifdef ENABLE_RF12
<span style="color: #CC6600;">void</span> send_packet_rf12(DataPacket *packet)
{
<span style="color: #CC6600;">if</span> (rf12_canSend()) { <span style="color: #7E7E7E;">//check if radio is free</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING PACKET RF12"</span>);
#endif
<span style="color: #CC6600;">byte</span> header = (packet->payload[PACKET_SETTINGS] == PACKET_TCP) ? RF12_HDR_ACK : 0;
<span style="color: #7E7E7E;">//Serial.print("Node Header: ");</span>
<span style="color: #7E7E7E;">//Serial.println(header,DEC);</span>
<span style="color: #CC6600;">byte</span> toNode = get_node(packet,PACKET_TO);
<span style="color: #7E7E7E;">//Serial.print("Send to Node: ");</span>
<span style="color: #7E7E7E;">//Serial.println(toNode,DEC);</span>
<span style="color: #CC6600;">if</span> (toNode > 0){
<span style="color: #CC6600;">if</span>(toNode > 32){
toNode = 1;<span style="color: #7E7E7E;">//if port is too high send to basestation to retransmit</span>
}
header |= RF12_HDR_DST | toNode;
}
<span style="color: #7E7E7E;">//rf12 does it's own check sum. no need to waste resources doing it twice</span>
rf12_sendStart(0, packet->payload, packet->payload[PACKET_LENGTH]-OFFSET_FOOTER);
sendLed(1);
<span style="color: #CC6600;">delay</span>(100);
sendLed(0);
packet-><span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
sending = <span style="color: #CC6600;">false</span>;
}
}
#endif
<span style="color: #CC6600;">void</span> process_command(DataPacket *packet)
{
uint8_t plug = get_plug(packet,PACKET_TO);
<span style="color: #CC6600;">if</span>(plug == 0){ <span style="color: #7E7E7E;">//system function</span>
<span style="color: #CC6600;">switch</span> (packet->payload[PACKET_COMMAND]) {
<span style="color: #CC6600;">case</span> CMD_ERROR:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_VERSION:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_BATTERYLEVEL:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_PING:
build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_PONG:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_ACK:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_GETNODEID:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_SETNODEID:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_GETPLUG:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> CMD_SETPLUG:
<span style="color: #7E7E7E;">//build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #CC6600;">break</span>;
}
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(plug == 2){ <span style="color: #7E7E7E;">//system function</span>
<span style="color: #7E7E7E;">/* switch (packet->payload[PACKET_COMMAND]) {</span>
<span style="color: #7E7E7E;"> case CMD_STRING:</span>
<span style="color: #7E7E7E;"> Payload *p = get_payload(packet);</span>
<span style="color: #7E7E7E;"> lcd.setCursor(0, 1);</span>
<span style="color: #7E7E7E;"> // print the number of seconds since reset:</span>
<span style="color: #7E7E7E;"> for(int a = 0; a < p->length; a++){</span>
<span style="color: #7E7E7E;"> lcd.print(p->data[a]);</span>
<span style="color: #7E7E7E;"> }</span>
<span style="color: #7E7E7E;"> break;</span>
<span style="color: #7E7E7E;"> }*/</span>
}
}
#ifdef ENABLE_RF12
<span style="color: #7E7E7E;">//build rf12 packet</span>
DataPacket* receive_rf12(const <span style="color: #CC6600;">void</span>* payload, uint8_t length){
DataPacket* packet = getNewPacket();
memcpy(packet->payload,payload, length);
packet-><span style="color: #CC6600;">status</span> = STATUS_RECEIVED;
packet->from = PORT_RF12;
<span style="color: #CC6600;">return</span> packet;
}
#endif
DataPacket* clonePacket(DataPacket* packet){
DataPacket* packet2 = getNewPacket();
memcpy(packet2,packet, sizeof(packet)) ;
<span style="color: #CC6600;">return</span> packet2;
}
<span style="color: #CC6600;">void</span> build_incoming_packet(uint8_t byteIn)
{
<span style="color: #7E7E7E;">//mark which port it is coming from</span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7E7E7E;">//Packet length</span>
<span style="color: #CC6600;">if</span>(byteIn == 0) { <span style="color: #7E7E7E;">//resend last</span>
sendingPacket-><span style="color: #CC6600;">status</span> = STATUS_SENDING;
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span>(byteIn == 255) { <span style="color: #7E7E7E;">//aknowledge</span>
sendingPacket-><span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span> (byteIn > 128) {
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">flush</span>();
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(0,<span style="color: #006699;">BYTE</span>);
<span style="color: #CC6600;">return</span>;
}
receiving = <span style="color: #CC6600;">true</span>;
packetTimer = <span style="color: #CC6600;">millis</span>();
incomingPacket.payload[PACKET_LENGTH] = byteIn;
incomingPacket.<span style="color: #CC6600;">status</span> = STATUS_RECEVING;
checksum = 0;
}
<span style="color: #7E7E7E;">//checksum </span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr < (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = byteIn;
checksum = _crc16_update(checksum, byteIn);
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(incomingPacket.ptr == (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//get first byte of checksum</span>
incomingPacket.checksum = byteIn;
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> { <span style="color: #7E7E7E;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | (byteIn & 0xFF);
<span style="color: #CC6600;">if</span>(checksum != incomingPacket.checksum) {
DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_ERROR, packet_to_payload(&incomingPacket));
p-><span style="color: #CC6600;">status</span> = STATUS_READY;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">flush</span>();
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(1,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node to resend last</span>
} <span style="color: #CC6600;">else</span> {
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_RECEIVED;
DataPacket *packet = getNewPacket();
incomingPacket.from = PORT_SERIAL;
*packet = incomingPacket;
<span style="color: #7E7E7E;">//Serial.flush();</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(255,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node the packet was successful</span>
}
<span style="color: #7E7E7E;">//reset incomingPacket</span>
receiving = <span style="color: #CC6600;">false</span>;
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_CLEAR;
incomingPacket.ptr = 0;
}
}
<span style="color: #7E7E7E;">//determine where to send packet. how to expand when we have 4 serial ports?</span>
<span style="color: #CC6600;">void</span> process_stack(){
<span style="color: #7E7E7E;">//sending = false; //only send one pack per cycle</span>
<span style="color: #CC6600;">for</span>(i=0;i<PACKET_BUFFER;i++){
process_packet(&data[i]);
}
<span style="color: #7E7E7E;">//check for packets to send</span>
<span style="color: #7E7E7E;">//check for packets to resend if ACKs are late</span>
<span style="color: #7E7E7E;">//check for data packets that can be deleted from the stack </span>
}
<span style="color: #CC6600;">void</span> process_packet(DataPacket *packet){
<span style="color: #CC6600;">switch</span> (packet-><span style="color: #CC6600;">status</span>){
<span style="color: #CC6600;">case</span> STATUS_CLEAR:
#ifdef DEBUG
<span style="color: #7E7E7E;">//Serial.println("CLEAR");</span>
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVING:
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEIVED:
#ifdef DEBUG
debug_packet(packet);
#endif
<span style="color: #CC6600;">if</span>(get_node(packet,PACKET_TO) == NODE_ID){
process_command(packet);
packet-><span style="color: #CC6600;">status</span> = STATUS_CLEAR;
} <span style="color: #CC6600;">else</span> {
packet-><span style="color: #CC6600;">status</span> = STATUS_READY;
}
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEIVED"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_WAITING:
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"WAITING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_READY:
<span style="color: #7E7E7E;">//check for free port</span>
<span style="color: #CC6600;">if</span>(sending == <span style="color: #CC6600;">false</span>){
packet-><span style="color: #CC6600;">status</span> = STATUS_SENDING;
sendingPacket = packet;
sending = <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">//if reset pointer and set to send</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"READY"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENDING:
<span style="color: #7E7E7E;">//because of the above, only one packet will be changed to sending</span>
#if defined(ENABLE_SERIAL) && defined(ENABLE_RF12)
<span style="color: #CC6600;">if</span>(packet->from == 0){ <span style="color: #7E7E7E;">//self generated send to both ports</span>
packet->from = PORT_RF12;
DataPacket *packet2 = getNewPacket();
packet2 = packet;
}
#endif
#ifdef ENABLE_RF12
<span style="color: #CC6600;">if</span>(packet->from != PORT_RF12){
send_packet_rf12(packet);
}
#endif
#ifdef ENABLE_SERIAL
<span style="color: #CC6600;">if</span>(packet->from != PORT_SERIAL){
send_packet_serial(packet);
packet-><span style="color: #CC6600;">status</span> = STATUS_SENT;
}
#endif
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENT:
<span style="color: #7E7E7E;">//if is a ack packet </span>
<span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] == 1){
packet-><span style="color: #CC6600;">status</span> = STATUS_ACK;
<span style="color: #7E7E7E;">//start packets ack timer</span>
} <span style="color: #CC6600;">else</span> {
<span style="color: #7E7E7E;">//packet->status = STATUS_SUCCESS;</span>
}
#ifdef DEBUG
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_ACK:
<span style="color: #7E7E7E;">//if execeded timer resen</span>
<span style="color: #7E7E7E;">//count resends if exceds max kill packet and add error</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SUCCESS:
<span style="color: #7E7E7E;">//option to post status to screen</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_CLEAR;
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SUCCESS"</span>);
#endif
<span style="color: #CC6600;">break</span>;
}
}
<span style="color: #CC6600;">static</span> <span style="color: #CC6600;">void</span> sendLed (<span style="color: #CC6600;">byte</span> on) {
leds.mode(<span style="color: #006699;">OUTPUT</span>);
leds.digiWrite(on);
}
<span style="color: #CC6600;">static</span> <span style="color: #CC6600;">void</span> receiveLed (<span style="color: #CC6600;">byte</span> on) {
leds.mode2(<span style="color: #006699;">OUTPUT</span>);
leds.digiWrite2(!on); <span style="color: #7E7E7E;">// inverse, because LED is tied to VCC</span>
}
<span style="color: #CC6600;">long</span> counter;
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>setup</b></span>()
{
#if defined(ENABLE_SERIAL) || defined(DEBUG)
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">begin</span>(115200);
#endif
#ifdef ENABLE_RF12
rf12_initialize(NODE_ID, RF12_915MHZ, 33);
#endif
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"DEBUGGING MODE"</span>);
#endif
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> lcd.begin(16, 2);</span>
<span style="color: #7E7E7E;"> // Print a message to the LCD.</span>
<span style="color: #7E7E7E;"> lcd.print("Hello, Matthew");</span>
<span style="color: #7E7E7E;"> lcd.backlight();*/</span>
counter = <span style="color: #CC6600;">millis</span>();
sendLed(1);
receiveLed(1);
<span style="color: #CC6600;">delay</span>(500);
sendLed(0);
receiveLed(0);
}
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>loop</b></span>() {
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> if(counter == 100000) {</span>
<span style="color: #7E7E7E;"> Serial.print(availableMemory(),DEC);</span>
<span style="color: #7E7E7E;"> // DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_STRING, str_to_payload("ha ha ha22222"));</span>
<span style="color: #7E7E7E;"> // p->status = STATUS_READY;</span>
<span style="color: #7E7E7E;"> // counter = 0;</span>
<span style="color: #7E7E7E;"> }</span>
<span style="color: #7E7E7E;"> counter++;*/</span>
process_stack();
<span style="color: #7E7E7E;">//recieve timer</span>
#ifdef ENABLE_SERIAL
<span style="color: #7E7E7E;">//and send command to resend last</span>
<span style="color: #CC6600;">int</span> byteIn;
<span style="color: #CC6600;">if</span> (<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">available</span>()>0) {
byteIn = <span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">read</span>();
build_incoming_packet(byteIn);
}
process_stack();
<span style="color: #CC6600;">if</span>(receiving == <span style="color: #CC6600;">true</span>) {
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - packetTimer) > PACKET_TIMEOUT) {
<span style="color: #7E7E7E;">//Serial.flush();</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(2,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node to resend last</span>
<span style="color: #7E7E7E;">//DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_ERROR, packet_to_payload(&incomingPacket));</span>
<span style="color: #7E7E7E;">// p->status = STATUS_READY;</span>
receiving = <span style="color: #CC6600;">false</span>;
}
}
#endif
#ifdef ENABLE_RF12
<span style="color: #CC6600;">if</span> (rf12_recvDone() && rf12_crc == 0) {
<span style="color: #7E7E7E;">// receiveLed(1);</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RF12 Receiving"</span>);
#endif
<span style="color: #CC6600;">if</span> ((rf12_hdr & RF12_HDR_ACK) && !(rf12_hdr & RF12_HDR_CTL) && (NODE_ID & COLLECT) == 0) {
<span style="color: #CC6600;">byte</span> addr = rf12_hdr & RF12_HDR_MASK;
<span style="color: #7E7E7E;">// if request was sent only to us, send ack back as broadcast</span>
rf12_sendStart(rf12_hdr & RF12_HDR_DST ? RF12_HDR_CTL : RF12_HDR_CTL | RF12_HDR_DST | addr, 0, 0);
}
DataPacket *p = receive_rf12((<span style="color: #CC6600;">void</span>*)rf12_data,rf12_len);
<span style="color: #7E7E7E;">//blink led</span>
receiveLed(1);
<span style="color: #CC6600;">delay</span>(100);
receiveLed(0);
}
#endif
<span style="color: #7E7E7E;">//delay(5); </span>
<span style="color: #CC6600;">if</span> (sendTimer.poll(5000)){
light.mode2(<span style="color: #006699;">INPUT</span>);
<span style="color: #CC6600;">byte</span> l = light.anaRead()/4;
DataPacket *p = build_udp_packet(NODE_ID, 0, 3, 2, CMD_BYTE, byte_to_payload(l));
<span style="color: #7E7E7E;">//p->from = PORT_SERIAL;</span>
}
<span style="color: #CC6600;">delay</span>(5);
}
<span style="color: #7E7E7E;">/*FINISHED*/</span>
Payload *get_payload(DataPacket *packet)
{
Payload payload;
payload.length = packet->payload[PACKET_LENGTH] - OFFSET_PACKET;
<span style="color: #CC6600;">for</span>(i=0; i < payload.length; i++){
<span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
payload.data[i] = packet->payload[i+OFFSET_HEADER];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> &payload;
}
Payload *packet_to_payload(DataPacket *packet)
{
Payload payload;
payload.length = packet->payload[PACKET_LENGTH];
<span style="color: #CC6600;">for</span>(i=0; i < (payload.length - OFFSET_FOOTER); i++){
payload.data[i] = packet->payload[i];
}
payload.data[payload.length - OFFSET_FOOTER] = <span style="color: #CC6600;">highByte</span>(packet->checksum);
payload.data[payload.length - OFFSET_FOOTER + 1] = <span style="color: #CC6600;">lowByte</span>(packet->checksum);
<span style="color: #CC6600;">return</span> &payload;
}
uint16_t get_node(DataPacket *packet, uint8_t location)
{
uint16_t node;
node = packet->payload[location];
node = node << 4;
node = node | (packet->payload[location+1] >> 4);
<span style="color: #CC6600;">return</span> node;
}
uint8_t get_plug(DataPacket *packet, uint8_t location)
{
<span style="color: #CC6600;">return</span> (packet->payload[location+1] & 0x0F);
}
Payload *str_to_payload(<span style="color: #CC6600;">char</span> string[])
{
Payload payload;
i=0;
<span style="color: #CC6600;">while</span>(string[i] != 0){
payload.data[i] = <span style="color: #CC6600;">byte</span>(string[i]);
i++;
}
payload.length = i;
<span style="color: #7E7E7E;">//Serial.print("sizeOf: ");</span>
<span style="color: #7E7E7E;">// Serial.println(i,DEC);</span>
<span style="color: #CC6600;">return</span> &payload;
}
Payload *long_to_payload(<span style="color: #CC6600;">long</span> number)
{
Payload payload;
i=(sizeof(number)-1);
payload.length = i;
<span style="color: #CC6600;">while</span>(i != 0){
payload.data[i] = number & 0xFF;
number = number >> 8;
i--;
}
<span style="color: #CC6600;">return</span> &payload;
}
Payload *byte_to_payload(<span style="color: #CC6600;">byte</span> number)
{
Payload payload;
payload.length = 1;
payload.data[0] = number & 0xFF;
<span style="color: #CC6600;">return</span> &payload;
}
Payload *uint16_to_payload(uint16_t number)
{
Payload payload;
payload.length = 2;
payload.data[0] = <span style="color: #CC6600;">highByte</span>(number);
payload.data[1] = <span style="color: #CC6600;">lowByte</span>(number);
<span style="color: #CC6600;">return</span> &payload;
}
DataPacket *build_tcp_packet(uint16_t fromNode, uint8_t fromPlug, uint16_t toNode, uint8_t toPlug, uint8_t command, Payload *payload)
{
DataPacket *packet = getNewPacket();
packet-><span style="color: #CC6600;">status</span> = STATUS_READY;
packet->payload[PACKET_LENGTH] = payload->length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet->payload[PACKET_SETTINGS] = 1;
uint16_t address = compressAddress(fromNode, fromPlug);
packet->payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet->payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet->payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet->payload[PACKET_TO+1] = address & 0xFF;
packet->payload[PACKET_ID] = getId();
packet->payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload->length;i++){
packet->payload[PACKET_PAYLOAD+i] = payload->data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> * @return DataPacket * Pointer to the New DataPacket</span>
<span style="color: #7E7E7E;"> */</span>
DataPacket *build_udp_packet(uint16_t fromNode, uint8_t fromPlug, uint16_t toNode, uint8_t toPlug, uint8_t command, Payload *payload)
{
DataPacket *packet = getNewPacket();
packet-><span style="color: #CC6600;">status</span> = STATUS_READY;
packet->payload[PACKET_LENGTH] = payload->length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet->payload[PACKET_SETTINGS] = 2;
uint16_t address = compressAddress(fromNode, fromPlug);
packet->payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet->payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet->payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet->payload[PACKET_TO+1] = address & 0xFF;
packet->payload[PACKET_ID] = getId();
packet->payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload->length;i++){
packet->payload[PACKET_PAYLOAD+i] = payload->data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
DataPacket *build_broadcast_packet(uint16_t fromNode, uint8_t fromPlug, uint8_t ttl, Payload payload)
{
DataPacket *packet = getNewPacket();
packet-><span style="color: #CC6600;">status</span> = STATUS_WAITING;
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/**</span>
<span style="color: #7E7E7E;"> * turns a packet into a decoded packet</span>
<span style="color: #7E7E7E;"> */</span>
DataPacketDecoded decode_packet(DataPacket *packet)
{
DataPacketDecoded decodedPacket;
decodedPacket.ttl = 0;
<span style="color: #7E7E7E;">//Set Packet length</span>
decodedPacket.length = packet->payload[PACKET_LENGTH];
decodedPacket.<span style="color: #CC6600;">status</span> = packet-><span style="color: #CC6600;">status</span>;
<span style="color: #7E7E7E;">//settings </span>
decodedPacket.settings = packet->payload[PACKET_SETTINGS];
decodedPacket.type = packet->payload[PACKET_SETTINGS]; <span style="color: #7E7E7E;">//right now these are the same things</span>
<span style="color: #7E7E7E;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet->payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet->payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPlug = packet->payload[PACKET_FROM+1] &0xF;
<span style="color: #7E7E7E;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet->payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet->payload[PACKET_TO+1] >> 4);
decodedPacket.toPlug = packet->payload[PACKET_TO+1] &0xF;
<span style="color: #7E7E7E;">//packet id</span>
decodedPacket.id = packet->payload[PACKET_ID];
<span style="color: #7E7E7E;">//Command</span>
decodedPacket.command = packet->payload[PACKET_COMMAND];
decodedPacket.ptr = packet->payload[PACKET_LENGTH] - OFFSET_PACKET;
Payload *payload = get_payload(packet);
<span style="color: #CC6600;">for</span>(i=0; i < payload->length; i++){
<span style="color: #CC6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP </span>
decodedPacket.payload[i] = payload->data[i];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
decodedPacket.checksum=packet->checksum;
<span style="color: #CC6600;">return</span> decodedPacket;
}
<span style="color: #CC6600;">void</span> debug_packet(DataPacket *packet){
DataPacketDecoded sendPacketedDecoded = decode_packet(packet);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Decode Packet"</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" sent: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.<span style="color: #CC6600;">status</span>,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" length: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.length,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"settings: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.settings,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" type: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.type,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"fromNode: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.fromNode,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"fromPlug: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.fromPlug,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" toNode: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.toNode,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" toPlug: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.toPlug,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" ttl: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.ttl,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" id: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.id,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" command: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.command,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" payload: "</span>);
<span style="color: #CC6600;">for</span>(i=0; i < sendPacketedDecoded.ptr; i++){
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(sendPacketedDecoded.payload[i],<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">","</span>);
}
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" payload: "</span>);
<span style="color: #CC6600;">for</span>(i=0; i < sendPacketedDecoded.ptr; i++){
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(sendPacketedDecoded.payload[i],<span style="color: #006699;">BYTE</span>);
}
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"checksum: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.checksum,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" ptr: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.ptr,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" from: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.from,<span style="color: #006699;">DEC</span>);
}
<span style="color: #CC6600;">int</span> availableMemory() {
<span style="color: #CC6600;">int</span> size = 2048; <span style="color: #7E7E7E;">// Use 2048 with ATmega328</span>
<span style="color: #CC6600;">byte</span> *buf;
<span style="color: #CC6600;">while</span> ((buf = (<span style="color: #CC6600;">byte</span> *) malloc(--size)) == NULL)
;
free(buf);
<span style="color: #CC6600;">return</span> size;
}
</pre><br />
Processing code:<br />
<pre>import processing.serial.*;
<span style="color: #7E7E7E;">//shortcuts to important bytes</span>
<span style="color: #7E7E7E;">//keeps from having to decode the whole thing to check simple parts</span>
final <span style="color: #CC6600;">int</span> PACKET_LENGTH = 0;
final <span style="color: #CC6600;">int</span> PACKET_SETTINGS = 1;
final <span style="color: #CC6600;">int</span> PACKET_FROM = 2;
final <span style="color: #CC6600;">int</span> PACKET_TO = 4;
final <span style="color: #CC6600;">int</span> PACKET_TTL = 4;
final <span style="color: #CC6600;">int</span> PACKET_ID = 6;
final <span style="color: #CC6600;">int</span> PACKET_COMMAND = 7;
final <span style="color: #CC6600;">int</span> PACKET_PAYLOAD = 8;
final <span style="color: #CC6600;">int</span> CMD_PING = 0x3E;
final <span style="color: #CC6600;">int</span> CMD_PONG = 0xE3;
final <span style="color: #CC6600;">int</span> CMD_STRING = 0xF1;
<span style="color: #7E7E7E;">//an enum might be better here</span>
final <span style="color: #CC6600;">int</span> STATUS_CLEAR = 0;
final <span style="color: #CC6600;">int</span> STATUS_RECEVING = 1;
final <span style="color: #CC6600;">int</span> STATUS_RECEVIED = 2;
final <span style="color: #CC6600;">int</span> STATUS_WAITING = 3;
final <span style="color: #CC6600;">int</span> STATUS_READY = 4;
final <span style="color: #CC6600;">int</span> STATUS_SENDING = 5;
final <span style="color: #CC6600;">int</span> STATUS_SENT = 6;
final <span style="color: #CC6600;">int</span> STATUS_ACK = 7;
final <span style="color: #CC6600;">int</span> STATUS_SUCCESS = 8;
final <span style="color: #CC6600;">int</span> OFFSET_PACKET = 10;
final <span style="color: #CC6600;">int</span> OFFSET_HEADER = 8;
final <span style="color: #CC6600;">int</span> OFFSET_FOOTER = 2;
<span style="color: #CC6600;">class</span> DataPacketDecoded {
<span style="color: #CC6600;">int</span> command, length, <span style="color: #CC6600;">status</span> = 0, settings, type, fromPort, toPort, id, ttl = 0, ptr = 0;
<span style="color: #CC6600;">int</span> fromNode, toNode, checksum = 0;
<span style="color: #CC6600;">int</span>[] payload = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[56];
DataPacketDecoded(){ }
}
<span style="color: #7E7E7E;">//simple data packet</span>
<span style="color: #CC6600;">class</span> DataPacket {
<span style="color: #CC6600;">int</span> ptr = 0, <span style="color: #CC6600;">status</span> = 0, checksum = 0;
<span style="color: #CC6600;">int</span>[] payload = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[64];
DataPacket(){ }
}
<span style="color: #CC6600;">class</span> Payload {
<span style="color: #CC6600;">int</span> length;
<span style="color: #CC6600;">int</span>[] data = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[56];
Payload() { }
}
<span style="color: #7E7E7E;">//What should master ports be?</span>
final <span style="color: #CC6600;">int</span> NODE_ID = 255;
final <span style="color: #CC6600;">int</span> PACKET_BUFFER = 10;
final <span style="color: #CC6600;">int</span> PACKET_TIMEOUT = 150;
<span style="color: #7E7E7E;">//Should be an ArrayList so we can add and remove elements</span>
DataPacket[] data = <span style="color: #CC6600;">new</span> DataPacket[PACKET_BUFFER];
DataPacket incomingPacket = <span style="color: #CC6600;">new</span> DataPacket(); <span style="color: #7E7E7E;">//current incoming packet</span>
<span style="color: #CC6600;">int</span> checksum;
<span style="color: #CC6600;">int</span> uniqueId = 0;
<span style="color: #CC6600;">int</span> i;
<span style="color: #CC6600;">boolean</span> sending = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">boolean</span> receiving = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">long</span> packetTimer;
<span style="color: #CC6600;">int</span> bgcolor; <span style="color: #7E7E7E;">// Background color</span>
<span style="color: #CC6600;">int</span> fgcolor; <span style="color: #7E7E7E;">// Fill color</span>
<span style="color: #CC6600;"><b>Serial</b></span> myPort; <span style="color: #7E7E7E;">// The serial port</span>
PFont myFont;
XMLElement xmlConfig;
<span style="color: #7E7E7E;">//build rf12 packet</span>
<span style="color: #CC6600;">void</span> build_incoming_packet(<span style="color: #CC6600;">int</span> byteIn)
{
<span style="color: #7E7E7E;">//mark which port it is coming from</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"count: "</span>+incomingPacket.ptr + <span style="color: #006699;">" byte: "</span> + byteIn);
<span style="color: #CC6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7E7E7E;">//Packet length</span>
<span style="color: #CC6600;">if</span>(byteIn <= 2) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RESENDING LAST"</span>);
<span style="color: #7E7E7E;">//resend last</span>
sendingPacket.<span style="color: #CC6600;">status</span> = STATUS_SENDING;
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span>(byteIn == 255) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK SUCCESS"</span>);
sendingPacket.<span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
<span style="color: #7E7E7E;">//aknowledge</span>
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span> (byteIn > 128) {
myPort.<span style="color: #CC6600;">clear</span>();
myPort.<span style="color: #CC6600;">write</span>(0);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"BYTE to high"</span>);
<span style="color: #CC6600;">return</span>;
}
receiving = <span style="color: #CC6600;">true</span>;
packetTimer = <span style="color: #CC6600;">millis</span>();
incomingPacket.payload[PACKET_LENGTH] = byteIn;
incomingPacket.<span style="color: #CC6600;">status</span> = STATUS_RECEVING;
checksum = 0;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"length: "</span> + byteIn);
}
<span style="color: #7E7E7E;">//checksum </span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr < (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = byteIn;
checksum = _crc16_update(checksum, byteIn);
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(incomingPacket.ptr == (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//get first byte of checksum</span>
incomingPacket.checksum = byteIn;
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> { <span style="color: #7E7E7E;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | (byteIn & 0xFF);
<span style="color: #CC6600;">if</span>(checksum != incomingPacket.checksum) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Failed CRC Check"</span>);
myPort.<span style="color: #CC6600;">clear</span>();
myPort.<span style="color: #CC6600;">write</span>(<span style="color: #CC6600;">int</span>(0));
} <span style="color: #CC6600;">else</span> {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Passed CRC Check"</span>);
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_RECEVIED;
DataPacket packet = getNewPacket();
packet = incomingPacket;
myPort.<span style="color: #CC6600;">clear</span>();
myPort.<span style="color: #CC6600;">write</span>(<span style="color: #CC6600;">int</span>(255));
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT ACK"</span>);
<span style="color: #7E7E7E;">//packet</span>
debug_incoming_packet(packet);
<span style="color: #7E7E7E;">// incomingPacket.payload;</span>
<span style="color: #7E7E7E;">//incomingPacket = DataPacket;</span>
}
<span style="color: #7E7E7E;">//reset incoming packet</span>
incomingPacket = <span style="color: #CC6600;">new</span> DataPacket();
receiving = <span style="color: #CC6600;">false</span>;
}
}
<span style="color: #7E7E7E;">//determine where to send packet. how to expand when we have 4 serial ports?</span>
<span style="color: #CC6600;">void</span> process_stack(){
<span style="color: #7E7E7E;">//sending = false; //only send one pack per cycle</span>
<span style="color: #CC6600;">for</span>(i=0;i<PACKET_BUFFER;i++){
process_packet(data[i]);
}
<span style="color: #7E7E7E;">//check for packets to send</span>
<span style="color: #7E7E7E;">//check for packets to resend if ACKs are late</span>
<span style="color: #7E7E7E;">//check for data packets that can be deleted from the stack </span>
}
DataPacket sendingPacket;
<span style="color: #CC6600;">void</span> process_packet(DataPacket packet){
<span style="color: #CC6600;">switch</span> (packet.<span style="color: #CC6600;">status</span>){
<span style="color: #CC6600;">case</span> STATUS_CLEAR:
<span style="color: #7E7E7E;">//println("CLEAR");</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVING:
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVIED:
<span style="color: #7E7E7E;">//if(get_node(packet,PACKET_TO) == NODE_ID){</span>
<span style="color: #7E7E7E;">//process_command(packet);</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_CLEAR;
<span style="color: #7E7E7E;">// } else {</span>
<span style="color: #7E7E7E;">// packet.status = STATUS_READY; </span>
<span style="color: #7E7E7E;">// }</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVIED"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_WAITING:
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"WAITING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_READY:
<span style="color: #7E7E7E;">//check for free port</span>
<span style="color: #CC6600;">if</span>(sending == <span style="color: #CC6600;">false</span>){
packet.<span style="color: #CC6600;">status</span> = STATUS_SENDING;
sending = <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">//if reset pointer and set to send</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"READY"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENDING:
<span style="color: #7E7E7E;">//because of the above, only one packet will be changed to sending</span>
<span style="color: #7E7E7E;">//if(get_node(packet,PACKET_FROM) < 30){</span>
<span style="color: #7E7E7E;">// send_packet_rf12(packet); </span>
<span style="color: #7E7E7E;">//} else {</span>
send_packet_serial(packet);
sendingPacket = packet;
<span style="color: #7E7E7E;">// }</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_SENT;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENT:
<span style="color: #7E7E7E;">//if is a ack packet </span>
<span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] == 1){
packet.<span style="color: #CC6600;">status</span> = STATUS_ACK;
<span style="color: #7E7E7E;">//start packets ack timer</span>
} <span style="color: #CC6600;">else</span> {
<span style="color: #7E7E7E;">//packet.status = STATUS_SUCCESS;</span>
}
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_ACK:
<span style="color: #7E7E7E;">//if execeded timer resen</span>
<span style="color: #7E7E7E;">//count resends if exceds max kill packet and add error</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SUCCESS:
<span style="color: #7E7E7E;">//option to post status to screen</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_CLEAR;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SUCCESS"</span>);
<span style="color: #CC6600;">break</span>;
}
}
<span style="color: #CC6600;">String</span> findXMLid(XMLElement[] xml , <span style="color: #CC6600;">int</span> value, <span style="color: #CC6600;">String</span> rAttribute){
<span style="color: #CC6600;">String</span> rValue = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">for</span>(<span style="color: #CC6600;">int</span> a = 0; a<commands.length;a++){
<span style="color: #CC6600;">if</span>(unhex(commands[a].getAttribute(<span style="color: #006699;">"id"</span>)) == value){
<span style="color: #CC6600;">return</span> commands[a].getAttribute(rAttribute);
}
}
<span style="color: #CC6600;">return</span> rValue;
}
XMLElement commands[];
XMLElement devices[];
<span style="color: #CC6600;">long</span> sendTimer;
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>setup</b></span>() {
size(600, 400); <span style="color: #7E7E7E;">// Stage size</span>
<span style="color: #7E7E7E;">//noStroke(); // No border on the next thing drawn</span>
myFont = createFont(<span style="color: #006699;">"Consolas"</span>, 14);
textFont(myFont);
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
data[i] = <span style="color: #CC6600;">new</span> DataPacket();
data[i].<span style="color: #CC6600;">status</span> = STATUS_CLEAR;
}
xmlConfig = <span style="color: #CC6600;">new</span> XMLElement(<span style="color: #CC6600;">this</span>, <span style="color: #006699;">"config.txt"</span>);
devices = xmlConfig.getChildren(<span style="color: #006699;">"devices/device"</span>);
commands = xmlConfig.getChildren(<span style="color: #006699;">"commands/command"</span>);
<span style="color: #7E7E7E;">// Print a list of the serial ports, for debugging purposes:</span>
<span style="color: #7E7E7E;">//println(PFont.list());</span>
<span style="color: #CC6600;">String</span> portName = <span style="color: #CC6600;"><b>Serial</b></span>.list()[0];
myPort = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;"><b>Serial</b></span>(<span style="color: #CC6600;">this</span>, portName, 115200);
}
<span style="color: #CC6600;">boolean</span> arduinoBoot = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">int</span> count = 0;
<span style="color: #CC6600;">void</span> draw() {
<span style="color: #CC6600;">if</span>(arduinoBoot == <span style="color: #CC6600;">false</span>){
<span style="color: #CC6600;">delay</span>(2500);
sendTimer = <span style="color: #CC6600;">millis</span>();
arduinoBoot = <span style="color: #CC6600;">true</span>;;
}
process_stack();
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - sendTimer) > 2000){
<span style="color: #7E7E7E;">//DataPacket packet = build_udp_packet(NODE_ID,0,3,2,CMD_STRING,str_to_payload("Hello "+count));</span>
<span style="color: #7E7E7E;">// packet.status = STATUS_READY;</span>
sendTimer=<span style="color: #CC6600;">millis</span>();
count++;
}
<span style="color: #CC6600;">if</span>(receiving == <span style="color: #CC6600;">true</span>) {
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - packetTimer) > PACKET_TIMEOUT) {
myPort.<span style="color: #CC6600;">clear</span>();
myPort.<span style="color: #CC6600;">write</span>(0); <span style="color: #7E7E7E;">//tell the node to resend last</span>
incomingPacket = <span style="color: #CC6600;">new</span> DataPacket();
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"bad packet"</span>);
receiving = <span style="color: #CC6600;">false</span>;
}
}
}
<span style="color: #CC6600;">void</span> serialEvent(<span style="color: #CC6600;"><b>Serial</b></span> myPort) {
<span style="color: #7E7E7E;">// read a byte from the serial port:</span>
<span style="color: #CC6600;">int</span> inByte = myPort.<span style="color: #CC6600;">read</span>();
build_incoming_packet(inByte);
<span style="color: #7E7E7E;">//print(inByte);</span>
<span style="color: #7E7E7E;">//print(",");</span>
}
<span style="color: #7E7E7E;">//Done</span>
DataPacket getNewPacket() {
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
<span style="color: #CC6600;">if</span>(data[i].<span style="color: #CC6600;">status</span> == STATUS_CLEAR){
<span style="color: #CC6600;">return</span> data[i];
}
}
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"BUFFER FULL"</span>);
<span style="color: #CC6600;">return</span> <span style="color: #CC6600;">new</span> DataPacket();
}
<span style="color: #CC6600;">int</span> get_node(DataPacket packet, <span style="color: #CC6600;">int</span> location)
{
<span style="color: #CC6600;">int</span> node;
node = packet.payload[location];
node = node << 4;
node = node | (packet.payload[location+1] >> 4);
<span style="color: #CC6600;">return</span> node;
}
Payload get_payload(DataPacket packet)
{
Payload payload = <span style="color: #CC6600;">new</span> Payload();
payload.length = packet.payload[PACKET_LENGTH] - OFFSET_PACKET;
<span style="color: #CC6600;">for</span>(i=0; i < payload.length; i++){
<span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
payload.data[i] = packet.payload[i+OFFSET_HEADER];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> payload;
}
Payload str_to_payload(<span style="color: #CC6600;">String</span> string)
{
Payload payload = <span style="color: #CC6600;">new</span> Payload();
<span style="color: #7E7E7E;">//println("Payload Length: "+ string.length());</span>
<span style="color: #CC6600;">for</span>(i=0;i<string.length();i++){
payload.data[i] = <span style="color: #CC6600;">int</span>(string.charAt(i));
}
payload.length = string.length();
<span style="color: #CC6600;">return</span> payload;
}
<span style="color: #CC6600;">void</span> process_command(DataPacket packet)
{
<span style="color: #CC6600;">switch</span> (packet.payload[PACKET_COMMAND]) {
<span style="color: #CC6600;">case</span> CMD_PING:
<span style="color: #7E7E7E;">// DataPacket reply = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));</span>
<span style="color: #7E7E7E;">// reply.status = STATUS_READY;</span>
<span style="color: #7E7E7E;">//change status to ready to send</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #7E7E7E;">//default:</span>
<span style="color: #7E7E7E;">//send_packet(COMMAND_ERROR,NULL,0);</span>
<span style="color: #7E7E7E;">// break;</span>
}
}
<span style="color: #CC6600;">int</span> _crc16_update(<span style="color: #CC6600;">int</span> crc, <span style="color: #CC6600;">int</span> a)
{
<span style="color: #CC6600;">int</span> i;
crc ^= a;
<span style="color: #CC6600;">for</span> (i = 0; i < 8; ++i){
<span style="color: #CC6600;">if</span> ((crc & 1) == 1){
crc = (crc >> 1) ^ 0xA001;
}<span style="color: #CC6600;">else</span>{
crc = (crc >> 1);
}
}
<span style="color: #CC6600;">return</span> crc & 0xFFFF;
}
<span style="color: #CC6600;">int</span> getId() {
<span style="color: #CC6600;">if</span>(uniqueId == 255){
uniqueId = 0;
}
<span style="color: #CC6600;">return</span> uniqueId++; <span style="color: #7E7E7E;">//what happens when this wraps?</span>
}
<span style="color: #CC6600;">int</span> compressAddress(<span style="color: #CC6600;">int</span> node, <span style="color: #CC6600;">int</span> port)
{
node = node << 4; <span style="color: #7E7E7E;">//make space</span>
port = port & 0x0F;
<span style="color: #CC6600;">return</span> node | port;
}
DataPacket build_tcp_packet(<span style="color: #CC6600;">int</span> fromNode, <span style="color: #CC6600;">int</span> fromPlug, <span style="color: #CC6600;">int</span> toNode, <span style="color: #CC6600;">int</span> toPlug, <span style="color: #CC6600;">int</span> command, Payload payload)
{
DataPacket packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet.payload[PACKET_LENGTH] = payload.length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet.payload[PACKET_SETTINGS] = 1;
<span style="color: #CC6600;">int</span> address = compressAddress(fromNode, fromPlug);
packet.payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet.payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload.length;i++){
packet.payload[PACKET_PAYLOAD+i] = payload.data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> * @return DataPacket * Pointer to the New DataPacket</span>
<span style="color: #7E7E7E;"> */</span>
DataPacket build_udp_packet(<span style="color: #CC6600;">int</span> fromNode, <span style="color: #CC6600;">int</span> fromPlug, <span style="color: #CC6600;">int</span> toNode, <span style="color: #CC6600;">int</span> toPlug, <span style="color: #CC6600;">int</span> command, Payload payload)
{
DataPacket packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet.payload[PACKET_LENGTH] = payload.length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet.payload[PACKET_SETTINGS] = 2;
<span style="color: #CC6600;">int</span> address = compressAddress(fromNode, fromPlug);
packet.payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet.payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload.length;i++){
packet.payload[PACKET_PAYLOAD+i] = payload.data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;">uint8_t build_broadcast_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t payload[48], uint8_t length, uint8_t ttl )</span>
<span style="color: #7E7E7E;">{</span>
<span style="color: #7E7E7E;"> byte packetId = getNewPacketId();</span>
<span style="color: #7E7E7E;"> data[packetId].sent = 0;</span>
<span style="color: #7E7E7E;"> return packetId;</span>
<span style="color: #7E7E7E;">}</span>
<span style="color: #7E7E7E;">*/</span>
<span style="color: #CC6600;">boolean</span> send_packet_serial(DataPacket packet)
{
<span style="color: #CC6600;">int</span> dataChecksum = 0;
<span style="color: #CC6600;">for</span>(i=0; i < (packet.payload[PACKET_LENGTH]-2); i++){
dataChecksum = _crc16_update(dataChecksum, packet.payload[i]);
myPort.<span style="color: #CC6600;">write</span>(packet.payload[i] & 0xFF);
<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">int</span>((packet.payload[i] & 0xFF)) + <span style="color: #006699;">","</span>);
}
<span style="color: #CC6600;">print</span>((dataChecksum >>8)&0xFF);
<span style="color: #CC6600;">print</span>(<span style="color: #006699;">","</span>);
<span style="color: #CC6600;">print</span>(dataChecksum & 0xFF);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Packet Sent"</span>);
packet.<span style="color: #CC6600;">status</span> = 1;
myPort.<span style="color: #CC6600;">write</span>((dataChecksum >> 8) & 0xFF);
myPort.<span style="color: #CC6600;">write</span>(dataChecksum & 0xFF);
<span style="color: #CC6600;">return</span> <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">/**</span>
<span style="color: #7E7E7E;"> * turns a packet into a decoded packet</span>
<span style="color: #7E7E7E;"> */</span>
DataPacketDecoded decode_packet(DataPacket packet)
{
DataPacketDecoded decodedPacket = <span style="color: #CC6600;">new</span> DataPacketDecoded();
<span style="color: #7E7E7E;">//Set Packet length</span>
decodedPacket.length = packet.payload[PACKET_LENGTH];
decodedPacket.<span style="color: #CC6600;">status</span> = packet.<span style="color: #CC6600;">status</span>;
<span style="color: #7E7E7E;">//settings </span>
decodedPacket.settings = packet.payload[PACKET_SETTINGS];
decodedPacket.type = packet.payload[PACKET_SETTINGS]; <span style="color: #7E7E7E;">//right now these are the same things</span>
<span style="color: #7E7E7E;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet.payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet.payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPort = packet.payload[PACKET_FROM+1] &0xF;
<span style="color: #7E7E7E;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet.payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet.payload[PACKET_TO+1] >> 4);
decodedPacket.toPort = packet.payload[PACKET_TO+1] &0xF;
<span style="color: #7E7E7E;">//packet id</span>
decodedPacket.id = packet.payload[PACKET_ID];
<span style="color: #7E7E7E;">//Command</span>
decodedPacket.command = packet.payload[PACKET_COMMAND];
decodedPacket.checksum = packet.checksum;
decodedPacket.ptr = packet.payload[PACKET_LENGTH] - 10;
<span style="color: #CC6600;">for</span>(i=PACKET_PAYLOAD; i < packet.payload[PACKET_LENGTH]; i++){
<span style="color: #CC6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
decodedPacket.payload[i-PACKET_PAYLOAD] = packet.payload[i];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> decodedPacket;
}
<span style="color: #CC6600;">void</span> debug_incoming_packet(DataPacket packet)
{
background(0);
<span style="color: #7E7E7E;">//println("show packet info");</span>
text(<span style="color: #006699;">"Packet Info"</span>,5,15);
<span style="color: #CC6600;">int</span> x = 20;
DataPacketDecoded packetDecoded = decode_packet(packet);
text(<span style="color: #006699;">" status: "</span> + packetDecoded.<span style="color: #CC6600;">status</span>,10,x+=20);
text(<span style="color: #006699;">" length: "</span> + packetDecoded.length,10,x+=20);
text(<span style="color: #006699;">"settings: "</span> + packetDecoded.settings,10,x+=20);
text(<span style="color: #006699;">" type: "</span> + packetDecoded.type,10,x+=20);
text(<span style="color: #006699;">"fromNode: "</span> + packetDecoded.fromNode,10,x+=20);
text(<span style="color: #006699;">"fromPort: "</span> + packetDecoded.fromPort,10,x+=20);
text(<span style="color: #006699;">" toNode: "</span> + packetDecoded.toNode,10,x+=20);
text(<span style="color: #006699;">" toPort: "</span> + packetDecoded.toPort,10,x+=20);
text(<span style="color: #006699;">" ttl: "</span> + packetDecoded.ttl,10,x+=20);
text(<span style="color: #006699;">" id: "</span> + packetDecoded.id,10,x+=20);
text(<span style="color: #006699;">" command: "</span> + findXMLid(commands, packetDecoded.command,<span style="color: #006699;">"code"</span>),10,x+=20);
<span style="color: #CC6600;">String</span> message = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">String</span> message2 = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">for</span>(i=0; i < packetDecoded.ptr; i++){
message += <span style="color: #CC6600;">int</span>(packetDecoded.payload[i]);
message += <span style="color: #006699;">","</span>;
message2 += <span style="color: #CC6600;">char</span>(packetDecoded.payload[i]);
}
text(<span style="color: #006699;">" payload: "</span> + message,10,x+=20);
text(<span style="color: #006699;">" payload: "</span> + message2,10,x+=20);
text(<span style="color: #006699;">"checksum: "</span> + packetDecoded.checksum,10,x+=20);
text(<span style="color: #006699;">" ptr: "</span> + packetDecoded.ptr,10,x+=20);<span style="color: #7E7E7E;">//*/</span>
}
</pre>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-61256331323427820112010-11-09T04:32:00.000-08:002010-11-12T11:11:56.126-08:00XML Config FileIts starting to be pain to setup on the constants in both Arduino and processing and in the future php so it's time to create a configuration file that all of these different languages can use (sort of)<br />
<br />
And here it is:<br />
<pre><?xml version="1.0"?>
<configuration>
<devices>
<device id="0x01" code="DVC_TMP37">Temperature Sensor TMP37</device>
<device id="0x02" code="DVC_LIGHT">Light Sensor LDR</device>
<device id="0x03" code="DVC_SHT21">Temperature and Humidy Sensor SHT21</device>
<device id="0x04" code="DVC_DOORCONTACT">Door Contact Sensor</device>
<device id="0x05" code="DVC_WINDOWCONTACT">Window Contact Sensor</device>
<device id="0x06" code="DVC_MOTION">Motion Sensor</device>
<device id="0x07" code="DVC_2LINEDISPLAY">2 Line Character Display</device>
<device id="0x08" code="DVC_POWER30">30A Current Sensor</device>
<device id="0x09" code="DVC_POWER100">100A Current Sensor</device>
<device id="0x10" code="DVC_SMARTOUTLET">Smart Outlet</device>
<device id="0x11" code="DVC_RGBLIGHT">RGN LED Light</device>
<device id="0x12" code="DVC_sound">Sound Sensor</device>
<device id="0x13" code="DVC_SWITCH">Simple Switch</device>
<device id="0x14" code="DVC_STATUSLED">Simple Status LEDS</device>
<device id="0x15" code="DVC_BUZZER">Alert Buzzer</device>
</devices>
<commands>
<!-- System Commands Port 0 -->
<command id="0x00" code="CMD_ERROR" payload="message" return="CMD_ACK"></command>
<command id="0x01" code="CMD_VERSION" payload="" return="CMD_FLOAT">
Get current version of firmware on the node
</command>
<command id="0x03" code="CMD_BATTERYLEVEL" payload="" return="">
Get current battery level
</command>
<command id="0x3E" code="CMD_PING" payload="varies" return="CMD_PONG">
Send Test Pack, node should reply back pong
</command>
<command id="0xE3" code="CMD_PONG" payload="varies" return="CMD_ACK">
Response to a Ping Command
</command>
<command id="0x11" code="CMD_ACK" payload="packetid" return="CMD_BYTE">
Acknowledge Packet, letting the sender of a packet know that data arriced safely
</command>
<command id="0x21" code="CMD_GETNODEID" payload="" return="CMD_BYTE">
Get Node's current ID (node id 0 is for broadcast)
</command>
<command id="0x22" code="CMD_SETNODEID" payload="passcode" return="CMD_ACK">
Changes NODE ID, used for initial setup
</command>
<command id="0x23" code="CMD_GETPLUG" payload="byte port" return="CMD_BYTE">
Get the device code for what is attached on the node
</command>
<command id="0x24" code="CMD_SETPLUG" payload="passcode" return="CMD_ACK">
Changes Device ID, used for initial setup
</command>
<!-- Plug commands Ports 1-15 -->
<command id="0xC1" code="CMD_AUTOSENDSTART" payload="node to, int" return="CMD_ACK">
Set up the node to automatically send sensor data to a particular node
</command>
<command id="0xC2" code="CMD_AUTOSENDSTOP" payload="node to" return="CMD_ACK">
Stop auto sending sensor data
</command>
<command id="0xD0" code="CMD_GETVALUE" payload="" return="Value">
Get a value from a plug
</command>
<command id="0xD1" code="CMD_SETVALUE" payload="" return="Value">
Send a value to a plug
</command>
<command id="0xE0" code="CMD_ON" payload="" return="CMD_ACK">
Simple Turn on
</command>
<command id="0xE1" code="CMD_OFF" payload="" return="CMD_ACK">
Simple Turn Off
</command>
<command id="0xE2" code="CMD_LEVEL" payload="byte" return="CMD_ACK">
Set a light to a level 0-255
</command>
<!-- Value commands -->
<command id="0xF0" code="CMD_BYTE" payload="byte" return="CMD_ACK"></command>
<command id="0xF1" code="CMD_STRING" payload="string" return="CMD_ACK"></command>
<command id="0xF2" code="CMD_INT" payload="int" return="CMD_ACK"></command>
<command id="0xF3" code="CMD_FLOAT" payload="float" return="CMD_ACK"></command>
<command id="0xF4" code="CMD_LONG" payload="long" return="CMD_ACK"></command>
</commands>
<!-- One day more stuff will be setup too -->
<pachube>
<apikey></apikey>
<feeds>
<feed name="Bedroom">
<datastream id="0" node="" plug="" device="" />
</feed>
</feeds>
</pachube>
<webserver>
<address></address>
</webserver>
</configuration>
</pre><br />
Processing has built in tools for reading XML and this quick sketch reads the XML file a translates it in to list of #defines for the Arduino. this way as the lists of devices and commands evolve, it's very easy to translate it from one language to another.<br />
<pre><span style="color: #CC6600;">XMLElement</span> xml;
<span style="color: #CC6600;">PFont</span> myFont;
<span style="color: #CC6600;">PrintWriter</span> file;
<span style="color: #CC6600;">int</span> i;
<span style="color: #CC6600;">String</span> spaces(<span style="color: #CC6600;">int</span> count){
<span style="color: #CC6600;">String</span> spaces = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">for</span>(<span style="color: #CC6600;">int</span> a = 0;a<count;a++){
spaces += <span style="color: #006699;">" "</span>;
}
<span style="color: #CC6600;">return</span> spaces;
}
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>setup</b></span>() {
<span style="color: #CC6600;">size</span>(200, 200);
myFont = <span style="color: #CC6600;">createFont</span>(<span style="color: #006699;">"Consolas"</span>, 14);
<span style="color: #CC6600;">textFont</span>(myFont);
xml = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">XMLElement</span>(<span style="color: #CC6600;">this</span>, <span style="color: #006699;">"config.txt"</span>); <span style="color: #7E7E7E;">//in txt</span>
file = <span style="color: #CC6600;">createWriter</span>(<span style="color: #006699;">"define.txt"</span>);
<span style="color: #CC6600;">XMLElement</span> commands[] = xml.<span style="color: #CC6600;">getChildren</span>(<span style="color: #006699;">"commands/command"</span>);
<span style="color: #CC6600;">for</span>(i = 0; i<commands.<span style="color: #CC6600;">length</span>;i++){
file.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"#define "</span>+ commands[i].getAttribute(<span style="color: #006699;">"code"</span>)+spaces(20 - commands[i].getAttribute(<span style="color: #006699;">"code"</span>).<span style="color: #CC6600;">length</span>())+commands[i].getAttribute(<span style="color: #006699;">"id"</span>));
}
file.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>); <span style="color: #7E7E7E;">//blank line</span>
<span style="color: #CC6600;">XMLElement</span> devices[] = xml.<span style="color: #CC6600;">getChildren</span>(<span style="color: #006699;">"devices/device"</span>);
<span style="color: #CC6600;">for</span>(i = 0; i<devices.<span style="color: #CC6600;">length</span>;i++){
file.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"#define "</span>+ devices[i].getAttribute(<span style="color: #006699;">"code"</span>)+spaces(20 - devices[i].getAttribute(<span style="color: #006699;">"code"</span>).<span style="color: #CC6600;">length</span>())+devices[i].getAttribute(<span style="color: #006699;">"id"</span>));
}
file.<span style="color: #CC6600;">flush</span>(); <span style="color: #7E7E7E;">// Write the remaining data</span>
file.<span style="color: #CC6600;">close</span>();
<span style="color: #CC6600;">exit</span>();
}
</pre>And here is the Arduino Code the script above generated for me<br />
<pre>#define CMD_ERROR 0x00
#define CMD_VERSION 0x01
#define CMD_BATTERYLEVEL 0x03
#define CMD_PING 0x3E
#define CMD_PONG 0xE3
#define CMD_ACK 0x11
#define CMD_SETNODEID 0x21
#define CMD_GETNODEID 0x21
#define CMD_SETNODEID 0x22
#define CMD_GETPLUG 0x23
#define CMD_SETPLUG 0x24
#define CMD_AUTOSENDSTART 0xC1
#define CMD_AUTOSENDSTOP 0xC2
#define CMD_GETVALUE 0xD0
#define CMD_SETVALUE 0xD1
#define CMD_ON 0xE0
#define CMD_OFF 0xE1
#define CMD_LEVEL 0xE2
#define CMD_BYTE 0xF0
#define CMD_STRING 0xF1
#define CMD_INT 0xF2
#define CMD_FLOAT 0xF3
#define CMD_LONG 0xF4
#define DVC_TMP37 0x01
#define DVC_LIGHT 0x02
#define DVC_SHT21 0x03
#define DVC_DOORCONTACT 0x04
#define DVC_WINDOWCONTACT 0x05
#define DVC_MOTION 0x06
#define DVC_2LINEDISPLAY 0x07
#define DVC_POWER30 0x08
#define DVC_POWER100 0x09
#define DVC_SMARTOUTLET 0x10
#define DVC_RGBLIGHT 0x11
#define DVC_sound 0x12
#define DVC_SWITCH 0x13
#define DVC_STATUSLED 0x14
#define DVC_BUZZER 0x15
</pre>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-2638648277736616652010-11-08T09:10:00.000-08:002010-11-30T16:06:00.977-08:00Ping Pong PacketsAfter another week of work on my packet code, I finally have a working example of call and response working. Processing sends a Ping packet to the Arduino and the Arduino replies back Pong along with the payload of the original packet. Next step is to expand this to connect to wireless nodes.<br />
<br />
Code after the jump<br />
<a name='more'></a><br />
<br />
Processing:<br />
<pre><span style="color: #CC6600;">import</span> processing.serial.*;
<span style="color: #7E7E7E;">//Device Codes</span>
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_LM33 = 0x01;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_ST11 = 0x02;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_ST15 = 0x03;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_DOORCONTACT = 0x04;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_FLIPSWITCH = 0x05;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_LIGHT = 0x06;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_MOTION = 0x07;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_2LINECHAR = 0x08;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_POWER30 = 0x08;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_POWER100 = 0x09;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_SMARTOUTLET = 0x10;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> DVC_RGBLIGHT = 0x11;
<span style="color: #7E7E7E;">//Command Codes</span>
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_GET_VERSION = 0x01;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_PING = 0x3E;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_PONG = 0xE3;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_ACK = 0x11;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_READ = 0xAA;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_WRITE = 0xBB;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_PORTTYPE = 0xCC;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_AUTOSENDSTART = 0xC1;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_AUTOSENDSTOP = 0xC2;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> CMD_ERROR = 0xFF;
<span style="color: #7E7E7E;">//shortcuts to important bytes</span>
<span style="color: #7E7E7E;">//keeps from having to decode the whole thing to check simple parts</span>
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_LENGTH = 0;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_SETTINGS = 1;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_FROM = 2;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_TO = 4;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_TTL = 4;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_ID = 6;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_COMMAND = 7;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_PAYLOAD = 8;
<span style="color: #7E7E7E;">//an enum might be better here</span>
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_CLEAR = 0;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_RECEVING = 1;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_RECEVIED = 2;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_WAITING = 3;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_READY = 4;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_SENDING = 5;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_SENT = 6;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_ACK = 7;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> STATUS_SUCCESS = 8;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> OFFSET_PACKET = 10;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> OFFSET_HEADER = 8;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> OFFSET_FOOTER = 2;
<span style="color: #CC6600;">class</span> DataPacketDecoded {
<span style="color: #CC6600;">int</span> command, <span style="color: #CC6600;">length</span>, <span style="color: #CC6600;">status</span> = 0, settings, type, fromPort, toPort, id, ttl = 0, ptr = 0;
<span style="color: #CC6600;">int</span> fromNode, toNode, checksum = 0;
<span style="color: #CC6600;">int</span>[] payload = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[56];
DataPacketDecoded(){ }
}
<span style="color: #7E7E7E;">//simple data packet</span>
<span style="color: #CC6600;">class</span> DataPacket {
<span style="color: #CC6600;">int</span> ptr = 0, <span style="color: #CC6600;">status</span> = 0, checksum = 0;
<span style="color: #CC6600;">int</span>[] payload = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[64];
DataPacket(){ }
}
<span style="color: #CC6600;">class</span> Payload {
<span style="color: #CC6600;">int</span> <span style="color: #CC6600;">length</span>;
<span style="color: #CC6600;">int</span>[] data = <span style="color: #CC6600;">new</span> <span style="color: #CC6600;">int</span>[56];
Payload() { }
}
<span style="color: #7E7E7E;">//What should master ports be?</span>
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> NODE_ID = 0x02;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PORT_A = DVC_LM33;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PORT_B = DVC_LM33;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PORT_C = DVC_LM33;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PORT_D = DVC_LM33;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_BUFFER = 10;
<span style="color: #CC6600;">final</span> <span style="color: #CC6600;">int</span> PACKET_TIMEOUT = 100;
DataPacket[] data = <span style="color: #CC6600;">new</span> DataPacket[PACKET_BUFFER];
DataPacket incomingPacket = <span style="color: #CC6600;">new</span> DataPacket(); <span style="color: #7E7E7E;">//current incoming packet</span>
<span style="color: #CC6600;">int</span> checksum;
<span style="color: #CC6600;">int</span> uniqueId = 0;
<span style="color: #CC6600;">int</span> i;
<span style="color: #CC6600;">boolean</span> sending = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">boolean</span> receiving = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">long</span> packetTimer;
<span style="color: #CC6600;">int</span> bgcolor; <span style="color: #7E7E7E;">// Background color</span>
<span style="color: #CC6600;">int</span> fgcolor; <span style="color: #7E7E7E;">// Fill color</span>
Serial myPort; <span style="color: #7E7E7E;">// The serial port</span>
<span style="color: #CC6600;">PFont</span> myFont;
<span style="color: #7E7E7E;">//build rf12 packet</span>
<span style="color: #CC6600;">void</span> build_incoming_packet(<span style="color: #CC6600;">int</span> byteIn)
{
<span style="color: #7E7E7E;">//mark which port it is coming from</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"count: "</span>+incomingPacket.ptr + <span style="color: #006699;">" byte: "</span> + byteIn);
<span style="color: #CC6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7E7E7E;">//Packet length</span>
<span style="color: #CC6600;">if</span>(byteIn <= 1) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RESENDING LAST"</span>);
<span style="color: #7E7E7E;">//resend last</span>
sendingPacket.<span style="color: #CC6600;">status</span> = STATUS_SENDING;
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span>(byteIn == 255) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK SUCCESS"</span>);
sendingPacket.<span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
<span style="color: #7E7E7E;">//aknowledge</span>
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span> (byteIn > 128) {
myPort.clear();
myPort.write(0);
<span style="color: #CC6600;">return</span>;
}
receiving = <span style="color: #CC6600;">true</span>;
packetTimer = <span style="color: #CC6600;">millis</span>();
incomingPacket.payload[PACKET_LENGTH] = byteIn;
incomingPacket.<span style="color: #CC6600;">status</span> = STATUS_RECEVING;
checksum = 0;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"length: "</span> + byteIn);
}
<span style="color: #7E7E7E;">//checksum </span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr < (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = byteIn;
checksum = _crc16_update(checksum, byteIn);
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(incomingPacket.ptr == (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//get first byte of checksum</span>
incomingPacket.checksum = byteIn;
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> { <span style="color: #7E7E7E;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | (byteIn & 0xFF);
<span style="color: #CC6600;">if</span>(checksum != incomingPacket.checksum) {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Failed CRC Check"</span>);
myPort.clear();
myPort.write(<span style="color: #CC6600;">int</span>(0));
} <span style="color: #CC6600;">else</span> {
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Passed CRC Check"</span>);
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_RECEVIED;
DataPacket packet = getNewPacket();
packet = incomingPacket;
myPort.clear();
myPort.write(<span style="color: #CC6600;">int</span>(255));
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT ACK"</span>);
<span style="color: #7E7E7E;">//packet</span>
debug_incoming_packet(packet);
<span style="color: #7E7E7E;">// incomingPacket.payload;</span>
<span style="color: #7E7E7E;">//incomingPacket = DataPacket;</span>
}
<span style="color: #7E7E7E;">//reset incoming packet</span>
incomingPacket = <span style="color: #CC6600;">new</span> DataPacket();
receiving = <span style="color: #CC6600;">false</span>;
}
}
<span style="color: #7E7E7E;">//determine where to send packet. how to expand when we have 4 serial ports?</span>
<span style="color: #CC6600;">void</span> process_stack(){
<span style="color: #7E7E7E;">//sending = false; //only send one pack per cycle</span>
<span style="color: #CC6600;">for</span>(i=0;i<PACKET_BUFFER;i++){
process_packet(data[i]);
}
<span style="color: #7E7E7E;">//check for packets to send</span>
<span style="color: #7E7E7E;">//check for packets to resend if ACKs are late</span>
<span style="color: #7E7E7E;">//check for data packets that can be deleted from the stack </span>
}
DataPacket sendingPacket;
<span style="color: #CC6600;">void</span> process_packet(DataPacket packet){
<span style="color: #CC6600;">switch</span> (packet.<span style="color: #CC6600;">status</span>){
<span style="color: #CC6600;">case</span> STATUS_CLEAR:
<span style="color: #7E7E7E;">//println("CLEAR");</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVING:
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVIED:
process_command(packet);
packet.<span style="color: #CC6600;">status</span> = STATUS_CLEAR;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVIED"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_WAITING:
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"WAITING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_READY:
<span style="color: #7E7E7E;">//check for free port</span>
<span style="color: #CC6600;">if</span>(sending == <span style="color: #CC6600;">false</span>){
packet.<span style="color: #CC6600;">status</span> = STATUS_SENDING;
sending = <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">//if reset pointer and set to send</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"READY"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENDING:
<span style="color: #7E7E7E;">//because of the above, only one packet will be changed to sending</span>
<span style="color: #7E7E7E;">//if(get_node(packet,PACKET_FROM) < 30){</span>
<span style="color: #7E7E7E;">// send_packet_rf12(packet); </span>
<span style="color: #7E7E7E;">//} else {</span>
send_packet_serial(packet);
sendingPacket = packet;
<span style="color: #7E7E7E;">// }</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_SENT;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENT:
<span style="color: #7E7E7E;">//if is a ack packet </span>
<span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] == 1){
packet.<span style="color: #CC6600;">status</span> = STATUS_ACK;
<span style="color: #7E7E7E;">//start packets ack timer</span>
} <span style="color: #CC6600;">else</span> {
<span style="color: #7E7E7E;">//packet.status = STATUS_SUCCESS;</span>
}
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_ACK:
<span style="color: #7E7E7E;">//if execeded timer resen</span>
<span style="color: #7E7E7E;">//count resends if exceds max kill packet and add error</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK"</span>);
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SUCCESS:
<span style="color: #7E7E7E;">//option to post status to screen</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_CLEAR;
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SUCCESS"</span>);
<span style="color: #CC6600;">break</span>;
}
}
<span style="color: #CC6600;">long</span> sendTimer;
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>setup</b></span>() {
<span style="color: #CC6600;">size</span>(600, 400); <span style="color: #7E7E7E;">// Stage size</span>
<span style="color: #7E7E7E;">//noStroke(); // No border on the next thing drawn</span>
myFont = <span style="color: #CC6600;">createFont</span>(<span style="color: #006699;">"Consolas"</span>, 14);
<span style="color: #CC6600;">textFont</span>(myFont);
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
data[i] = <span style="color: #CC6600;">new</span> DataPacket();
}
<span style="color: #7E7E7E;">// Print a list of the serial ports, for debugging purposes:</span>
<span style="color: #7E7E7E;">//println(PFont.list());</span>
sendTimer = <span style="color: #CC6600;">millis</span>();
<span style="color: #CC6600;">String</span> portName = Serial.<span style="color: #CC6600;">list</span>()[1];
myPort = <span style="color: #CC6600;">new</span> Serial(<span style="color: #CC6600;">this</span>, portName, 115200);
}
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>draw</b></span>() {
process_stack();
<span style="color: #7E7E7E;">//process_stack();</span>
<span style="color: #7E7E7E;">//process_stack();</span>
<span style="color: #7E7E7E;">// process_stack();</span>
<span style="color: #7E7E7E;">// process_stack();</span>
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"loop"</span>);
<span style="color: #7E7E7E;">//delay(1000);</span>
<span style="color: #7E7E7E;">//text("Hello",10,10);</span>
<span style="color: #7E7E7E;">//text("Z", 10, 220);</span>
<span style="color: #7E7E7E;">// Draw the shape</span>
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - sendTimer) > 2500){
DataPacket packet = build_udp_packet(0,0,1,0,CMD_PING,str_to_payload(<span style="color: #006699;">"Hello"</span>));
packet.<span style="color: #CC6600;">status</span> = STATUS_READY;
sendTimer=<span style="color: #CC6600;">millis</span>();
}
<span style="color: #7E7E7E;">//send_packet_serial(packet);</span>
<span style="color: #CC6600;">if</span>(receiving == <span style="color: #CC6600;">true</span>) {
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - packetTimer) > PACKET_TIMEOUT) {
myPort.clear();
myPort.write(0); <span style="color: #7E7E7E;">//tell the node to resend last</span>
incomingPacket = <span style="color: #CC6600;">new</span> DataPacket();
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"bad packet"</span>);
receiving = <span style="color: #CC6600;">false</span>;
}
}
}
<span style="color: #CC6600;">void</span> serialEvent(Serial myPort) {
<span style="color: #7E7E7E;">// read a byte from the serial port:</span>
<span style="color: #CC6600;">int</span> inByte = myPort.read();
build_incoming_packet(inByte);
<span style="color: #7E7E7E;">//print(inByte);</span>
<span style="color: #7E7E7E;">//print(",");</span>
}
<span style="color: #7E7E7E;">//Done</span>
DataPacket getNewPacket() {
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
<span style="color: #CC6600;">if</span>(data[i].<span style="color: #CC6600;">status</span> == STATUS_CLEAR){
<span style="color: #CC6600;">return</span> data[i];
}
}
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"BUFFER FULL"</span>);
<span style="color: #CC6600;">return</span> <span style="color: #CC6600;">new</span> DataPacket();
}
<span style="color: #CC6600;">int</span> get_node(DataPacket packet, <span style="color: #CC6600;">int</span> location)
{
<span style="color: #CC6600;">int</span> node;
node = packet.payload[location];
node = node << 4;
node = node | (packet.payload[location+1] >> 4);
<span style="color: #CC6600;">return</span> node;
}
Payload get_payload(DataPacket packet)
{
Payload payload = <span style="color: #CC6600;">new</span> Payload();
payload.<span style="color: #CC6600;">length</span> = packet.payload[PACKET_LENGTH] - OFFSET_PACKET;
<span style="color: #CC6600;">for</span>(i=0; i < payload.<span style="color: #CC6600;">length</span>; i++){
<span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
payload.data[i] = packet.payload[i+OFFSET_HEADER];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(packet.payload[PACKET_SETTINGS] == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> payload;
}
Payload str_to_payload(<span style="color: #CC6600;">String</span> string)
{
Payload payload = <span style="color: #CC6600;">new</span> Payload();
<span style="color: #7E7E7E;">//println("Payload Length: "+ string.length());</span>
<span style="color: #CC6600;">for</span>(i=0;i<string.<span style="color: #CC6600;">length</span>();i++){
payload.data[i] = <span style="color: #CC6600;">int</span>(string.<span style="color: #CC6600;">charAt</span>(i));
}
payload.<span style="color: #CC6600;">length</span> = string.<span style="color: #CC6600;">length</span>();
<span style="color: #CC6600;">return</span> payload;
}
<span style="color: #CC6600;">void</span> process_command(DataPacket packet)
{
<span style="color: #CC6600;">switch</span> (packet.payload[PACKET_COMMAND]) {
<span style="color: #CC6600;">case</span> CMD_PING:
DataPacket reply = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));
reply.<span style="color: #CC6600;">status</span> = STATUS_READY;
<span style="color: #7E7E7E;">//change status to ready to send</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #7E7E7E;">//default:</span>
<span style="color: #7E7E7E;">//send_packet(COMMAND_ERROR,NULL,0);</span>
<span style="color: #7E7E7E;">// break;</span>
}
}
<span style="color: #CC6600;">int</span> _crc16_update(<span style="color: #CC6600;">int</span> crc, <span style="color: #CC6600;">int</span> a)
{
<span style="color: #CC6600;">int</span> i;
crc ^= a;
<span style="color: #CC6600;">for</span> (i = 0; i < 8; ++i){
<span style="color: #CC6600;">if</span> ((crc & 1) == 1){
crc = (crc >> 1) ^ 0xA001;
}<span style="color: #CC6600;">else</span>{
crc = (crc >> 1);
}
}
<span style="color: #CC6600;">return</span> crc & 0xFFFF;
}
<span style="color: #CC6600;">int</span> getId() {
<span style="color: #CC6600;">if</span>(uniqueId == 255){
uniqueId = 0;
}
<span style="color: #CC6600;">return</span> uniqueId++; <span style="color: #7E7E7E;">//what happens when this wraps?</span>
}
<span style="color: #CC6600;">int</span> compressAddress(<span style="color: #CC6600;">int</span> node, <span style="color: #CC6600;">int</span> port)
{
node = node << 4; <span style="color: #7E7E7E;">//make space</span>
port = port & 0x0F;
<span style="color: #CC6600;">return</span> node | port;
}
DataPacket build_tcp_packet(<span style="color: #CC6600;">int</span> fromNode, <span style="color: #CC6600;">int</span> fromPlug, <span style="color: #CC6600;">int</span> toNode, <span style="color: #CC6600;">int</span> toPlug, <span style="color: #CC6600;">int</span> command, Payload payload)
{
DataPacket packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet.payload[PACKET_LENGTH] = payload.<span style="color: #CC6600;">length</span> + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet.payload[PACKET_SETTINGS] = 1;
<span style="color: #CC6600;">int</span> address = compressAddress(fromNode, fromPlug);
packet.payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet.payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload.<span style="color: #CC6600;">length</span>;i++){
packet.payload[PACKET_PAYLOAD+i] = payload.data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> * @return DataPacket * Pointer to the New DataPacket</span>
<span style="color: #7E7E7E;"> */</span>
DataPacket build_udp_packet(<span style="color: #CC6600;">int</span> fromNode, <span style="color: #CC6600;">int</span> fromPlug, <span style="color: #CC6600;">int</span> toNode, <span style="color: #CC6600;">int</span> toPlug, <span style="color: #CC6600;">int</span> command, Payload payload)
{
DataPacket packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet.<span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet.payload[PACKET_LENGTH] = payload.<span style="color: #CC6600;">length</span> + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet.payload[PACKET_SETTINGS] = 2;
<span style="color: #CC6600;">int</span> address = compressAddress(fromNode, fromPlug);
packet.payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet.payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload.<span style="color: #CC6600;">length</span>;i++){
packet.payload[PACKET_PAYLOAD+i] = payload.data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;">uint8_t build_broadcast_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t payload[48], uint8_t length, uint8_t ttl )</span>
<span style="color: #7E7E7E;">{</span>
<span style="color: #7E7E7E;"> byte packetId = getNewPacketId();</span>
<span style="color: #7E7E7E;"> data[packetId].sent = 0;</span>
<span style="color: #7E7E7E;"> return packetId;</span>
<span style="color: #7E7E7E;">}</span>
<span style="color: #7E7E7E;">*/</span>
<span style="color: #CC6600;">boolean</span> send_packet_serial(DataPacket packet)
{
<span style="color: #CC6600;">int</span> dataChecksum = 0;
<span style="color: #CC6600;">for</span>(i=0; i < (packet.payload[PACKET_LENGTH]-2); i++){
dataChecksum = _crc16_update(dataChecksum, packet.payload[i]);
myPort.write(packet.payload[i] & 0xFF);
<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">int</span>((packet.payload[i] & 0xFF)) + <span style="color: #006699;">","</span>);
}
<span style="color: #CC6600;">print</span>((dataChecksum >>8)&0xFF);
<span style="color: #CC6600;">print</span>(<span style="color: #006699;">","</span>);
<span style="color: #CC6600;">print</span>(dataChecksum & 0xFF);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>);
<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"Packet Sent"</span>);
packet.<span style="color: #CC6600;">status</span> = 1;
myPort.write((dataChecksum >> 8) & 0xFF);
myPort.write(dataChecksum & 0xFF);
<span style="color: #CC6600;">return</span> <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">/**</span>
<span style="color: #7E7E7E;"> * turns a packet into a decoded packet</span>
<span style="color: #7E7E7E;"> */</span>
DataPacketDecoded decode_packet(DataPacket packet)
{
DataPacketDecoded decodedPacket = <span style="color: #CC6600;">new</span> DataPacketDecoded();
<span style="color: #7E7E7E;">//Set Packet length</span>
decodedPacket.<span style="color: #CC6600;">length</span> = packet.payload[PACKET_LENGTH];
decodedPacket.<span style="color: #CC6600;">status</span> = packet.<span style="color: #CC6600;">status</span>;
<span style="color: #7E7E7E;">//settings </span>
decodedPacket.settings = packet.payload[PACKET_SETTINGS];
decodedPacket.type = packet.payload[PACKET_SETTINGS]; <span style="color: #7E7E7E;">//right now these are the same things</span>
<span style="color: #7E7E7E;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet.payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet.payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPort = packet.payload[PACKET_FROM+1] &0xF;
<span style="color: #7E7E7E;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet.payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet.payload[PACKET_TO+1] >> 4);
decodedPacket.toPort = packet.payload[PACKET_TO+1] &0xF;
<span style="color: #7E7E7E;">//packet id</span>
decodedPacket.id = packet.payload[PACKET_ID];
<span style="color: #7E7E7E;">//Command</span>
decodedPacket.command = packet.payload[PACKET_COMMAND];
decodedPacket.checksum = packet.checksum;
decodedPacket.ptr = packet.payload[PACKET_LENGTH] - 10;
<span style="color: #CC6600;">for</span>(i=PACKET_PAYLOAD; i < packet.payload[PACKET_LENGTH]; i++){
<span style="color: #CC6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
decodedPacket.payload[i-PACKET_PAYLOAD] = packet.payload[i];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> decodedPacket;
}
<span style="color: #CC6600;">void</span> debug_incoming_packet(DataPacket packet)
{
<span style="color: #CC6600;">background</span>(0);
<span style="color: #7E7E7E;">//println("show packet info");</span>
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">"Packet Info"</span>,5,15);
<span style="color: #CC6600;">int</span> x = 20;
DataPacketDecoded packetDecoded = decode_packet(packet);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" status: "</span> + packetDecoded.<span style="color: #CC6600;">status</span>,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" length: "</span> + packetDecoded.<span style="color: #CC6600;">length</span>,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">"settings: "</span> + packetDecoded.settings,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" type: "</span> + packetDecoded.type,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">"fromNode: "</span> + packetDecoded.fromNode,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">"fromPort: "</span> + packetDecoded.fromPort,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" toNode: "</span> + packetDecoded.toNode,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" toPort: "</span> + packetDecoded.toPort,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" ttl: "</span> + packetDecoded.ttl,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" id: "</span> + packetDecoded.id,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" command: "</span> + packetDecoded.command,10,x+=20);
<span style="color: #CC6600;">String</span> message = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">String</span> message2 = <span style="color: #006699;">""</span>;
<span style="color: #CC6600;">for</span>(i=0; i < packetDecoded.ptr; i++){
message += <span style="color: #CC6600;">int</span>(packetDecoded.payload[i]);
message += <span style="color: #006699;">","</span>;
message2 += <span style="color: #CC6600;">char</span>(packetDecoded.payload[i]);
}
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" payload: "</span> + message,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" payload: "</span> + message2,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">"checksum: "</span> + packetDecoded.checksum,10,x+=20);
<span style="color: #CC6600;">text</span>(<span style="color: #006699;">" ptr: "</span> + packetDecoded.ptr,10,x+=20);<span style="color: #7E7E7E;">//*/</span>
}
</pre><br />
Arduino<br />
<br />
Protocol.h<br />
<pre><span style="color: #7E7E7E;">//Device Codes</span>
#define DVC_LM33 0x01
#define DVC_ST11 0x02
#define DVC_ST15 0x03
#define DVC_DOORCONTACT 0x04
#define DVC_FLIPSWITCH 0x05
#define DVC_LIGHT 0x06
#define DVC_MOTION 0x07
#define DVC_2LINECHAR 0x08
#define DVC_POWER30 0x08
#define DVC_POWER100 0x09
#define DVC_SMARTOUTLET 0x10
#define DVC_RGBLIGHT 0x11
<span style="color: #7E7E7E;">//Command Codes</span>
#define CMD_GET_VERSION 0x01
#define CMD_PING 0x3E
#define CMD_PONG 0xE3
#define CMD_ACK 0x11
#define CMD_READ 0xAA
#define CMD_WRITE 0xBB
#define CMD_PORTTYPE 0xCC
#define CMD_AUTOSENDSTART 0xC1
#define CMD_AUTOSENDSTOP 0xC2
#define CMD_VALUE 0x02
#define CMD_ERROR 0xFF
<span style="color: #7E7E7E;">//@todo commands for different data types?</span>
<span style="color: #7E7E7E;">//decoded packet struct</span>
typedef struct {
uint8_t command;
<span style="color: #7E7E7E;">//if 255 = ready to send // 0 = resend last</span>
uint8_t length;
uint8_t <span style="color: #CC6600;">status</span>;
uint8_t settings; <span style="color: #7E7E7E;">//01010101 //version //type direct or broadcast //ack //ttl //priority //multi</span>
uint8_t type; <span style="color: #7E7E7E;">//1 single tcp, 2 single udp, 3 multipacket tcp</span>
uint16_t fromNode;
uint8_t fromPlug;
uint16_t toNode; <span style="color: #7E7E7E;">//00 is base //xffff is broadcast</span>
uint8_t toPlug;
uint8_t id;
uint8_t ttl;
uint8_t payload[48];
uint16_t checksum;
uint8_t ptr;
} DataPacketDecoded;
<span style="color: #7E7E7E;">//simple data packet</span>
typedef struct {
uint8_t ptr;
uint8_t port;
uint8_t <span style="color: #CC6600;">status</span>;
uint8_t payload[56];
uint16_t checksum;
} DataPacket;
<span style="color: #7E7E7E;">//payload type</span>
typedef struct {
uint8_t length;
uint8_t data[56];
} Payload;
typedef struct {
<span style="color: #CC6600;">long</span> start;
uint8_t waiting;
uint8_t ptr;
} ACKStatus;
typedef struct {
uint8_t type;
uint8_t <span style="color: #CC6600;">status</span>;
} Port;
<span style="color: #7E7E7E;">//shortcuts to important bytes</span>
<span style="color: #7E7E7E;">//keeps from having to decode the whole thing to check simple parts</span>
#define PACKET_LENGTH 0
#define PACKET_SETTINGS 1
#define PACKET_FROM 2
#define PACKET_TO 4
#define PACKET_TTL 4
#define PACKET_ID 6
#define PACKET_COMMAND 7
#define PACKET_PAYLOAD 8
<span style="color: #7E7E7E;">//an enum might be better here</span>
#define STATUS_CLEAR 0
#define STATUS_RECEVING 1
#define STATUS_RECEVIED 2
#define STATUS_WAITING 3
#define STATUS_READY 4
#define STATUS_SENDING 5
#define STATUS_SENT 6
#define STATUS_ACK 7
#define STATUS_SUCCESS 8
#define OFFSET_PACKET 10
#define OFFSET_HEADER 8
#define OFFSET_FOOTER 2
</pre><br />
<br />
Basenode.pde<br />
<pre>#include <util/crc16.<span style="color: #CC6600;">h</span>> <span style="color: #7E7E7E;">//checksum functions</span>
#include <span style="color: #006699;">"protocol.h"</span>
#define NODE_ID 0x02
#define PLUG_A DVC_LM33
#define PLUG_B DVC_LM33
#define PLUG_C DVC_LM33
#define PLUG_D DVC_LM33
#define PACKET_BUFFER 10 <span style="color: #7E7E7E;">//can be adujsted based on availbe space</span>
<span style="color: #7E7E7E;">//#define DEBUG 1;</span>
#define PACKET_TIMEOUT 100
#define PORTTYPE_SERIAL 0
#define PORTTYPE_RF12 1
#define PORT_COUNT 2
#define PORT_0 PORTTYPE_SERIAL
#define PORT_1 PORTTYPE_RF12
<span style="color: #7E7E7E;">//types</span>
<span style="color: #7E7E7E;">//ACK</span>
<span style="color: #7E7E7E;">//Single TCp //requires 2byte packet ID</span>
<span style="color: #7E7E7E;">//Single UDP</span>
<span style="color: #7E7E7E;">//Multi TCP //requires 2byte total ID, 2 byte Packet ID + byte current packet + byte total packets</span>
<span style="color: #7E7E7E;">//multi packet</span>
<span style="color: #7E7E7E;">//packet id</span>
<span style="color: #7E7E7E;">//current packets</span>
<span style="color: #7E7E7E;">//total packets</span>
<span style="color: #7E7E7E;">//</span>
Port ports[] = {{PORTTYPE_SERIAL,STATUS_CLEAR},
{PORTTYPE_RF12,STATUS_CLEAR}};
<span style="color: #7E7E7E;">//list attached ports</span>
<span style="color: #7E7E7E;">//1 2 3 4 //rf12</span>
DataPacket data[PACKET_BUFFER];
uint16_t checksum;
<span style="color: #CC6600;">byte</span> uniqueId = 0;
<span style="color: #CC6600;">byte</span> i;
DataPacket incomingPacket; <span style="color: #7E7E7E;">//current incoming packet</span>
<span style="color: #7E7E7E;">//incomingPacket.ptr = 0;</span>
DataPacket *sendingPacket;
<span style="color: #CC6600;">boolean</span> sending = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">boolean</span> receiving = <span style="color: #CC6600;">false</span>;
<span style="color: #CC6600;">long</span> packetTimer;;
DataPacket *getNewPacket() {
<span style="color: #CC6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
<span style="color: #CC6600;">if</span>(data[i].<span style="color: #CC6600;">status</span> == STATUS_CLEAR){
<span style="color: #CC6600;">return</span> &data[i];
}
}
<span style="color: #7E7E7E;">//Serial.println("all full");</span>
<span style="color: #CC6600;">return</span> 0;
}
uint8_t getId()
{
<span style="color: #CC6600;">return</span> uniqueId++; <span style="color: #7E7E7E;">//loops when it overflows</span>
}
uint16_t compressAddress(uint16_t node, uint8_t port)
{
<span style="color: #CC6600;">return</span> (node << 4) | (port & 0x0F);
}
<span style="color: #7E7E7E;">//byte m = 1;</span>
<span style="color: #CC6600;">void</span> send_packet_serial(DataPacket *packet)
{
uint16_t dataChecksum = 0;
<span style="color: #7E7E7E;">//cause a problem</span>
<span style="color: #7E7E7E;">// m++;</span>
<span style="color: #CC6600;">for</span>(i=0; i < (packet->payload[PACKET_LENGTH]-OFFSET_FOOTER); i++){
dataChecksum = _crc16_update(dataChecksum, packet->payload[i]);
<span style="color: #7E7E7E;">//if((m == 3) && (i == 0)){</span>
<span style="color: #7E7E7E;">// Serial.print(packet->payload[0]-5,BYTE);</span>
<span style="color: #7E7E7E;">// } else {</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(packet->payload[i],<span style="color: #006699;">BYTE</span>);
<span style="color: #7E7E7E;">// }</span>
<span style="color: #7E7E7E;">//Serial.print(",");</span>
}
packet->checksum = dataChecksum;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">highByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);
<span style="color: #7E7E7E;">// Serial.print(",");</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #CC6600;">lowByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);
packet-><span style="color: #CC6600;">status</span> = STATUS_SENT;
<span style="color: #7E7E7E;">//Serial.println("");</span>
}
<span style="color: #CC6600;">void</span> send_packet_rf12(DataPacket *packet)
{
<span style="color: #7E7E7E;">/** //check address only 0-30 allowed</span>
<span style="color: #7E7E7E;"> </span>
<span style="color: #7E7E7E;"> * @todo</span>
<span style="color: #7E7E7E;"> */</span>
}
<span style="color: #CC6600;">void</span> process_command(DataPacket *packet)
{
<span style="color: #CC6600;">switch</span> (packet->payload[PACKET_COMMAND]) {
<span style="color: #CC6600;">case</span> CMD_PING:
DataPacket *reply = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, get_payload(packet));
reply-><span style="color: #CC6600;">status</span> = STATUS_READY;
<span style="color: #7E7E7E;">//change status to ready to send</span>
<span style="color: #CC6600;">break</span>;
<span style="color: #7E7E7E;">//default:</span>
<span style="color: #7E7E7E;">//send_packet(COMMAND_ERROR,NULL,0);</span>
<span style="color: #7E7E7E;">// break;</span>
}
}
<span style="color: #7E7E7E;">//build rf12 packet</span>
<span style="color: #CC6600;">void</span> build_incoming_packet(uint8_t byteIn)
{
<span style="color: #7E7E7E;">//mark which port it is coming from</span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7E7E7E;">//Packet length</span>
<span style="color: #CC6600;">if</span>(byteIn == 0) {
<span style="color: #7E7E7E;">//resend last</span>
sendingPacket-><span style="color: #CC6600;">status</span> = STATUS_SENDING;
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span>(byteIn == 255) {
sendingPacket-><span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
<span style="color: #7E7E7E;">//aknowledge</span>
<span style="color: #CC6600;">return</span>;
}
<span style="color: #CC6600;">if</span> (byteIn > 128) {
<span style="color: #7E7E7E;">//Serial.flush();</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(0,<span style="color: #006699;">BYTE</span>);
<span style="color: #CC6600;">return</span>;
}
receiving = <span style="color: #CC6600;">true</span>;
packetTimer = <span style="color: #CC6600;">millis</span>();
incomingPacket.payload[PACKET_LENGTH] = byteIn;
incomingPacket.<span style="color: #CC6600;">status</span> = STATUS_RECEVING;
checksum = 0;
}
<span style="color: #7E7E7E;">//checksum </span>
<span style="color: #CC6600;">if</span>(incomingPacket.ptr < (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = byteIn;
checksum = _crc16_update(checksum, byteIn);
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(incomingPacket.ptr == (incomingPacket.payload[PACKET_LENGTH] - OFFSET_FOOTER)){ <span style="color: #7E7E7E;">//get first byte of checksum</span>
incomingPacket.checksum = byteIn;
incomingPacket.ptr++;
<span style="color: #CC6600;">return</span>;
} <span style="color: #CC6600;">else</span> { <span style="color: #7E7E7E;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | (byteIn & 0xFF);
<span style="color: #CC6600;">if</span>(checksum != incomingPacket.checksum) {
<span style="color: #7E7E7E;">//Serial.println(checksum, DEC); </span>
<span style="color: #7E7E7E;">//Serial.println(incomingPacket.checksum, DEC); </span>
DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_ERROR, packet_to_payload(&incomingPacket));
p-><span style="color: #CC6600;">status</span> = STATUS_READY;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">flush</span>();
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(1,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node to resend last</span>
} <span style="color: #CC6600;">else</span> {
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_RECEVIED;
DataPacket *packet = getNewPacket();
*packet = incomingPacket;
<span style="color: #7E7E7E;">//Serial.flush();</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(255,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node the packet was successful</span>
}
<span style="color: #7E7E7E;">//reset incomingPacket</span>
receiving = <span style="color: #CC6600;">false</span>;
incomingPacket.<span style="color: #CC6600;">status</span>=STATUS_CLEAR;
incomingPacket.ptr = 0;
}
}
<span style="color: #7E7E7E;">//determine where to send packet. how to expand when we have 4 serial ports?</span>
<span style="color: #CC6600;">void</span> process_stack(){
<span style="color: #7E7E7E;">//sending = false; //only send one pack per cycle</span>
<span style="color: #CC6600;">for</span>(i=0;i<PACKET_BUFFER;i++){
process_packet(&data[i]);
}
<span style="color: #7E7E7E;">//check for packets to send</span>
<span style="color: #7E7E7E;">//check for packets to resend if ACKs are late</span>
<span style="color: #7E7E7E;">//check for data packets that can be deleted from the stack </span>
}
<span style="color: #CC6600;">void</span> process_packet(DataPacket *packet){
<span style="color: #CC6600;">switch</span> (packet-><span style="color: #CC6600;">status</span>){
<span style="color: #CC6600;">case</span> STATUS_CLEAR:
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"CLEAR"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVING:
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_RECEVIED:
process_command(packet);
packet-><span style="color: #CC6600;">status</span> = STATUS_CLEAR;
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"RECEVIED"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_WAITING:
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"WAITING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_READY:
<span style="color: #7E7E7E;">//check for free port</span>
<span style="color: #CC6600;">if</span>(sending == <span style="color: #CC6600;">false</span>){
packet-><span style="color: #CC6600;">status</span> = STATUS_SENDING;
sendingPacket = packet;
sending = <span style="color: #CC6600;">true</span>;
}
<span style="color: #7E7E7E;">//if reset pointer and set to send</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"READY"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENDING:
<span style="color: #7E7E7E;">//because of the above, only one packet will be changed to sending</span>
<span style="color: #7E7E7E;">//if(get_node(packet,PACKET_FROM) < 30){</span>
<span style="color: #7E7E7E;">// send_packet_rf12(packet); </span>
<span style="color: #7E7E7E;">//} else {</span>
send_packet_serial(packet);
<span style="color: #7E7E7E;">// }</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_SENT;
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENDING"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SENT:
<span style="color: #7E7E7E;">//if is a ack packet </span>
<span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] == 1){
packet-><span style="color: #CC6600;">status</span> = STATUS_ACK;
<span style="color: #7E7E7E;">//start packets ack timer</span>
} <span style="color: #CC6600;">else</span> {
<span style="color: #7E7E7E;">//packet->status = STATUS_SUCCESS;</span>
}
#ifdef DEBUG
sending = <span style="color: #CC6600;">false</span>; <span style="color: #7E7E7E;">//allow next packet to send</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_SUCCESS;
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SENT"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_ACK:
<span style="color: #7E7E7E;">//if execeded timer resen</span>
<span style="color: #7E7E7E;">//count resends if exceds max kill packet and add error</span>
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"ACK"</span>);
#endif
<span style="color: #CC6600;">break</span>;
<span style="color: #CC6600;">case</span> STATUS_SUCCESS:
<span style="color: #7E7E7E;">//option to post status to screen</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_CLEAR;
#ifdef DEBUG
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">"SUCCESS"</span>);
#endif
<span style="color: #CC6600;">break</span>;
}
}
<span style="color: #CC6600;">unsigned</span> counter = 0;
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>setup</b></span>()
{
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">begin</span>(115200);
<span style="color: #7E7E7E;">//Serial.println("Ping:");</span>
<span style="color: #7E7E7E;">//Serial.print("nodeID: ");</span>
<span style="color: #7E7E7E;">// Serial.println(NODE_ID,DEC);</span>
<span style="color: #7E7E7E;">// int sendPacketId = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PING, (byte*)"TEST TEST TEST", 1);</span>
<span style="color: #7E7E7E;">// int sendPacketId2 = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, (byte*)"HA HA HA", 8);</span>
<span style="color: #7E7E7E;">//send_packet_serial(sendPacketId);</span>
<span style="color: #7E7E7E;">//Serial.println("");</span>
<span style="color: #7E7E7E;">/**/</span>
<span style="color: #7E7E7E;">//DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, str_to_payload("TEEEST"));</span>
<span style="color: #7E7E7E;">// send_packet_serial(p);</span>
<span style="color: #7E7E7E;">// debug_packet(p);</span>
}
<span style="color: #CC6600;">void</span> <span style="color: #CC6600;"><b>loop</b></span>() {
<span style="color: #7E7E7E;">//byte message[1] = {uniqueId};</span>
<span style="color: #7E7E7E;">//message[15] = uniqueId;</span>
<span style="color: #7E7E7E;">//int sendPacketId = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PING, message, 1);</span>
<span style="color: #7E7E7E;">// int sendPacketId2 = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PONG, (byte*)"HA HA HA", 8);</span>
<span style="color: #CC6600;">if</span>(counter > 50000) {
DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_VALUE, str_to_payload(<span style="color: #006699;">"ha ha ha22222"</span>));
p-><span style="color: #CC6600;">status</span> = STATUS_READY;
counter = 0;
}
counter++;
process_stack();
<span style="color: #7E7E7E;">//recieve timer</span>
<span style="color: #7E7E7E;">//and send command to resend last</span>
<span style="color: #CC6600;">int</span> byteIn;
<span style="color: #CC6600;">if</span> (<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">available</span>()>0) {
byteIn = <span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">read</span>();
build_incoming_packet(byteIn);
}
process_stack();
<span style="color: #CC6600;">if</span>(receiving == <span style="color: #CC6600;">true</span>) {
<span style="color: #CC6600;">if</span>((<span style="color: #CC6600;">millis</span>() - packetTimer) > PACKET_TIMEOUT) {
<span style="color: #7E7E7E;">//Serial.flush();</span>
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(2,<span style="color: #006699;">BYTE</span>); <span style="color: #7E7E7E;">//tell the node to resend last</span>
<span style="color: #7E7E7E;">//DataPacket *p = build_udp_packet(NODE_ID, 1, 0, 0, CMD_ERROR, packet_to_payload(&incomingPacket));</span>
<span style="color: #7E7E7E;">// p->status = STATUS_READY;</span>
receiving = <span style="color: #CC6600;">false</span>;
}
}
<span style="color: #7E7E7E;">//delay(5); </span>
}
<span style="color: #7E7E7E;">/*FINISHED*/</span>
Payload *get_payload(DataPacket *packet)
{
Payload payload;
payload.length = packet->payload[PACKET_LENGTH] - OFFSET_PACKET;
<span style="color: #CC6600;">for</span>(i=0; i < payload.length; i++){
<span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP</span>
payload.data[i] = packet->payload[i+OFFSET_HEADER];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(packet->payload[PACKET_SETTINGS] == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
<span style="color: #CC6600;">return</span> &payload;
}
Payload *packet_to_payload(DataPacket *packet)
{
Payload payload;
payload.length = packet->payload[PACKET_LENGTH];
<span style="color: #CC6600;">for</span>(i=0; i < (payload.length - OFFSET_FOOTER); i++){
payload.data[i] = packet->payload[i];
}
payload.data[payload.length - OFFSET_FOOTER] = <span style="color: #CC6600;">highByte</span>(packet->checksum);
payload.data[payload.length - OFFSET_FOOTER + 1] = <span style="color: #CC6600;">lowByte</span>(packet->checksum);
<span style="color: #CC6600;">return</span> &payload;
}
uint16_t get_node(DataPacket *packet, uint8_t location)
{
uint16_t node;
node = packet->payload[location];
node = node << 4;
node = node | (packet->payload[location+1] >> 4);
<span style="color: #CC6600;">return</span> node;
}
Payload *str_to_payload(<span style="color: #CC6600;">char</span> string[])
{
Payload payload;
i=0;
<span style="color: #CC6600;">while</span>(string[i] != 0){
payload.data[i] = <span style="color: #CC6600;">byte</span>(string[i]);
i++;
}
payload.length = i;
<span style="color: #7E7E7E;">//Serial.print("sizeOf: ");</span>
<span style="color: #7E7E7E;">// Serial.println(i,DEC);</span>
<span style="color: #CC6600;">return</span> &payload;
}
Payload *long_to_payload(<span style="color: #CC6600;">long</span> number)
{
Payload payload;
i=(sizeof(number)-1);
payload.length = i;
<span style="color: #CC6600;">while</span>(i != 0){
payload.data[i] = number & 0xFF;
number = number >> 8;
i--;
}
<span style="color: #CC6600;">return</span> &payload;
}
Payload *uint16_to_payload(uint16_t number)
{
Payload payload;
payload.length = 2;
payload.data[0] = <span style="color: #CC6600;">highByte</span>(number);
payload.data[1] = <span style="color: #CC6600;">lowByte</span>(number);
<span style="color: #CC6600;">return</span> &payload;
}
DataPacket *build_tcp_packet(uint16_t fromNode, uint8_t fromPlug, uint16_t toNode, uint8_t toPlug, uint8_t command, Payload *payload)
{
DataPacket *packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet->payload[PACKET_LENGTH] = payload->length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet->payload[PACKET_SETTINGS] = 1;
uint16_t address = compressAddress(fromNode, fromPlug);
packet->payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet->payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet->payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet->payload[PACKET_TO+1] = address & 0xFF;
packet->payload[PACKET_ID] = getId();
packet->payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload->length;i++){
packet->payload[PACKET_PAYLOAD+i] = payload->data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/*</span>
<span style="color: #7E7E7E;"> * @return DataPacket * Pointer to the New DataPacket</span>
<span style="color: #7E7E7E;"> */</span>
DataPacket *build_udp_packet(uint16_t fromNode, uint8_t fromPlug, uint16_t toNode, uint8_t toPlug, uint8_t command, Payload *payload)
{
DataPacket *packet = getNewPacket();
<span style="color: #7E7E7E;">//*packet.status = STATUS_READY;</span>
packet-><span style="color: #CC6600;">status</span> = STATUS_WAITING;
packet->payload[PACKET_LENGTH] = payload->length + OFFSET_PACKET; <span style="color: #7E7E7E;">//header 8 crc 2</span>
packet->payload[PACKET_SETTINGS] = 2;
uint16_t address = compressAddress(fromNode, fromPlug);
packet->payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet->payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPlug);
packet->payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet->payload[PACKET_TO+1] = address & 0xFF;
packet->payload[PACKET_ID] = getId();
packet->payload[PACKET_COMMAND] = command;
<span style="color: #CC6600;">for</span>(i=0;i < payload->length;i++){
packet->payload[PACKET_PAYLOAD+i] = payload->data[i];
}
<span style="color: #CC6600;">return</span> packet;
}
DataPacket *build_broadcast_packet(uint16_t fromNode, uint8_t fromPlug, uint8_t ttl, Payload payload)
{
DataPacket *packet = getNewPacket();
packet-><span style="color: #CC6600;">status</span> = STATUS_WAITING;
<span style="color: #CC6600;">return</span> packet;
}
<span style="color: #7E7E7E;">/**</span>
<span style="color: #7E7E7E;"> * turns a packet into a decoded packet</span>
<span style="color: #7E7E7E;"> */</span>
DataPacketDecoded decode_packet(DataPacket *packet)
{
DataPacketDecoded decodedPacket;
decodedPacket.ttl = 0;
<span style="color: #7E7E7E;">//Set Packet length</span>
decodedPacket.length = packet->payload[PACKET_LENGTH];
decodedPacket.<span style="color: #CC6600;">status</span> = packet-><span style="color: #CC6600;">status</span>;
<span style="color: #7E7E7E;">//settings </span>
decodedPacket.settings = packet->payload[PACKET_SETTINGS];
decodedPacket.type = packet->payload[PACKET_SETTINGS]; <span style="color: #7E7E7E;">//right now these are the same things</span>
<span style="color: #7E7E7E;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet->payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet->payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPlug = packet->payload[PACKET_FROM+1] &0xF;
<span style="color: #7E7E7E;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet->payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet->payload[PACKET_TO+1] >> 4);
decodedPacket.toPlug = packet->payload[PACKET_TO+1] &0xF;
<span style="color: #7E7E7E;">//packet id</span>
decodedPacket.id = packet->payload[PACKET_ID];
<span style="color: #7E7E7E;">//Command</span>
decodedPacket.command = packet->payload[PACKET_COMMAND];
decodedPacket.ptr = packet->payload[PACKET_LENGTH] - OFFSET_PACKET;
Payload *payload = get_payload(packet);
<span style="color: #CC6600;">for</span>(i=0; i < payload->length; i++){
<span style="color: #CC6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7E7E7E;">//single packet TCP or UDP </span>
decodedPacket.payload[i] = payload->data[i];
} <span style="color: #CC6600;">else</span> <span style="color: #CC6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7E7E7E;">//broadcast</span>
<span style="color: #7E7E7E;">//todo</span>
}
}
decodedPacket.checksum=packet->checksum;
<span style="color: #CC6600;">return</span> decodedPacket;
}
<span style="color: #CC6600;">void</span> debug_packet(DataPacket *packet){
DataPacketDecoded sendPacketedDecoded = decode_packet(packet);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" sent: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.<span style="color: #CC6600;">status</span>,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" length: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.length,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"settings: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.settings,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" type: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.type,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"fromNode: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.fromNode,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"fromPlug: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.fromPlug,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" toNode: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.toNode,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" toPlug: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.toPlug,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" ttl: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.ttl,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" id: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.id,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" command: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.command,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" payload: "</span>);
<span style="color: #CC6600;">for</span>(i=0; i < sendPacketedDecoded.ptr; i++){
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(sendPacketedDecoded.payload[i],<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">","</span>);
}
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" payload: "</span>);
<span style="color: #CC6600;">for</span>(i=0; i < sendPacketedDecoded.ptr; i++){
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(sendPacketedDecoded.payload[i],<span style="color: #006699;">BYTE</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">","</span>);
}
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(<span style="color: #006699;">""</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">"checksum: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.checksum,<span style="color: #006699;">DEC</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">print</span>(<span style="color: #006699;">" ptr: "</span>);
<span style="color: #CC6600;"><b>Serial</b></span>.<span style="color: #CC6600;">println</span>(sendPacketedDecoded.ptr,<span style="color: #006699;">DEC</span>);
}
</pre><br />
Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-12961940224318320362010-11-03T00:08:00.000-07:002010-11-03T00:20:23.616-07:00Goals and IssuesBelow is current look at some of goals and issues I'm currently dealing with-<br />
<br />
So far my project has three main components: <br />
<br />
Sensor Network <-> Base Station <-> Web Interface<br />
<br />
They are interconnected and pass data between each other.<br />
<br />
<h2>Sensor Network </h2><br />
The sensor network is gathering the sensor data is currently based on Jeenodes which are Arduino based nodes.<br />
<br />
<b>Status</b>: Hardware has been solder together, sensors have been purchased and the code for the protocol has been written. <br />
<br />
<b>Goals</b><br />
<ul><li>Create robust adaptable nodes that can easily be reconfigured</li>
<li>Create Wired and Wireless Links</li>
<li>Create a Mesh Network</li>
</ul><b> Current Issues </b><br />
<ul><li>How to design so an average user can configure a node? Pre programed ROM? Dip switches? Web interface?</li>
<ul><li>Solution: Processing sketch that directly communicates with node to set address and sensor configuration to the Arduino ROM</li>
</ul><li>Current Wireless Chip doesn't do mesh networking: cost prohibitive </li>
</ul><br />
<h2>Base Station</h2><br />
A Server program running on a PC reads packets of data from the sensor network and passes them on to a web interface. Currently using a Processing.org Java Program<br />
<br />
<b>Status</b>: Protocol code has been ported to java. Actual interface still needs to be built. <br />
<br />
<b>Goals</b><br />
<ul><li>Be user configurable</li>
<li>Easy to deploy/setup</li>
</ul><br />
<b>Current Issues</b><br />
<ul><li>How to Connect to Web server?</li>
<ul><li>XML-RPC seems like the simplest solution right now and offers a lot of flexibility. </li>
<li>Using EEML like pachube might work too but would require a lot more code.</li>
</ul><li>How to save settings? flat file, SQL database, remotel? </li>
<ul><li>I haven't decided how to solve this yet. Some settings must be saved locally, ie web server address, Pachube api key. Using an XML file is the best soultion for this. </li>
<li>Other settings like node and sensors names would be better stored in a better database if it is to scale to thousands of sensors. Can it call a remote server to get this info or should it be local?</li>
</ul><li>How to store data if Internet Connection goes down? </li>
<ul><li>Store it memory is the easiest, SQL would be better</li>
</ul></ul><br />
<h2>Web Interface</h2><br />
<b>Status</b>: In planning. <br />
<br />
The web interface right now is going to be using LAMP Linux, Apache, mySQL and PHP. The code is going to based on the Zend Framework and a UI library I started writng a while back. The front end is going to use jQuery and jQueryUI. Graphs will use the Google Graph API.<br />
<br />
<b>Goals</b><br />
<ul><li>Work on a varety of platforms and screen sizes</li>
<li>Use Web 2.0 Ajax etc. Jquery</li>
<li>Create an interactive Remote for the network </li>
</ul><b>Current Issues</b><br />
<ul><li> Server local or remote?</li>
<ul><li>A good webserver is hard for an average user to setup. A remote server can also handle more users. User can also access the remote to get info about power/data outages</li>
</ul></ul>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-66415345465370209462010-11-02T17:15:00.000-07:002010-11-02T20:04:57.376-07:00XML-RPC A better way to connect Processing and the WebAfter yesterdays post about how to connect the webserver to the processing sketch, I thought that there had to be a better way and there is.<br />
<br />
There is a nice <a href="http://plw.media.mit.edu/people/arikan/xmlrpclib/">XML-RPC Library</a> for Processing that someone at MIT wrote. XML-RPC is very common on the web so there are multiple ways to implement in php, <strike>the best way is probably with the built in <a href="http://php.net/manual/en/book.xmlrpc.php">XML-RPC Class</a></strike>. After reading the documentation the built in funtions aren't well documented. It looks like I will be using the <a href="http://zendframework.com/manual/en/zend.xmlrpc.html">ZendFramework XML-RPC Module</a>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-24554282746090446042010-11-01T20:56:00.000-07:002010-11-30T16:04:31.076-08:00First Packet TestThe Arduino sends test packets to processing which decodes them on screen<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5138157141/" title="IMG_3087 by ArchiCroc, on Flickr"><img alt="IMG_3087" height="500" src="http://farm2.static.flickr.com/1402/5138157141_58aa49084d.jpg" width="333" /></a><br />
<br />
Code after the jump<br />
<a name='more'></a><br />
Arduino Code<br />
<pre><span style="color: #7e7e7e;">//protocol.h</span>
<span style="color: #7e7e7e;">//Device Codes</span>
#define DVC_LM33 0x01
#define DVC_ST11 0x02
#define DVC_ST15 0x03
#define DVC_DOORCONTACT 0x04
#define DVC_FLIPSWITCH 0x05
#define DVC_LIGHT 0x06
#define DVC_MOTION 0x07
#define DVC_2LINECHAR 0x08
#define DVC_POWER30 0x08
#define DVC_POWER100 0x09
#define DVC_SMARTOUTLET 0x10
#define DVC_RGBLIGHT 0x11
<span style="color: #7e7e7e;">//Command Codes</span>
#define CMD_GET_VERSION 0x01
#define CMD_PING 65
#define CMD_PONG 0xE3
#define CMD_ACK 0x11
#define CMD_READ 0xAA
#define CMD_WRITE 0xBB
#define CMD_PORTTYPE 0xCC
#define CMD_AUTOSENDSTART 0xC1
#define CMD_AUTOSENDSTOP 0xC2
#define CMD_ERROR 0xFF
<span style="color: #7e7e7e;">//@todo commands for different data types?</span>
<span style="color: #7e7e7e;">//decoded packet struct</span>
typedef struct {
uint8_t command;
<span style="color: #7e7e7e;">//if 255 = ready to send // 0 = resend last</span>
uint8_t length;
uint8_t sent;
uint8_t settings; <span style="color: #7e7e7e;">//01010101 //version //type direct or broadcast //ack //ttl //priority //multi</span>
uint8_t type; <span style="color: #7e7e7e;">//1 single tcp, 2 single udp, 3 multipacket tcp</span>
uint16_t fromNode;
uint8_t fromPort;
uint16_t toNode; <span style="color: #7e7e7e;">//00 is base //xffff is broadcast</span>
uint8_t toPort;
uint8_t id;
uint8_t ttl;
uint8_t payload[48];
uint16_t checksum;
uint8_t ptr;
} DataPacketDecoded;
<span style="color: #7e7e7e;">//simple data packet</span>
typedef struct {
uint8_t ptr;
uint8_t sent;
uint8_t payload[56];
uint16_t checksum;
} DataPacket;
<span style="color: #7e7e7e;">//shortcuts to important bytes</span>
<span style="color: #7e7e7e;">//keeps from having to decode the whole thing to check simple parts</span>
#define PACKET_LENGTH 0
#define PACKET_SETTINGS 1
#define PACKET_FROM 2
#define PACKET_TO 4
#define PACKET_TTL 4
#define PACKET_ID 6
#define PACKET_COMMAND 7
#define PACKET_PAYLOAD 8
<span style="color: #7e7e7e;">//send_test_packet.pde</span>
#include <util crc16.=""><span style="color: #cc6600;">h</span>> <span style="color: #7e7e7e;">//checksum functions</span>
#include <span style="color: #006699;">"protocol.h"</span>
#define NODE_ID 0x02
#define PORT_A DVC_LM33
#define PORT_B DVC_LM33
#define PORT_C DVC_LM33
#define PORT_D DVC_LM33
#define PACKET_BUFFER 4 <span style="color: #7e7e7e;">//can be adujsted based on availbe space</span>
#define debug 1;
<span style="color: #7e7e7e;">//types</span>
<span style="color: #7e7e7e;">//ACK</span>
<span style="color: #7e7e7e;">//Single TCp //requires 2byte packet ID</span>
<span style="color: #7e7e7e;">//Single UDP</span>
<span style="color: #7e7e7e;">//Multi TCP //requires 2byte total ID, 2 byte Packet ID + byte current packet + byte total packets</span>
<span style="color: #7e7e7e;">//multi packet</span>
<span style="color: #7e7e7e;">//packet id</span>
<span style="color: #7e7e7e;">//current packets</span>
<span style="color: #7e7e7e;">//total packets</span>
<span style="color: #7e7e7e;">//</span>
DataPacket data[PACKET_BUFFER];
DataPacketDecoded dataDecoded[2];
<span style="color: #cc6600;">byte</span> dataPtr = 0;
uint16_t checksum;
<span style="color: #cc6600;">byte</span> dataId = 0;
<span style="color: #cc6600;">byte</span> packetIds = 0;
<span style="color: #cc6600;">byte</span> uniqueId = 0;
<span style="color: #cc6600;">byte</span> i;
DataPacket incomingPacket; <span style="color: #7e7e7e;">//current incoming packet</span>
<span style="color: #7e7e7e;">//incomingPacket.ptr = 0;</span>
<span style="color: #cc6600;">byte</span> getNewPacketId() {
<span style="color: #cc6600;">for</span>(i=0; i < PACKET_BUFFER; i++) {
<span style="color: #cc6600;">if</span>(data[i].payload[PACKET_SETTINGS] == 0){
<span style="color: #cc6600;">return</span> i;
}
}
}
<span style="color: #cc6600;">byte</span> getId() {
<span style="color: #cc6600;">return</span> uniqueId++; <span style="color: #7e7e7e;">//what happens when this overflows?</span>
}
uint16_t compressAddress(uint16_t node, uint8_t port)
{
<span style="color: #cc6600;">return</span> (node << 4) | (port & 0x0F);
}
<span style="color: #cc6600;">boolean</span> send_packet_serial(uint8_t packetId)
{
uint16_t dataChecksum = 0;
<span style="color: #cc6600;">for</span>(i=0; i < (data[packetId].payload[PACKET_LENGTH]-2); i++){
dataChecksum = _crc16_update(dataChecksum, data[packetId].payload[i]);
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(data[packetId].payload[i],<span style="color: #006699;">BYTE</span>);
<span style="color: #7e7e7e;">// Serial.print(",");</span>
}
data[packetId].<span style="color: #cc6600;">status</span> = 1;
data[packetId].checksum = dataChecksum;
<span style="color: #7e7e7e;">//Serial.println("");</span>
<span style="color: #7e7e7e;">// Serial.print("checksum: ");</span>
<span style="color: #7e7e7e;">//Serial.print(dataChecksum,BYTE);</span>
<span style="color: #7e7e7e;">//Serial.print("checksum: ");</span>
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(<span style="color: #cc6600;">highByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);
<span style="color: #7e7e7e;">// Serial.print(",");</span>
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(<span style="color: #cc6600;">lowByte</span>(dataChecksum),<span style="color: #006699;">BYTE</span>);<span style="color: #7e7e7e;">//*/</span>
}
uint8_t build_tcp_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t command, uint8_t payload[48], uint8_t length)
{
<span style="color: #cc6600;">byte</span> packetId = getNewPacketId();
data[packetId].<span style="color: #cc6600;">status</span> = 0;
data[packetId].payload[PACKET_LENGTH] = length + 10; <span style="color: #7e7e7e;">//header 8 crc 2</span>
data[packetId].payload[PACKET_SETTINGS] = 1;
uint16_t address = compressAddress(fromNode, fromPort);
data[packetId].payload[PACKET_FROM] = <span style="color: #cc6600;">highByte</span>(address);
data[packetId].payload[PACKET_FROM+1] = <span style="color: #cc6600;">lowByte</span>(address);
address = compressAddress(toNode, toPort);
data[packetId].payload[PACKET_TO ] = <span style="color: #cc6600;">highByte</span>(address);
data[packetId].payload[PACKET_TO+1] = <span style="color: #cc6600;">lowByte</span>(address);
data[packetId].payload[PACKET_ID] = getId();
data[packetId].payload[PACKET_COMMAND] = command;
<span style="color: #cc6600;">for</span>(i=0;i < length;i++){
data[packetId].payload[PACKET_PAYLOAD+i] = payload[i];
}
<span style="color: #cc6600;">return</span> packetId;
}
<span style="color: #cc6600;">byte</span> build_udp_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t command, uint8_t payload[48], uint8_t length)
{
<span style="color: #cc6600;">byte</span> packetId = getNewPacketId();
data[packetId].<span style="color: #cc6600;">status</span> = 0;
data[packetId].payload[PACKET_LENGTH] = length + 10;
data[packetId].payload[PACKET_SETTINGS] = 2;
uint16_t address = compressAddress(fromNode, fromPort);
data[packetId].payload[PACKET_FROM] = <span style="color: #cc6600;">highByte</span>(address);
data[packetId].payload[PACKET_FROM+1] = <span style="color: #cc6600;">lowByte</span>(address);
address = compressAddress(toNode, toPort);
data[packetId].payload[PACKET_TO ] = <span style="color: #cc6600;">highByte</span>(address);
data[packetId].payload[PACKET_TO+1] = <span style="color: #cc6600;">lowByte</span>(address);
data[packetId].payload[PACKET_ID] = getId();
data[packetId].payload[PACKET_COMMAND] = command;
<span style="color: #cc6600;">for</span>(i=0;i < length;i++){
data[packetId].payload[PACKET_PAYLOAD+i] = payload[i];
}
<span style="color: #cc6600;">return</span> packetId;
}
uint8_t build_broadcast_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t payload[48], uint8_t length, uint8_t ttl )
{
<span style="color: #cc6600;">byte</span> packetId = getNewPacketId();
data[packetId].<span style="color: #cc6600;">status</span> = 0;
<span style="color: #cc6600;">return</span> packetId;
}
<span style="color: #cc6600;">void</span> process_command(DataPacketDecoded packet)
{
<span style="color: #cc6600;">switch</span> (packet.command) {
<span style="color: #cc6600;">case</span> CMD_PING:
<span style="color: #7e7e7e;">//replyPacket.payload = packet.payload;</span>
<span style="color: #7e7e7e;">//replyPacket.command = CMD_PONG;</span>
<span style="color: #7e7e7e;">//replyPacket.fromNode = NODE_ID;</span>
<span style="color: #7e7e7e;">//send_packet(packet);</span>
<span style="color: #cc6600;">break</span>;
<span style="color: #cc6600;">default</span>:
<span style="color: #7e7e7e;">//send_packet(COMMAND_ERROR,NULL,0);</span>
<span style="color: #cc6600;">break</span>;
}
}
<span style="color: #7e7e7e;">/**</span>
<span style="color: #7e7e7e;"> * turns a packet into a decoded packet</span>
<span style="color: #7e7e7e;"> */</span>
DataPacketDecoded decode_packet(DataPacket packet)
{
DataPacketDecoded decodedPacket;
decodedPacket.ttl = 0;
<span style="color: #7e7e7e;">//Set Packet length</span>
decodedPacket.length = packet.payload[PACKET_LENGTH];
decodedPacket.<span style="color: #cc6600;">status</span> = packet.<span style="color: #cc6600;">status</span>;
<span style="color: #7e7e7e;">//settings </span>
decodedPacket.settings = packet.payload[PACKET_SETTINGS];
decodedPacket.type = packet.payload[PACKET_SETTINGS]; <span style="color: #7e7e7e;">//right now these are the same things</span>
<span style="color: #7e7e7e;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet.payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet.payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPort = packet.payload[PACKET_FROM+1] &0xF;
<span style="color: #7e7e7e;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet.payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet.payload[PACKET_TO+1] >> 4);
decodedPacket.toPort = packet.payload[PACKET_TO+1] &0xF;
<span style="color: #7e7e7e;">//packet id</span>
decodedPacket.id = packet.payload[PACKET_ID];
<span style="color: #7e7e7e;">//Command</span>
decodedPacket.command = packet.payload[PACKET_COMMAND];
decodedPacket.ptr = packet.payload[PACKET_LENGTH] - 8;
<span style="color: #cc6600;">for</span>(i=PACKET_PAYLOAD; i < (packet.payload[PACKET_LENGTH] - 2); i++){
<span style="color: #cc6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7e7e7e;">//single packet TCP or UDP</span>
decodedPacket.payload[i-PACKET_PAYLOAD] = packet.payload[i];
} <span style="color: #cc6600;">else</span> <span style="color: #cc6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7e7e7e;">//broadcast</span>
<span style="color: #7e7e7e;">//todo</span>
}
}
decodedPacket.checksum=packet.checksum;
<span style="color: #cc6600;">return</span> decodedPacket;
}
<span style="color: #cc6600;">void</span> build_incoming_packet(uint8_t bIn)
{
<span style="color: #cc6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7e7e7e;">//Packet length</span>
<span style="color: #cc6600;">if</span>(bIn == 0) {
<span style="color: #7e7e7e;">//resend last</span>
<span style="color: #cc6600;">return</span>;
}
<span style="color: #cc6600;">if</span>(bIn == 255) {
<span style="color: #7e7e7e;">//aknowledge</span>
<span style="color: #7e7e7e;">//delete packet from que</span>
<span style="color: #7e7e7e;">//reset last pointer</span>
<span style="color: #cc6600;">return</span>;
}
<span style="color: #cc6600;">if</span> (bIn > 128) {
<span style="color: #7e7e7e;">//stop sending current packet</span>
<span style="color: #7e7e7e;">//flush</span>
<span style="color: #cc6600;">return</span>;
}
incomingPacket.payload[PACKET_LENGTH] = bIn;
uint16_t temp;
checksum = 0;
}
<span style="color: #7e7e7e;">//checksum </span>
<span style="color: #cc6600;">if</span>(incomingPacket.ptr < incomingPacket.payload[PACKET_LENGTH]){ <span style="color: #7e7e7e;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = bIn;
checksum = _crc16_update(checksum, bIn);
} <span style="color: #cc6600;">else</span> <span style="color: #cc6600;">if</span>(incomingPacket.ptr == incomingPacket.payload[PACKET_LENGTH]){ <span style="color: #7e7e7e;">//get first byte of checksum</span>
incomingPacket.checksum = bIn;
} <span style="color: #cc6600;">else</span> { <span style="color: #7e7e7e;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | bIn;
<span style="color: #cc6600;">if</span>(checksum != incomingPacket.checksum) {
<span style="color: #7e7e7e;">//Serial.println(checksum, DEC); </span>
<span style="color: #7e7e7e;">//Serial.println(incomingPacket.checksum, DEC); </span>
<span style="color: #7e7e7e;">//Serial.println("Failed CRC Check"); </span>
incomingPacket.ptr=0;
} <span style="color: #cc6600;">else</span> {
i = getNewPacketId();
data[i] = incomingPacket;
incomingPacket.ptr=0;
}
}
incomingPacket.ptr++;
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>()
{
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">begin</span>(115200);
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>loop</b></span>() {
<span style="color: #cc6600;">byte</span> message[1] = {uniqueId};
<span style="color: #cc6600;">int</span> sendPacketId = build_udp_packet(NODE_ID, 1, 0, 0, CMD_PING, message, 1);
send_packet_serial(sendPacketId);
<span style="color: #cc6600;">delay</span>(2000);
}
</util></pre><br />
Processing Code <br />
<pre><span style="color: #7e7e7e;">//Device Codes</span>
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_LM33 = 0x01;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_ST11 = 0x02;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_ST15 = 0x03;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_DOORCONTACT = 0x04;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_FLIPSWITCH = 0x05;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_LIGHT = 0x06;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_MOTION = 0x07;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_2LINECHAR = 0x08;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_POWER30 = 0x08;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_POWER100 = 0x09;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_SMARTOUTLET = 0x10;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> DVC_RGBLIGHT = 0x11;
<span style="color: #7e7e7e;">//Command Codes</span>
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_GET_VERSION = 0x01;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_PING = 65;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_PONG = 0xE3;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_ACK = 0x11;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_READ = 0xAA;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_WRITE = 0xBB;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_PORTTYPE = 0xCC;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_AUTOSENDSTART = 0xC1;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_AUTOSENDSTOP = 0xC2;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> CMD_ERROR = 0xFF;
<span style="color: #cc6600;">class</span> DataPacketDecoded {
<span style="color: #cc6600;">int</span> command, <span style="color: #cc6600;">length</span>, <span style="color: #cc6600;">status</span> = 0, settings, type, fromPort, toPort, id, ttl = 0, ptr = 0;
<span style="color: #cc6600;">int</span> fromNode, toNode, checksum = 0;
<span style="color: #cc6600;">int</span>[] payload = <span style="color: #cc6600;">new</span> <span style="color: #cc6600;">int</span>[56];
DataPacketDecoded() {
}
}
<span style="color: #7e7e7e;">//simple data packet</span>
<span style="color: #cc6600;">class</span> DataPacket {
<span style="color: #cc6600;">int</span> ptr = 0, <span style="color: #cc6600;">status</span> = 0, checksum = 0;
<span style="color: #cc6600;">int</span>[] payload = <span style="color: #cc6600;">new</span> <span style="color: #cc6600;">int</span>[64];
DataPacket() {
}
}
<span style="color: #7e7e7e;">//shortcuts to important bytes</span>
<span style="color: #7e7e7e;">//keeps from having to decode the whole thing to check simple parts</span>
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_LENGTH = 0;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_SETTINGS = 1;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_FROM = 2;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_TO = 4;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_TTL = 4;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_ID = 6;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_COMMAND = 7;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PACKET_PAYLOAD = 8;
<span style="color: #cc6600;">int</span> _crc16_update(<span style="color: #cc6600;">int</span> crc, <span style="color: #cc6600;">int</span> a)
{
<span style="color: #cc6600;">int</span> i;
crc ^= a;
<span style="color: #cc6600;">for</span> (i = 0; i < 8; ++i){
<span style="color: #cc6600;">if</span> ((crc & 1) == 1){
crc = (crc >> 1) ^ 0xA001;
}<span style="color: #cc6600;">else</span>{
crc = (crc >> 1);
}
}
<span style="color: #cc6600;">return</span> crc & 0xFFFF;
}
<span style="color: #cc6600;">int</span> getId() {
<span style="color: #cc6600;">return</span> uniqueId++; <span style="color: #7e7e7e;">//what happens when this wraps?</span>
}
<span style="color: #cc6600;">int</span> compressAddress(<span style="color: #cc6600;">int</span> node, <span style="color: #cc6600;">int</span> port)
{
node = node << 4; <span style="color: #7e7e7e;">//make space</span>
port = port & 0x0F;
<span style="color: #cc6600;">return</span> node | port;
}
<span style="color: #cc6600;">import</span> processing.serial.*;
<span style="color: #7e7e7e;">//What should master ports be?</span>
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> NODE_ID = 0x02;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PORT_A = DVC_LM33;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PORT_B = DVC_LM33;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PORT_C = DVC_LM33;
<span style="color: #cc6600;">final</span> <span style="color: #cc6600;">int</span> PORT_D = DVC_LM33;
DataPacket data[];
<span style="color: #cc6600;">int</span> dataPtr = 0;
<span style="color: #cc6600;">int</span> checksum;
<span style="color: #cc6600;">int</span> dataId = 0;
<span style="color: #cc6600;">int</span> packetIds = 0;
<span style="color: #cc6600;">int</span> uniqueId = 0;
<span style="color: #cc6600;">int</span> i;
DataPacket incomingPacket = <span style="color: #cc6600;">new</span> DataPacket(); <span style="color: #7e7e7e;">//current incoming packet</span>
<span style="color: #cc6600;">int</span> bgcolor; <span style="color: #7e7e7e;">// Background color</span>
<span style="color: #cc6600;">int</span> fgcolor; <span style="color: #7e7e7e;">// Fill color</span>
Serial myPort; <span style="color: #7e7e7e;">// The serial port</span>
<span style="color: #cc6600;">int</span>[] serialInArray = <span style="color: #cc6600;">new</span> <span style="color: #cc6600;">int</span>[3]; <span style="color: #7e7e7e;">// Where we'll put what we receive</span>
<span style="color: #cc6600;">int</span> serialCount = 0; <span style="color: #7e7e7e;">// A count of how many bytes we receive</span>
<span style="color: #cc6600;">boolean</span> firstContact = <span style="color: #cc6600;">false</span>; <span style="color: #7e7e7e;">// Whether we've heard from the microcontroller</span>
<span style="color: #cc6600;">PFont</span> myFont;
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>() {
<span style="color: #cc6600;">size</span>(400, 400); <span style="color: #7e7e7e;">// Stage size</span>
<span style="color: #7e7e7e;">//noStroke(); // No border on the next thing drawn</span>
myFont = <span style="color: #cc6600;">createFont</span>(<span style="color: #006699;">"Consolas"</span>, 14);
<span style="color: #cc6600;">textFont</span>(myFont);
<span style="color: #7e7e7e;">// Print a list of the serial ports, for debugging purposes:</span>
<span style="color: #7e7e7e;">//println(PFont.list());</span>
<span style="color: #cc6600;">String</span> portName = Serial.<span style="color: #cc6600;">list</span>()[1];
myPort = <span style="color: #cc6600;">new</span> Serial(<span style="color: #cc6600;">this</span>, portName, 115200);
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>draw</b></span>() {
<span style="color: #7e7e7e;">//text("Hello",10,10);</span>
<span style="color: #7e7e7e;">//text("Z", 10, 220);</span>
<span style="color: #7e7e7e;">// Draw the shape</span>
}
<span style="color: #cc6600;">void</span> serialEvent(Serial myPort) {
<span style="color: #7e7e7e;">// read a byte from the serial port:</span>
<span style="color: #cc6600;">int</span> inByte = myPort.read();
build_incoming_packet(inByte);
}
<span style="color: #7e7e7e;">//#include <util crc16.h=""> //checksum functions</util></span>
<span style="color: #cc6600;">boolean</span> send_packet_serial(DataPacket packet)
{
<span style="color: #cc6600;">int</span> dataChecksum = 0;
<span style="color: #cc6600;">for</span>(i=0; i < (packet.payload[PACKET_LENGTH]-2); i++){
dataChecksum = _crc16_update(dataChecksum, packet.payload[i]);
myPort.write(packet.payload[i] & 0xFF);
}
packet.<span style="color: #cc6600;">status</span> = 1;
myPort.write(dataChecksum & 0xFFFF);
<span style="color: #cc6600;">return</span> <span style="color: #cc6600;">true</span>;
}
DataPacket build_tcp_packet(<span style="color: #cc6600;">int</span> fromNode, <span style="color: #cc6600;">int</span> fromPort, <span style="color: #cc6600;">int</span> toNode, <span style="color: #cc6600;">int</span> toPort, <span style="color: #cc6600;">int</span> command, <span style="color: #cc6600;">int</span> payload[])
{
DataPacket packet = <span style="color: #cc6600;">new</span> DataPacket();
<span style="color: #7e7e7e;">//packet.payload[PACKET_LENGTH] = length + 8;</span>
packet.payload[PACKET_SETTINGS] = 1;
<span style="color: #cc6600;">int</span> address = compressAddress(fromNode, fromPort);
packet.payload[PACKET_FROM] = (address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = address & 0xFF;
address = compressAddress(toNode, toPort);
packet.payload[PACKET_TO ] = (address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #cc6600;">for</span>(i=0;i < payload.<span style="color: #cc6600;">length</span>;i++){
packet.payload[PACKET_PAYLOAD+i] = payload[i];
}
<span style="color: #cc6600;">return</span> packet;
}
DataPacket build_udp_packet(<span style="color: #cc6600;">int</span> fromNode, <span style="color: #cc6600;">int</span> fromPort, <span style="color: #cc6600;">int</span> toNode, <span style="color: #cc6600;">int</span> toPort, <span style="color: #cc6600;">int</span> command, <span style="color: #cc6600;">int</span> payload[])
{
DataPacket packet = <span style="color: #cc6600;">new</span> DataPacket();
<span style="color: #7e7e7e;">//packet.payload[PACKET_LENGTH] = length + 8;</span>
packet.payload[PACKET_SETTINGS] = 2;
<span style="color: #cc6600;">int</span> address = compressAddress(fromNode, fromPort);
packet.payload[PACKET_FROM] = (<span style="color: #cc6600;">char</span>)(address >> 8) & 0xFF;
packet.payload[PACKET_FROM+1] = (<span style="color: #cc6600;">char</span>)address & 0xFF;
address = compressAddress(toNode, toPort);
packet.payload[PACKET_TO ] = (<span style="color: #cc6600;">char</span>)(address >> 8) & 0xFF;
packet.payload[PACKET_TO+1] = (<span style="color: #cc6600;">char</span>)address & 0xFF;
packet.payload[PACKET_ID] = getId();
packet.payload[PACKET_COMMAND] = command;
<span style="color: #cc6600;">for</span>(i=0;i < payload.<span style="color: #cc6600;">length</span>;i++){
packet.payload[PACKET_PAYLOAD+i] = payload[i];
}
<span style="color: #cc6600;">return</span> packet;
}
<span style="color: #7e7e7e;">/*</span>
<span style="color: #7e7e7e;">uint8_t build_broadcast_packet(uint16_t fromNode, uint8_t fromPort, uint16_t toNode, uint8_t toPort, uint8_t payload[48], uint8_t length, uint8_t ttl )</span>
<span style="color: #7e7e7e;">{</span>
<span style="color: #7e7e7e;"> byte packetId = getNewPacketId();</span>
<span style="color: #7e7e7e;"> data[packetId].sent = 0;</span>
<span style="color: #7e7e7e;"> return packetId;</span>
<span style="color: #7e7e7e;">}</span>
<span style="color: #7e7e7e;">*/</span>
<span style="color: #cc6600;">void</span> process_command(DataPacketDecoded packet)
{
<span style="color: #cc6600;">switch</span> (packet.command) {
<span style="color: #cc6600;">case</span> CMD_PING:
<span style="color: #7e7e7e;">//replyPacket.payload = packet.payload;</span>
<span style="color: #7e7e7e;">//replyPacket.command = CMD_PONG;</span>
<span style="color: #7e7e7e;">//replyPacket.fromNode = NODE_ID;</span>
<span style="color: #7e7e7e;">//send_packet(packet);</span>
<span style="color: #cc6600;">break</span>;
<span style="color: #cc6600;">default</span>:
<span style="color: #7e7e7e;">//send_packet(COMMAND_ERROR,NULL,0);</span>
<span style="color: #cc6600;">break</span>;
}
}
<span style="color: #7e7e7e;">/**</span>
<span style="color: #7e7e7e;"> * turns a packet into a decoded packet</span>
<span style="color: #7e7e7e;"> */</span>
DataPacketDecoded decode_packet(DataPacket packet)
{
DataPacketDecoded decodedPacket = <span style="color: #cc6600;">new</span> DataPacketDecoded();
<span style="color: #7e7e7e;">//Set Packet length</span>
decodedPacket.<span style="color: #cc6600;">length</span> = packet.payload[PACKET_LENGTH];
decodedPacket.<span style="color: #cc6600;">status</span> = packet.<span style="color: #cc6600;">status</span>;
<span style="color: #7e7e7e;">//settings </span>
decodedPacket.settings = packet.payload[PACKET_SETTINGS];
decodedPacket.type = packet.payload[PACKET_SETTINGS]; <span style="color: #7e7e7e;">//right now these are the same things</span>
<span style="color: #7e7e7e;">//From 12bit node id, 4 bit plug id</span>
decodedPacket.fromNode = packet.payload[PACKET_FROM];
decodedPacket.fromNode = decodedPacket.fromNode << 4;
decodedPacket.fromNode = decodedPacket.fromNode | (packet.payload[PACKET_FROM+1] >> 4);
decodedPacket.fromPort = packet.payload[PACKET_FROM+1] &0xF;
<span style="color: #7e7e7e;">//To 12bit node id, 4 bit plug id</span>
decodedPacket.toNode = packet.payload[PACKET_TO];
decodedPacket.toNode = decodedPacket.toNode << 4;
decodedPacket.toNode = decodedPacket.toNode | (packet.payload[PACKET_TO+1] >> 4);
decodedPacket.toPort = packet.payload[PACKET_TO+1] &0xF;
<span style="color: #7e7e7e;">//packet id</span>
decodedPacket.id = packet.payload[PACKET_ID];
<span style="color: #7e7e7e;">//Command</span>
decodedPacket.command = packet.payload[PACKET_COMMAND];
decodedPacket.checksum = packet.checksum;
decodedPacket.ptr = packet.payload[PACKET_LENGTH] - 10;
<span style="color: #cc6600;">for</span>(i=PACKET_PAYLOAD; i < packet.payload[PACKET_LENGTH]; i++){
<span style="color: #cc6600;">if</span>(decodedPacket.type < 3) { <span style="color: #7e7e7e;">//single packet TCP or UDP</span>
decodedPacket.payload[i-PACKET_PAYLOAD] = packet.payload[i];
} <span style="color: #cc6600;">else</span> <span style="color: #cc6600;">if</span>(decodedPacket.type == 3) { <span style="color: #7e7e7e;">//broadcast</span>
<span style="color: #7e7e7e;">//todo</span>
}
}
<span style="color: #cc6600;">return</span> decodedPacket;
}
<span style="color: #cc6600;">void</span> build_incoming_packet(<span style="color: #cc6600;">int</span> bIn)
{
<span style="color: #7e7e7e;">//add timout to reset if packets get jamed</span>
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"count: "</span>+incomingPacket.ptr + <span style="color: #006699;">" byte: "</span> + bIn);
<span style="color: #cc6600;">if</span>(incomingPacket.ptr == 0){ <span style="color: #7e7e7e;">//Packet length</span>
<span style="color: #cc6600;">if</span>(bIn == 0) {
<span style="color: #7e7e7e;">//resend last</span>
<span style="color: #cc6600;">return</span>;
}
<span style="color: #cc6600;">if</span>(bIn == 255) {
<span style="color: #7e7e7e;">//aknowledge</span>
<span style="color: #7e7e7e;">//delete packet from que</span>
<span style="color: #7e7e7e;">//reset last pointer</span>
<span style="color: #cc6600;">return</span>;
}
<span style="color: #cc6600;">if</span> (bIn > 66) {
<span style="color: #7e7e7e;">//stop sending current packet</span>
<span style="color: #7e7e7e;">//flush</span>
<span style="color: #cc6600;">return</span>;
}
incomingPacket.payload[PACKET_LENGTH] = bIn;
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"length: "</span>+bIn);
checksum = 0;
}
<span style="color: #7e7e7e;">//checksum </span>
<span style="color: #cc6600;">if</span>(incomingPacket.ptr < (incomingPacket.payload[PACKET_LENGTH]-2)){ <span style="color: #7e7e7e;">//add to check sum</span>
incomingPacket.payload[incomingPacket.ptr] = bIn;
checksum = _crc16_update(checksum, bIn);
} <span style="color: #cc6600;">else</span> <span style="color: #cc6600;">if</span>(incomingPacket.ptr == (incomingPacket.payload[PACKET_LENGTH]-2)){ <span style="color: #7e7e7e;">//get first byte of checksum</span>
incomingPacket.checksum = bIn;
} <span style="color: #cc6600;">else</span> { <span style="color: #7e7e7e;">//get second byte and check the checksum</span>
incomingPacket.checksum = (incomingPacket.checksum << 8) | (bIn & 0xFF);
<span style="color: #cc6600;">if</span>(checksum != incomingPacket.checksum) {
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"Failed CRC Check"</span>);
} <span style="color: #cc6600;">else</span> {
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"processing checksum: "</span> + checksum);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">" packet checksum: "</span> + incomingPacket.checksum);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"Passed CRC Check"</span>);
debug_incoming_packet(incomingPacket);
<span style="color: #7e7e7e;">//check packet address, if it matches, process command, if not add to queue to resend to other nodes</span>
<span style="color: #7e7e7e;">//i = getNewPacketId();</span>
<span style="color: #7e7e7e;">//data[i] = incomingPacket;</span>
<span style="color: #7e7e7e;">//process_command(incomingPacket);</span>
<span style="color: #7e7e7e;">//incomingPacket = DataPacket;</span>
}
<span style="color: #7e7e7e;">//reset incoming packet</span>
incomingPacket = <span style="color: #cc6600;">new</span> DataPacket();
<span style="color: #cc6600;">return</span>;
}
incomingPacket.ptr++;
}
<span style="color: #cc6600;">void</span> debug_incoming_packet(DataPacket packet)
{
<span style="color: #cc6600;">background</span>(0);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"show packet info"</span>);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Packet Info"</span>,5,15);
<span style="color: #cc6600;">int</span> x = 20;
DataPacketDecoded packetDecoded = decode_packet(packet);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" status: "</span> + packetDecoded.<span style="color: #cc6600;">status</span>,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" length: "</span> + packetDecoded.<span style="color: #cc6600;">length</span>,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"settings: "</span> + packetDecoded.settings,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" type: "</span> + packetDecoded.type,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"fromNode: "</span> + packetDecoded.fromNode,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"fromPort: "</span> + packetDecoded.fromPort,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" toNode: "</span> + packetDecoded.toNode,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" toPort: "</span> + packetDecoded.toPort,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" ttl: "</span> + packetDecoded.ttl,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" id: "</span> + packetDecoded.id,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" command: "</span> + packetDecoded.command,10,x+=20);
<span style="color: #cc6600;">String</span> message = <span style="color: #006699;">""</span>;
<span style="color: #cc6600;">for</span>(i=0; i < packetDecoded.ptr; i++){
message += <span style="color: #cc6600;">int</span>(packetDecoded.payload[i]);
<span style="color: #7e7e7e;">//message += char(packetDecoded.payload[i]);</span>
}
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" payload: "</span> + message,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"checksum: "</span> + packetDecoded.checksum,10,x+=20);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">" ptr: "</span> + packetDecoded.ptr,10,x+=20);<span style="color: #7e7e7e;">//*/</span>
}
</pre>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-47854258399694623622010-11-01T19:58:00.000-07:002010-11-02T17:03:33.491-07:00From Processing to the WebAn Arduino is connected to a PC that is running a program created in Processing. It reads the data stream from the arduino and then it can publish the data to an online service like pachube or my own server.<br />
<br />
The main user interface of my project is going to be web based so it can be used on all sorts of devices from laptops to cellphones. Processing doesn't make a very good webserver to build an interface around however there is some really good webserver software - Apache, PHP and MySQL. <br />
<br />
Linking the webserver to the Processing program is a bit of challenge. A webserver doesn't typically have a program always running, rather the program runs only when generating a web page. To send data to the webserver involved calling a webpage with get/post data. For the webserver to send data to the Processing sketch involves using a simple socket server. I haven't found any example of this online but I think I can combine some of this <a href="http://processing.org/reference/libraries/net/index.html">processing code</a> and some of this <a href="http://us2.php.net/manual/en/sockets.examples.php">php code</a> and make it work.<br />
<br />
Update: there is a better way to connect things- XML RPCMatthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-30311240325281560412010-11-01T14:47:00.000-07:002010-11-01T18:54:22.490-07:00Communication ProtocolOne of the big steps is developing a language for how all the nodes talk to each other.<br />
<br />
There are several existing protocols like <a href="http://en.wikipedia.org/wiki/BACnet">BACnet</a> and <a href="http://en.wikipedia.org/wiki/LonWorks">LonWorks</a>. These a both full featured but almost too complex for what I need right now. I looked to see if anyone had used an arduino with either of these protocols but my search turned up blank. So I decided to write my own.<br />
<br />
Data is sent in packets. Each packet is like a letter that has a to and from address and carries a payload inside.<br />
<br />
There are several types of packets based on what sort of data is being carried<br />
<br />
The first three I plan on implementing are<br />
<ul><li>TCP Packet - based on the <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol">Transmission Control Protocol</a>, well a very simplified version but when a node receives one of these packets it sends a ack (acknowledgment) packet letting the sender know that the packet reached it destination.</li>
<li>UDP Packet - Based on the <a href="http://en.wikipedia.org/wiki/User_Datagram_Protocol">User Datagram Protocol</a>, again a simplified version. These are packets that don't need acknowledgment. These is used when data is constantly being sent and lost packets would be outdated by the time they were resent</li>
<li>Broadcast - this is variant of UDP that doesn't have a set destination, rather it has a max number of hops that the packet will take and all nodes will take a look at it's data</li>
</ul><br />
Each packet has a 8 byte header and 2 byte footer. this a lot smaller than the 20 byte header of a standard TCP packet.<br />
<br />
8 bits = 1 byte<br />
<br />
So far my protocol looks like this <br />
<ol><li>8 bits - Length of Packet (could be shorter if we don't need big packets</li>
<li>8 bits - Settings (could be smaller only using 2 bits right now</li>
<li>12 bits - From node, allows for 4096 nodes</li>
<li>4 bits - From ports (allows 16 ports on a node)</li>
<li>12 bits - To Node (or ttl Time to live, if broadcast)</li>
<li>4 bits - From Port</li>
<li>8 bits - Packet ID; So that packets can be put back in the right order</li>
<li>8 bits - Command; read, write, etc (could be shorter)</li>
<li>56 bytes Payload</li>
<li>16 bits - Checksum (verifies data didn't get corrupted in transmission) </li>
</ol>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-37415602396135989082010-10-20T18:42:00.000-07:002010-11-01T18:44:55.168-07:00Midterm Powerpoint<object width="500" height="375"> <param name="flashvars" value="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Farchicroc%2Fsets%2F72157625168350691%2Fshow%2F&page_show_back_url=%2Fphotos%2Farchicroc%2Fsets%2F72157625168350691%2F&set_id=72157625168350691&jump_to="></param><param name="movie" value="http://www.flickr.com/apps/slideshow/show.swf?v=71649"></param><param name="allowFullScreen" value="true"></param><embed type="application/x-shockwave-flash" src="http://www.flickr.com/apps/slideshow/show.swf?v=71649" allowFullScreen="true" flashvars="offsite=true&lang=en-us&page_show_url=%2Fphotos%2Farchicroc%2Fsets%2F72157625168350691%2Fshow%2F&page_show_back_url=%2Fphotos%2Farchicroc%2Fsets%2F72157625168350691%2F&set_id=72157625168350691&jump_to=" width="500" height="375"></embed></object>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-44208558251704329602010-10-20T13:14:00.000-07:002010-10-20T13:14:07.238-07:00A Little Bit of Privacy<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/rKhbUjVyKIc?fs=1&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/rKhbUjVyKIc?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-20266029976931254822010-10-19T23:27:00.001-07:002010-10-20T14:18:44.696-07:00Soldering FunA while back I got a free sample of some power meter chips. These awesome little chips can very accurately measure power consumption. I really want to build my own smart outlet and hook it up to my network. These chips will enable me to do it.<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5098349221/" title="IMG_2347 by ArchiCroc, on Flickr"><img src="http://farm2.static.flickr.com/1230/5098349221_e40dbf1106.jpg" width="500" height="333" alt="IMG_2347" /></a><br />
they are tiny surface mount chips<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5098349433/" title="IMG_2354 by ArchiCroc, on Flickr"><img src="http://farm2.static.flickr.com/1197/5098349433_f154b38d50.jpg" width="500" height="333" alt="IMG_2354" /></a><br />
to test one out on breadboard i had to solder an adapter board. And success! One side is perfect and the other side was close, 3 pin got bridged with solder but it was easy to fix. So far this is the smallest thing I've hand soldered.Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-32333231041500256552010-10-13T18:08:00.000-07:002010-10-13T18:08:40.968-07:00Where good Ideas come from...<object height="340" width="560"><param name="movie" value="http://www.youtube.com/v/eNwMut3-z1Y?fs=1&hl=en_US&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/eNwMut3-z1Y?fs=1&hl=en_US&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br />
<br />
There was also an Article in the <a href="http://online.wsj.com/article/SB10001424052748703989304575503730101860838.html">Wall Street Journal</a> about Ideas<br />
<blockquote>The premise that innovation prospers when ideas can serendipitously connect and recombine with other ideas may seem logical enough, but the strange fact is that a great deal of the past two centuries of legal and folk wisdom about innovation has pursued the exact opposite argument, building walls between ideas. Ironically, those walls have been erected with the explicit aim of encouraging innovation. They go by many names: intellectual property, trade secrets, proprietary technology, top-secret R&D labs. But they share a founding assumption: that in the long run, innovation will increase if you put restrictions on the spread of new ideas, because those restrictions will allow the creators to collect large financial rewards from their inventions. And those rewards will then attract other innovators to follow in their path. <br />
<br />
The problem with these closed environments is that they make it more difficult to explore the adjacent possible, because they reduce the overall network of minds that can potentially engage with a problem, and they reduce the unplanned collisions between ideas originating in different fields. This is why a growing number of large organizations—businesses, nonprofits, schools, government agencies—have begun experimenting with more open models of idea exchange. </blockquote>[<a href="http://online.wsj.com/article/SB10001424052748703989304575503730101860838.html">WSJ</a>]Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-32781097485612390092010-10-13T12:45:00.000-07:002010-10-13T12:45:24.886-07:00Smart Mirrors<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/TP64GolT-UU?fs=1&hl=en_US&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/TP64GolT-UU?fs=1&hl=en_US&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object><br />
<br />
[<a href="http://www.engadget.com/2010/10/13/cybertecture-mirror-reflects-our-fantasies-looks-set-to-become/">Engadget</a>]Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-78076347165254878632010-10-10T11:51:00.000-07:002010-10-10T11:51:27.916-07:00Testing the JeeNodesThis week I finished Soldering together my first set of JeeNodes and I tested out them out by running the PingPong test program.<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5066845471/" title="IMG_2330 by ArchiCroc, on Flickr"><img alt="IMG_2330" height="333" src="http://farm5.static.flickr.com/4103/5066845471_2e40f573c9.jpg" width="500" /></a><br />
<br />
<object height="340" width="560"><param name="movie" value="http://www.youtube.com/v/4NWFTZBVSeY?fs=1&hl=en_US&rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/4NWFTZBVSeY?fs=1&hl=en_US&rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-79378568793755492892010-10-10T11:41:00.000-07:002010-10-10T11:41:30.413-07:00Adding to my Room SensorI also bought an ambient light sensor that suppose to be more sensitive than a Light Dependent Resistors. I needed my small arduino for another experiment so I moved everything over to a arduino mega. i2c is in a different spot so that's why the Temp/Humidity sensor moved.<br />
<a href="http://www.flickr.com/photos/archicroc/5066856487/" title="IMG_2341 by ArchiCroc, on Flickr"><img alt="IMG_2341" height="333" src="http://farm5.static.flickr.com/4085/5066856487_8cfb3640a0.jpg" width="500" /></a><br />
<br />
Here is the arduino code<br />
<pre>#include <<span style="color: #cc6600;">Wire</span>.h>
#include <libhumidity.h>
#define samples 5
<span style="color: #cc6600;">float</span> H[samples];
<span style="color: #cc6600;">float</span> T[samples];
<span style="color: #cc6600;">int</span> L[samples];
<span style="color: #cc6600;">byte</span> current = 0;
LibHumidity humidity=LibHumidity(0);
<span style="color: #cc6600;">boolean</span> readSerial()
{
<span style="color: #cc6600;">if</span>(<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">available</span>() && (<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">read</span>()==65)) {
<span style="color: #cc6600;">return</span> <span style="color: #cc6600;">true</span>;
}
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">flush</span>();
<span style="color: #cc6600;">return</span> <span style="color: #cc6600;">false</span>;
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>(){
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">begin</span>(9600);
<span style="color: #cc6600;">pinMode</span>(58, <span style="color: #006699;">OUTPUT</span>);
<span style="color: #cc6600;">pinMode</span>(59, <span style="color: #006699;">OUTPUT</span>);
<span style="color: #cc6600;">digitalWrite</span>(58, <span style="color: #006699;">HIGH</span>);
<span style="color: #cc6600;">digitalWrite</span>(59, <span style="color: #006699;">LOW</span>);
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>loop</b></span>(){
H[current]=(<span style="color: #cc6600;">float</span>)humidity.GetHumidity();
T[current]=(<span style="color: #cc6600;">float</span>)(humidity.GetTemperature() * 1.8 )+32;
L[current] = <span style="color: #cc6600;">analogRead</span>(3);
current++;
<span style="color: #cc6600;">if</span>(current == samples){
current = 0;
}
<span style="color: #cc6600;">if</span>(readSerial() == <span style="color: #cc6600;">true</span>){
<span style="color: #cc6600;">float</span> h2 = 0;
<span style="color: #cc6600;">float</span> t2 = 0;
<span style="color: #cc6600;">int</span> l2 = 0;
<span style="color: #cc6600;">for</span>(<span style="color: #cc6600;">byte</span> a=0;a<samples;a++){ h2 +=" H[a];" l2 +=" L[a];" t2 +=" T[a];" ="" }=""><span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(h2/samples);
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(<span style="color: #006699;">','</span>,<span style="color: #006699;">BYTE</span>);
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(t2/samples);
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">print</span>(<span style="color: #006699;">','</span>,<span style="color: #006699;">BYTE</span>);
<span style="color: #cc6600;"><b>Serial</b></span>.<span style="color: #cc6600;">println</span>(l2/samples);
}
<span style="color: #cc6600;">delay</span>(1000);
}
</samples;a++){></libhumidity.h></pre>And here is the Processing code that uploads the data to Pachube<br />
<pre><span style="color: #cc6600;">import</span> processing.serial.*;
<span style="color: #cc6600;">import</span> eeml.*;
DataOut dOut;
<span style="color: #cc6600;">float</span> lastUpdate;
Serial myPort; <span style="color: #7e7e7e;">// The serial port</span>
<span style="color: #cc6600;">int</span> whichKey = -1; <span style="color: #7e7e7e;">// Variable to hold keystoke values</span>
<span style="color: #cc6600;">String</span> inByte;<span style="color: #7e7e7e;">// = ' '; // Incoming serial data</span>
<span style="color: #cc6600;">String</span>[] message;
<span style="color: #cc6600;">float</span> humidity;
<span style="color: #cc6600;">float</span> temp;
<span style="color: #cc6600;">int</span> light;
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>setup</b></span>() {
<span style="color: #cc6600;">size</span>(400, 300);
<span style="color: #7e7e7e;">// create a font with the third font available to the system:</span>
<span style="color: #cc6600;">PFont</span> myFont = <span style="color: #cc6600;">createFont</span>(<span style="color: #cc6600;">PFont</span>.<span style="color: #cc6600;">list</span>()[2], 14);
<span style="color: #cc6600;">textFont</span>(myFont);
<span style="color: #cc6600;">println</span>(Serial.<span style="color: #cc6600;">list</span>()); <span style="color: #7e7e7e;">// List all the available serial ports:</span>
<span style="color: #cc6600;">String</span> portName = Serial.<span style="color: #cc6600;">list</span>()[2];
myPort = <span style="color: #cc6600;">new</span> Serial(<span style="color: #cc6600;">this</span>, portName, 9600);
myPort.bufferUntil(10);
<span style="color: #7e7e7e;">// set up DataOut object; requires URL of the EEML you are updating, and your Pachube API key </span>
dOut = <span style="color: #cc6600;">new</span> DataOut(<span style="color: #cc6600;">this</span>, <span style="color: #006699;">"http://api.pachube.com/v2/feeds/10505.xml"</span>, <span style="color: #006699;">"API KEY GOES HERE"</span>);
<span style="color: #7e7e7e;">// and add and tag a datastream </span>
dOut.addData(0,<span style="color: #006699;">"Humidity"</span>);
dOut.addData(1,<span style="color: #006699;">"Temperature"</span>);
dOut.addData(2,<span style="color: #006699;">"Light"</span>);
}
<span style="color: #cc6600;">void</span> <span style="color: #cc6600;"><b>draw</b></span>() {
<span style="color: #cc6600;">background</span>(0);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Light: "</span> + light, 10, 220);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Temp: "</span> + temp, 10, 190);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Humidity: "</span> + humidity, 10, 160);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Last Received: "</span> + inByte, 10, 130);
<span style="color: #cc6600;">text</span>(<span style="color: #006699;">"Last Sent: "</span> + lastUpdate, 10, 100);
<span style="color: #cc6600;">if</span> ((<span style="color: #cc6600;">millis</span>() - lastUpdate) > 60000){
myPort.write(65);
<span style="color: #cc6600;">delay</span>(5000);
<span style="color: #cc6600;">println</span>(<span style="color: #006699;">"ready to POST: "</span>);
dOut.update(0, humidity); <span style="color: #7e7e7e;">// update the datastream </span>
dOut.update(1, temp); <span style="color: #7e7e7e;">// update the datastream </span>
dOut.update(2, light); <span style="color: #7e7e7e;">// update the datastream </span>
<span style="color: #cc6600;">int</span> response = dOut.updatePachube(); <span style="color: #7e7e7e;">// updatePachube() updates by an authenticated PUT HTTP request</span>
<span style="color: #cc6600;">println</span>(response); <span style="color: #7e7e7e;">// should be 200 if successful; 401 if unauthorized; 404 if feed doesn't exist</span>
lastUpdate = <span style="color: #cc6600;">millis</span>();
}
}
<span style="color: #cc6600;">void</span> serialEvent(Serial myPort) {
inByte = <span style="color: #cc6600;">trim</span>(myPort.readString());
message = <span style="color: #cc6600;">split</span>(inByte,<span style="color: #006699;">','</span>);
humidity = <span style="color: #cc6600;">float</span>(message[0]);<span style="color: #7e7e7e;">//float(myPort.readStringUntil(','));</span>
temp = <span style="color: #cc6600;">float</span>(message[1]);<span style="color: #7e7e7e;">//float(myPort.readString());</span>
light = <span style="color: #cc6600;">int</span>(message[2]);
}
<span style="color: #cc6600;">void</span> <span style="color: #006699;">keyPressed</span>() {
<span style="color: #7e7e7e;">// Send the keystroke out:</span>
myPort.write(65);
whichKey = <span style="color: #006699;">key</span>;
}
</pre>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-40167304552021314952010-10-01T07:06:00.000-07:002010-10-01T07:06:46.896-07:00Soldering FunI got my new soldering Iron Yesterday so I got right to work soldering one of the JeeNodes Together<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5041867636/" title="IMG_2312 by ArchiCroc, on Flickr"><img alt="IMG_2312" height="333" src="http://farm5.static.flickr.com/4148/5041867636_3cf54e782b.jpg" width="500" /></a><br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5041261974/" title="IMG_2308 by ArchiCroc, on Flickr"><img alt="IMG_2308" height="333" src="http://farm5.static.flickr.com/4131/5041261974_eb188c2743.jpg" width="500" /></a><br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5041262202/" title="IMG_2310 by ArchiCroc, on Flickr"><img alt="IMG_2310" height="333" src="http://farm5.static.flickr.com/4110/5041262202_78cd5392e2.jpg" width="500" /></a><br />
<br />
Haven't tested it yet. Saving that fun for later.Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-29489777657950128332010-10-01T00:26:00.000-07:002010-10-01T00:28:57.759-07:00First Experiment: A Success!Today I officially started my Internet of Things.<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5041261792/" title="IMG_2300 by ArchiCroc, on Flickr"><img alt="IMG_2300" height="333" src="http://farm5.static.flickr.com/4132/5041261792_862b377d3d.jpg" width="500" /></a><br />
Arduino with a Humidity/Temperature Sensor<br />
<br />
<a href="http://www.flickr.com/photos/archicroc/5041262288/" title="upload feed by ArchiCroc, on Flickr"><img alt="upload feed" height="327" src="http://farm5.static.flickr.com/4111/5041262288_685c9f82a9.jpg" width="406" /></a><br />
Basic Processing Script uploads the Humidity/Temperature of my Apartment to Pachube<br />
<br />
<img src="http://www.pachube.com/feeds/10505/datastreams/0/history.png" /><br />
Humidity<br />
<br />
<img src="http://www.pachube.com/feeds/10505/datastreams/1/history.png" /><br />
Temperature <br />
<br />
Check out the <a href="http://www.pachube.com/feeds/10505">Live feed</a>Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0tag:blogger.com,1999:blog-5434766342184750662.post-17976655362106022602010-09-28T22:28:00.000-07:002010-09-28T22:28:25.847-07:00Reading: Interactive Architecture<a href="http://www.amazon.com/Interactive-Architecture-Michael-Fox/dp/1568988362?ie=UTF8&tag=ilot-20&link_code=btl&camp=213689&creative=392969" target="_blank">Interactive Architecture</a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=ilot-20&l=btl&camp=213689&creative=392969&o=1&a=1568988362" style="border: medium none ! important; margin: 0px ! important; padding: 0px ! important;" width="1" /><br />
"Interactive Architecture" by Michael Fox and Miles Kemp, 2009. <br />
<br />
This book is amazing. It covers the changing paradigm of architecture in the 21st century. The book covers many aspects of my Master's Project from. the embedded computing to it's environmental impact and it's effect on the sociological and psychological implications. through the next week, I write about each of it's sections and my thoughts.<br />
<br />
Physical Change - Kinetic Architecture<br />
<br />
Embedded Computation<br />
<br />
Project Landscape - Adaptable Space; Living, Working, Entertainment and Public Environments<br />
<br />
Environmental Impact - Energy Efficiency, Sustainable Solutions, Environmental Cognizance<br />
<br />
Enhancing and Extending Activities - Active Participation<br />
<br />
<br />
Sociological and Psychological Implications - Changing Lifestyle Patterns, Behavior Awareness, Building Awareness, Sense of Place, Control of Space, Attachment to Space<br />
<br />
Design and the Profession - Designing Interactive Systems, Economic Feasibility<br />
<br />
New Horizons - Technology Transfer, Interface Design, Autonomous Robotics, Evolutionary Systems<br />
<br />
“A new epoch has begun!”Matthewhttp://www.blogger.com/profile/05818659732501156825noreply@blogger.com0