mercoledì 5 ottobre 2016

COIN-OP: mini arcade cabinet photos

The completed COIN OP ARCADE machine (with missing only coins drawer)

The interior (with back cover removed):
In the upper part is located the usb pc speakers.
In the bottom side is visible the temporary ... coin storage solution.

Don't miss the Arduino uno keyboard previous series of posts.

COIN-OP: mini arcade cabinet build log 3/3

This is a 3 part post, in which i cover:

INTRODUCTION Arduino Uno Keyboard emulator - dfu mode / programming
SKETCH Arduino Uno keyboard emulator - ino sketch
COINS Coin acceptor (3 coins)

Source code is available on Google Drive folder:

I use this model by SparkFun: CH-923 sourced at Robot Italy.
The device is a robust independent coin acceptor with more than 95% coin recognition performance.
Here after the manual:

Is possible to use 1, 2 or 3 coin types. Each time an unrecognised coin is inserted the acceptor ejects it in the front.
If recognised, the coin drop from the bottom.

Voltage is +12Vdc sourced from the PC ATX connector (Yellow for 12V, Black for GND). Output is TTL compatible so you can use directly with arduino. You need only to interconnect GND from PC to GND to the Arduino part.

The output is programmable, so each time you insert a coin you can choose how many pulses the Acceptor are sent to the Arduino.

Because i use Euros coins, i've set 10 cents / pulse:
20 euro cents: 2 pulses
50 euro cents: 5 pulses
1 euro: 10 pulses
You can use a metal coin of your choice, and once programmed it will works with your coins.

On the Arduino Uno part i've connected the Grey wire to Pin 2 (INTERRUPT 1) acting as a switch using a 10k pulldown resistor. Each time a pulse is received an internal counter is incremented by 0.10 euro.
In the main loop each time the counter is > than 20 cents, is decremented by 20 cents and a keystroke is sent to PC.
The corresponding keystroke is then mapped on Mame as coin insert.

The sketch part is really simple:

  • Declare coinvalue variable as volatile so you can change in interrupt routine
  • Attach in Setup the interrupt handler using: attachInterrupt(digitalPinToInterrupt(PIN_COIN), coinInserted, FALLING);
  • Handle the interrupt incrementing the coinvalue variable, and setting coinchange bool to 1.
  • In the loop - once the coinchange value is set to 1 - decrement the coinvalue variable and send the keystroke as described in the previous post. Because the Byte is shared with Start and Menu routine, immediately send the keystroke to clear the byte usage for the latest Start/Menu routine.

The coin acceptor up to now was really reliable, so the arduino keyboard.
Customize it as you need.

COIN-OP: mini arcade cabinet build log 2/3

This is a 3 part post, in which i cover:

INTRODUCTION Arduino Uno Keyboard emulator - dfu mode / programming
SKETCH Arduino Uno keyboard emulator - ino sketch
COINS Coin acceptor (3 coins)

In this post is covered for convenience the Arduino sketch part.

The sketch uses a simple Serial.write(buf) to send a keystroke / keyrelease for each switch, like
Serial.write(buf, 8); // Send keypress

The HID message sent in the serial part is a byte array:
uint8_t buf[8] = { 0 };

Byte 0 is a modifier bye. If you set a bit with another keypress, you will have a combination like CTRL-X.

Modifier keys:
Bit 0 - Left CTRL
Bit 1 - Left SHIFT
Bit 2 - Left ALT
Bit 3 - Left GUI
Bit 4 - Right CTRL
Bit 5 - Right SHIFT
Bit 6 - Right ALT
Bit 7 - Right GUI

Byte 1 - Not used

The useful part starts from byte 2 up to byte 7, where are mapped the HID active key usage codes. This accepts up to 6 keys being pressed at the same time.

Because i have more than 6 keys, i had to join more than one key in each byte. In this situation the same byte is used to send KEY_UP or KEY_DOWN: this works because the switches are inside a joystick and cannot be sent at the same time.

This is my mapping, modify as you require your situation (S1 means Switch 1):
#define PIN_UP 6
#define PIN_DOWN 4 
My joins are:
Byte 4: PIN_S1 & PIN_S5

This mapping helps to send joystick on upper left (PIN_UP + PIN_LEFT) while pressing a fire switch (PIN_S1) and jump switch . Less attention needs the Start/Select and Exit switch.

Each time the loop function finds a specific pin press, in the buffer is wrote the key code. 
To send the keypress "Enter" write 0x28 into the buf, using this code:
buf[2] = 0x28; //Or define a variable for convenience

To emulate a key release: buf[2] = 0;

More HID Keyboard codes could be found at this link

Debounce: I carefully tested the sketch on debounce matter. With simple timing check, a debounce routine is not needed at all.

In the next part i'll cover the coin acceptor part.

COIN-OP: mini arcade cabinet build log 1/3

This is a 3 part post, in which i cover:
  1. INTRODUCTION Arduino Uno Keyboard emulator - dfu mode / programming
  2. SKETCH Arduino Uno keyboard emulator - ino sketch
  3. COINS Coin acceptor (3 coins)
Source code is available on Google Drive folder:


Finally i had the opportunity to complete the Arduino Uno Keyboard emulator, including the Coin Acceptor (3 coins) from Sparkfun (SPARKFUN COM-11719).

After some tweaking the emulator works like a charm.
I had some trouble with key press & release, because we need to leave to OS the key repeat function.
The current version works very well with Mame on Windows 98.

The Keyboard HID hex is based on LUFA and is needed to make Arduino Uno act as a Keyboard, Joystick, Mouse, etc: for more information, check this link Arduino UNO Keyboard HID version 0.3 from darran

There is a copy attached also to this post. Please use at your own risk, this is working for me, but i cannot guarantee for your hardware.

A note: while using keyboard LUFA hex, pins 0 and 1 (TX and RX) will not work as digital pin, so don't use them.

  • From terminal, change directory to the sketch dir, and execute:
    • sudo dfu-programmer atmega16u2 erase
    • sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-keyboard-0.3.hex
    • sudo dfu-programmer atmega16u2 reset
  • Disconnect and reconnect usb
If you want to revert Arduino to usb bootloader to update the sketch (this is the tricky part), simply repeat these steps:
  • Disconnect and reconnect usb
  • From terminal, change directory to sketch dir, and execute:
    • sudo dfu-programmer atmega16u2 erase
    • sudo dfu-programmer atmega16u2 flash --debug 1 Arduino-usbserial-atmega16u2-Uno-Rev3.hex
    • sudo dfu-programmer atmega16u2 reset
  • Disconnect and reconnect usb
The dfu mode is always available, i never had trouble with this.

In the next post, i'll cover the keyboard sketch to make the Arduino working.

domenica 28 dicembre 2014

EMBROIDERY CNC: Software completed

The software for the cnc embroidery is finally completed and fully functional.

Screenshot: Main screen

Screenshot: Palette selection

Screenshot: Color selection

Screenshot: Artwork translate panel

Screenshot: Grbl dashboard panel (realtime via browser thanks to Websocket)

Screenshot: G-Code Inspection panel

domenica 13 aprile 2014

COIN-OP: mini arcade cabinet build log

My father bought some wood panels from Ikea. He donated two to build a mini arcade cabinet for my son. The arcade cabinet will use a raspberry pi with PiMame and some Sparkfun arcade goods, like a Zippy arcade joystick and concave buttons. In this post you'll find a short build log. The cabinet is 1 meter tall (39") and 0.42 meter wide (17").

Cutting the hpl boards. Masking tape installed for marking

The monitor, a 19" sony sdm-hs95

Build log:

Monitor installation test

domenica 16 marzo 2014

BOXEDCNC: Brushless ESC pwm response, linearizing output for PID control, and smoothing the sensor values

Once assembled and tested, i had a lot of data collected from brushless spindle controller, i've used to implements a better control method, a PID control. I've spent long time updating the code to find what was going wrong. Regarding PID, there are a lot of good articles in the web, some implemented also on the Arduino universe. Start your readings from the incredible series of post from Brett, if you want to know more about PID.
In this post i want to describe my solution to some of the headache i had to implement:
  1. Keep it fast if what you want to control react fast (a spindle is really different from sous-vide or temperature PID room controller). My timing between refresh is now 50ms.
  2. Keep it steady, eliminating every distraction from the PID computation (like delays).
  3. Linearize the output of the PID, before applying to the ESC to get rid of the PID constants.
  4. Try to guess the output value, before enabling PID.
  5. Divide the PID constants in aggressive and conservative variants depending from the error between desired set point and actual reading.
  6. Don't try to find a magic method to find constants. Try various values starting only from progressive, then enabling integrative, and only at last using derivative.
The next image shows the schematic of the brushless controller. There are four sensors in the system, but the fourth is not showed because is a temperature sensor.

The main loop in CNC mode use the GCode Spindle commands (like S5000) as target value to control with PID in a closed loop the motor RPM, trying to minimize the error between target and actual speed.

The major drawback i discovered using the affordable Turnigy ESC is the non linear response of the motor's rpm in the basic free spinning condition (without torque applied). As you can see in the next image, the RPM relation between Arduino PWM uS interval and motor RPM is something similar to a quartic function. I think this is quite common when using the writeMicroseconds function approach. In fact you can control the servo with high precision writing an interval typically between 1000uS and 2000uS. In the next graph is possible to see the real data registered regarding RPM and the Power Source output tension and current given to the ESC. Without any resistance applied to the motor's  shaft, the ESC absorbs circa 70W at the maximum speed. The power source drop voltage between zero and maximum speed is only 0.30V (from 12.87V to 12.50V).

To avoid strange PID behaviors, i needed to implement a fast transformation function. 
The rest of the post is about how i've implemented a SMA (Simple Moving Average) to smooth the RPM readings, and about the linearization of the output of the ESC.

The start is a simple moving average using integer array to take care of the fast RPM refresh process, without dedicated onboard hardware. This was software implemented using a simple array which hold a certain number of integer numbers (from 30 to 50). These values are the microseconds between two consequents falling edge (or raising, is the same) of the rpm optical sensor, collected on   interrupt pin. This happen continuously with a period in a range from 2.000 and 15.000 uS. The array index is incremented every interrupt, and is zeroed using the modulo operator in one code row.
The result is a Simple Moving Average of the continuous RPM data, which is implemented using  this code in the interrupt function:
   RPMIndex = (RPMIndex +1)%(RPMIndexSize-1); 
   RPMTimes[RPMIndex] = micros() - RPMTimeold;
   RPMTimeold = micros();
Once 50ms i compute the sum of the array, and divide the result by number of elements in the array to obtain a smoothed RPM fresh value.

The next step is to transform the output from the horrible quartic function to a simple linear response.
This happens using another array containing the uS timing values at which corresponds the desired output. I think this is a fast method because the loop only need to lookup in a prewritten array using the index as input.

The next graph shows the test results without smoothing (real data). In the x axis there are the values of the linearized output range, in the y axis the RPM logged.