AndiHub

Code-Outlet von Andreas Bahr, Zürich

Durst-O-Mat

Eine Cocktail-Rezept-Würfelmaschine by DJ Fridgemonster

Foto vom Durst-O-Mat
Durst-O-Mat

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.

Die Maschine in Aktion

Wenn das Resultat nicht gefällt, können die einzelnen Walzen mittels der korrespondierenden Tasten nochmals gestartet werden.

D-O-M Hardware

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.

Nächste Schritte

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

Schema

D-O-M Schema - Klick für Zoom

D-O-M Software

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.

Aktuelle Version: Download

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.

D-O-M Rückseite

Blick von Hinten auf die Steuerung

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