A few weeks back I got a functioning mini version of the popular UFO Catcher game (or Crane Game or Claw Machine). If you haven't seen any yet, it is a simple arcade game, where after you insert a coin you have a limited time while you can control a claw to get a toy.
The one I got is a very basic one: you have three handles to move the crane on all three dimensions. When you insert a coin, it pushes a button, starting the game. For power it uses three D batteries.
For this project I modified in two ways: instead of physical coins it uses IOTA to start a new round and a switched the batteries with a power supply allowing it to buy power for itself with IOTA. The raw schematics of it is the fallowing:
In the next sections I will show how I achieved it.
Swapping the batteries with a power supplyOriginally it used three serially connected D batteries, which made very simple to be replaced with a power supply, as it produces arround 4, 5V. It is close to a standard 5V power supply (I used an old phone charger). I also removed the on-off switch, as I didn't need it anymore.
If you really want to play safe, you can insert a diode, as is lowers the voltage from 5V to around 4, 5V.
Replacing the coin acceptorAs the toy was intended to be used the included plastic tokens, the coin acceptor uses a very simple mechanism:
Basically if you insert a coin, it pushes a momentary switch, sending an impulse to the processing module. To replace this I used a relay connected to one of the GPIO ports of the Raspberry Pi. I have also added a led to indicate if there is a paid round available and a button to start the game (if funds are available).
To test the setup, you can use the following code:
#main.py
import RPi.GPIO as GPIO
import time
statusPin = 22
buttonPin = 27
relayPin = 17
coins = 1
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(relayPin,GPIO.OUT)
GPIO.setup(statusPin,GPIO.OUT)
GPIO.setup(buttonPin,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.output(statusPin,GPIO.LOW)
while True:
if coins > 0:
buttonState = GPIO.input(buttonPin)
if buttonState == False:
print "Game-start signal sent"
GPIO.output(relayPin,GPIO.HIGH)
time.sleep(1)
GPIO.output(relayPin,GPIO.LOW)
coins -= 1
if coins > 0:
GPIO.output(statusPin,GPIO.HIGH)
else:
GPIO.output(statusPin,GPIO.LOW)
You can now run it with the code bellow:
python main.py
Building simple Raspberry controlled power switchTo be able to control the power usage of the game I built a simple switch using a Raspberry Pi and a relay:
With all hardware modifications set, it was time to implement the feature to pay for the game with IOTA coins. For this I used ZMQ.
First I had to subscribe the 'tx' channel, where the transactions are broadcasted.
socket.setsockopt(zmq.SUBSCRIBE, b'tx')
socket.connect('tcp://zmq.devnet.iota.org:5556')
To check incoming transactions, I used the following code:
while True:
topic, data = socket.recv().decode().split(' ', 1)
if topic == 'tx':
tx_hash, address, value, obs_tag, ts, index, lastindex, bundle_hash, trunk_hash, branch_hash, received_ts, tag = data.split(' ')
if address == "ADDRESS" and tag == "IOTACATCHERCOIN999999999999":
coins += int(value)
This check the address and tag to locate the right transactions and increases the balance with the coins paid.
I have also moved the code waiting for button press to a new thread to enable parallel processing.
def button_processor():
global coins
while True:
if coins > 0:
buttonState = GPIO.input(buttonPin)
if buttonState == False:
print "Game-start signal sent"
print "New balance: " + str(coins)
GPIO.output(relayPin,GPIO.HIGH)
time.sleep(1)
GPIO.output(relayPin,GPIO.LOW)
coins -= 1
if coins > 0:
GPIO.output(statusPin,GPIO.HIGH)
else:
GPIO.output(statusPin,GPIO.LOW)
The thread can be started with the
x = threading.Thread(target=button_processor)
x.start()
command.
I have also created a new thread to periodically pay for the power consumption to the power switch.
def payment_processor():
seed = 'SEED'
address = 'SWITCH_ADDRESS'
p_api = Iota('https://nodes.devnet.iota.org:443', seed)
while True:
tx = ProposedTransaction(
address=Address(address),
message=TryteString.from_unicode('Power Socket payment.'),
tag=Tag('POWERSWITCHCOIN'),
value=1
)
time.sleep(60)
Paying for powerThe final step was paying for the power used by the arcade. I have made only a simple version of it, as it is not main part of the project.
I does two things: periodically checks the balance, adding the change to the remaining paid time, and cuts power if no paid time is remaining.
import RPi.GPIO as GPIO
import time
import sys
from iota import Iota
import pprint
import json
relayPin = 17
timeRemaining = 0
lastBalance = 0
seed = 'SEED'
api = Iota('https://nodes.devnet.iota.org:443', seed)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(relayPin,GPIO.OUT)
while True:
if timeRemaining > 0:
timeRemaining -= 1
GPIO.output(relayPin,GPIO.HIGH)
else:
GPIO.output(relayPin,GPIO.LOW)
x = api.get_account_data()
balance = int(x["balance"])
change = balance - lastBalance
timeRemaining += change
time.sleep(60)
ConclusionIt was a very exciting project to work on. Although it is just a simple prototype making a toy "smarter", but gave me a great insight into the thoughts behind the IOTA framework.
As closure here is the finished project in work:
Comments