Discuss Scratch
- Discussion Forums
- » Show and Tell
- » Mesh server for raspberry pi - control Pi GPIO remotely
- joncassidy
-
Scratcher
1 post
Mesh server for raspberry pi - control Pi GPIO remotely
I run a raspberry pi without a display or keyboard, and access it from a laptop. Mostly I'm playing with it to see what it will do, so this seems fine.
I like Scratch, but I want to interact with the real world more. I can run X remotely, but here's another approach, using the scratch mesh function to send commands to a (small) python listener on the raspberry pi, and switching LEDs on and off from scratch. I think it's a good way to show children about controlling the real world.
This needs:
Code: (Save as meshServer.py on the pi):
I like Scratch, but I want to interact with the real world more. I can run X remotely, but here's another approach, using the scratch mesh function to send commands to a (small) python listener on the raspberry pi, and switching LEDs on and off from scratch. I think it's a good way to show children about controlling the real world.
This needs:
- Scratch 1.4, set up to use the mesh function. Very quick to do for any scratch - instructions at
http://wiki.scratch.mit.edu/wiki/Mesh#Mesh_by_Modification_of_Scratch. Unfortunately not available for Scratch 2.0 - A raspberry pi, and something connected to the GPIO pins. I used a berryclip, because they are cheap and simple, but you do have to solder them yourself.
- The wiringPi library
- A little bit of python script running on the pi. I started with the one at http://archive.scratch.mit.edu/forums/viewtopic.php?id=95283, and extended it to control the GPIO pins, as below. I would have liked to just add this to that posting, as it;s a great piece of work, but the forums are closed.
- Run the python as superuser (“sudo python meshServer.py”)
- Connect to it by joining the mesh session from another computer running scratch (as at the mesh link above, by Shift-clicking on the Share menu)
- Broadcast commands like ‘pin 7 on’ to switch pin 7 on. Currently set up for the berryclip as above. Next I'll make it more generic, but don't be afraid of changing the python - I don't know python either!
Code: (Save as meshServer.py on the pi):
#!/usr/bin/env python
import select
import socket
import sys
import threading
import RPi.GPIO as GPIO
import pdb
import struct
class Server:
def __init__(self):
self.host = ''
self.port = 42001
self.backlog = 5
self.size = 1024
self.server = None
self.threads = []
GPIO.setmode(GPIO.BOARD)
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
self.server.bind((self.host,self.port))
self.server.listen(5)
except socket.error, (value,message):
if self.server:
self.server.close()
print "Could not open socket: " + message
sys.exit(1)
def run(self):
self.open_socket()
input = [self.server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == self.server:
# handle the server socket
c = Client(self.server.accept())
c.start()
self.threads.append(c)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
print("Just set running to 0")
# close all threads
self.server.close()
for c in self.threads:
c.join()
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
def processMessage(self, message):
if (message == 'broadcast kill'): running = 0
# broadcasts = pinX output. X=number, output = on or off
message=message.replace('\"','')
if message[0:9] == 'broadcast':
messageParts = message[11:].split()
pinNumber = int(messageParts[1])
#pdb.set_trace()
if (messageParts[2] == "on") | (messageParts[2] == "1"):
pinSetting = GPIO.HIGH
else:
pinSetting = GPIO.LOW
print("Pin:" + str(pinNumber) + "to:" + str(pinSetting))
GPIO.output(pinNumber, pinSetting)
def run(self):
running = 1
GPIO.setup(7, GPIO.OUT) # Red 1
GPIO.setup(11, GPIO.OUT) # Yellow 1
GPIO.setup(15, GPIO.OUT) # Green 1
GPIO.setup(19, GPIO.OUT) # Red 2
GPIO.setup(21, GPIO.OUT) # Yellow 2
GPIO.setup(23, GPIO.OUT) # Green 2
GPIO.setup(26, GPIO.IN) # Push Button
while running:
try:
data = self.client.recv(self.size)
except KeyboardInterrupt:
running = 0
except Exception, e:
self.log(str(e))
data = ''
if data:
for user in s.threads:
try:
pointer = 0
while pointer < len(data):
messageLength = struct.unpack(">l",data[pointer:pointer+4])[0]
thisMessage = data[pointer+4:pointer+4+messageLength]
pointer += messageLength + 4
self.processMessage(thisMessage)
except KeyboardInterrupt:
running = 0
except Exception, e:
self.log(str(e))
GPIO.cleanup()
self.client.close()
running = 0
def log(self, string):
try:
log_file = open("mesh.log", 'a')
log_file.write('\n' + string)
log_file.close()
except IOError, e:
log_file = open("mesh.log", 'w')
log_file.write(string)
log_file.close()
if __name__ == "__main__":
s = Server()
s.daemon = True
s.run()
Last edited by joncassidy (Oct. 24, 2013 20:56:35)
- Magnie
-
Scratcher
100+ posts
Mesh server for raspberry pi - control Pi GPIO remotely
That's brilliant! You should probably ask for this to be moved to Advanced Topics, it'll be more at home there. You should also put the code inside [code] tags so it's easier to read on the site.
- Discussion Forums
- » Show and Tell
-
» Mesh server for raspberry pi - control Pi GPIO remotely