Code-Outlet von Andreas Bahr, Zürich
Der Durst-O-Mat ist eine Spielmaschine in der Tradition des "einarmigen Banditen". Die Maschine produziert ein zufällig zusammengestelltes Cocktail-Rezept.
Das Gerät wurde von DJ Fridgemonster mit Hilfe eines Lasercutter gebaut. Meine Aufgabe: Hard- & Software der Maschine zu realisieren.
Wenn das Resultat nicht gefällt, können die einzelnen Walzen mittels der korrespondierenden Tasten nochmals gestartet werden.
Die Elektronik der Maschine besteht aus Microcontroller-Komponenten rund um das Modell CORE des chinesischen Herstellers M5. Die Schrittmotoren sind vom TYP NEMA 17.
Die Maschine wird mit einem 12V 1A Netzteil betrieben.
Zur Zeit in Arbeit ist ein weiterer M5 Microcontroller vom Typ ATOM, mit Treiber für einen einzelnen Schrittmotor für die "Gemüse" Auswahl. Trotz identischer Chips funktioniert die bereits bewährte Software dort fehlerhaft.
Ausserdem arbeitet DJ Fridgemonster an weiteren Modulen...
In der M5-Welt wird mit MicroPython in einer Web-IDE programmiert.
Bei meinen ersten Tests machten die Schrittmotoren bei starten verrückte Dinge. Vermutlich haben die Anlauf-Ströme der drei gleichzeitig gestarteten Motoren das Controller-Board überlastet. Das Problem konnte durch gestaffeltes Anlaufen der Motoren gelöst werden.
Den Inhalt der hier angebotenen Datei können Sie in die offizielle IDE kopieren. Sie lässt sich aber auch mit einem normalen Text-Editor lesen.
""" DURST-O-MAT v0.2.3 Target: M5Stack Core 2022 Andreas Bahr --------------------- Stepmotor Driver 13.2: X = Left Wheel L0 = Start Game L1 = Left Wheel Trigger ----------------------- 4 Relay: Relay 1: start game button lamp Relay 2: wheel buttons lamps """ from m5stack import * from m5ui import * from uiflow import * import machine import i2c_bus import unit import time import random from numbers import Number # setup: motorIntMs = 4 # wheels control variables trigger = False triggerX = False triggerY = False triggerZ = False wheelX = 0 wheelY = 0 wheelZ = 0 finitoX = None finitoY = None finitoZ = None def blinkGreen(relayBar): if relayBar.get_relay_status(1): relayBar.set_relay_status(1, 0) # green lamp OFF else: relayBar.set_relay_status(1, 1) # green lamp ON # display setScreenColor(0x33cc00) lcd.font(lcd.FONT_DejaVu18) lcd.print('Startup...', 0, 0, 0x000000) # stepmotor driver setup pin0 = machine.Pin(16, mode=machine.Pin.OUT, pull=0x00) # step X pin1 = machine.Pin(17, mode=machine.Pin.OUT, pull=0x00) # direction X pin1.on() # off = turn left, on = turn right pin2 = machine.Pin(12, mode=machine.Pin.OUT, pull=0x00) # step Y pin3 = machine.Pin(13, mode=machine.Pin.OUT, pull=0x00) # direction X pin3.on() # off = turn left, on = turn right pin4 = machine.Pin(0, mode=machine.Pin.OUT, pull=0x00) # direction Z pin4.on() # off = turn left, on = turn right pin4 = machine.Pin(15, mode=machine.Pin.OUT, pull=0x00) # step Z i2c0 = i2c_bus.easyI2C(i2c_bus.PORTA, 0x00, freq=400000) # port expander i2c0.addr=(0x27) i2c0.write_u8(0x03, 0x0F) # config I/O # relay module setup relayBar = unit.get(unit.RELAY4, unit.PORTA) relayBar.set_mode(1) # loop-o-grande lcd.clear() while True: randomRecipe = '' lcd.print('DURST-O-MAT v0.2.3', 0, 0, 0x000000) relayBar.set_relay_status(1, 1) # green lamp ON relayBar.set_relay_status(2, 1) # red lamps ON # wait for trigger's trigger = (~(i2c0.read_u8(0x00) & 0x01) & 0x01) triggerX = (i2c0.read_u8(0x00) & 0x02) >> 1 triggerX = not triggerX triggerY = (i2c0.read_u8(0x00) & 0x04) >> 2 triggerY = not triggerY triggerZ = (i2c0.read_u8(0x00) & 0x08) >> 3 triggerZ = not triggerZ if (trigger | triggerX | triggerY | triggerZ): lcd.print('Play Game', 0, 25, 0x000000) relayBar.set_relay_status(1, 0) # green lamp OFF relayBar.set_relay_status(2, 0) # red lamps OFF if trigger: wheelX = 1800 + (random.randint(0, 7) * 25) - 60 randomRecipe = str(wheelX + 60) elif triggerX: wheelX = 1000 + (random.randint(0, 7) * 25) randomRecipe = str(wheelX) + '-0-0' if trigger: wheelY = 2000 + (random.randint(0, 7) * 25) - 30 randomRecipe = randomRecipe + '-' + str(wheelY + 30) elif triggerY: wheelY = 1000 + (random.randint(0, 7) * 25) randomRecipe = '0-' + str(wheelY) + '-0' if trigger: wheelZ = 2200 + (random.randint(0, 7) * 25) randomRecipe = randomRecipe + '-' + str(wheelZ) elif triggerZ: wheelZ = 1000 + (random.randint(0, 7) * 25) randomRecipe = '0-0-' + str(wheelZ) lcd.print(randomRecipe, 0, 50, 0x000000) finitoX = False finitoY = False finitoZ = False # switch motors ON i2c0.write_u8(0x01, 0x00) wait_ms(200) # spin up the wheels, 1 by 1, max. 60 steps if trigger: for count in range(30): pin0.on() wait_ms(motorIntMs) pin0.off() wait_ms(motorIntMs) for count in range(30): pin0.on() pin2.on() wait_ms(motorIntMs) pin0.off() pin2.off() wait_ms(motorIntMs) # spin the wheels i = 0 while not (finitoX & finitoY & finitoZ): if wheelX == 0: finitoX = True else: pin0.on() wheelX = wheelX - 1 if wheelY == 0: finitoY = True else: pin2.on() wheelY = wheelY - 1 if wheelZ == 0: finitoZ = True else: pin4.on() wheelZ = wheelZ - 1 wait_ms(motorIntMs) pin0.off() pin2.off() pin4.off() wait_ms(motorIntMs) # green blinkr if i == 99: blinkGreen(relayBar) i = 0 else: i = i + 1 # hold position lcd.print('Motors on hold', 0, 75, 0x000000) wait_ms(2000) # switch motors OFF i2c0.write_u8(0x01, 0x10) lcd.clear() wait_ms(20)