Differenze tra le versioni di "ScratchRobot"
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 16: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.