Differenze tra le versioni di "ScratchRobot"

Da raspibo.
Jump to navigation Jump to search
(Script per la comunicazione tra scratch e arduino via python)
 
(Aggiunto script python)
 
Riga 50: Riga 50:
 
La controparte python invece si attacca ad una istanza scratch e fa da ponte/interprete
 
La controparte python invece si attacca ad una istanza scratch e fa da ponte/interprete
 
dei comandi verso arduino.
 
dei comandi verso arduino.
 +
 +
<pre>
 +
import serial
 +
import socket
 +
import time
 +
from array import array
 +
import struct
 +
import atexit
 +
 +
PORT = 42001
 +
HOST = "192.168.11.40"
 +
 +
def decode_message(socket):
 +
payload_size = socket.recv(4)
 +
if not payload_size:
 +
return ("broadcast", '"quit"')
 +
payload_size = struct.unpack("xxxB",payload_size)[0]
 +
msg = socket.recv(payload_size)
 +
msgtype = msg.split(" ")[0]
 +
args = msg.split(" ")[1:]
 +
return (msgtype, args)
 +
 +
def quitting(arduino, scratch):
 +
print " exiting... "
 +
arduino.close()
 +
scratch.close()
 +
 +
def manage_broadcast(payload, serialConnection):
 +
payload = payload[1:-1]
 +
if payload=="go":
 +
serialConnection.write('n')
 +
if payload=="stop":
 +
serialConnection.write('f')
 +
if payload=="quit":
 +
serialConnection.write('f')
 +
for i in range(3):
 +
serialConnection.write('n')
 +
time.sleep(0.1)
 +
serialConnection.write('f')
 +
time.sleep(0.1)
 +
quit()
 +
 +
def manage_sensor_update(sensor, value, serialConnection):
 +
# Modificando/creando una variabile globale viene inviato un messaggio di
 +
# tipo sensor-update con il nome della variabile ed il suo valore attuale
 +
sensor = sensor[1:-1]
 +
if payload=="go":
 +
serialConnection.write('n')
 +
if payload=="stop":
 +
serialConnection.write('f')
 +
if payload=="quit":
 +
serialConnection.write('f')
 +
for i in range(3):
 +
serialConnection.write('n')
 +
time.sleep(0.1)
 +
serialConnection.write('f')
 +
time.sleep(0.1)
 +
quit()
 +
 +
def arduino_connect(**kwargs):
 +
ports = ["/dev/ttyUSB0", "/dev/ttyACM0"]
 +
for i in ports:
 +
try:
 +
print ("Arduino Connect: trying %i", i)
 +
return serial.Serial(i, baudrate=9600, timeout=1)
 +
except:
 +
pass
 +
print "Arduino not found. Abort."
 +
quit()
 +
 +
arduino=arduino_connect(baudrate=9600, timeout=1)
 +
print ("Arduino Found.")
 +
 +
scratch = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 +
try:
 +
scratch.connect((HOST, PORT))
 +
print ("Scratch Found.")
 +
except:
 +
print "Scratch not found. Abort."
 +
arduino.close()
 +
quit()
 +
 +
atexit.register(quitting, arduino, scratch)
 +
print "Waiting for messages..."
 +
while 1:
 +
time.sleep(0.01)
 +
type, args = decode_message(scratch)
 +
if type == "broadcast":
 +
manage_broadcast(*args, serialConnection=arduino)
 +
if type == "sensor-update":
 +
manage_sensor_update(*args, serialConnection=arduino)
 +
 +
</pre>
 +
 +
 
'Nota: ' Se arduino è collegato via usb alla macchina host quando Scratch va in modalità server
 
'Nota: ' Se arduino è collegato via usb alla macchina host quando Scratch va in modalità server
 
scratch sembra inviare direttamente i comandi anche a lui (penso che in realta cerchi un handshake
 
scratch sembra inviare direttamente i comandi anche a lui (penso che in realta cerchi un handshake
 
senza successo) e python non riesce più ad interfacciardi ad arduino.
 
senza successo) e python non riesce più ad interfacciardi ad arduino.

Versione attuale delle 17:06, 25 lug 2013

Due righe e qualche pezzo di codice da riorganizzare:

La parte arduino sta semplicemente in attesa di un comando sulla seriale e, in caso lo riconosca esegue le istruzioni associate.

/*
  Python interface via usb serial
  Language: Wiring/Arduino

  Il programma si mette in attesa di un input sulla seriale
  ed agisce a seconda dell'input ricevuto.

  This example code is in the public domain.
 */

int led = 13;    // first analog sensor
int inByte = 0;         // incoming serial byte

void setup()
{
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

//  establishContact();  // send a byte to establish contact until receiver responds
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    if ((char) inByte=='n') { // oN
        digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    } else if ((char) inByte=='f') { // ofF
        digitalWrite(led, LOW);   // turn the LED off
    } else { //      default:
        Serial.print(inByte); // send back the unrecognized command to the sender
    }
  }
}

La controparte python invece si attacca ad una istanza scratch e fa da ponte/interprete dei comandi verso arduino.

import serial
import socket
import time
from array import array
import struct
import atexit

PORT = 42001
HOST = "192.168.11.40"

def decode_message(socket):
	payload_size = socket.recv(4)
	if not payload_size: 
		return ("broadcast", '"quit"')
	payload_size = struct.unpack("xxxB",payload_size)[0]
	msg = socket.recv(payload_size)
	msgtype = msg.split(" ")[0]
	args = msg.split(" ")[1:]
	return (msgtype, args)

def quitting(arduino, scratch):
	print " exiting... "
	arduino.close()
	scratch.close()

def manage_broadcast(payload, serialConnection):
	payload = payload[1:-1]
	if payload=="go":
		serialConnection.write('n')
	if payload=="stop":
		serialConnection.write('f')
	if payload=="quit":
		serialConnection.write('f')
		for i in range(3):
			serialConnection.write('n')
			time.sleep(0.1)
			serialConnection.write('f')
			time.sleep(0.1)
		quit()

def manage_sensor_update(sensor, value, serialConnection):
	# Modificando/creando una variabile globale viene inviato un messaggio di
	# tipo sensor-update con il nome della variabile ed il suo valore attuale
	sensor = sensor[1:-1]
	if payload=="go":
		serialConnection.write('n')
	if payload=="stop":
		serialConnection.write('f')
	if payload=="quit":
		serialConnection.write('f')
		for i in range(3):
			serialConnection.write('n')
			time.sleep(0.1)
			serialConnection.write('f')
			time.sleep(0.1)
		quit()

def arduino_connect(**kwargs):
	ports = ["/dev/ttyUSB0", "/dev/ttyACM0"]
	for i in ports:
		try:
			print ("Arduino Connect: trying %i", i)
			return serial.Serial(i, baudrate=9600, timeout=1)
		except:
			pass
	print "Arduino not found. Abort."
	quit()
		
arduino=arduino_connect(baudrate=9600, timeout=1)
print ("Arduino Found.")

scratch = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
	scratch.connect((HOST, PORT))
	print ("Scratch Found.")
except:
	print "Scratch not found. Abort."
	arduino.close()
	quit()

atexit.register(quitting, arduino, scratch) 
print "Waiting for messages..."
while 1:
	time.sleep(0.01)
	type, args = decode_message(scratch)
	if type == "broadcast":
		manage_broadcast(*args, serialConnection=arduino)	
	if type == "sensor-update":
		manage_sensor_update(*args, serialConnection=arduino)	


'Nota: ' Se arduino è collegato via usb alla macchina host quando Scratch va in modalità server scratch sembra inviare direttamente i comandi anche a lui (penso che in realta cerchi un handshake senza successo) e python non riesce più ad interfacciardi ad arduino.