Archive Page 2

NickelBot – Complete

The NickelBot is complete and it works great. The goal of the project was to create an easily portable machine that creates low cost items that could be given away at events like Maker Faires. I think it has completely achieved that goal. The nickels are purchased from Amazon and cost about $0.08 each.

Here is a video that explains the machine.

Results

It is quite reliable and the cycle time is is just about right at 1-2 minutes per nickel. I think the engraving quality is quite good. I ran it at the Chicago Northside Maker Faire last weekend. It made about 60 nickels without any problems. Here are some of the nickels it made.

Mechatronics

The NickelBot uses (2) NEMA14 stepper motors in a T-Bot configuration. These drive a single GT2 6mm belt. The linear bearings are (2) 6mm rods per axis with (1) LM6LUU per rod.

To handle the nickel loading and unloading, it uses a single micro hobby servo. This servo  connects via a 0.03″ brass wire to a clamp. The firmware has (3) positions hard coded for the servo for fully open, nickel support only and supported plus clamped.

All 3D printed parts are PLA printed on a Lulzbot TAZ6. The colors just represent the color that happened to be in the printer at the time.

The Laser Module

The laser module is a 3.5W peak, 450nm (blue) laser. It comes with a laser power supply that has a 12V power input and TTL laser control input. It also comes with a 12V 5A power supply. I bought it a few months ago from Banggood.com when it was on sale for about $70, but they are typically around $99.  I control the engraving power with a 5kHZ PWM from the microcontroller.

Controller

I used a PSoC5 development board as a plug in on a custom PCB.  I knew adding an additional, accurate PWM for the servo was going to be vastly easier on the PSoC5 vs. an Arduino.

This dev board has a built in programmer debugger that makes firmware development very easy. It is great to be able to set breakpoints and check values with the debugger. I have have a another blog post with more details on this here.

Firmware

The firmware is a modified version of my PSoC5 Grbl port. The only modification needed was the code to handle the clamp servo. Rather than adding special gcodes for the clamp, I simply re-coded the M7,M8 and M9 coolant commands. I did this because all of the parsing and protocol issues were already done.  Each command represents one of the clamp positions.

I may post the source code on Github soon.

Calibration

The machine has (2) home switches (X and Y). A homing sequence needs to be run each time you power up the machine.  All other locations are referenced to this location. A one time  calibration is done to locate the following locations.

  • G54: G54 is the the default work offset. I decided to use the center of the nickel as the 0,0. I jogged the machine visually until the nickel looked centered. I then set the G54 location with this gcode line”G20 L10 P0 X0 Y0″. I made a target shaped graphic that I used to test engrave this location(see above). I used a caliper to measure the centering error, jogged that amount and reset the 0,0. I did this about 5 times until I was satisfied with the centering.
  • G28: I used the G28 location as the location under the nickel hopper. You jog to the location and set it with “G28.1”.
  • G30: I used the G30 location as the position over the eject chute. This is set with the G30.1 gcode command.

Software

I am using LaserGRBL.

This is a great program for this application. It does everything, starting with a bitmap image, to gcode sending in one application. It also has some macro (multi-line gcode) buttons that are very handy. The only drawback for some is that it is Windows only.

Here is an example of the macro to get the nickel.

G90G0X0Y0 ; rapid move to absolute 0,0
M9 ; loosen clamp
G28 ; move under nickels
G4 P0.75 ; wait for nickel to fall and settle
M7 ; close clamp
G4 P0.5; wait a bit
G0X0Y0 ; return to 0,0

Source Files

Possible Improvements

  • Interlock switch: Right now there is no interlock switch for the door. If I make a new PCB, I will add a provision for that. I’ll probably just break all power to the laser module.
  • Nickel Flip: Right now the nickel always comes out of the chute upside down. This is not the best presentation. This was a compromise to make the machine as small as possible. The nickel has to fall between the Y rods. Rather than makethe distance between the rods wider than the nickel, I designed and aligned the clamp/support system so that one side of the nickel falls first and goes between the rods closer to vertical.  There is a probably a way to design the chute to catch the nickel before flips over completely or re-flips it back.
  • Software:
    • More automation: LaserGRBL has macro buttons for the nickel feed and eject features, but it would be nice if that was automatic. They have added a gcode header and footer feature to the roadmap. Right now you can generate the gcode, save the file and paste the nickel handling code in an editor. That file is then fully automatic.
    • Customizing: It would have been fun to easily add names, etc to nickels for people.

If you want to be notified of future blog posts, please subscribe.

NickelBot – Laser Controller

Here are some details on the custom laser controller I made for the NickelBot, wooden nickel engraving machine.

I want to use Grbl to control the machine. Grbl has support for lasers that allows better power control during the engrave. It also has the Core XY support I need for the H-bot mechanism it uses. The only feature I needed that it did not have is a hobby servo output.

A hobby servo requires a PWM signal. Normal Grbl runs on a ATMega328p cpu (Arduino UNO). The 328p has 3 timers that can be used to generate PWM signals. Grbl uses all 3 of them. You can attach more than PWM output to a timer, but the only timers that would work are only 8 bit timers. That is not going to give me the resolution I want.

A hobby servo uses a 1ms to 2ms pulse that repeats every 20ms. This means you are only using 1/20th of the duty cycle range. 1/20th of an 8bit signal is pretty rough. I could have used an Arduino Mega to get some more free timers, but I did not want to deal with the physical the size of a Mega.

My solution was to use a PSoC5. I have already ported Grbl to it and it has plenty of high resolution PWM components. I used the following PWM configuration…

  • 16-Bit resolution
  • 1 MHz Timer
  • 20000 for the period (=20ms)
  • 1000 to 2000 and my compare value range (1ms to 2ms)

This gives me a resolution of 1000 or 0.18° (exceeds servo’s capability)

Here is an image of the raw PCB.

Here are the features of the PCB

  • Has a socket for a CY8CKIT-059 PSoC5 development board (only $10-$15). The only drawback is the wiggly printed USB connector.
  • 1A 5V power supply for servo
  • (2) Sockets for Pololu footprint stepper drivers.
  • (2) 12V fan connectors
  • Servo connector
  • Homing switch connector
  • Laser connector (power and PWM)
  • (2) general purpose I/O for buttons, etc
  • Extra 5V power access connector.

Source Files.

Status

The board is fully tested and 100% functional. I have it hooked up the the machine and have tested the following.

  • Home switches
  • CoreXY motor control
  • Servo control
  • Laser PWM.
  • Fans

Suggested Changes

  • The control signal on the laser supply appears to turn on the laser if left open. Therefore if the controller is not powered or actively driving the pin low, the laser will fire. That is not good. I have not tested a solution, but I think a resistor of 2k-5k Ohm pulling the pin to ground will keep the beam off when not driven low. It should be quite easy to solder this resistor between the laser pulse pin and the adjacent ground pin.

 

 


If you want to be notified of future blog posts, please subscribe.

Wooden Nickel Engraver Update

I got a chance to do some work into this project and I made some progress.

The X,Y mechanism is a free standing H-Bot. Here is a bottom view. You can see the Y home switch and the bottom of the servo to control the nickel.

Here is a top view of the mechanism. The yellow clamp piece opens partially to create a platform (ledge) for the nickel. This slides under the nickel feed tube and a nickel drops in. The bed is extra wide, so there is always something supporting the nickels in the feed tube.

The servo then clamps the nickel by pushing the tang on the yellow clamp piece into the nickel. Once the engraving is complete, the clamp completely retracts, removing the ledge. The nickel falls through into a hopper that is accessible from the front. This allows for a fully automated process and you don’t need to open the machine.

Here it is with a nickel in the clamp.

I have a temporary enclosure for testing. This supports the XY mech. You can see the nickel feed tube and the laser module support bracket. Currently it is open and a little larger than necessary to make it easy to test. It will eventually be cleaned up and get an access door with a window.

The next step is to work on the firmware. I plan to use Grbl in Core XY mode. I need to add a way to control the servo and figure out some commands to  control the nickel handling.


If you want to be notified of future blog posts, please subscribe.

Building a TWANG32

ESP32 Programming

The first step is to program your ESP32. The kit I sell on Tindie requires the use of the NodeMCU-32s. It needs to match this footprint and pinout. Note: Some version of my kits include a pre-programmed ESP32.

Arduino IDE Setup

You need to compile and upload the firmware using the Arduino IDE. Get the latest version here. You need to add some additional software.

  • Install Arduino Core for ESP32. This gets the files require to program an ESP32 There are instructions here.
  • Install FastLED Library. The FastLED library is used to control the LED strip. Go to this page and download the latest version as a zip file. In the Arduino IDE select the SketchInclude LibraryAdd Zip Library. Then select the zip file you just downloaded.
  • Install RunningMedian Library: This library is used to filter (reduce noise) the accelerometer sensor using a 5 point median filter. You can get the library here.
  • Download the TWANG32 Sketch Source files. All of the files should be placed in a folder called TWANG32.

Programming

Open the TWANG32.ino sketch in the Arduino IDE you will see this near the beginning of the file…

// what type of LED Strip....uncomment only one
#define USE_APA102
//#define USE_NEOPIXEL

You need to uncomment (remove //) in front of the line for the strip type you have. In the case above the program will compile for the APA102 type strips. Make sure only one of the #define lines is uncommented.

Open the settings.h file in the same folder as TWANG32.ino. Change the #define NUM_LEDS  144 to the LED count you plan to use. This sets the default number of LEDs in your strip.

Next to the following steps to compile and upload the firmware. This could take several minutes to compile.

  • Under the ToolsBoards menu, select the NodeMCU-32S board
  • Connect the ESP32 to your computer.
  • Select the correct com port from the ToolsPort menu.
  • Click on the Upload button.

Install the ESP32 in the PCB.

The ESP32 should be installed with the USB connector aligned with the edge of the PCB. See the image below.

Print the plastic parts

The STL files are here. If you don’t have a printed, reply in the comments and I can get you some for a reasonable price.

All of the files can be printed in high speed mode. No fine details are required. They can all be printed with no support, except for the cover which has a small pocket on the bed side. I use PLA with 2 perimeters and 20% in fill. All of the screws self tap into the plastic.

Note: I made a recent change to eliminate the use of hot glue, some of the pictures are from earlier versions.

Attach the Adhesive Rubber Feet to the Chassis.

Attach the feet into the pockets on the bottom of the chassis.

Install the PCB into the chassis.

The PCB mounts directly on the bosses on the bottom of the chassis. Use flat head M3 x 12mm screw installed inserted the chassis bottom, through the PCB and into M3 x 12mm plastic spacers. Spacers are easier to use than nuts because they are easier to hold during installation.

Assemble Joystick.

Place clamp ring over door spring. It is important to do this first because it is difficult to do later. Next screw on the the lower part of the knob.

Slide the accelerometer module wires through the lower knob and spring. Push the accelerometer module into the pocket. I have recently made changes to remove the need for hot glue. This uses M3 x 10mm (button or pan head) to hold on the cap. I use a little piece of anti-static foam (in kits) to hold the MPU-6050 accelerometer module down. If you don’t have the foam use 2 dots of hot glue in the corners with the mounting holes.

 

Attach the cap. Align the hollow arrow side of the cap with the little notch at the top of the lower knob. This hollow arrow will show you which side points forward in a later step.

Attach the metal cap to the bottom of the spring. This cap allows the spring end to sit flat on the cover. It should be screwed on about as much as shown in the image.

Attach the joystick to the cover. Make sure the hollow arrow is pointed forward (the closer edge). Before it is fully tightened twang it a few times. This will relax  the spring so you can see if it still points forward. Do this a few times and adjust to make sure it points forward. It does not need to be perfect… +/- a few degrees is OK.

Attach the speaker using M3 x 10mm screws.  If you angle the wires a little, it makes the wiring a little easier later.

 

Attach the LED cable. Your LED strip should have come with a mating connector. Some types have 3 wires and some have 4. Mate it to the LED strip. See what colors do what functions by looking at the strip labels. The strips have an arrow pointing the ways go from zero up.  Most strips have connectors on both ends. Us the connector on the base of arrow side.

All LED strips should have a + and -. These could be labeled 5V and Gnd. Do not rely on the traditional red+ and black- wire coloring. The strips are often not wired that way. Attach the wires to the terminal block. I like to add a cable tie behind the wall to act as a strain relief. I also label my wires, but you need a heat shrink printer for that.

Attach the rest of the wires from the cover. Attach the speaker connector and the accelerometer wires.

Attach the cover.

At this point you should be able to power up and play.

Reference

 

 

 

 

 

 

 

 

 

 

 

 

 

TWANG Shield Rev. 2

I recently ran out of the original TWANG shields. I took the opportunity to make a few changes.

Audio Jack

The internal speaker is powered by the Arduino I/O pins. This limits it to the low voltage and current that those pins can provide. In normal environments that sound has plenty of volume. I have used it at some very loud events where that sound level is not loud enough.

This version adds a standard 3mm (1/8 in.) audio jack. You can connect this to a powered, external speaker.

Power Capacitor

Some old LED strips like the WS2812 are very sensitive to voltage spikes that might come from lower quality power supplies at turn on. They recommend adding a large capacitor to reduce voltage spikes.  A larger 1000uF capacitor has been added to the PCB, so you do not need to install it externally.

Life LEDs

The TWANG firmware supports the use of remaining life LEDs. The firmware normally shows the remaining life LEDs on the LED strip.  This has the advantage of making it easy to change the lives per level without having to change your hardware. On version 1, there was a place to install (3) life LEDs, but the LEDs were never installed.  This version removes that feature.

Where to Get One

They are currently for sale on Tindie.


If you want to be notified of future blog posts, please subscribe.

Next Project – Wooden Nickel Engraver

I started working on my next backpack scale CNC project. My backpack scale projects are tiny CNC machines that I can easy carry in a backpack to tech meetups and events. This machine is going to be a wooden nickel laser engraver.

Wooden nickels are small wooden discs. You can buy blanks from various places, including Amazon. You can usually get 100 for less than $10. The goal is to create a machine that loads them from a feed tube, engraves them, then ejects them.

Mechatronics

The basic drive will be an H-Bot. It will be similar to the midTbot, but the motors are at the ends of the X axis. It will be fully enclosed, but I not started work on that part yet.

Disc Feed System

I hope to be able to use a single hobby servo to handle the loading and unloading of the blanks. The servo will control a sliding device that has three positions.

  • In the first position it acts like a support shelf for the disc. The bed slides under the feed tube and a disk drops into the pocket.
  • The next position is the clamping position. This holds the disc still while engraving.
  • The final position retracts the shelf so the disc drops through.

Electronics

The goal is to use a low cost controller like an Arduino Nano.

  • (2) Stepper motors for the X,Y motion
  • (1) Hobby servo for the disc feed system (PWM)
  • (1) Laser power control (PWM)
  • (2) homing switches
  • (1) interlock switch loop if there is a door and/or cover

Status

The major new feature of this design is the disc feed system, so I am primarily working on that right now.


If you want to be notified of future blog posts, please subscribe.

TWANG32 – An ESP32 Port of TWANG

 

I ported the TWANG game over to ESP32. I wanted to do this for several reasons.

  • Cost: The ESP32 is generally lower cost than the Arduino Mega
  • Speed: The ESP32 has a dual core 80MHz processor vs. the 16MHz Arduino Mega
  • Memory: The ESP32 has much more RAM and program space to allow more features, levels and audio files.
  • Physical Size: A Mega is very big. This creates a large enclosure that takes a while to print. The smaller enclosure is also more portable.
  • DAC Pins: The audio capabilities on the Mega are very crude and basically limited to square wave tones. A DAC can output digital audio. Currently I am just using a similar square wave tone to the Mega, but it works much better for adjusting the volume.
  • Wireless: The ESP32 has Wifi and Bluetooth. This will allow easier (smartphone) interfacing for options (brightness, volume) and level pack uploads. I also want to consider dual player battle type games with linked controllers.

The Audio

The original TWANG bit banged audio directly from I/O to a speaker. This was super simple, but the volume at max was not loud enough for noisy environments. The ESP32 I/O is a lower voltage (3.3v) and less current, so something needed to be done. I prototyped with a PAM8403 based amplifier (~$4 on Amazon). This worked great, so I added that I.C. to my shield. The volume is controlled by the amplitude of the DAC.

The Shield

I made a shield to simply the wiring and provide a stable way to mount the ESP32. I used a NodeMCU 32S development board for the ESP32. Under the ESP32 is a the audio circuitry. I should have some extra boards to sell on Tindie soon. I will publish the source files soon.

The Firmware

The code is on Github. The port was relatively easy, but I had to rewrite a few libraries. They were designed so the main “setup” and “loop” parts did not change much. Currently the serial port based setup from the Mega version was not ported. This probably won’t be used. A wireless version is in the works.

Enclosure

The new enclosure is smaller. It prints quicker and is easier to fit in my backpack. The size is still big enough to hold comfortably while playing. The files will be uploaded to Thingiverse within the week.

Next Steps

  • Wireless control: I want a simple way to read the game statistics (average score, levels played, boos kills, etc) and tweak simple settings like audio volume and brightness. I think the easiest way is to make it a wifi access point with a simple web server. This eliminates having to write any client side apps and any smartphone or computer can hope on easily.
  • Levels: Make some way to edit or upload levels via wifi.
  • Multiplayer: I should be able to link multiple controllers. If I can think of a good dual player game idea, I might try to add that.
  • Python: It might be a fun challenge to write the game in Micro Python. This might open up the development to more people.

If you want to be notified of future blog posts, please subscribe.

 

Game Audio for the ESP32

I have been working on some games for the ESP32 and needed some decent quality audio with a minimum number of additional components.  I was bouncing between using the DAC and using the I2S bus. The DAC requires less external parts, so I went that way. I ended up creating a very simple library for use in he Arduino IDE. (Note: This only works with ESP32)

DACs

The ESP32 has (2) internal 8 bit DACs. DACs are Digital to Analog Converters. You give them an 8 bit value and they output an analog voltage. The voltage range of the 0-255 8-bit value is roughly Gnd to 3.3V on the ESP32. If you digitize an audio file, you can then play it back through the DAC. The DAC can’t directly drive a basic speaker, but you can connect it to an amplifier or amplified external speakers. The 8-bit quality is not great, but more than good enough for simple games.

The sound data comes from wave (.wav) files. This uses the 8 bit, unsigned, uncompressed format.  Wave files can be saved with any sampling rate you want. To get a decent sound you need to sample the  analog files at thousands of times per second. I have found that 4000 Hz is about the minimum for anything musical or spoken. 8000 sounds pretty good for most stuff. For reference, CDs are sampled a 44100 Hz (also 16-bit not 8-bit). This means there is a lot of data even for short duration audio. The typical ESP32 board has 2 to 4MB. At an 8000Hz sampling rate that gives you 125 seconds per MB. That is plenty for what I am working on, so I decided to store the data on the ESP32. If that is not good enough, you could use an SD card.

Here is a reference of the wave format. Only a few of the values are used.

ByteLengthDescription
04Always "RIFF"
44File size in Bytes
84Always "WAVE"
124Always "fmt " with a null
164Length of format
202Audio format (1=PCM)
222Number of channels
244Sample rate
284Byte Rate
322Block Align
342Bits per sample (8,16)
364Alaways "data"
404File size
44...Start of data

References

I found some good references to help me with this library.

I started with the Xtronical XT_DAC_Audio library, but found it got be very unstable when I added it to my game. It often crashed when seemingly unrelated code was added. I think the problem was due to trying to use floating point math in the interrupt. As soon as I took that out, it got very stable. They make reference to the issue in the code and suggest it could get fixed via compiler updates.

How it works

The wave data is stored in large char arrays. An interrupt reads the data and feeds that to the DAC. Using an interrupt allows the audio to play “in the background” while the game is running. The Xtronical library uses a fixed interrupt rate of 50kHz. It does some floating math in the interrupt to adjust to the actual sample rate of the wav file. I decided to change the interrupt rate to the actual sample rate of the wav data.

Here is a snippet of what wave data array looks like.

unsigned char PROGMEM pacman[33850] = {
  0x52, 0x49, 0x46, 0x46, 0x32, 0x84, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45,
  0x66, 0x6D, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
  0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00,
  0x64, 0x61, 0x74, 0x61, 0xC6, 0x83, 0x00, 0x00, 0x7F, 0x7F, 0x7F, 0x7F,
  0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
  0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F,
  0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x80, 0x7E, 0x80, 0x7E, 0x80,
  0x7E, 0x80, 0x7D, 0x84, 0xA2, 0x9F, 0xAF, 0xC0, 0xCE, 0xE1, 0xED, 0xF1,
  0xED, 0xE8, 0xDC, 0xCB, 0xB5, 0xA4, 0x95, 0x92, 0x91, 0x94, 0x9D, 0xB1,
  0xB6, 0xB5, 0xB9, 0xBB, 0x99, 0x7D, 0x66, 0x51, 0x64, 0x65, 0x5E, 0x74,
  0x9D, 0xAF, 0xC9, 0xC4, 0xB8, 0xC1, 0xBB, 0xA3, 0x89, 0x73, 0x54, 0x3B,
  0x2E, 0x30, 0x35, 0x42, 0x56, 0x70, 0x7F, 0x89, 0x8E, 0x8C, 0x86, 0x77,
  0x5E, 0x49, 0x3E, 0x34, 0x31, 0x42, 0x5A, 0x72, 0x91, 0xB1, 0xC2, 0xC1,
  ...... 

 

The sample rate is stored in the header of the wav data. When you play the file, it sets the interrupt rate to match the sample rate, so no math is required. You can use a mix of sample rates in the waves you use. It will adjust as needed before it is played back. It allows 2000Hz to 50000Hz sample rates. If you try to go outside that range it will use 2000 Hz. You will easily know there is a problem if you hear that.

Game Related Features

I added some features that might be needed when using with a game.

  • Check to see if the audio player is currently playing anything.
  • Interrupt The Current Wave – If something happens like an explosion you need to immediately switch to that sound. This is an option when you send a command to play a wave.
  • Change the Frequency – I had some sounds that needed to change based on game speed. There is an option speed up r slow down the play back speed by a multiplier to give.

Using the library

  • Download the zip file.
  • Install the library using the Sketch…Include Library…Add .ZIP Library menus.
  • It will also add an example. Open that using the File…Examples…Game_Audio menus.
  • Create a character array of the wav data. See this video from XTronical for how to do that.
  • Give the XTronical video a thumbs up and a nice comment 🙂
  • Create a Game_Audio_Class object. The first parameter is the DAC pin number you want to use. It should be 25, 26. The second parameter is the timer number to use. Example: Game_Audio_Class GameAudio(25,0);
  • Create a Game_Audio_Wav_Class object. The only parameter is name of the char array of you wave data. Example: Game_Audio_Wav_Class pmDeath(pacmanDeath);

Here is the demo that installs with the library

#include "SoundData.h";
#include "Game_Audio.h";

Game_Audio_Class GameAudio(25,0);

Game_Audio_Wav_Class pmDeath(pacmanDeath); // pacman dyingsound
Game_Audio_Wav_Class pmWav(pacman); // pacman theme

void setup() {
Serial.begin(115200);
Serial.println("Begin...");
}

void loop() {

// ------------- Play 2 wavs one after the other ----------------

Serial.print("Pacman Theme Sample Rate (Hz):");
Serial.println(pmWav.getSampleRate());
Serial.print("Duration (secs):");
Serial.println(pmWav.getDuration());

GameAudio.PlayWav(&pmWav, false, 1.0);

// wait until done
while(GameAudio.IsPlaying()){
}

delay(200);

GameAudio.PlayWav(&pmDeath, false, 1.0);

// wait until done
while(GameAudio.IsPlaying())
{
}

// -------- Play a wav then interrupt it after 600ms ------------

GameAudio.PlayWav(&pmWav, false, 1.0);
delay(600); // this is less than the duration of the last wav

// this wav will not play because the other is playing and interruptCurrent is false
GameAudio.PlayWav(&pmWav, false, 1.0);
// this will interrupt the playing file
GameAudio.PlayWav(&pmDeath, true, 1.0);

// --------- Play a wav with increacing sample rate (speeds up playback)
for (int i=0; i<10; i += 2)
{
while(GameAudio.IsPlaying()){// wait for wav to complete
}
GameAudio.PlayWav(&pmWav, false, (1.0) + (float)i / 10.0);
}

while (true) { // stop here program is done...but anything still playing will complete
}

}

Video

Next Steps

  • I’ll am working on some games, so new features might be added.
  • I’ll probably add the option to use I2S audio rather than the DAC.
  • I might add the option to pull files from an SD card.

If you want to be notified of future blog posts, please subscribe.

Laser Galvo Control Experiments

 

 

I recently bought some laser galvos from Aliexpress. What I got was the basic guts of a laser light show system. It came with everything I needed except the lasers. My goal is to control a laser to make a large interactive artistic display or game controlled by a micro controller with a DAC. I have a PSoC 5 and an ESP32 that have DACs, so I may use those.

Galvos work like speakers, old school analog meters or hard drive arms. They move proportional to a current. They can move extremely fast and precisely with the ability to move to 30,000 positions per second. The galvos came with drivers. This simplifies the control to a simple differential voltage. A differential voltage is used to increase noise immunity. The ILDA spec says the differencial voltage is 0 to 10V. This means at one end of travel you supply -5V and 5V and at the other end of travel you swap the voltages supply +5V and -5V.

My DACs are 0V to 5V (0r 3.3V). I need to convert this range to a 10V differential voltage. The easiest way for me to do this is to use some op amps. With what I have on hand it is easiest to get the 10V differencial using 0 to 10V and -10V to 0. I tested on the galvos by outputting a -10V to 10V sin wave from a function generator. It worked great.

Assuming I use the 0-5V DAC, I need to map that to a -10V to 10V range. That is a 20V span and requires a 4x gain. I then need to offset that by -10V. The op amp circuit I show below is what I made.

I used an LM324N because I had some. That has (4) op amps in a single package. The rails of the device need to be hooked up to a + and – supply that is greater than the range I will be using. Fortunately the galvos came with a power supply that outputs +15V and -15V. I used some potentiometers in the circuit to allow me to adjust the circuit.

The lower op amp provides the gain. The gain on the positive side is 1 + 30k/10k which is 4. The negative side is used for the offset and its gain is 30k/10k which is 3. I need an offset of 10V, so 10V divided by the gain of 3 is 3.33V.  I need that value to come from the upper op amp. That op amp has a gain of 1 so I simply need to adjust the pot in front of that to output 3.33V.

 

The DAC is connected to the lower left voltage source in the schematic shown as 2.49V. The galvos would be connected to Gnd and the output of the lower op amp (green line).  The schematic is interactive. Click the link below and try adjusting the input voltage between 0V and 5V.

Click here to interact with the circuit.

I needed to create 1 circuit for each axis. Here is my breadboard.

Here are the signals on an oscilloscope. The yellow trace is the 0-5V input as a 5kHz sin wave. The blue trace is the output. Both traces use the center line as the 0V. The scale is 5V per division. The input has a low of 0V and a high of 5V. The output goes from -10v to 10v.

 

I am using the tiniest laser I could find so that I don’t have to worry about safety yet. I 3D printed a base to keep things in line.

Here is a short Instagram video of some testing.

 

Playing with my laser galvos at NERP tonight.

A post shared by @ buildlog on


If you want to be notified of future blog posts, please subscribe.

Building a TWANG

Introduction

First…. Most of the credit must go to Robin Baumgarten and Critters for the inspiration and firmware. While I have hacked and tweaked the firmware a lot, the basic design is still all Critter’s. He did a great job.

A lot of people have asked me to help them build one, so this blog post is here to help them out. It is easy and fun to design and build your own parts and electronics. You can also either use my or Critters 3D printed parts.

The Electronics

The electronics are quite simple and only consist of a few basic pieces.

Arduino Mega – The firmware will not fit on an Arduino UNO, so you must use an Arduino Mega or anything using the the atmega2560 micro-controller. You can tpyically find a clone for less than $10.

MPU-6050 – This is a 3 axis MEMS accelerometer and gyroscope. The easiest way is to buy a GY-521 breakout board. You only need to use the VCC, GND, SCL and SDA pins. Note: My shield also has the INT pin, but that was for experimentation. You can find these breakout boards on Amazon for less than $5.

Speaker – You need a small standard speaker. The sound quality is not great, so don’t invest in anything expensive. I used an 8 Ohm speaker, but anything should probably work. The speaker is hooked directly to the Mega I/O, so you also need a 100 Ohm resistor in the speaker circuit. Typically a 1/10w to 1/4w resistor would be used. Note: This resistor is included on my shield. If you use my 3D printed design you will want a 40mm diameter with very little depth to it. Note: Do not connect directly to an amplifier. It is not designed for that.

LED Strip – The FastLED library that is used, supports a lot of types. I like the APA102C (Dotstar) type. I have also tested WS2812 (Neopixel) types. Most of the testing I did was on a 1 meter 144 LED APA102C strand and it looked great. The game gets difficult when there are less LEDs, so I would recommend at least 90. I have also tested with (2) 1 meter 144/m strips soldered together and a giant 5 meter 90 LED/M strip. They all look and work great.  The firmware supports up to 1000. Most longer strips are soldered smaller sections. It is easy to solder strips together like the image below. Be sure the 5V, Gnd, etc. are aligned the right way. I have some strips that are waterproof. That is not required, but does not hurt.

Note: Do not power the LED strip directly from the Arduino. Power it separately from a power supply. Note: My shield has an input for this. It will also power the Arduino.

Power Supply – Technically, you could need upwards of 40mA per LED. I bought a 10A supply and it has worked fine without getting hot up to 450 LEDs.

Life LEDs – The firmware supports remaining “life” LEDs. I prefer to use the main LED strip for this. It is fun to live within the limitations of the LED strip as the sole display. Using the strip also allows you to adjust the life count in firmware. The default is 3 lives per level, but I have boosted it to 5 for testing.  Note: My shield uses different I/O pins for the LED than the original TWANG firmware, so you need to check this if using them.

Wiring

The image below shows all the required connections to the Arduino Mega. My prototype used male header pins poked into the Arduino headers. It worked fine, but wires did often pop out when removing the cover.

The TWANG Shield

While hand wiring is very simple, I found it to be messy and I worried about failures. I made a basic shield to clean everything up. Here are the features of the shield.

  • LED Strip Terminal Block – It is very easy to hook up the strip. It works with both 3 and 4 wire strips. The power comes from the shield and no additional connections are required on the strip. Connections are clearly labeled. 3 wires LED strips do not use the CLK connection.
  • Accelerometer Terminal Block: This has clearly labeled connections using the same names that are on the MPU-6050 accelerometer module. Just hook them up 1 to 1.
  • Speaker Terminal Block: This also has 5V and Gnd if your hacking requires these connections. The 10 Ohm speaker resistor is mounted on the board.
  • Main 5V power entry connector: This powers the LED strip. It also powers the Arduino. It uses a diode so you can also power the Arduino via USB for programming.
  • Arduino UNO compatible: While the default firmware will not fit on an UNO, future compact version might be possible.
  • Life LEDs – My enclosure does not use them, but you could wire some in. The resistors are included, but not the LEDs. You could solder LEDS on the board or remotely locate them and solder wires to the PCB.

Shield Source Files

The 3D Printed Parts and other hardware

You need to 3D print a bunch of parts, a door spring, some hardware and a little hot glue.

Tindie Store

Typically I buy a small batch of PCBs for all my projects. If everything goes well I sell the rest on Tindie and often order more if they sell out.

  • Just the assembled shield. (coming soon)
  • A kit with all the custom parts
    • Assembled Shield
    • MPU-6050 wired and terminated with wire ferrules.
    • Speaker wired and terminated with wire ferrules
    • Door Spring

The Firmware

All of this is fully compatible with the original TWANG firmware. I forked the original and added a few changes. I would be happy to merge back to the original some time in future. The firmware relies on several libraries. Follow the instructions on GitHub pages to get those libraries.

Hacking the Firmware.

Hacking the firmware is quite easy. You should at least try editing some levels. More advanced hacking could improve the graphics and sounds.  Please give feedback if anyone has made any improvements.

At a minimum you have to set the number of LEDs and the LED strip type in the firmware before compiling.

Video

(coming soon) This thing looks so awesome in person, but is nearly impossible to video due to the crazy brightness of the LEDs. A friend is going to help me try to get a decent video.

In the mean time, take a look at Critter’s videos.


If you want to be notified of future blog posts, please subscribe.