Monday, March 01, 2010

Ignite LA tonight (Monday, March 1)

Tonight is Ignite/LA, the event where speakers get 5 minutes/20
slides/15 seconds per slide to give a lightning presentation.

At the last Ignite/LA, talks included:
- The Future of Money
- Turning AI gurus into Comets and Star Field Explosions
- Bubble Nets among Humpback Whales

- A talk by former Dorkbot SoCal speaker Heather Knight on Social Robotics:

- A talk on physical interactions over IP by myself

You MUST sign up to attend tonight ASAP here:


7PM
Cinespace
6356 Hollywood Boulevard
Los Angeles, CA 90028

Cinespace is an awesome venue, and after the talks you stay there for
live band karaoke hosted by Cedric Yarbrough of Reno 911.

-Thomas
http://www.t11s.com

Tuesday, February 23, 2010

Dorkbot SoCal March 20, 2010

Dorkbot SoCal 39

***** Saturday, March 20, 2010
***** 1:00pm
***** Machine Project
***** 1200 D North Alvarado Street
***** Los Angeles, CA 90026
***** Google map of Machine Project

Ruth West, Todd Margolis, Joachim Gossmann
http://www.atlasinsilico.net/

"ATLAS in silico" is the result of a vibrant collaboration between artists and scientists spanning new media, computer science, metagenomics, biology, and engineering.

Ruth West is an artist with background as a molecular genetics researcher. She is Director, Interactive Technologies for CENS (Center for Embedded Networked Sensing) on the UCLA campus and is concurrently an Artist-Research Associate at the UCSD Center for Research in Computing and the Arts, where she is the first CALIT2 New Media Artist crossing over to the Digitally Enabled Genomic Medicine Layer.

Todd Margolis is currently the Technical Director of the Center for Research in Computing and the Arts (CRCA) at UCSD. In 2004, he received his MFA in Electronic Visualization from the Electronic Visualization Laboratory at the University of Illinois at Chicago. He is a founding member of the immersive and interactive art and technology non-profit organization, Applied Interactives, and also a member of the art collaborative Sine::apsis Experiments.

Joachim Gossmann is an audiocentric media artist interested in a true interdisciplinary discourse between science and the senses. He is currently working on a PhD in Computer Music at the Center for Research and Computing in the Arts at U. C. San Diego. He also holds a a Tonmeister degree from University of the Arts, Berlin, a MFA in Composition/Experimental Sound Practices from the Californian Institute of the Arts, and has 6 years of professional experience in research, production and development of music in experimental media working at Fraunhofer IMK and the Center for Arts and Media Technology in Karlsruhe, Germany.



Dane Picard
http://www.danepicard.com/

Dane holds an MFA from CALARTS, and creates electronic sculptural works that blur the line between organic and inorganic.



MluM
http://mlum.com
MLuM is a Long Beach and Singapore based punceptual histriophonic art ensemble, comprised of multi-national artists whose creato-researchive interests include: The utilization and/or incorporation of scientific, scientistic and pseudo-scientific technologies, methodologies, idealogies and procedures in(to) aesthetic and artistic processes and practices; The aesthetics of sustainability; Sustainability as artistic tradition and genre; The geographics of social networking pertaining to the environmentics of location and mindset; Performance orientations relative to interactive systems within improvisational structures and environments; Charting influence within the aesthetic-ismos.

Always in search of collaborators, MLuM will deliver a paper (presented at MUSICACOUSTICA, Beijing) entitled "Databasethetics."


Tuesday, January 26, 2010

Breath-over-IP for Arduino

This is the code for breath-over-IP for an Arduino. This code uses the NewSoftSerial library, and assumes the use of a Lantronix Xport / Xport Direct (perhaps with a LadyAda Ethernet Shield).

#include <NewSoftSerial.h>

// breath-over-IP for Arduino

unsigned long time = 0; // time of last edge
int minTime = 25; // minimum time for edge
int good = 0; // number of consecutive good (fast) edges
int minGoods = 20; // minimum number of consecutive good (fast) edges to indicate breath

int ledPin = 13; // on-board LED pin
int irLedPin = 10; // IR LED attached to pin 12 with 220 ohm resistor
int irDetPin = 0; // IR phototransistor attached to analog 0 with 5V and 10K
int relayPin = 11; // solid-state relay pin

unsigned long onTime = 0; // relay on time'

int i=0; // counts up received breath packets for diagnostics
int light=0; // whether IR detector sees light or dark
int lastLight=0; // what IR detector saw last time
int state=0; // current state of state machine for reading HTTP

char c=0;

unsigned long sendTime=0; // last time breath packet was sent out

NewSoftSerial xport(3,2);

void setup()
{
pinMode(relayPin,OUTPUT);
digitalWrite(relayPin, LOW);

Serial.begin(57600);
xport.begin(9600);
xport.print("GET /update?d=B2&s=0 HTTP/1.1\r\nHost: phy-to-phy.appspot.com\r\n\r\n");
pinMode(ledPin, OUTPUT);
pinMode(irLedPin, OUTPUT);
digitalWrite(irLedPin, HIGH);
//Serial.print("Starting up");
}

void loop()
{
//Serial.println(analogRead(irDetPin));
if(analogRead(irDetPin)>850){
light=0; // impeller blade blocking IR
}
else{
light=1; // impeller blade not blocking IR
}

if(light != lastLight){
// edge
if(millis()-time<minTime){
// fast edge
good++;
}
else{
// not fast edge
good=0;
}
time=millis();
lastLight=light;
}

if(good>minGoods) {
// enough good (fast) edges
digitalWrite(ledPin,HIGH);
if(millis()-sendTime>100){
// send a breath, not too fast though
//Serial.print("I'm sending a breath\n");
xport.print("GET /update?d=B2&s=1 HTTP/1.1\r\nHost: phy-to-phy.appspot.com\r\n\r\n");
sendTime = millis();
}
}
else{
// not enough good (fast) edges
digitalWrite(ledPin,LOW);
if(millis()-sendTime>500){
// send a non-breath, not too fast though
//Serial.print("I'm sending a non-breath...\n");
xport.print("GET /update?d=B2&s=0&q=B1 HTTP/1.1\r\nHost: mylameapp.appspot.com\r\n\r\n");
sendTime = millis();

}
}
if(millis() - onTime > 5000){ // timeout after 5 seconds
digitalWrite(relayPin,LOW);
}

while(xport.available()){
c=(char)xport.read();
//Serial.print(c);
if((c=='B') && (state==0)){state=1;}
else if((c=='1') && (state==1)){state=2;}
else if((c==':') && (state==2)){state=3;}
else if((c=='1') && (state==3)){
digitalWrite(relayPin,HIGH);
onTime = millis();
//Serial.print("REMOTE BREATH!!!\n");
state=0;
}
else if((c=='0') && (state==3)){
digitalWrite(relayPin,LOW);
//Serial.print("No remote breath\n");
}
else state=0;
}
}

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()