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.