efinf:blcks2017:tetristable:python

nur Dateien vom tigerjython Ordner, neu mit Joystick-Emulation

helper.py für den ESP32 (neu mit Joystick-Unterstützung), Drähte von Eingängen D32 und D25 vertauschen, siehe Verdrahtung.

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).

Alte Version

Alte Version

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.

Hier mal ein POC (Proof of concept). Die Benutzung ist wie folgt:

  1. Server starten
  2. Clients starten
  3. Beim Server einen der unteren Knöpfe drücken (→ warten auf eingehenden Verbindung).
  4. Beim ersten client einen der unteren Knöpfe drücke (→ Verbindung mit Server)
  5. Die letzten zwei Schritte für alle clients wiederholen
  6. Beim Server einen der oberen Knöpfe drücken (→ Demo startet).

Source code

Source code

wificlient.rb
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()

Source code

Source code

wifiserver.rb
# 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<len(self.connections):
                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, (), (),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()

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.
  • 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).

Auf der Konsole (putty oder screen)

import helper
h = helper.Helper()
while True:
   print(h.getJoyStick(0))
  • efinf/blcks2017/tetristable/python.txt
  • Last modified: 2018/05/22 13:23
  • by Ivo Blöchliger