From 3137b57c6fb4cd60584493ca09f0208ad287c733 Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Tue, 12 Sep 2017 03:03:52 +0200 Subject: [PATCH] Simple synchronization based on UDP broadcast --- raspi/pySejf.py | 77 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/raspi/pySejf.py b/raspi/pySejf.py index 5ba3927..95a5407 100644 --- a/raspi/pySejf.py +++ b/raspi/pySejf.py @@ -7,6 +7,8 @@ import serial import webapp import threading import logging +import socket +import json logging.basicConfig(level=logging.INFO) import random, math, pygame @@ -16,7 +18,7 @@ from virtualKeyboard import VirtualKeyboard import threading from math import cos import time -import RPi.GPIO as GPIO +import RPi.GPIO as GPIO class Slide(object): def __init__(self): @@ -44,6 +46,10 @@ class ImageSlide(Slide): screen.blit(self.image, (0, 0)) class FinalSlide(ImageSlide): + def exit(self, next_slide): + return False + +class FinalEverythingSlide(ImageSlide): def enter(self, prev_slide): global wall_a if(wall_a): @@ -51,6 +57,9 @@ class FinalSlide(ImageSlide): pygame.mixer.music.load("media/win.mp3") pygame.mixer.music.play(MP3_LOOPS) pygame.mixer.music.set_volume(1.0) + + return True + def exit(self, next_slide): return False @@ -254,6 +263,7 @@ SLIDE_MAZE = 7 SLIDE_MP3 = 8 SLIDE_KEYBOARD = 11 SLIDE_CONGRATS = 9 +SLIDE_CONGRATS_EVERYTHING = 12 SLIDE_SNAKE_DEAD = 10 #to nie slajd, tylko wartosc potrzebna do resetowania snake po przegranej @@ -270,6 +280,7 @@ slides = { SLIDE_MAZE: ImageSlide(IMG_MAZE), SLIDE_MP3: ImageSlide(IMG_MP3), SLIDE_CONGRATS: FinalSlide(IMG_WIN), + SLIDE_CONGRATS_EVERYTHING: FinalEverythingSlide(IMG_WIN), SLIDE_SNAKE: SnakeSlide(), } @@ -311,11 +322,48 @@ class SerialThread(threading.Thread): go_to_slide(int(args)) print('Setting slide to: ', slide) +class BroadcastThread(threading.Thread): + def run(self): + cs = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + cs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + cs.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + while True: + global slide + + print('sending') + cs.sendto(json.dumps({ + 'slide': slide, + }), ('255.255.255.255', 54545)) + time.sleep(1) + +class ReceiveThread(threading.Thread): + states = None + + def run(self): + self.states = {} + + s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.bind(('',54545)) + while True: + try: + msg, (host, port) = s.recvfrom(1024) + self.states[host] = json.loads(msg) + print(self.states) + + if all(s['slide'] in [SLIDE_CONGRATS, SLIDE_CONGRATS_EVERYTHING] + for s in self.states.values()): + go_to_slide(SLIDE_CONGRATS_EVERYTHING) + except: + logging.exception('Receiver failed') + time.sleep(0.5) + + for c in ['/dev/ttyUSB0', '/dev/ttyACM0']: try: ser = serial.Serial(c, 115200) except: continue + print('Using ', c) webapp.init(ser) th = SerialThread() @@ -323,12 +371,19 @@ for c in ['/dev/ttyUSB0', '/dev/ttyACM0']: th.daemon = True th.start() + bth = BroadcastThread() + bth.daemon = True + bth.start() + + rth = ReceiveThread() + rth.daemon = True + rth.start() + def win(): print "GAME OVER - YOU WIN" - GPIO.output(PIN_RELAY, 0) - - + GPIO.output(PIN_RELAY, 0) + def signalWin(success): pin = 0 if success == 4: @@ -337,15 +392,15 @@ def signalWin(success): pin = PIN_SUC9 elif success == 10: pin = PIN_SUC10 - print("signalling win for task: ") + print("signalling win for task: ") print(success) - print("using GPIO pin: ") + print("using GPIO pin: ") print(pin) - GPIO.output(pin, 0) + GPIO.output(pin, 0) pygame.time.wait(200) - GPIO.output(pin, 1) + GPIO.output(pin, 1) print("done signalling.") - + def waitForEvents(): global slide print("waiting for events") @@ -385,7 +440,7 @@ def checkEvents(handler=None): def collide(x1, x2, y1, y2, w1, w2, h1, h2): if x1+w1>x2 and x1y2 and y1