A place for Stuff

  • Home
  • About
  • Contact
  • Arduino Bits’n Pieces
  • Departments
    • Arduino
    • Uncategorized
  • Subscribe via RSS

Arduino + Ethernet shield + XML-RPC + Python

November 5th, 2009  |  Published in Arduino  |  2 Comments

The Problem: In the middle of an exhibition space visitors are encouraged to play a piano.  At the end of the gallery a screen and speakers blare to the music of Tiny Tim.  The visitor at the piano should be able to mute the audio from the piano.  Technical limitations.  There is no way to run cables from the piano any distance but there is power in a floor pit.  The AV at the end of the gallery is run by a Mac Mini buried in the floor.

BTW this is currently installed in the Martin Sharp exhibition at the Museum of Sydney in Sydney, Australia.

31102009568

The Solution. Button -> Arduino with ethernet shield -> ethernet over power -> XML-RPC -> Python -> apple script.

I already had some ethernet over power devices so getting one ethernet shield was cheeper than Xbee or Wi-fi.

Hardware

Basically just a box with a button and an arduino and ethernet shield.  I modified a black cat5 cable to also do power over ethernet so I only had to have one cable going from the box to the floor.

30102009565

Power. I discovered right at the last minute that the arduino with ethernet shield is way more fussy than lots of other projects.  A 9 or 12 volt supply along with the extra draw from the ethernet shield makes for an overloaded power regulator.  When I finally figured out what the problem was a 7.5 volt power supply came to the rescue.

Software

On the ardunio side I didn’t have time for writing a XML-RPC library or anything fancy so I just manually created the one call I needed with basic print statements. You will need to manually calculate your content-length value if you intend to modify.


#include <Ethernet.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { blah, blah, blah, blah };
byte server[] = { blah, blah, blah, blah };

int button_pin = 3;
int buttonState = 0;
int val1;
int val2;

Client client(server, 8888);

void setup()
{
  Serial.begin(9600);
  pinMode(button_pin, INPUT);
}

void muteaudio() {
  Ethernet.begin(mac, ip);
  Serial.println("connecting...");
  if (client.connect()) {
    Serial.println("connected");
    client.println("POST /RPC2 HTTP/1.0");
    client.println("User-Agent: Arduino");
    client.println("Host: blah.blah.blah.blah");
    client.println("Content-Type: text/xml");
    client.println("Content-length: 83");
    client.println("<?xml version=\"1.0\"?>");
    client.println("<methodCall>");
    client.println("   <methodName>doMute</methodName>");
    client.println("</methodCall>");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
    client.println("");
  } else {
    Serial.println("connection failed");
  }

  client.stop();
}

void loop()
{

// Ethernet Feedback
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

 // Button 

   val1 = digitalRead(button_pin);
   delay(10);
    val2 = digitalRead(button_pin);
    if ( val1 == val2){
  	if (val1 != buttonState){ // state has changed
  		if (val1 == 1 and buttonState == 0){
                        Serial.print("Muting Audio");
                        muteaudio();
  		}
  	}
  	buttonState = val1 ;
  }

}

The empty carriage returns are something I accidentally discovered while testing with telnet that makes the python XMLRPC server accept the RPC request.  I don’t know why, but it works.

The python script is pretty basic and just takes the request and writes an applescript command to the shell to switch the audio on and off.

# import modules
import SimpleXMLRPCServer
import subprocess

global toggle
toggle = 1

#The server object
class button:
	def doMute(self):
		global toggle
		if toggle == 0 :
			cl = 'osascript -e \"set volume 0\"'
			print cl
			subprocess.Popen(cl, shell=True)
			toggle = 1
		elif toggle == 1:
			cl = 'osascript -e \"set volume 10\"'
			print cl
			subprocess.Popen(cl, shell=True)
			toggle = 0
		return "Done"

button_object = button()
server = SimpleXMLRPCServer.SimpleXMLRPCServer(("bla.bla.bla.bla", 8888))
server.register_instance(button_object)
#Go into the main listener loop
print "Listening on port 8888"
server.serve_forever()

Responses

Feed
  1. Roundup: simple hacks - Hack a Day says:

    November 10th, 2009 at 8:01 am (#)

    [...] for some speakers at the other end of the room. The music was played by a Mac mini so he built a mute button that sends commands over a network. By using an Ethernet shield for an Arduino he’s able to detect a button press and send [...]

  2. Roundup: simple hacks says:

    November 10th, 2009 at 12:29 pm (#)

    [...] for some speakers at the other end of the room. The music was played by a Mac mini so he built a mute button that sends commands over a network. By using an Ethernet shield for an Arduino he’s able to detect a button press and send [...]



©2010 A place for Stuff
Powered by WordPress using the Gridline Lite theme by Graph Paper Press.