Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
| efinf:blcks2017:tetristable:python [2018/03/14 14:00] – [Ablauf der Programmierung] Ivo Blöchliger | efinf:blcks2017:tetristable:python [2018/05/22 11:23] (current) – [Wifi: Verbund von Tischen] Ivo Blöchliger | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ===== Emulation und Driver (Helper) ===== | ||
| + | {{ : | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | {{ : | ||
| + | |||
| + | Verwenden Sie dieses Archiv für ein Update (die Datei helper.py unterhalb des tigerjython Verzeichnisses soll nicht überschrieben werden). | ||
| + | |||
| + | <hidden Alte Version> | ||
| + | * {{ : | ||
| + | |||
| + | Die Datei '' | ||
| + | |||
| + | Alle Zugriffe auf die Hardware müssen über die Helper-Klasse erfolgen. So sind die Programme auf allen Tischen lauffähig. Eigene Programme werden idealerweise wie die Demos erstellt. So sind diese sehr einfach auszutauschen und einzubauen. | ||
| + | </ | ||
| + | |||
| + | ===== Wifi: Verbund von Tischen ===== | ||
| + | Hier mal ein POC (Proof of concept). Die Benutzung ist wie folgt: | ||
| + | |||
| + | - Server starten | ||
| + | - Clients starten | ||
| + | - Beim Server einen der unteren Knöpfe drücken (-> warten auf eingehenden Verbindung). | ||
| + | - Beim ersten client einen der unteren Knöpfe drücke (-> Verbindung mit Server) | ||
| + | - Die letzten zwei Schritte für alle clients wiederholen | ||
| + | - Beim Server einen der oberen Knöpfe drücken (-> Demo startet). | ||
| + | ==== Client ==== | ||
| + | <hidden Source code> | ||
| + | <code python wificlient.rb> | ||
| + | |||
| + | import network | ||
| + | |||
| + | import time | ||
| + | import usocket as socket | ||
| + | |||
| + | # Hack to get ticks_ms() method in Tigerjython working | ||
| + | if not hasattr(time, | ||
| + | from types import MethodType | ||
| + | def ticks_ms(self): | ||
| + | return int(round(self.time() * 1000)) | ||
| + | time.ticks_ms = MethodType(ticks_ms, | ||
| + | | ||
| + | def sleep_ms(self, | ||
| + | time.sleep(a/ | ||
| + | time.sleep_ms = MethodType(sleep_ms, | ||
| + | # END of Hack | ||
| + | |||
| + | class WifiClient: | ||
| + | |||
| + | def __init__(self, | ||
| + | self.helper = helper | ||
| + | |||
| + | def setup(self): | ||
| + | self.wlan = network.WLAN(network.STA_IF) | ||
| + | self.wlan.active(True) | ||
| + | self.wlan.connect(' | ||
| + | | ||
| + | while not self.wlan.isconnected(): | ||
| + | print(self.wlan.status()) | ||
| + | time.sleep_ms(1000) # 1 second sleep | ||
| + | print(" | ||
| + | | ||
| + | def connect(self): | ||
| + | self.addr = socket.getaddrinfo(' | ||
| + | self.sk = socket.socket() | ||
| + | self.sk.connect(self.addr) | ||
| + | print(" | ||
| + | |||
| + | def update(self): | ||
| + | bytesread = 0 | ||
| + | buf = b'' | ||
| + | while bytesread< | ||
| + | chunk = self.sk.recv(450) | ||
| + | buf+=chunk | ||
| + | bytesread+=len(chunk) | ||
| + | if bytesread==450 and self.helper: | ||
| + | for y in range(15): | ||
| + | for x in range(10): | ||
| + | p = 3*(y*10+x) | ||
| + | self.helper.setPixel(x, | ||
| + | self.helper.np.write() | ||
| + | # | ||
| + | |||
| + | |||
| + | def sendButtons(self): | ||
| + | if self.helper: | ||
| + | btns = bytearray([self.helper.getButtons()]) | ||
| + | self.sk.send(btns) | ||
| + | | ||
| + | |||
| + | def play(self): | ||
| + | self.setup() | ||
| + | if self.helper: | ||
| + | while self.helper.getButtons()!=255: | ||
| + | pass | ||
| + | while self.helper.getButtons()==255: | ||
| + | pass | ||
| + | self.connect() | ||
| + | while True: | ||
| + | self.update() | ||
| + | |||
| + | # Start with execfile(" | ||
| + | |||
| + | if __name__==" | ||
| + | from helper import Helper | ||
| + | helper = Helper() | ||
| + | # helper = None | ||
| + | c = WifiClient(helper) | ||
| + | c.play() | ||
| + | | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | ==== Server ==== | ||
| + | <hidden Source code> | ||
| + | <code python wifiserver.rb> | ||
| + | # See https:// | ||
| + | |||
| + | import network | ||
| + | import socket | ||
| + | import math | ||
| + | import time | ||
| + | |||
| + | # Hack to get ticks_ms() method in Tigerjython working | ||
| + | if not hasattr(time, | ||
| + | from types import MethodType | ||
| + | def ticks_ms(self): | ||
| + | return int(round(self.time() * 1000)) | ||
| + | time.ticks_ms = MethodType(ticks_ms, | ||
| + | | ||
| + | def sleep_ms(self, | ||
| + | time.sleep(a/ | ||
| + | time.sleep_ms = MethodType(sleep_ms, | ||
| + | # END of Hack | ||
| + | |||
| + | |||
| + | |||
| + | class WifiServer: | ||
| + | |||
| + | def __init__(self, | ||
| + | self.helper = helper | ||
| + | |||
| + | |||
| + | def setup(self): | ||
| + | self.ap = network.WLAN(network.AP_IF) | ||
| + | self.ap.active(True) | ||
| + | self.ap.config(essid=' | ||
| + | self.ap.ifconfig((' | ||
| + | print(" | ||
| + | self.connections=[] | ||
| + | # self.cfiles=[] | ||
| + | self.graphBuffers=[] | ||
| + | self.buttons=bytearray([]) | ||
| + | addr = socket.getaddrinfo(' | ||
| + | self.sk = socket.socket() | ||
| + | self.sk.bind(addr) | ||
| + | self.sk.listen(1) | ||
| + | print(" | ||
| + | |||
| + | def clearBuffers(self): | ||
| + | if self.helper: | ||
| + | for i in range(150): | ||
| + | self.helper.np[i]=(0, | ||
| + | for b in self.graphBuffers: | ||
| + | for i in range(450): | ||
| + | b[i]=0 | ||
| + | |||
| + | def waitForConnection(self): | ||
| + | print(" | ||
| + | cl, addr = self.sk.accept() | ||
| + | self.connections.append(cl) | ||
| + | print(' | ||
| + | #cl_file = cl.makefile(' | ||
| + | # | ||
| + | self.graphBuffers.append(bytearray([0 for i in range(450)])) | ||
| + | self.buttons.append(255) | ||
| + | |||
| + | def setPixel(self, | ||
| + | if (x<10): | ||
| + | if self.helper: | ||
| + | self.helper.setPixel(x, | ||
| + | else: | ||
| + | table = x//10-1 | ||
| + | if table< | ||
| + | n = y*10+x | ||
| + | if n>=0 and n<149: | ||
| + | self.graphBuffers[table][3*n]=color[0] | ||
| + | self.graphBuffers[table][3*n+1]=color[1] | ||
| + | self.graphBuffers[table][3*n+2]=color[2] | ||
| + | | ||
| + | |||
| + | |||
| + | def getButtons(self): | ||
| + | # Get list with available bytes | ||
| + | available = select.select(self.connections, | ||
| + | for i in range(len(self.connections)): | ||
| + | if self.connections[i] in available: | ||
| + | b = self.connections[i].recv(1) | ||
| + | if b=='': | ||
| + | self.buttons[i]=255 | ||
| + | else: | ||
| + | self.buttons[i]=b[0] | ||
| + | | ||
| + | |||
| + | def write(self): | ||
| + | if self.helper: | ||
| + | self.helper.np.write() | ||
| + | for i in range(len(self.connections)): | ||
| + | totalsent = 0 | ||
| + | while totalsent< | ||
| + | sent = self.connections[i].send(bytes(self.graphBuffers[i][totalsent: | ||
| + | if sent == 0: | ||
| + | print(" | ||
| + | break | ||
| + | totalsent+=sent | ||
| + | time.sleep_ms(40) # 25 fps | ||
| + | # | ||
| + | |||
| + | def demo(self, | ||
| + | xmax = (len(self.connections)+1)*10; | ||
| + | self.clearBuffers() | ||
| + | for x in range(xmax): | ||
| + | y = int(math.sin(0.1*(x+i))*7+8) | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | y = int(math.sin(0.06189*(x+i+5))*7+8) | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | y = int(math.sin(0.04189*(x+i+10))*7+8) | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | self.setPixel(x, | ||
| + | self.write() | ||
| + | |||
| + | | ||
| + | def play(self): | ||
| + | self.setup() | ||
| + | if self.helper: | ||
| + | while True: | ||
| + | while self.helper.getButtons()!=255: | ||
| + | pass | ||
| + | while self.helper.getButtons()==255: | ||
| + | pass | ||
| + | if (self.helper.getButtons()^0xff) & | ||
| + | self.waitForConnection() | ||
| + | else: | ||
| + | break | ||
| + | else: | ||
| + | self.waitForConnection() | ||
| + | | ||
| + | i=0 | ||
| + | while True: | ||
| + | self.demo(i) | ||
| + | i+=1 | ||
| + | |||
| + | |||
| + | # Start with execfile(" | ||
| + | |||
| + | if __name__==" | ||
| + | print(" | ||
| + | # from helper import Helper | ||
| + | # helper = Helper() | ||
| + | helper = None | ||
| + | print(helper) | ||
| + | s = WifiServer(helper) | ||
| + | s.play() | ||
| + | | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | ===== Ablauf der Programmierung ===== | ||
| + | **Achtung**: | ||
| + | * Entwicklung des Codes im Texteditor, speichern einer Datei, z.B. '' | ||
| + | * Eventuell Datei lokal mit Python ausführen, erste Bugs werden so schon gefunden. | ||
| + | * Datei mit '' | ||
| + | * Wenn die Datei '' | ||
| + | * Reset am Tisch | ||
| + | * Sonst: | ||
| + | * Verbinden mit Putty (oder pico-dingsbums auf Mac), evtl. Ctrl-C um Programm zu stoppen | ||
| + | * Programm mit '' | ||
| + | |||
| + | ===== Tools auf dem ESP ===== | ||
| + | * Dateien anschauen, löschen, umbennen, direkt auf dem ESP: | ||
| + | * Mit Putty verbinden | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | |||
| + | |||
| + | ===== Joysticks testen ===== | ||
| + | Auf der Konsole (putty oder screen) | ||
| + | <code python> | ||
| + | import helper | ||
| + | h = helper.Helper() | ||
| + | while True: | ||
| + | | ||
| + | |||
| + | </ | ||