Friday, December 25, 2009

New ARM Microcontroller boards

I have found out about some new ARM microcontroller boards:

Mbed - founded by ARM folks, an LPC1768 ARM Cortex-M3 based board. The "special sauce" is that the board looks like a USB drive that you drop your programs onto, as well as providing a web-based development environment, making it more cross-platform and usable even with "locked-down" computers. It comes in a "STAMP-like" 40-pin 0.1" pitch DIP form-factor. C++ programming with many peripheral API libraries. It has 10/100 Ethernet MAC and an IP stack, but you need to add an Ethernet jack (like the MagJack SI-60002-F, which is ~$5). A 100 MHz ARM with 64 KB of SRAM, 512 KB of Flash. It looks like 25 GPIOs pins that can also be 6x12-bit A/D, one 10-bit D/A, 6xPWM out, 2x I2C, 2x CAN, 2x SPI, 3xSerial ports. 4.5v-9.0v input, 3.3v and 5.0v regulated outputs. Pre-order price is $60. Supposedly final MSRP is $99. I think $60 is more reasonable, because at $99 you have to ask yourself why not go Make Controller kit at $120 and have all the motor drivers.

ET-STM32 Stamp Module - ARM Cortex M3 processor in "STAMP" form-factor with 512K flash, 64K RAM. Has 48 GPIO ports including 16x12-bit A/D, 2xD/A, 5 USARTs, CAN, I2C, USB (but no USB connector), needs 3.3VDC, $24.90.

LeafLabs Maple - Another ARM Cortex M3 board in an Arduino form-factor. 128K flash, 20K RAM, 39 digital input/output pins, 16 analog inputs, USB, 3 USARTs, SPI/I2C, 3-18VDC input. Uses an open-source, Arduino like sketch programming interface. $39.99, but sold out right now.






Tuesday, December 22, 2009

Example Phy2Phy Interaction web service

So here is an example of a Phy2Phy interaction web service: http://phy-to-phy.appspot.com

The concept is that the web service is a database of devices and their states. The main URL is a "human interface" that displays the entire database and lets you enter a device name and it's current state.

The "computer interface" is at http://phy-to-phy.appspot.com/update. You perform an HTTP GET, with a URL of the form:

http://phy-to-phy.appspot.com/update?q=[device to query]&d=[device to set state]&s=[state]

So for example, if I want to set the state of device "PIR" to "1" and at the same time query the state of "SolarCell", I'd send:

http://phy-to-phy.appspot.com/update?d=PIR&s=1&q=SolarCell


And the response would be something like:

SolarCell:1.8

Indicating that the device "SolarCell" has a state "1.8". When calling the service, you can leave out the "q=" query if you just want to set a device to a state, or leave out the "d=" and "s=" if you just want to query for a device state.

So for example, on an Arduino you would attach an Xport set to connect using TCP to IP address 74.125.91.141 (phy-to-phy.appspot.com), port 80, and using the NewSoftSerial library, your code snippet to set "PIR" to "1" would look like:

NewSoftSerial xport(3,2);

...

xport.print("GET /update?d=PIR&s=1 HTTP/1.1\r\nHost: phy-to-phy.appspot.com\r\n\r\n");

On a Make Controller, you would send the same string using SocketWrite.

In a few weeks, I will put up some code that also reads queries back from the phy2phy intermediation web service as well.

Sunday, December 20, 2009

Web service for phy2phy working

I have been able to get an Arduino+Xport Direct and a Make Controller to talk to each other over my Google web app for phy2phy interconnection! More details later.


- Posted using BlogPress from my iPhone

Location:World Way,Los Angeles,United States

Friday, December 11, 2009

Google App for Networked Physical Computing

Networked physical computing projects face two major problems: finding each other on the Internet, and dealing with NAT filtering at Internet access routers.

Previously, I have dealt with this using a cheap shell account, where I ran a python server program at a known IP address to receive UDP packets sent by physical computing devices. The server program could then help the devices communicate by sending UDP packets back to the physical computing devices.

Unfortunately, I am finding that UDP, the unreliable datagram protocol, is becoming less and less reliable all the time. In particular, it looks like my cheap shell account system is rejecting small UDP packets with just a few characters of payload.

Given that the world is going to Web services, I figured hey, Google Apps are free (for low-CPU utilization use), so I went ahead and created a Google App for generalized physical computing networking.

The App keeps a database of devices and their states. For example, device "board1lLED" may have the state "1" to indicate an LED is on. If you hit the main "/" URL, you get a human-readable display of all the received devices and their states and an opportunity to enter your own device and state for an update.

Physical computing devices interface with the web service through the "/update" URL using a GET. The "d" parameter is a device to set to a state indicated by the "s" parameter, and a "q" parameter allows you to also query for the state of a device. For example GETing "/update?d=board1LED&s=1&q=button1" sets board1LED to 1 and gets the value of button1, which may return "button1:pressed" if its state is "pressed".

The App uses about 40 CPU mS per run, thus the 6.5 CPU hour/day quota should allow me to hit it 6 times per second all the time without running over the quota.
import cgi
from google.appengine.ext
import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db

class DeviceState(db.Model):
device
= db.StringProperty()
device_state
= db.StringProperty()

class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write(
'<html><body>')
states
=db.GqlQuery("SELECT * FROM DeviceState ORDER BY device")
for state in states:
self.response.out.write(
"<div>"+cgi.escape(state.device)+":"+
cgi.escape(state.device_state)
+"</div>")
self.response.out.write(
"""
<form action="/humanSet" method="get">
<div>Device:<input type="text" name="d"></div>
<div>State:<input type="text" name="s"></div>
<div><input type="submit" value="submit"></div>
</form>
</body>
</html>
""")

class UpdateState(webapp.RequestHandler):
def get(self):
if(self.request.get('d')):
states
=db.GqlQuery("SELECT * FROM DeviceState WHERE device = :1",
self.request.get(
'd'))
if(states.count()>0):
for state in states:
state.device_state
=self.request.get('s')
state.put()
else:
deviceState
= DeviceState()
deviceState.device
= self.request.get('d')
deviceState.device_state
= self.request.get('s')
deviceState.put()
if(self.request.get('q')):
if(self.request.get('q')=='*'):
states
=db.GqlQuery("SELECT * FROM DeviceState ORDER BY device")
else:
states
=db.GqlQuery("SELECT * FROM DeviceState WHERE device='"+
self.request.get(
'q')+"'")
for state in states:
self.response.out.write(cgi.escape(state.device)
+":"+
cgi.escape(state.device_state)
+"\r\n")

class HumanSet(webapp.RequestHandler):
def get(self):
states
=db.GqlQuery("SELECT * FROM DeviceState WHERE device = :1",
self.request.get(
'd'))
if(states.count()>0):
for state in states:
state.device_state
=self.request.get('s')
state.put()
else:
deviceState
= DeviceState()
deviceState.device
= self.request.get('d')
deviceState.device_state
= self.request.get('s')
deviceState.put()
self.redirect(
'/')

class Reset(webapp.RequestHandler):
def get(self):
states
=DeviceState.all()
for state in states:
state.delete()
self.response.out.write(
"All Data Deleted\n")

application
= webapp.WSGIApplication([('/',MainPage),
(
'/humanSet',HumanSet),
(
'/update',UpdateState),
(
'/reset',Reset)],debug=True)

def main():
run_wsgi_app(application)

if __name__ == "__main__":
main()