===== Emulation und Driver (Helper) =====
{{ :efinf:blcks2017:tetristable:tigerjython.zip |nur Dateien vom tigerjython Ordner, neu mit Joystick-Emulation}}
{{ :efinf:blcks2017:tetristable:helper.py |helper.py für den ESP32 (neu mit Joystick-Unterstützung)}}, Drähte von Eingängen D32 und D25 vertauschen, siehe [[efinf:blcks2017:tetristable:bauanleitung#verdrahtung|Verdrahtung]].
{{ :efinf:blcks2017:tetristable:mcp.py |mcp.py}} für den ESP32.
Verwenden Sie dieses Archiv für ein Update (die Datei helper.py unterhalb des tigerjython Verzeichnisses soll nicht überschrieben werden).
* {{ :efinf:blcks2017:tetristable:tetris-table.zip |Zip-Archiv mit Demo (Lauffähig auch in TigerJython)}}
Die Datei ''helper.py'' unterhalb des tigerjython Verzeichnisses muss eventuell angepasst werden für den eigenen Tisch.
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 ====
import network
import time
import usocket as socket
# Hack to get ticks_ms() method in Tigerjython working
if not hasattr(time, 'ticks_ms'):
from types import MethodType
def ticks_ms(self):
return int(round(self.time() * 1000))
time.ticks_ms = MethodType(ticks_ms, time)
def sleep_ms(self,a):
time.sleep(a/1000.0)
time.sleep_ms = MethodType(sleep_ms, time)
# END of Hack
class WifiClient:
def __init__(self,helper):
self.helper = helper
def setup(self):
self.wlan = network.WLAN(network.STA_IF)
self.wlan.active(True)
self.wlan.connect('esp32')
while not self.wlan.isconnected():
print(self.wlan.status())
time.sleep_ms(1000) # 1 second sleep
print("WLAN ok")
def connect(self):
self.addr = socket.getaddrinfo('10.42.42.1', 80)[0][-1]
self.sk = socket.socket()
self.sk.connect(self.addr)
print("Connected to server")
def update(self):
bytesread = 0
buf = b''
while bytesread<450:
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,y,(buf[p], buf[p+1], buf[p+2]))
self.helper.np.write()
#print("Updated")
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("wificlient.py")
if __name__=="__main__":
from helper import Helper # Import der Klasse
helper = Helper() # Erzeugen der Instanz
# helper = None
c = WifiClient(helper)
c.play()
==== Server ====
# See https://docs.micropython.org/en/latest/esp8266/library/network.html
import network
import socket
import math
import time
# Hack to get ticks_ms() method in Tigerjython working
if not hasattr(time, 'ticks_ms'):
from types import MethodType
def ticks_ms(self):
return int(round(self.time() * 1000))
time.ticks_ms = MethodType(ticks_ms, time)
def sleep_ms(self,a):
time.sleep(a/1000.0)
time.sleep_ms = MethodType(sleep_ms, time)
# END of Hack
class WifiServer:
def __init__(self, helper):
self.helper = helper
def setup(self):
self.ap = network.WLAN(network.AP_IF)
self.ap.active(True)
self.ap.config(essid='esp32', authmode=0)
self.ap.ifconfig(('10.42.42.1', '255.255.255.0', '10.42.42.1', '10.42.42.1'))
print("AP up an running")
self.connections=[]
# self.cfiles=[]
self.graphBuffers=[]
self.buttons=bytearray([])
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
self.sk = socket.socket()
self.sk.bind(addr)
self.sk.listen(1)
print("Server up an running")
def clearBuffers(self):
if self.helper:
for i in range(150):
self.helper.np[i]=(0,0,0)
for b in self.graphBuffers:
for i in range(450):
b[i]=0
def waitForConnection(self):
print("Wait for connection...")
cl, addr = self.sk.accept()
self.connections.append(cl)
print('client connected from', addr)
#cl_file = cl.makefile('rwb', 0)
#self.cfiles.append(cl_file)
self.graphBuffers.append(bytearray([0 for i in range(450)]))
self.buttons.append(255)
def setPixel(self,x,y,color):
if (x<10):
if self.helper:
self.helper.setPixel(x,y,color)
else:
table = x//10-1
if table=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, (), (),0)
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<450:
sent = self.connections[i].send(bytes(self.graphBuffers[i][totalsent:]))
if sent == 0:
print("socket connection broken")
break
totalsent+=sent
time.sleep_ms(40) # 25 fps
#print("sent")
def demo(self,i):
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, y, (255,0,0))
self.setPixel(x, y+1, (50,0,0))
self.setPixel(x, y-1, (50,0,0))
y = int(math.sin(0.06189*(x+i+5))*7+8)
self.setPixel(x, y, (0,255,0))
self.setPixel(x, y+1, (0,50,0))
self.setPixel(x, y-1, (0,50,0))
y = int(math.sin(0.04189*(x+i+10))*7+8)
self.setPixel(x, y, (0,0,255))
self.setPixel(x, y+1, (0,0,50))
self.setPixel(x, y-1, (0,0,50))
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) &0xf>0:
self.waitForConnection()
else:
break
else:
self.waitForConnection()
i=0
while True:
self.demo(i)
i+=1
# Start with execfile("wifiserver.py")
if __name__=="__main__":
print("Start Main")
# from helper import Helper # Import der Klasse
# helper = Helper() # Erzeugen der Instanz
helper = None
print(helper)
s = WifiServer(helper)
s.play()
===== Ablauf der Programmierung =====
**Achtung**: Wenn Putty verbunden ist, funktioniert ampy nicht (und umgekehrt).
* Entwicklung des Codes im Texteditor, speichern einer Datei, z.B. ''beispiel.py''
* Eventuell Datei lokal mit Python ausführen, erste Bugs werden so schon gefunden.
* Datei mit ''ampy'' auf EPS laden.
* Wenn die Datei ''main.py'' heisst (oder von main.py aufgerufen wird):
* Reset am Tisch
* Sonst:
* Verbinden mit Putty (oder pico-dingsbums auf Mac), evtl. Ctrl-C um Programm zu stoppen
* Programm mit ''import beispiel.py'' ausführen, Fehlermeldungen verstehen.
===== Tools auf dem ESP =====
* Dateien anschauen, löschen, umbennen, direkt auf dem ESP:
* Mit Putty verbinden
* ''import os''
* ''help(os)'' (Zeigt Befehle an, wie Liste der Dateien, löschen, umbenennen).
===== Joysticks testen =====
Auf der Konsole (putty oder screen)
import helper
h = helper.Helper()
while True:
print(h.getJoyStick(0))