tag:blogger.com,1999:blog-89094597623672204802024-03-02T09:30:28.407-08:00Stuff and Nonsensehotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.comBlogger59125tag:blogger.com,1999:blog-8909459762367220480.post-29801852481386957992022-08-24T06:49:00.002-07:002022-08-24T06:49:59.134-07:00A Solar Power, Light Modulated, Buzzing Mobile<div>I was asked to make an installation for the Sound Plotting sound-art festival at Brighton's Stanmer Park in August 2022. I had some small solar panels (Seeed Studio 0.5W solar panel) knocking about from another project and I decided to put those to use.</div><div><br /></div><div>I knew that these panels are very sensitive to changes in the amount of light falling on them and so I hit on the idea of making a mobile with the panel at one end of each arm, and an oscillator at the other. The idea being that the oscillator pitch would change as the mobile blew around and the angle of sunlight changed.</div><div><br /></div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dyeL3nb_ZmC85YgzsxgWsQ41slOFO_tMq4zkVeiskdqDmDYdVfGJ3fwehTF5ACStswbcv5fT3_UqOui-NaxwQ' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><br /><div><br /></div><div>My first experiements with simple Schmitt Trigger Inverter (74HC14) oscillators had mixed results; it seemed like the volume changed more than the pitch. </div><div><br /></div><div>I experimented with putting a JFET transistor in the feedback connection of the oscillator and found this gave a much more satisfying sweep of pitch as the power supply voltage changed. The gate of the JFET was simply held at half the power supply voltage using a divider made of two 10k resistors.</div><div><br /></div><div>Even better I found that, rather than tying the low side of that divider to ground, I could use the voltage from the high side of the timing capacitor of another oscillator and get some pitch modulation. Using a large capacitor value (slower frequency) on the modulating oscillator and smaller capacitor value on the modulated oscillator (audio frequency) gave some satisfying whining.</div><div><br /></div><div>The output from the higher frequency oscillator is buffered through a spare gate and fed to a speaked via a 100nF capacitor. I had some small speakers spare which had an (unusual?) 50ohm impedence, which worked well enough without any further amplification. The result is fairly quiet but just enough to give ambient chirps and tweets without being too intrusive.</div><div><br /></div><div>My mobile has four levels and I chose different capacitor values for each, so they have different sounds from each other, with 2.2uF and 4.7uF used on the audio oscillator side (C1) and 100nF, 470nF used on the low frequency oscillator sid (C2)</div><div><br /></div><div>I used enamalled copper wire to link the solar panel to the home-etched boards, and soldered the board directly to the speaker terminals.</div><div><br /></div><div>With a decent breeze and some sunshine it sounds like sad birds, crying kittens, dying angels (make your own mind up)</div><div><br /></div><div><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif" style="background-color: white; color: #262626; font-size: 14px;"><br /></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif" style="color: #262626;"><span style="background-color: white; font-size: 14px;">EAGLE project is available here : </span><span style="font-size: 14px;"><a href="https://github.com/hotchk155/buzmobil">https://github.com/hotchk155/buzmobil</a></span></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif" style="color: #262626;"><span style="font-size: 14px;"><br /></span></span></div><div style="text-align: center;"><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif" style="color: #262626;"><span style="font-size: 14px;">Here is the schematic (<a href="https://raw.githubusercontent.com/hotchk155/buzmobile/main/bb_schem2.png" target="_blank">click for original</a>)</span></span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif" style="color: #262626;"><span style="font-size: 14px;"><div class="separator" style="clear: both; text-align: center;"><a href="https://raw.githubusercontent.com/hotchk155/buzmobile/main/bb_schem2.png" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="1867" data-original-width="1920" height="389" src="https://blogger.googleusercontent.com/img/a/AVvXsEjYPwz1g2X7Osr42eiVZcSy1ni6S3oEQbrIIXmTQEJozYJYDJqOytwPeJBjSImFuYBtSO3GCyQnKLgxfGtX3KMgenTyy7HY-fo5EB8rsakI8t6mwaoi7aYyFjhrKCVyyJkQWoINqPc2VxwKw8__Cxy4QEuK52Pf_g-wDLs9jp_sqy638lZHj9zCzjI=w400-h389" width="400" /></a></div><br /><br /></span></span></div><div style="text-align: center;"><span face="-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif" style="color: #262626; font-size: 14px;">Here is the template for etching (<a href="https://raw.githubusercontent.com/hotchk155/buzmobile/main/bb_etch.jpg">click for original</a>)</span></div><div><span face="-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif" style="color: #262626;"><span style="font-size: 14px;"><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><div class="separator" style="clear: both; text-align: center;"><a href="https://raw.githubusercontent.com/hotchk155/buzmobile/main/bb_etch.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="434" data-original-width="482" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiV5C7IspA_FBKtXWGQCc2BY6c9NQJDxCfveWCE4xVRe4jXHjf_8JOVMccb2hBAcPwX5BiS4bMfIirp0QWFX_Ia51c9dUQfxkbDAryyR5HQDcFMZFjgoc1vbX4LXL1I5qIioPCL_MMHUEcgIVTVeJoRhQNLFcKTXtlgCSBojjyTr2bc8Va8U-0TRrM/w200-h180/bb2.jpg" width="200" /></a></div><br /><div class="separator" style="clear: both; text-align: center;"><span style="text-align: left;">Component Layout</span></div><div class="separator" style="clear: both; text-align: center;"><br /></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/a/AVvXsEhsPiO3gmvygjN8YbzNNBMA7kj9latgbzOGvkYt3adapnCoOCOt--TXPvRN4KUABlPhpHxOD9DLcFisUV6OziudZ4gqH8uxAobgG3AmjWpvp_IZ8xTlelS2ombuALHW3ehXWee6HnjX6WlyXHcLvaNqb0kZP6bzc_IVc7ocPHpSQQ8C38dwpF18uf0" style="margin-left: 1em; margin-right: 1em;"><img alt="" data-original-height="218" data-original-width="242" src="https://blogger.googleusercontent.com/img/a/AVvXsEhsPiO3gmvygjN8YbzNNBMA7kj9latgbzOGvkYt3adapnCoOCOt--TXPvRN4KUABlPhpHxOD9DLcFisUV6OziudZ4gqH8uxAobgG3AmjWpvp_IZ8xTlelS2ombuALHW3ehXWee6HnjX6WlyXHcLvaNqb0kZP6bzc_IVc7ocPHpSQQ8C38dwpF18uf0=s16000" /></a></div><br /><br /></div><br /><br /></div><br /><br /></span></span></div>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com2tag:blogger.com,1999:blog-8909459762367220480.post-56969085239376902792020-04-13T12:56:00.000-07:002020-04-13T12:58:51.058-07:00Isometric surface plotting on a Vectrex CRT under analog voltage controlA while back I converted an old Vectrex vector CRT games console so that the display could be controlled directly by voltage signals from a modular synth (after being inspired by a demo I saw from Andrew Duff)<br />
<br />
Since then I have occasionally thoughts about making synth modules that might work well with the setup and one idea was something to enable isometric "3D" surface plotting from the synth. Back in my school days I messed around with making little isometric 3D demo programs on the BBC Micro computers at school and remembered it being pretty easy to do.. Basically if you have "logical" x and y position and a z position which is some function of x and y, then you can plot on the screen as basically<br />
<br />
Xscreen = (x - y)<br />
Yscreen = (x + y + z)<br />
<br />
with appropriate scaling and offsetting to place (0,0) at the bottom centre of the screen. The line x=y then runs vertically up the middle of the screen.<br />
<br />
My idea was that I'd use a ramp waveform from an oscillator (VCO) on my modular synth to scan the "logical" x axis at high frequency. Every time the scan completed I'd increment a position along the y axis until we'd traced a series of (say) 16 horizontal lines. <br />
<br />
To generate the screen X and Y (which can be fed to the Vectrex as analog voltages) we can use voltage summing to evaluate the equations above (subtraction would mean inverting a voltage before adding it)<br />
<br />
Once we've done that we can add a z component from another oscillator etc, which is then added to the Y voltage, and with appropriate scaling and offsetting we should get a "3D" plot of the z component on an isometric grid.. in theory!<br />
<br />
Ideally we'd have a z that is a function of x and y so that the plot remains "fixed" on the grid. To start with I intended trying to get the same effect by messing by trial and error fine-tuning and messing with oscillator hard syncing.<br />
<br />
So the first challenge was to generate the logical y coordinate from the VCO ramp voltage (x). What we want is a "stepped" voltage ramp with 16 equally spaced steps, where we move to the next step (y) only when the VCO ramp resets back to zero at the end of its cycle. Each full y-ramp should take exactly 16 x-ramps to complete.<br />
<br />
I did this with a counter chip (CD4040) which fed into an R-2R resistor ladder (forming a digital to analog converter). Using one gate of a CD40106 hex inverter schmitt-trigger i could convert the VCO ramp into a pulse wave with a falling edge at the end of the cycle. This pulse clocked the counter and the lower 4 output bits of the counter fed the DAC (the upper 8 bits can just be left unconnected and ignored).<br />
<br />
I had an integrated R-2R resistor network (4610X-R2R-103LF) component handy and used the 4 most significant bits (I tied lower bits to ground) but it would have been pretty easy to make an R-2R network from discrete resistors.<br />
<br />
The R-2R DAC output is buffered by an LM358. I also buffered the VCO input using the other opamp gate. Note that the LM358 is not rail to rail so I ran it at 12V and ran the IC's through a 9V voltage reg so there was plenty of headroom.<br />
<br />
This is what it looked like on breadboard...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjNb_cECuYtD7Z6gBTnjkUoUPItBpxBn8joATi2nCI3mz81Q0iGShT67nLn8SCgsAJtLi_FvyXmvEkKLTULCBMpIBCb9rrI9SdAU7TCTQZhqCmYR8POqZkllNU7Mlgi8yr9P8JRJli8IE/s1600/P1050727.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjNb_cECuYtD7Z6gBTnjkUoUPItBpxBn8joATi2nCI3mz81Q0iGShT67nLn8SCgsAJtLi_FvyXmvEkKLTULCBMpIBCb9rrI9SdAU7TCTQZhqCmYR8POqZkllNU7Mlgi8yr9P8JRJli8IE/s320/P1050727.JPG" width="320" /></a></div>
<br />
<br />
<br />
It seemed to get the desired result!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkdpy7nxulhAffLNom1_Oj2KIP1DLmqiZ7Qs89du1wx_Gw7FTg0zB4m0MD1E4ZslVtpmfBtjEJ68bi6Yqxct1lXsSdp66qIP__7vEE9ysIZuwcpQRVzbX6TKUoh-FK8WYu3KXGDrN_YY/s1600/P1050724.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkdpy7nxulhAffLNom1_Oj2KIP1DLmqiZ7Qs89du1wx_Gw7FTg0zB4m0MD1E4ZslVtpmfBtjEJ68bi6Yqxct1lXsSdp66qIP__7vEE9ysIZuwcpQRVzbX6TKUoh-FK8WYu3KXGDrN_YY/s320/P1050724.JPG" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxfwkLNwM_EVu2cuMVx_x3xqb273XaiGmLDNV2aDKetNFusLgKKEkWxDHFDdh86vMc0TPtGgyO1ryxb6lsPOZfSPnf5coPOObEGZ28ICpg9JNJ2-bKC5AJKK4B8ComX0xh_Sreos83AKw/s1600/P1050725.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxfwkLNwM_EVu2cuMVx_x3xqb273XaiGmLDNV2aDKetNFusLgKKEkWxDHFDdh86vMc0TPtGgyO1ryxb6lsPOZfSPnf5coPOObEGZ28ICpg9JNJ2-bKC5AJKK4B8ComX0xh_Sreos83AKw/s320/P1050725.JPG" width="320" /></a></div>
<br />
<br />
I also thought it would be useful to have a "start of plot" signal output from the circuit for hard syncing a VCO at the start of the grid plot. For this I just hooked up bit 3 of the counter output to another gate on the 40106 (so I'd get a buffered rising edge when the bit 3 of the counter rolls round to zero). I also buffered the counter clock via the 40106 as I thought that might also be useful for hard synching an oscillator.<br />
<br />
Then I got to work playing..<br />
<br />
<ul>
<li>I used the ramp out of a Befaco Even VCO module to drive the logical x axis. </li>
<li>A Befaco dual A*B+C module did the x-y and x+y voltage adding</li>
<li>A second Befaco dual A*B+C module did the z-scaling/adding to x+y voltage and also x-y offsetting</li>
<li>The X and Y voltages went via an mcop 4x4 matrix mixer where they could also be attenuated, sent to the Vectrex X and Y connections and to audio (although none of this sounded so good!) plus a component of these voltages could be sent to the Vectrex brightness channel so brightness patterns could also be "plotted" on the grid</li>
<li>I tried various sources for the z-voltage, from simple sine waves with and without hard-sync, FM'd sines, triggering two ramps on the Maths etc. Some results in the video below..<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdjrqLvU9PlmCnLLhWULZfO6lmegOtZ91mT8TiUO3ZidEB1AiNCe0jTOLlRH7Rz-Rcj1N5TsTzUj8spnEtxvl20PmWVg3qbpOrioQmubE4dRO6kW4S914B-ADZ6Xwr7dcJ3Qpb_VMfZxA/s1600/P1050730.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdjrqLvU9PlmCnLLhWULZfO6lmegOtZ91mT8TiUO3ZidEB1AiNCe0jTOLlRH7Rz-Rcj1N5TsTzUj8spnEtxvl20PmWVg3qbpOrioQmubE4dRO6kW4S914B-ADZ6Xwr7dcJ3Qpb_VMfZxA/s320/P1050730.JPG" width="320" /></a></div>
</li>
</ul>
<br />
<br />
There is definitely some potential there but to really make the most of it needs "static" plots (patterns that jump around can easily be made without all this grid plotting). There is definitely mileage in hard sync and triggering waveforms (e.g. using Maths module) but I some kind of "function of x and y" would be really interesting to try... something for more experimentation<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i9.ytimg.com/vi/Eq08p1WCaEU/default.jpg?sqp=CJSH0_QF&rs=AOn4CLDu65xM934UuceeJJxWPzbGnae4pg" src="https://www.youtube.com/embed/Eq08p1WCaEU?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-22445021471116830662019-05-28T07:08:00.001-07:002019-05-28T07:09:52.669-07:00Run a Korg SQ-1 Sequencer from a 9V Stompbox SupplyThe Korg SQ-1 is a great little sequencer, and one of my favourite bits of kit for its simple hands-on feel and penchant for lucky randomness (I have 3 of them!)<br />
<br />
I tend to use it in a live setup with no computer but with a lot of guitar effect pedals on 9V daisy chain cables. The fact that the SQ-1 can only use batteries or USB power becomes a bit annoying so I decided to hack one so it can run on the same power supply as the pedals.<br />
<br />
This is a pretty straightforward mod and I actually did this a couple of years ago (just found the photos again :) so I can say it didn't break the SQ-1, which is still working just fine. Also the SQ-1 still works fine on USB power, this mod just gives you an additional option.<br />
<br />
However follow these instructions at your own risk and only if you feel confident making electronic circuits. You might break your SQ-1 if you mess this up!<br />
<br />
So you're gonna need<br />
<br />
<ul>
<li>A 2.1mm barrel socket with plastic body</li>
<li>LM7805 +5V voltage regulator (0.5A rating is OK, higher is fine)</li>
<li>2 x 10uF/35V electrolytic capacitors</li>
<li>2 x 100nF ceramic capacitors</li>
<li>2 x 1N5817 schottky rectifier diode</li>
<li>Stripboard</li>
<li>Wire</li>
</ul>
<br />
<br />
Lets cut off a 9x9 hole piece of strip board and build the regulator circuit<br />
<br />
The schematic is pretty simple. The 7805 regulator reduces its input voltage (at least ~7V) down to 5V. The capacitors stabilise the regulator. Diode D1 protects the circuit from incorrect polarity input and D2 prevents backflow of current when the SQ-1 is running from other power sources.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAZojLgP68uVtp-RzDEmQinoNwipz0l0WLewpnGZkdFvkFHeISae9E56eyIBzoIqhZ4xFHUFQ88KWmkYgzZ-uFVbD7QSK2WwRdfFflR0cCNQShIPSJou7G2DdyVnxDp-I65sAoybpv8Nk/s1600/aa.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="189" data-original-width="558" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAZojLgP68uVtp-RzDEmQinoNwipz0l0WLewpnGZkdFvkFHeISae9E56eyIBzoIqhZ4xFHUFQ88KWmkYgzZ-uFVbD7QSK2WwRdfFflR0cCNQShIPSJou7G2DdyVnxDp-I65sAoybpv8Nk/s640/aa.png" width="640" /></a></div>
<br />
<b><u>(Note: Click on the photos to see the full image if it is cut off)</u></b><br />
<br />
Here is how I laid out the stripboard. The black and red wires are connected to the power socket.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-E-YgBvxyBZ-BSvuzmmArytks5IYd9MuCa3gl2kwJXczHyH7yqwHvRxQ3aAi59T3uy8MGcHGQ7KRVAiMZdj5S2ika5E2QVmzY1KzZO11p6XiuoE5L-lBS06pdFlJE7Kwgw3P-hXxWvc/s1600/DSC04191.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiT-E-YgBvxyBZ-BSvuzmmArytks5IYd9MuCa3gl2kwJXczHyH7yqwHvRxQ3aAi59T3uy8MGcHGQ7KRVAiMZdj5S2ika5E2QVmzY1KzZO11p6XiuoE5L-lBS06pdFlJE7Kwgw3P-hXxWvc/s640/DSC04191.JPG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
No track cutting is needed</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3eJAeLXjpEX94MsTY6cKYtC5AXBebzipchebSD4MdEx8Cq7NailZ9rH3VrI226MxffWPMBgVaPdA1IPqnOOQByto2Whq0IUwB06CYCJbMlD4oGr74H7een_wAhwlGMKFVs-lmvpNrRhQ/s1600/DSC04193.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3eJAeLXjpEX94MsTY6cKYtC5AXBebzipchebSD4MdEx8Cq7NailZ9rH3VrI226MxffWPMBgVaPdA1IPqnOOQByto2Whq0IUwB06CYCJbMlD4oGr74H7een_wAhwlGMKFVs-lmvpNrRhQ/s640/DSC04193.JPG" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
Take the SQ-1 apart and cut a hole in the end of the case the correct size for your power socket. Please note that the socket needs a <u><b>plastic body</b></u> if you are using a BOSS-style centre-negative guitar pedal supply. This is because the SQ-1 case is grounded and a metal socket wired for a centre-negative supply will short out when the case is put back together again. If you are using a centre-positive supply you should be OK.. I think!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Make sure the socket will fit when the case is back together, and that it will not touch any part of the SQ-1 PCB. See the final photo at the bottom of this post to see where I fitted the socket (and please note that the SQ-1 is upside down on the desk in the photo below, the hole is closer to the base than top)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvUEfge3P4NPSqmiI87cfUOYrfBd9ewNIWtfohcY-J89PuUco586p_0EzZKty6VDbdxoVtpam9fnUAUkJyHhYfpRQ5A86wLIRzuBg5-GqbzV2JfiITkHzbGMXU1_IU9fBSwzHn9nzx0Qo/s1600/DSC04184.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvUEfge3P4NPSqmiI87cfUOYrfBd9ewNIWtfohcY-J89PuUco586p_0EzZKty6VDbdxoVtpam9fnUAUkJyHhYfpRQ5A86wLIRzuBg5-GqbzV2JfiITkHzbGMXU1_IU9fBSwzHn9nzx0Qo/s400/DSC04184.JPG" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: left;">
Connect the 5V output wires to the regulator board as shown below. Do not try connect them to the SQ-1 yet! With the power socket wired to the regulator board and bolted to the case, plug in your 9V supply and use a multimeter check that you have a steady 5V from the output wires</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGURv5p78-SZBlazQfuXEzwVebi6mW2wGTWz2LDoiE78TfBTfGkmB09mXt-vS9CMXYQ9ehG-7lu7SUJVFGGQP-f4SxSvfOMy4loYZ4tyXKvTQ4llm8UKrqexnzRJaTw-oUqLL6LuFGxI/s1600/DSC04195.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGURv5p78-SZBlazQfuXEzwVebi6mW2wGTWz2LDoiE78TfBTfGkmB09mXt-vS9CMXYQ9ehG-7lu7SUJVFGGQP-f4SxSvfOMy4loYZ4tyXKvTQ4llm8UKrqexnzRJaTw-oUqLL6LuFGxI/s640/DSC04195.JPG" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now the scary bit - we need to solder the 5V wires on to the SQ-1 PCB... make sure all power is off, USB is disconnected and batteries removed.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
These are the solder points I used for the 5V</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_VIRsp5L6nXV0nIxmPdPy1qYekZYVICJrUoDrPyHb2trquDOaNaQS9LEMkJmJlDjxToNLrKOmFt6jUEZpLckOE8dfBCwoKrpxf1Ahm5FJE_0sTRrVT_ZH0poAE5eixp2TxrkY6XaM8Y4/s1600/DSC04182.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_VIRsp5L6nXV0nIxmPdPy1qYekZYVICJrUoDrPyHb2trquDOaNaQS9LEMkJmJlDjxToNLrKOmFt6jUEZpLckOE8dfBCwoKrpxf1Ahm5FJE_0sTRrVT_ZH0poAE5eixp2TxrkY6XaM8Y4/s640/DSC04182.JPG" width="640" /></a></div>
<br />
Then I secured the leads with tape<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgygGs43y1xQAQRYgKb-pXDSOI5L-QNNHjpmDpg5fsferR8vgDhdtQyE8iTzSopqNE5TtHUoYjuypUpbMrbfgyX7U2ZO_1DG5ZJqN_TvIkM6fshVjZxmj6bJEOCznbLfEzyea6RH4536Bs/s1600/DSC04197.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgygGs43y1xQAQRYgKb-pXDSOI5L-QNNHjpmDpg5fsferR8vgDhdtQyE8iTzSopqNE5TtHUoYjuypUpbMrbfgyX7U2ZO_1DG5ZJqN_TvIkM6fshVjZxmj6bJEOCznbLfEzyea6RH4536Bs/s640/DSC04197.JPG" width="640" /></a></div>
<br />
I attached the regulator board to the base of the case with sticky foam pads, making sure none of the stripboard was touching the case.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqV9gG2dgkuzcOxEGuiuUTJnkosiVtWmTQLYzAmBjM0jfmpBOALuuIRcxXVWt0bdwBTFydE6Yms8d_tMS1aCLQ3F_eLJrC_3KqygisZak4i_JU5wwU2NfAPp6wKuftkOs5N3o69bzdLC4/s1600/DSC04198.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqV9gG2dgkuzcOxEGuiuUTJnkosiVtWmTQLYzAmBjM0jfmpBOALuuIRcxXVWt0bdwBTFydE6Yms8d_tMS1aCLQ3F_eLJrC_3KqygisZak4i_JU5wwU2NfAPp6wKuftkOs5N3o69bzdLC4/s640/DSC04198.JPG" width="640" /></a></div>
<br />
At this point check all connections look good and (depending on your beliefs) maybe say a little prayer or take a long slurp of beer and power up. Press the SQ-1 power button and check it comes on. If it doesn't, disconnect everything quickly and check it all again.<br />
<br />
Finally reassemble and you're good to go!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz9au6qEfFYMltR1L7-brAKnQremD6ptE9SCbDzW3sMNn_n4bnWsnUlRoA-jvavgx-AbHtSvalDn8rD_51QQKkofwdEZBreYw2P3bJpgr2QNTWTmRNRXMRm1tvclo6h3e5PFebwSFo62A/s1600/DSC04201.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz9au6qEfFYMltR1L7-brAKnQremD6ptE9SCbDzW3sMNn_n4bnWsnUlRoA-jvavgx-AbHtSvalDn8rD_51QQKkofwdEZBreYw2P3bJpgr2QNTWTmRNRXMRm1tvclo6h3e5PFebwSFo62A/s640/DSC04201.JPG" width="640" /></a></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com4tag:blogger.com,1999:blog-8909459762367220480.post-86967739707632296972019-05-26T07:55:00.001-07:002019-05-27T03:57:52.182-07:00Circuit bending a talking alphabet toy with a MIDI upgrade!<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/YdV6DmshAH4/0.jpg" src="https://www.youtube.com/embed/YdV6DmshAH4?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
A few years ago my son had a Leapfrog "Alphabet Pal" toy, a kind of drag-along plastic caterpillar/centipede chimera with legs that function as push buttons. Depending on the mode, pressing a leg makes it announce letter sounds, phonic sounds or colours - all in a super jolly voice - or play various nursery-rhyme type tunes.<br />
<br />
A fun thing to do with this was to try and make it reel off absurd or mildly insulting sentences based on the letter sounds ("O, I, C... U, R, A, P", "R, U, A, B?" oh the fun is endless..) Interestingly there is actually some censorship going on - if you enter F, U, C... it spouts out "ooh that tickles!" and refuses to go any further (really!)<br />
<br />
I think our old one went to a charity shop years ago, but last week for no special reason I decided to try and find another one and see if could find a way to circuit bend it, and eBay did provide...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRT0TGBCsoFZJCPY0dDg0NR6JgSEC8ig7Y_78YoN7bCyUyJkJ8QUH0RopiwzRXpuQV_e8XTqbxw5oqlyxCgCmKXbHs_JZEklGFGrYeKePRYRQ6q2CEDXClLpqZOT3rUWSNCastSJ1RXPY/s1600/P1040153.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRT0TGBCsoFZJCPY0dDg0NR6JgSEC8ig7Y_78YoN7bCyUyJkJ8QUH0RopiwzRXpuQV_e8XTqbxw5oqlyxCgCmKXbHs_JZEklGFGrYeKePRYRQ6q2CEDXClLpqZOT3rUWSNCastSJ1RXPY/s400/P1040153.JPG" width="400" /></a></div>
<br />
So, first thing was to take a look inside... I was immediately quite impressed with the build quality of it - everything is nicely bolted together with Philips screws - even every one of those feet is screwed on! It also feels very solid<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKsgJToHrLfizNdoFpG47R1ijwZxiGCSEgPO6D-5xzy3_A1NYW20XMss5Che5u2j-iQWNCVivWGSJoF66aqlw0ItikXYZDXNWpHpsSII09J4PGBvdX33oK8tAaZq_payu5oY8vSfURxvI/s1600/P1040154.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKsgJToHrLfizNdoFpG47R1ijwZxiGCSEgPO6D-5xzy3_A1NYW20XMss5Che5u2j-iQWNCVivWGSJoF66aqlw0ItikXYZDXNWpHpsSII09J4PGBvdX33oK8tAaZq_payu5oY8vSfURxvI/s400/P1040154.JPG" width="400" /></a></div>
<br />
Inside, everything is also nicely put together with no melted-plastic-welding, flimsy clips or blobs of glue, just more Philips screws.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii11LMwSdVDYxdOjqjiuINjI4nziTLgkBWTsSJ6mG2T0bPmWPOrtBfPwkcVa_6oC53pj2qMtP86Lyk80W0YCq3QgFAHAelhqd2p9mMYvx8ktmI2jhePkozIPt-uOzPgVIqpYbTxG2qxqw/s1600/P1040157.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEii11LMwSdVDYxdOjqjiuINjI4nziTLgkBWTsSJ6mG2T0bPmWPOrtBfPwkcVa_6oC53pj2qMtP86Lyk80W0YCq3QgFAHAelhqd2p9mMYvx8ktmI2jhePkozIPt-uOzPgVIqpYbTxG2qxqw/s400/P1040157.JPG" width="400" /></a></div>
<br />
So here is the brain PCB. That flexible cable connects all the switch pads for the legs and has 12 tracks, show that some kind of keyboard matrix is in use (since there are 20 switches to read via that connector). This is good news! I will come back to that later. For now I'll remove the plastic bar and tape the connector out of the way.<br />
<br />
I already had a good idea of how I was going to tackle the MIDI conversion, so I started off by looking to see if there was a way I could control the pitch of the speech. When I lifted the PCB I found a through-hole resistor on the reverse (despite the fact the rest of the board is all surface mount components). Since there was no crystal oscillator visible, my thought was this resistor might be a timing component (perhaps in the factory they select a "best fit" resistor to make the voice pitch about right and solder it on as a last step)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoq3jlNphKBqpAJ8ZncswA4jbW-JW10NQ5ckwCF9lhGFVEYVLRaZ5Ig003MBNKW5FZmKVVctryMbNuqor1dxTH3uiM36OBMWwckS9OQM_by1SA-xbU3BJVHiX8vK0I6XfxNDK_W2AbuHQ/s1600/P1040164.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoq3jlNphKBqpAJ8ZncswA4jbW-JW10NQ5ckwCF9lhGFVEYVLRaZ5Ig003MBNKW5FZmKVVctryMbNuqor1dxTH3uiM36OBMWwckS9OQM_by1SA-xbU3BJVHiX8vK0I6XfxNDK_W2AbuHQ/s400/P1040164.JPG" width="400" /></a></div>
<br />
Anyway I took a punt on this resistor being for the timing and I clipped the lead so I could experiment with a potentiometer. Sure enough, a 100k potentiometer in place of the resistor (which measured as 36k ohm) gave a good swing of pitch from shrill squeaking to bitcrusher-like digital croak. However at the faster end of the range it would cause a lock up until everything was powered off and on again. This was fixed by putting a 15k resistor in series with the 100k pot. I then made a hole in the back of the caterpillar and fitted the pot - one great thing about this toy is that its mostly hollow, so plenty of space for additional circuitry!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmF783ubkH7T5pje2gEoJ9moYRsQpLzSYuXWCo2nh_KnKJApjiV_wpdMxLWccwt7vX9xN0F3e5qTKtVe3hTqwnX5LYMJmyOZ8X8jkibE4GLvyH7zLbmIqkeutL1d6LgHNGEAxRpDp5qeA/s1600/P1040172.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmF783ubkH7T5pje2gEoJ9moYRsQpLzSYuXWCo2nh_KnKJApjiV_wpdMxLWccwt7vX9xN0F3e5qTKtVe3hTqwnX5LYMJmyOZ8X8jkibE4GLvyH7zLbmIqkeutL1d6LgHNGEAxRpDp5qeA/s400/P1040172.JPG" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
So, back to the keyboard matrix, and time for some probing with a bit of wire. There are 12 pads on the edge of the "brain" PCB that mate up with the flexible ribbon cable. I tried a quick wire connection between each combination of wires to see which letter the toy spoke, and quickly had a key matrix worked out<br />
<br />
Pad 1 vs Pads 9, 10, 11, 12.... "P", "O", "N", n/a<br />
Pad 2 vs Pads 9, 10, 11, 12.... "K", "L", "M", n/a<br />
Pad 3 vs Pads 9, 10, 11, 12.... "S", "R", "Q", n/a<br />
Pad 4 vs Pads 9, 10, 11, 12.... "H", "I", "J", n/a<br />
Pad 5 vs Pads 9, 10, 11, 12.... "V", "U", "T", n/a<br />
Pad 6 vs Pads 9, 10, 11, 12.... "E", "F", "G", n/a<br />
Pad 7 vs Pads 9, 10, 11, 12.... "Z", "Y", "X", "W"<br />
Pad 8 vs Pads 9, 10, 11, 12.... "A", "B", "C", "D"<br />
<br />
so there is a matrix configuration with pads 1-8 as columns and 9-12 as rows (or vice-versa). Sticking an oscilloscope probe on pad 9 shows a positive going pulses at a little under 200Hz<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-6kuxVOxE-v_kUfeLkn9i1DBRHti1EihPpMTtmfea5Duhj0gU3cp9jDoPsZIyasfLa4uV5bqLmdBqNlgOI7zMZCYb3qamO387J8NcfT7UvPk5Q0bi7XjHTHKdKbV8_CMrdOxlDi62Qo8/s1600/P1040163.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-6kuxVOxE-v_kUfeLkn9i1DBRHti1EihPpMTtmfea5Duhj0gU3cp9jDoPsZIyasfLa4uV5bqLmdBqNlgOI7zMZCYb3qamO387J8NcfT7UvPk5Q0bi7XjHTHKdKbV8_CMrdOxlDi62Qo8/s400/P1040163.JPG" width="400" /></a></div>
<br />
So about 200 times a second the processor in the toy is sending a pulse to each of the pads 9, 10, 11, 12 in turn and reading the voltage at pads 1,2,3,4,5,6,7,8.<br />
<br />
Each of the switches on the legs is making a connection between a row and a column, so where the "R" switch is pressed, pad 10 is connected to pad 3 via the switch and when the processor sends a voltage to pad 10 it will see that voltage appear at pad 3<br />
<br />
Even though the switch contacts for the letters A,B,C and X,Y,Z are on the main PCB (and so don't need to be routed via the flexible cable) they are part of the same key matrix anyway and can be triggered from the same 12 pads. This will make our job easier!<br />
<br />
To automatically trigger these switch inputs you might think we'd just put some kind of electronic switch or relay in place of the 26 buttons and control these from an Arduino etc... Well we could take this route but it would require a lot of electronics and wiring..<br />
<br />
Much simpler is to hijack the existing matrix scanning... with just the 12 connections used on the ribbon cable we can simulate any button press from our own microcontroller - we just need to listen out for the "pulse" coming in on pads 9,10,11,12 and set the values on pins 1,2,3,4,5,6,7,8 accordingly.<br />
<br />
For example if our "brain parasite" microcontroller wants the caterpillar brain to think "R" has been pressed it just sets pad 3 "high" whenever it sees pad 10 go high. It does needs to keep up with 200 pulses a second on each of the four input pads but even an 8-bit PIC can do that with ease.<br />
<br />
You could use an Arduino for this, but a full size one won't fit inside the toy. A Teensy LC would do the job nicely but I am going to use my usual go-to MCU, the PIC16F1825 (on in this case it's bigger sister, the 20-pin PIC16F1829, since I need more I/O pins for all those key matrix connections)<br />
<br />
Soldering one of these to an SOIC-20 breakout board, I have my brain parasite ready... (the header pins on the right are to connect the PIC programmer)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQztCGvLGBy7ztlcoJky7xwF63UVXuXatlLqFvLKiKE9LSaX_YUmwre_u1PZRps9f6DKwatKX1BEOYOhysbetPRp4xk_2R5CCOPhqhSCafSQuNfstXYo0na91EfaWNBwjf4hg5iiasqN0/s1600/P1040167.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQztCGvLGBy7ztlcoJky7xwF63UVXuXatlLqFvLKiKE9LSaX_YUmwre_u1PZRps9f6DKwatKX1BEOYOhysbetPRp4xk_2R5CCOPhqhSCafSQuNfstXYo0na91EfaWNBwjf4hg5iiasqN0/s400/P1040167.JPG" width="400" /></a></div>
<br />
We are going to need to take MIDI in, so we will requires an opto isolator circuit (per MIDI standard) and a MIDI socket.<br />
<br />
I decided to mount the opto on a separate bit of stripboard together with a 7805 voltage regulator so that I can run the whole thing from a 9V guitar pedal adaptor rather than batteries. My combined MIDI interface and power supply board is shown below<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH4mPSLp-1_ZUCLrCwLjFUFAmMRubMkYGelhEoJ2Ot9jozYUf9P2yn6ZphXPwFzi4rHnMfa61dMIjH_r2QoY4LVyn44Ms4gFwb3PtjV99oKLbart9S6N6g3WqH1rElY0MLn9faePVaHk0/s1600/P1040193.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgH4mPSLp-1_ZUCLrCwLjFUFAmMRubMkYGelhEoJ2Ot9jozYUf9P2yn6ZphXPwFzi4rHnMfa61dMIjH_r2QoY4LVyn44Ms4gFwb3PtjV99oKLbart9S6N6g3WqH1rElY0MLn9faePVaHk0/s640/P1040193.JPG" width="640" /></a></div>
<br />
I fitted a power socket, MIDI socket and a 6.35mm jack into the caterpillar's rear end and still had space for the stripboard. The old battery leads can now be connected to the output of the 7805 reg (I put in a couple of silicon diodes in series to drop a bit of voltage as this toy usually runs at 4.5V off 3 x AA batteries).<br />
<br />
The audio socket is simply connected to the speaker output (which makes the signal a lot hotter than I would like, but its a quick and dirty solution) and I used the break pole of the socket to cut the internal speaker when a jack is inserted.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxPY22aPiYPLhGToatRk3Y6BttCj1qcLcNlFc23YkOPdYM2lN3hf5zyTf9GuLoNP7HJ0ojOr6xGBM9pwgtqKzGXcQBobUV_UgfPxqsJgg6d66hyyNhUpl88PAJlUBtuMOoxhWEMwYkrUk/s1600/P1040200.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxPY22aPiYPLhGToatRk3Y6BttCj1qcLcNlFc23YkOPdYM2lN3hf5zyTf9GuLoNP7HJ0ojOr6xGBM9pwgtqKzGXcQBobUV_UgfPxqsJgg6d66hyyNhUpl88PAJlUBtuMOoxhWEMwYkrUk/s400/P1040200.JPG" width="400" /></a></div>
<br />
The microcontroller board is now connected to the keyboard matrix pads using ribbon cables<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgH37e7ruFVlmiSxNZ5TDfOW66RrLuV7T0zP49YFJ2D0UF1hKWpCE_JiGx7Bwi92Wh63QivVccYjFE_EUZ07ZskmwGE9N0BcgG14gsGYHTmEEtVEV10wFnrxv4NPbVMtxIidgBd6maxM/s1600/P1040212.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgH37e7ruFVlmiSxNZ5TDfOW66RrLuV7T0zP49YFJ2D0UF1hKWpCE_JiGx7Bwi92Wh63QivVccYjFE_EUZ07ZskmwGE9N0BcgG14gsGYHTmEEtVEV10wFnrxv4NPbVMtxIidgBd6maxM/s400/P1040212.JPG" width="400" /></a></div>
<br />
The soldering on to the pads means that the flexible ribbon cable does not fit right back on, but by trimming the leading edge of the flexible ribbon back a bit and using some foam under the bracket to add extra pressure I was able to get the flexible ribbon back in place and working, so that the original switches all still function in parallel with the new microcontroller<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpb4LCjJYNGw2i0_3J8RZL0JXxqNhR0s6AI32RoJ8RkgFqldRo6PjGrG7Ehc-kA0bzlfVz1TLEwBJ-dBsjahLd_bilwzsyM1YUhZkG_xBaC0pBYQf6KeBtWGVt-zzcX6I6sUj6wJAG2N0/s1600/P1040219.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpb4LCjJYNGw2i0_3J8RZL0JXxqNhR0s6AI32RoJ8RkgFqldRo6PjGrG7Ehc-kA0bzlfVz1TLEwBJ-dBsjahLd_bilwzsyM1YUhZkG_xBaC0pBYQf6KeBtWGVt-zzcX6I6sUj6wJAG2N0/s320/P1040219.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs8PLP1nYmnkyJqXSo4x_Pl9c9tV7chN7flYhcK-G4ri0hy7ibLT-ihRGDUDbDILVEmPQXulEREClm0ew305C2VBT8wiIlDNHbrj3ETG1ykyHnIWPkCQT_DtUuUT9cPfnVUda2_AzQJhA/s1600/P1040222.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhs8PLP1nYmnkyJqXSo4x_Pl9c9tV7chN7flYhcK-G4ri0hy7ibLT-ihRGDUDbDILVEmPQXulEREClm0ew305C2VBT8wiIlDNHbrj3ETG1ykyHnIWPkCQT_DtUuUT9cPfnVUda2_AzQJhA/s320/P1040222.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Now everything can be reassembled. Make sure its all working before adding the base and legs again. I also removed the wheels and the rolling ball mechanism and attached some rubber feet so it will stay put on a desktop.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ7diCwysLnQ9QrD11bMDME38va-jZTo37I3-hFhMRfr4P1hygdgHqGI_60K8xVt5xGJrxRGMiYBplPPUSmGIGSDB-JI90EYgKQEjUif-wZ3dizd5A6OusoyXjDRoxe3cm75MLkbAQblo/s1600/P1040226.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZ7diCwysLnQ9QrD11bMDME38va-jZTo37I3-hFhMRfr4P1hygdgHqGI_60K8xVt5xGJrxRGMiYBplPPUSmGIGSDB-JI90EYgKQEjUif-wZ3dizd5A6OusoyXjDRoxe3cm75MLkbAQblo/s640/P1040226.JPG" width="640" /></a></div>
<br />
So obviously somewhere in that process I needed to write firmware and program the PIC. Since I want the original switches to still work in parallel with the MIDI control, I need to make sure that inactive outputs to the key matrix are not driven low by the PIC when the signal is off...<br />
<br />
For example if we are sounding an "R", we set pad 3 high when we see pad 10 go high. However at other times we do not want to drive pad 3 low because this would prevent any other signal getting through from the switches. We don't want to have any effect at all on the state of a pad unless we are actively driving it high.<br />
<br />
So in general, all our outputs need to switch between "high" and "no effect" - rather than high/low. We do this by setting the pins into "high impedence" mode (digital input mode). Therefore our drive method on one of our outputs (i.e. key matrix pins 1-8) is either<br />
<br />
No output - pin is set to digital input mode<br />
OR<br />
Output high - pin is set to digital output mode and driven to HIGH digital output value<br />
<br />
On my PIC this means toggling the TRIS (port direction) registers while leaving the PORT (port data) register bit at 1 at all times. On Arduino you might use separate pinMode and digitalWrite calls to do the same thing - or go to the underlying port registers for your particular board.<br />
<br />
For reference here is my PIC Code - It is written for Sourceboost C on PIC16F1829 but should be fairly easily portable to other 8 bit PIC 'C' compilers<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<pre>//
//
// INCLUDE FILES
//
#include <system.h>
#include <memory.h>
// CONFIG OPTIONS
// - RESET INPUT DISABLED
// - WATCHDOG TIMER OFF
// - INTERNAL OSC
#pragma DATA _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF &_CLKOUTEN_OFF
#pragma DATA _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
#pragma CLOCK_FREQ 32000000
typedef unsigned char byte;
/*
VDD VSS
RA5 RA0-DAT
RA4 RA1-CLK
RA3-VPP RA2-SCAN0
RC5-K3 RC0-K0
RC4-K4 RC1-K1
RC3-K5 RC2-K2
RC6-K6 RB4-SCAN1
RC7-K7 RB5-RX
RB7-SCAN3 RB6-SCAN2
*/
#define P_SCAN0 porta.2
#define P_SCAN1 portb.4
#define P_SCAN2 portb.6
#define P_SCAN3 portb.7
#define P_TRISA 0b11111111
#define P_TRISB 0b11111111
#define P_TRISC 0b11111111
#define RX_BUFFER_MASK 0x1F
volatile byte rx_buffer[32];
volatile byte rx_head = 0;
volatile byte rx_tail = 0;
// State flags used while receiving MIDI data
byte midi_status = 0; // current MIDI message status (running status)
byte midi_num_params = 0; // number of parameters needed by current MIDI message
byte midi_params[2]; // parameter values of current MIDI message
char midi_param = 0; // number of params currently received
////////////////////////////////////////////////////////////
// INTERRUPT HANDLER
void interrupt( void )
{
// serial rx ISR
if(pir1.5)
{
// get the byte
byte b = rcreg;
// calculate next buffer head
byte next_rx_head = (rx_head + 1) & RX_BUFFER_MASK;
// if buffer is not full
if(next_rx_head != rx_tail)
{
// store the byte
rx_buffer[rx_head] = b;
rx_head = next_rx_head;
}
}
}
////////////////////////////////////////////////////////////
// INITIALISE SERIAL PORT FOR MIDI
void init_usart()
{
pir1.1 = 1; //TXIF
pir1.5 = 0; //RCIF
pie1.1 = 0; //TXIE no interrupts
pie1.5 = 1; //RCIE enable
baudcon.4 = 0; // SCKP synchronous bit polarity
baudcon.3 = 1; // BRG16 enable 16 bit brg
baudcon.1 = 0; // WUE wake up enable off
baudcon.0 = 0; // ABDEN auto baud detect
txsta.6 = 0; // TX9 8 bit transmission
txsta.5 = 0; // TXEN transmit enable
txsta.4 = 0; // SYNC async mode
txsta.3 = 0; // SEDNB break character
txsta.2 = 0; // BRGH high baudrate
txsta.0 = 0; // TX9D bit 9
rcsta.7 = 1; // SPEN serial port enable
rcsta.6 = 0; // RX9 8 bit operation
rcsta.5 = 1; // SREN enable receiver
rcsta.4 = 1; // CREN continuous receive enable
spbrgh = 0; // brg high byte
spbrg = 63; // brg low byte (31250)
}
////////////////////////////////////////////////////////////
// GET MESSAGES FROM MIDI INPUT
byte midi_in()
{
// loop until there is no more data or
// we receive a full message
for(;;)
{
// usart buffer overrun error?
if(rcsta.1)
{
rcsta.4 = 0;
rcsta.4 = 1;
}
// check for empty receive buffer
if(rx_head == rx_tail)
return 0;
// read the character out of buffer
byte ch = rx_buffer[rx_tail];
++rx_tail;
rx_tail&=RX_BUFFER_MASK;
// REALTIME MESSAGE
if((ch & 0xf0) == 0xf0)
{
}
// STATUS BYTE
else if(!!(ch & 0x80))
{
midi_param = 0;
midi_status = ch;
switch(ch & 0xF0)
{
case 0xA0: // Aftertouch 1 key touch
case 0xC0: // Patch change 1 instrument #
case 0xD0: // Channel Pressure 1 pressure
midi_num_params = 1;
break;
case 0x80: // Note-off 2 key velocity
case 0x90: // Note-on 2 key veolcity
case 0xB0: // Continuous controller 2 controller # controller value
case 0xE0: // Pitch bend 2 lsb (7 bits) msb (7 bits)
default:
midi_num_params = 2;
break;
}
}
else
{
if(midi_status)
{
// gathering parameters
midi_params[midi_param++] = ch;
if(midi_param >= midi_num_params)
{
// we have a complete message.. is it one we care about?
midi_param = 0;
switch(midi_status&0xF0)
{
case 0x80: // note off
case 0x90: // note on
case 0xE0: // pitch bend
case 0xB0: // cc
case 0xD0: // aftertouch
return midi_status;
}
}
}
}
}
// no message ready yet
return 0;
}
////////////////////////////////////////////////////////////
// MAIN
void main()
{
int i;
// set to 32MHz clock (also requires specific CONFIG1 and CONFIG2 settings)
osccon = 0b11110000;
trisa = P_TRISA;
trisb = P_TRISB;
trisc = P_TRISC;
latc=0xFF;
apfcon0.7 = 0; // RX/DT function is on RB5
ansela = 0;
anselb = 0;
anselc = 0;
init_usart();
// enable interrupts
intcon.7 = 1; //GIE
intcon.6 = 1; //PEIE
byte out_data0 = 0;
byte out_data1 = 0;
byte out_data2 = 0;
byte out_data3 = 0;
while(1) {
// check for MIDI note message
byte msg = midi_in();
if(msg == 0x90 || msg == 0x80)
out_data0 = 0;
out_data1 = 0;
out_data2 = 0;
out_data3 = 0;
if(msg == 0x90 && midi_params[1])
{
// note on message
switch(midi_params[0])
{
case 36: /* A */ out_data0 = 1<<7; break; //A
case 37: /* B */ out_data1 = 1<<7; break; //B
case 38: /* C */ out_data2 = 1<<7; break; //C
case 39: /* D */ out_data3 = 1<<7; break; //D
case 40: /* E */ out_data0 = 1<<3; break; //E
case 41: /* F */ out_data1 = 1<<3; break; //F
case 42: /* G */ out_data2 = 1<<3; break; //G
case 43: /* H */ out_data0 = 1<<5; break; //H
case 44: /* I */ out_data1 = 1<<5; break; //I
case 45: /* J */ out_data2 = 1<<5; break; //J
case 46: /* K */ out_data0 = 1<<1; break; //K
case 47: /* L */ out_data1 = 1<<1; break; //L
case 48: /* M */ out_data2 = 1<<1; break; //M
case 49: /* N */ out_data2 = 1<<0; break; //N
case 50: /* O */ out_data1 = 1<<0; break; //O
case 51: /* P */ out_data0 = 1<<0; break; //P
case 52: /* Q */ out_data2 = 1<<2; break; //Q
case 53: /* R */ out_data1 = 1<<2; break; //R
case 54: /* S */ out_data0 = 1<<2; break; //S
case 55: /* T */ out_data2 = 1<<4; break; //T
case 56: /* U */ out_data1 = 1<<4; break; //U
case 57: /* V */ out_data0 = 1<<4; break; //V
case 58: /* W */ out_data3 = 1<<6; break; //W
case 59: /* X */ out_data2 = 1<<6; break; //X
case 60: /* Y */ out_data1 = 1<<6; break; //Y
case 61: /* Z */ out_data0 = 1<<6; break; //Z
}
}
// respond to key matrix scan by changing correct
// output pin from high impedence (input mode) to
// a HIGH signal (digital out mode, PORTC register
// is already all high bits)
if(P_SCAN0) {
trisc = ~out_data0;
}
else if(P_SCAN1) {
trisc = ~out_data1;
}
else if(P_SCAN2) {
trisc = ~out_data2;
}
else if(P_SCAN3) {
trisc = ~out_data3;
}
else {
trisc = 0xFF;
}
}
}
//
// END
//
</pre>
hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-80449211891989064332018-01-18T02:18:00.003-08:002018-01-18T05:31:53.501-08:00Fixing PSU issues on old BOSS guitar pedalI recently bought an old BOSS GE-7B graphic equalizer pedal off eBay. It all looked in great condition and worked fine from a battery but not from a 9V supply. Since I don't want to keep changing batteries (the thing is drawing 12mA even when switched off) I couldn't be doing with that, but decided to investigate a bit more before assuming it was faulty<br />
<br />
Luckily these pedals come from a time when manufacturers still thought about making things serviceable, and BOSS openly provided the schematics (I think they used to be printed in the instruction sheet - imagine that these days..). These schematics are all over the internet - for example I found one here <a href="https://www.hobby-hour.com/electronics/s/ge7b-bass-equalizer.php" target="_blank">https://www.hobby-hour.com/electronics/s/ge7b-bass-equalizer.php</a><br />
<br />
Expecting that some component might be damaged, I looked for anything that might be part of the power supply circuit from the DC socket but not from the battery, and immediately saw a resistor and diode (D1 and R1 indicated below)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0MwdkbHy1_9N6dELNmnWqmJv-sgykTcxOcovQEPQ51345QLFrNuaNGicr_klxAcg0tCjcTsnQTfDw-gspGIhGpSDL-DbdTOP0VJC9whaERGn8Y7ikGU7Ntwwd2qlmfOtVW6adVuYVsA/s1600/boss1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="331" data-original-width="355" height="298" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0MwdkbHy1_9N6dELNmnWqmJv-sgykTcxOcovQEPQ51345QLFrNuaNGicr_klxAcg0tCjcTsnQTfDw-gspGIhGpSDL-DbdTOP0VJC9whaERGn8Y7ikGU7Ntwwd2qlmfOtVW6adVuYVsA/s320/boss1.gif" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Wierdly both components looked and tested out fine. I also did some tests on the power socket in case there was an issue there - all checked out fine...</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I was at a bit of a loss so did a bit more searching online and found this interesting article</div>
<div class="separator" style="clear: both; text-align: left;">
<a href="http://stinkfoot.se/archives/726" target="_blank">http://stinkfoot.se/archives/726</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So actually, BOSS's ACA240 supply, labelled 9V DC actually puts out an unregulated voltage that is more like 12V DC and the diode and resistor are a little kludge to reduce the voltage seen by the pedal electronics! Who knew it? I guess it did not hurt BOSS's sales of their own pricey supplies either when generic 9V supplies wouldn't work with the pedal (and don't get me started on the plug polarity...). </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Back to task in hand... to run the pedal on a proper regulated 9V supply I simply jumpered over D1 and R1 to remove them from the power circuit. This is easily done by bridging pads labelled 2 and 3 on the PCB using a short piece of wire</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmd_UcE0m2YOphhWjbYXJ8v2gUDj0Jtkv9msUKAjSFZw3SBYp1uXoJRjeKrdz50-tFG7XbCsBx_AepREiMBuyGcPM0SGUXICborZcFi-qRiRNB6fcB7rIVL6Rh4OvprOgLB5dw1E4WU8A/s1600/P1010027.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmd_UcE0m2YOphhWjbYXJ8v2gUDj0Jtkv9msUKAjSFZw3SBYp1uXoJRjeKrdz50-tFG7XbCsBx_AepREiMBuyGcPM0SGUXICborZcFi-qRiRNB6fcB7rIVL6Rh4OvprOgLB5dw1E4WU8A/s320/P1010027.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQMnhyphenhyphenh6_67nw8Rh6sMsMY1n7OxLU4Y-s3kAYLrHVjufU6EFgEM8BmOj0ThpsqGVYAdBTkwLyzkIoM1JjGd7gQimaIlCZKkBNE7V4etULMTXImUHRpgTy96AjW_D-lqc60-r8T8XSI-xU/s1600/P1010028.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1200" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQMnhyphenhyphenh6_67nw8Rh6sMsMY1n7OxLU4Y-s3kAYLrHVjufU6EFgEM8BmOj0ThpsqGVYAdBTkwLyzkIoM1JjGd7gQimaIlCZKkBNE7V4etULMTXImUHRpgTy96AjW_D-lqc60-r8T8XSI-xU/s320/P1010028.JPG" width="320" /></a></div>
<br />
The pedal now works a treat and I'm glad I held off leaving eBay feedback on this till now, since its actually in perfect working condition! I think a lot of older BOSS pedals (those labelled for use with ACA supply rather than PSA supply) can benefit from this little hack (but make sure you check the schematic of other pedals first before assuming the pads are labelled the same!)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzue7bm5GJkFGp6BhnaYFe7CO7ahZg-OZ8O9DP0gca4fcQ-pkHr5BRSmeEER-wWBEQRBIkrZ2-LloKnM0ZpuxzRYx0b1cr3byeNhQPwjLWavRN4wcV3OantrGFl2uKGFAa37ShFVPLUbw/s1600/P1010029.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="823" data-original-width="653" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzue7bm5GJkFGp6BhnaYFe7CO7ahZg-OZ8O9DP0gca4fcQ-pkHr5BRSmeEER-wWBEQRBIkrZ2-LloKnM0ZpuxzRYx0b1cr3byeNhQPwjLWavRN4wcV3OantrGFl2uKGFAa37ShFVPLUbw/s320/P1010029.JPG" width="253" /></a></div>
<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-51162458903267699392017-03-17T16:16:00.000-07:002017-03-18T16:31:31.943-07:00Cassette Player Hack! CV Pitch Control<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
A little while back I decided to have a play experimenting with cassette recorders; making tape loops etc, and I got on ebay looking for a cheap player (having junked all the ones I owned years ago). I got quite lucky finding a job lot of FOUR identical Panasonic players for just over £20 for the lot!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Not only that but I found there is a service manual online complete with schematics and all kinds of lovely technical info</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6dkAEEIaRT7DVSdJsxoS-cAtyCg3w3yZZ0AUIPVyEjkH8jojKkAeoypGPz0Jx-1w7ihDX0NbeNbxFtqkkD9-qpyFXVTmiS21uHlLqOeOj-8Zbi-XUOeuIuNAZuqhfRlhASc_88CE3Ieo/s1600/cass.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="290" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6dkAEEIaRT7DVSdJsxoS-cAtyCg3w3yZZ0AUIPVyEjkH8jojKkAeoypGPz0Jx-1w7ihDX0NbeNbxFtqkkD9-qpyFXVTmiS21uHlLqOeOj-8Zbi-XUOeuIuNAZuqhfRlhASc_88CE3Ieo/s400/cass.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For my first experiment I wanted to add a pitch control, and it actually turned out to be easier than I expected!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Q29xBvHBCP0/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/Q29xBvHBCP0?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
In this player, when one of the buttons on the player is pressed, a switch supplies power at 6V to the motor. There doesn't seem to be any electronic speed control of the motor, and I think the faster FF/Rewind speed is implemented via gearing and mechanical ratio selection. Therefore all I needed to do was find some way to slow down the motor!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Doing this by reducing the motor voltage or current directly is a bit tricky - for example putting a potentiometer in series with the motor would not be a good approach as the pot would need to dissipate a lot of power and would likely get hot and the carbon track would soon burn out. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Instead, the usual way of doing this type of speed control is to use Pulse Width Modulation (PWM) and some kind of electronic switch (e.g. a transistor). If you know synths, chances are you are familiar with PWM as a means of modulating a square wave to get a phasing kind of effect. What PWM does to a waveform is change the width of the "peaks" of a square wave relative to the "troughs" while keeping the frequency the same. As well as changing the audio character of the wave, PWM allows you to change the overall time a the square wave is "ON" vs "OFF" and therefore how much power the wave transfers averaged over time.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So lets say we feed the PWM'd square wave into a motor, the motor will spin faster as the proportion of time the power is ON vs OFF is increased. Therefore by controlling the PWM "duty cycle" (as this ratio is called) we can control the motor speed.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
There are various ways to make a PWM signal, and the first thing I used was a circuit using a 555 timer chip (rather like this http://www.instructables.com/id/Simple-and-dirty-Pulse-Width-Modulation-PWM-Wi/). To actually drive the motor I didn't feed the oscillator output directly into the motor but instead fed it into the base of a TIP115 transistor (PNP Darlington Type), which was placed in series to the cassette motor positive wire (high side). This means the oscillator activates the transistor which then does the switching (as this is a PNP transistor, the switch is actually ON when the oscillator output is LOW)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This worked nicely and let me work the tape speed using a potentiometer to control the oscillator duty cycle. The frequency of the PWM carrier needed to be quite low for the motor to rotate rather than just whining). I went for about 70Hz.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Rather than a pot, what I really wanted was to be able to control the speed using a 5V CV (control voltage) signal which I can generate from a music sequencer. When I put +5V to the CV input I want the motor to run at normal speed. 0V should stop the motor. +2.5V should run at half speed (ideally). You get the picture...!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I could have done this with a 555 but it seemed like it might be hard to get a suitable circuit that would work right at the extremes (i.e. support 100% and 0% duty), plus I had a load of PIC12F1822 microcontrollers and know them really well (and they are same size as the 555) </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
So I ended up with the following circuit (click to see full schematic)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgivp5-BHCyeMWbBl1nH_qkXQgb8P3WgkpuDx-KQPfG6kYIvlXxmO5u2G1NFSbPa4PJwdor-R0eTb4qF10QjFIXOrylzAkUo03ou9Hhj_xXTSCR9LNwP-xDG4JwejuwTt83PaYPNMgi-VA/s1600/schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgivp5-BHCyeMWbBl1nH_qkXQgb8P3WgkpuDx-KQPfG6kYIvlXxmO5u2G1NFSbPa4PJwdor-R0eTb4qF10QjFIXOrylzAkUo03ou9Hhj_xXTSCR9LNwP-xDG4JwejuwTt83PaYPNMgi-VA/s640/schem.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
The motor wires are shown at the right. The transistor (actually TIP115) is placed in series with the motor. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The two diodes on the top right are 1N4001's and are there to drop off some of the 6V motor power voltage so that it is below the 5.5V limit of the PIC supply. The circuit is powered from the motor power supply so it powered only when a key is pressed on the player.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The diodes on the left are 1N4148 and clamp the incoming CV to the PIC power rails. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
R2 limits clamped CV current and I used 1k but it could be higher (e,g. 4k7). I soldered R2 directly to the socket, so it is not on the stripboard. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
I used a 100k Linear pot for the manual control with a 3.5mm jack that breaks the connection to the pot and overrides with external CV input. JP1 is a programming header.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The box in the middle is the PIC12F1822 microcontroller (DIP-8). Of course this a microcontroller based project, which is nothing without firmware! I'll include the firmware source below. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The firmware works by having a loop in code actually do the PWM cycle (since I only want it to run at 70Hz there is no need to use the specialised PWM peripherals on the PIC). While the PWM cycle runs, the PIC's analog to digital converter (ADC) gets a 10 bit value from the CV input. I simply take the top 8 bits of the ADC reading and put them into my duty cycle variable.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
On each PWM cycle the transistor is ON when the cycle starts and goes OFF when the duty counter (controlled by CV) is reached. So a lower CV will mean a shorter duty cycle.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Since the motor is switched on the high side, I need a PNP transistor. To turn the transistor ON I need to draw current from the transistor base (I think of the 'P' in PNP as 'pulling' a current out of it to switch it on - hmm yeah I know there's a 'P' in NPN too - shut up! :) </div>
<div class="separator" style="clear: both; text-align: left;">
So to turn on the transistor the PIC output PIN is set to a LOW output voltage so it can sink current from the transistor based. However since the PIC output pin will have a HIGH voltage lower than the transistor emitter (since PIC is powered at < 5.5V) that wont cut off the transistor. Therefore I switch the transistor during the PWM cycle by alternating the pin between output mode (with LOW state) and input mode (High impedence) where no current is sunk by the pin.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Conclusion : This is the only cassette player I've modded so far, but I am pretty sure that the same principle should be applicable to other players. One key fact with this one is that the low side of the motor is grounded, so I can power my circuit using the voltage difference between the motor supply and ground. I needed to make sure the motor voltage would not damage the circuit - in this player it is 6V so a couple of silicon diodes in series can drop this down into a safe voltage for the PIC (each diode drops off something like 0.4V)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Something else I did was to remove the erase head - this is because I want to use loops of tape and be able to record and overdub loops on the same player. An erase head will always leave a sound gap in a loop (corresponding to the physical gap between the erase and record/playback heads) and will prevent overdubs. In this player the erase head was a simple permanent magnet on a plastic arm which can simply be unclipped without damaging it (great if I need to erase anything later)</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The tape I used is an answering machine outgoing message loop - works well but is quite long (30 seconds at normal speed). I might try making my own loops so they can be a bit shorter</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
This approach can only slow a tape down, not speed it up. I think you can only speed the tape up (at least using the same motor) by increasing the voltage, which might have consequences for other parts of the player circuitry. I think I prefer the effect of slowing playback right down to flappy graininess than speeding it up, but there is always the option of recording at slow speed to allow playback at faster speed.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVFuzUJoVNiv6mdgyvfPhjzsHTbq1bDCR6TLOHJ1pcmcmWQZ3LUeuyH6SkdQaTjhcFFl_9uCyReMUz9JK-hm81LBDik3cn2Si7ijnVUmMqH-EYrBGlTFkzzZrVUocz8jELEVVU-XTl1-Y/s1600/DSC04850.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVFuzUJoVNiv6mdgyvfPhjzsHTbq1bDCR6TLOHJ1pcmcmWQZ3LUeuyH6SkdQaTjhcFFl_9uCyReMUz9JK-hm81LBDik3cn2Si7ijnVUmMqH-EYrBGlTFkzzZrVUocz8jELEVVU-XTl1-Y/s320/DSC04850.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">First look inside</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfVkboY-5sUj0kkaEDGdPdCpdl8ybFoMP8G6zoulhtbTIXkEpGCym6UiMAENvGl_3Ql5WkUGzChdW0T6J0zzji2nOVyoXSQz9kMWc99t-EqxQDVqMShdCESJokSg6BFtUb8TLH1i5TaYU/s1600/DSC04853.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfVkboY-5sUj0kkaEDGdPdCpdl8ybFoMP8G6zoulhtbTIXkEpGCym6UiMAENvGl_3Ql5WkUGzChdW0T6J0zzji2nOVyoXSQz9kMWc99t-EqxQDVqMShdCESJokSg6BFtUb8TLH1i5TaYU/s320/DSC04853.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Simple 6V DC motor with grounded low side - nice!</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEttu126xCtjO222QWY0dkvZYMCi0BFiT7A_k5mx8ADQWThcpl6UQcJ5s6k_S_4e8vp1mCu_b1YWfj0wDdJeWVayeCNQThUN2RvbhWFWV_rz8m0YkkQMTwdyjETLTjDv1nQO-Am79itk0/s1600/DSC04854.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEttu126xCtjO222QWY0dkvZYMCi0BFiT7A_k5mx8ADQWThcpl6UQcJ5s6k_S_4e8vp1mCu_b1YWfj0wDdJeWVayeCNQThUN2RvbhWFWV_rz8m0YkkQMTwdyjETLTjDv1nQO-Am79itk0/s320/DSC04854.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding the wires to transistor and ground wire</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhega_SZeRWvgu0eRDyrLAJtldDDaIvp09pJ3FxpnIjIfXkTL3AzKo0mjhlFzGwYW-lFFoCABbgBrYYm1TZnxIfd8lIh49plX2Q99SgqV_wzo4hdc3voHxVb1LHFbXDMEV-8J1dMObLLqM/s1600/DSC04859.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhega_SZeRWvgu0eRDyrLAJtldDDaIvp09pJ3FxpnIjIfXkTL3AzKo0mjhlFzGwYW-lFFoCABbgBrYYm1TZnxIfd8lIh49plX2Q99SgqV_wzo4hdc3voHxVb1LHFbXDMEV-8J1dMObLLqM/s320/DSC04859.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The control circuit (will eventually be fitted inside player case)</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
The firmware source code - I am using SOURCEBOOST C but I think it should be fairly easy to port to other compilers or microcontrollers</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">#include <system .h=""></system></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">#pragma DATA _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _MCLRE_OFF &_CLKOUTEN_OFF</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">#pragma DATA _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _BORV_19 & _LVP_OFF</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">#pragma CLOCK_FREQ 16000000</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">typedef unsigned char byte;</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">void main()</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">{</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // osc control / 16MHz / internal</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> osccon = 0b01111010;</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // configure analog input AN3 enabled</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>ansela = 0b00010000;<span class="Apple-tab-span" style="white-space: pre;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // turn on the ADC</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // ADC clock is Fosc/32</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // Result left justified (8 bit value in adresh register)</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> // Voltage reference is power supply (VDD)</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> adcon1=0b00100000; //fOSC/32</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> adcon0=0b00001101; // Left justify / Vdd / AD on // AN3</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><br /></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>byte count = 0;</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>byte duty = 0;</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>delay_ms(250);<span class="Apple-tab-span" style="white-space: pre;"> </span>// delay to allow settling of power supply before starting to drive motor</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> for(;;) {</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(count == duty) {<span class="Apple-tab-span" style="white-space: pre;"> </span>// end of duty cycle (or start of zero duty cycle)</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>trisa.2 = 1; // set drive pin as input (high impedence, floating)</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>else if(!count) { <span class="Apple-tab-span" style="white-space: pre;"> </span>// start of duty cycle when 8 bit count rolls over</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>lata.2=0;<span class="Apple-tab-span" style="white-space: pre;"> </span>// drive output pin LOW to sink current </span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>trisa.2 = 0; // and enable pin output mode</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(!count) {<span class="Apple-tab-span" style="white-space: pre;"> </span>// at start of duty cycle we store the previous ADC result and </span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>// kick off a new ADC reading</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>duty = adresh;</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>adcon0.1=1;<span class="Apple-tab-span" style="white-space: pre;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span class="Apple-tab-span" style="white-space: pre;"><span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> </span></span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>++count;<span class="Apple-tab-span" style="white-space: pre;"> </span>// duty cycle count (just allow 8 bit value to roll over to 0)</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"><span class="Apple-tab-span" style="white-space: pre;"> </span>delay_us(50);<span class="Apple-tab-span" style="white-space: pre;"> </span>// delay gives ~50-70Hz carrier</span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;"> } </span></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="font-family: "courier new" , "courier" , monospace; font-size: xx-small;">}</span></div>
<div style="text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com5tag:blogger.com,1999:blog-8909459762367220480.post-51086413503625549882017-03-14T14:13:00.000-07:002017-03-14T14:15:59.745-07:00Calculator MusicWhen I was about 10, I really wanted a synthesizer! This was the start of the 80's and the cheapest synths probably cost about the same as cars or something. At 10 I didn't know anything about trying to make my own one, but I did discover that my stepdad's snazzy calculator would interfere with the radio.. and the buzzing tones it made changed pitch depending what combinations of keys I pressed ... .AWESOME!!! A SYNTH!!!!<br />
<br />
Having got back into making weird noises over the last few years, I decided to try and recreate this formative experience. I racked my brain trying to remember what that calculator looked like - I thought it was a Texas Instruments one, and after a look at the Datamath Calculator Museum (http://www.datamath.org/) I got a little ping of recognition when I saw the TI-2550 (actually it was the number I remember - the calculator itself I remember looking very snazzy, compact and futuristic not like the clunky brick I saw online :-) And there was a reasonably priced one going on eBay!!<br />
<br />
So here is the result - I think my expectations of synthesizer capabilites are rather higher these days - in my memory it wasn't restricted to about 3 notes or drowning in static, but here we go - it might still be interesting. I used a Moog MF Drive pedal for the distortion/lowpass (to try to make the static less harsh)<br />
<br />
The pitch seems to be generated by RF interference from the keyboard matrix scanning and changes depending on the number of keys (and which keys) pressed together. It shows up in medium wave AM band. Tuning around changes the timbre of the sound but it still only ever manages about 3 notes plus an open drone - but just look at all that crazy stuff happening on the display!!!<br />
<br />
I will probably open this up and see if I can get more sounds going on with it - I am wondering about bringing the display multiplexing into it - the refresh seems slow so maybe it can be played out at audio frequency - I wonder if the display signal can be fed back into the keyboard matrix scanning to get some crazy feedback loop going...?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/AsJcLnUppW0/0.jpg" src="https://www.youtube.com/embed/AsJcLnUppW0?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-56388238240689301802017-02-27T02:37:00.004-08:002017-02-27T05:15:23.250-08:00Meet the WOBATRON<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/N59dmpDMgM8/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/N59dmpDMgM8?feature=player_embedded" width="320"></iframe></div>
<br />
LED matrix displays are everywhere... I've made and used them in many projects. Typically the rows and columns of the display are driven by components called "shift registers" usually with eight outputs controlled by "shifting" in data, one bit at a time. when a "store clock" pulse is received all the data can be moved on to the output pins, lighting up a set of LEDs.<br />
<br />
Using a microcontroller (i.e. a computer chip), information can be loaded onto the display shift registers one row at a time and used to show text and so on. Most displays work by "multiplexing" the rows so that there is only one row lit at a time, but the persistance of vision of our eyes makes it seem that all the rows are on at once.<br />
<br />
A few weeks ago I was inspired by a chat with a friend (Brighton sound artist Lorah Pierre) to see what would happen if random noise signals were fed into the shift registers controlling the matrix instead of the usual orderly data from a computer. The easiest way to test that is simply to power it up and touch the data input wires! Stray electrical noise is enough to make the display think its getting data and for things to happen on the LEDs...<br />
<br />
The next step was to try it with something a bit more controllable. I did some experiments with an LED matrix I'd already made for another project and LOVED the results, so I decided to make something a bit bigger and more flexible especially for the purpose.<br />
<br />
The WOBATRON is an LED matrix made up of 16 x 16 white, 0.5W 8mm LEDs. These are fitted into a laser cut grid on a "honeycomb" pattern (which I though would look cooler than a square grid). The LED mounting sheet is 5mm acrylic with another sheet of 5mm acrylic in front, cut with the hexagonal baffles. The front diffuser is 3mm frosted blue acrylic.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIJ3IAVLSkdPs72GY6pDlu0tsHxaKS3ocgisRZ4SYafnl1V435XYDgIK7GLE4vGn6zMuxOncFOscHR0BUJ4AP7KXPz5fYo4zv1hDFBiRC76zu4Nuyjo__NA6pvehOWVx1rKXb0g46Z4hQ/s1600/DSC04482.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIJ3IAVLSkdPs72GY6pDlu0tsHxaKS3ocgisRZ4SYafnl1V435XYDgIK7GLE4vGn6zMuxOncFOscHR0BUJ4AP7KXPz5fYo4zv1hDFBiRC76zu4Nuyjo__NA6pvehOWVx1rKXb0g46Z4hQ/s320/DSC04482.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Baffle construction</td></tr>
</tbody></table>
<br />
The LEDs are wired in a grid. Every LED has a 100 ohm series resistor (Since the rows and columns are not going to be multiplexed. I didn't want to share current limiting resistors between LEDs).<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizClKfWsatNcvuXDtF-hZhMuR1DDZ1BcpBpYE5rKrtpNUI6GcaUSoTt-aU-orP3MtxIh7StPm7gpPLgX3UY82O76hecAO3MZLG4Bp7z40KqqJYK-AVxFF0y7oBcp2W7hfyj7d_jYMfj6U/s1600/DSC04478.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizClKfWsatNcvuXDtF-hZhMuR1DDZ1BcpBpYE5rKrtpNUI6GcaUSoTt-aU-orP3MtxIh7StPm7gpPLgX3UY82O76hecAO3MZLG4Bp7z40KqqJYK-AVxFF0y7oBcp2W7hfyj7d_jYMfj6U/s320/DSC04478.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Matrix wiring</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTyx1Yz4DjfjqAOQIodkel9qoYcrYSEqg7kMm1eeX8qK0z6rhEBG8e77nt0NwXXBB8z-gBMijRndhC-QAMSDcho_H7FDT-6OJ4dJAXDnDzmGnbffuHT4ZQMFd4JQMkw-WlcS43WzDoZfE/s1600/DSC04721.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTyx1Yz4DjfjqAOQIodkel9qoYcrYSEqg7kMm1eeX8qK0z6rhEBG8e77nt0NwXXBB8z-gBMijRndhC-QAMSDcho_H7FDT-6OJ4dJAXDnDzmGnbffuHT4ZQMFd4JQMkw-WlcS43WzDoZfE/s320/DSC04721.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Driver boards for matrix</td></tr>
</tbody></table>
The rows and columns are driven by transistor arrays (2 x ULN2803 on low side, 2 x A2982 on high side). These are driven by 74HC595 shift registers with the following signal inputs going to the control box where they are broken out to 4mm sockets.<br />
<br />
<ul>
<li>Column drive data line, shift clock line, store clock line</li>
<li>Row drive data line, shift clock line, store clock line</li>
<li>Output enable (pulled down when not connection) to allow display blanking</li>
</ul>
<br />
In the control box is a 74HC14 hex inverter chip which is used to create six individual square wave oscillators with frequency pots (100k with 1k resistor in series). Four are "high frequency" with 0.1uF capacitor, then two are lower frequency oscillators with 10uF and 4.7uF capacitors. All these six outputs go to 4mm sockets so they can be patched to the display signal inputs with external leads. There are 4k7 resistors inline with the outputs as to allow signals to be mixed together and to prevent problems due to outputs being shorted together.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1kUYsSf12D7zCKXuDqRZ25J8iwv9rbpj_8Z70fq4Mar1YKeVPS3QPePla9Aqu-C5I5TgtJMIh9ylP2ZyISYicwD7r0bFla_JiUqPnNifbYTSXUDFe9fCWlBQQ19hAWQlXW9ff09eNL5k/s1600/DSC04735.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1kUYsSf12D7zCKXuDqRZ25J8iwv9rbpj_8Z70fq4Mar1YKeVPS3QPePla9Aqu-C5I5TgtJMIh9ylP2ZyISYicwD7r0bFla_JiUqPnNifbYTSXUDFe9fCWlBQQ19hAWQlXW9ff09eNL5k/s320/DSC04735.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Control box with patch cables</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5QZzxPSesotKoyKvFDbGazhisFnxo4lvJ2amdhTtYwCQJGS4da9b5M6Lr5QgeFEk7KI2jtxuwXaEqUdITkLm33xrDCOvA2QCDT36DJ57wX3nNZx4Pi32YBBE4OWWGmqEe38nHJhfKiAY/s1600/DSC04728.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5QZzxPSesotKoyKvFDbGazhisFnxo4lvJ2amdhTtYwCQJGS4da9b5M6Lr5QgeFEk7KI2jtxuwXaEqUdITkLm33xrDCOvA2QCDT36DJ57wX3nNZx4Pi32YBBE4OWWGmqEe38nHJhfKiAY/s320/DSC04728.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Control box circuit</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Two of the oscillators also feed a pair of "linear feeback shift registers" (LFSRs). These are clever little circuits that work by feeding data into a standard shift register that is an exclusive OR function of some of its outputs. By some clever mathematical jiggery-pokery that is beyond me, it is possible to set this up to that the outputs of the shift register will cycle through all the 255 (exclusing 0) possible combinations of 8 bits, in a "random" order (of course its not random, it repeats time after time, but it is far from sequential)<br />
<br />
I think these are the best bit of the control box, since they allow for some very complex (but repeatable) signals to be generated, which give the best patterns on the display!<br />
<br />
I wanted to be able to control the "density" of this signal, so I put the 8 bits of the output into an R-2R DAC. This is another simple but clever circuit which does a binary addition of the 8 output bits of the shift register to generate a voltage level, just using a network of resistors of 2 values. This circuit is found inside most Digital to Analog Converters.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYb0MY8cFnyuwYVTF1dsaluKiw-r48QDzjcawCt1Om2zOLko4IGmMPQW-Cbj3yV_wt7cciUj5Dxzx6VlAfPTgn_Hlkvd9UMoL1oSze5-29o_JRyxAAAZeuxoDstYXgwExxLZJPLDjP6YE/s1600/DSC04737.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYb0MY8cFnyuwYVTF1dsaluKiw-r48QDzjcawCt1Om2zOLko4IGmMPQW-Cbj3yV_wt7cciUj5Dxzx6VlAfPTgn_Hlkvd9UMoL1oSze5-29o_JRyxAAAZeuxoDstYXgwExxLZJPLDjP6YE/s320/DSC04737.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Output from R2R DAC fed by LFSR</td></tr>
</tbody></table>
<br />
Once I had an analog voltage level, I can compare it with a reference voltage (from a 100k potentiometer connected across the power rails) using an op-amp as a comparator. When the DAC output exceeds the voltage dialled up on the pot, the comparator output is HIGH. Since the DAC output is a "random" sequence varying over the whole voltage range, changing the comparator reference voltage allows the pot to dial up a "density" of HIGH values on the comparator output. This works well when fed into the data lines of the display.<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHYuq4iAYa4SpZl-XwtAZVO6Zo2-FWjNGWiE8p7FFb1QNKoAqjHOtCgpwligpZC0x6jvjzPWbnzxT0NDN_cn_6ItcnpwnlJvzzwljPLeqovnjhHdaF-Mvw-4kIzALZBNwFmwWYURXPY1o/s1600/DSC04738.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHYuq4iAYa4SpZl-XwtAZVO6Zo2-FWjNGWiE8p7FFb1QNKoAqjHOtCgpwligpZC0x6jvjzPWbnzxT0NDN_cn_6ItcnpwnlJvzzwljPLeqovnjhHdaF-Mvw-4kIzALZBNwFmwWYURXPY1o/s320/DSC04738.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Pulse train after comparator stage</td></tr>
</tbody></table>
<br />
The two comparator outputs (one from each LFSR-DAC-comparator circuit) also go to a pair of output sockets.<br />
<br />
Now if an LFSR is in a state where all its output bits show zero, a zero will be fed back into it, so the sequence will not advance. When the circuit is powered up, there is a chance one or both LFSRs will be "stuck" in this state. To get around this there is a push button that will pull the LFSR inputs HIGH while pressed to get the LFSRs going if they are stuck.<br />
<br />
I really love playing with this build! I could twiddle the knobs and stare into the display for hours (and I have done :). Its really hypnotic and trippy, especially when the oscillators are audible too (i just mix the signals through 100k resistors and feed to a mono audio output)<br />
<br />
Despite the simple inputs, there are a lot of interactions possible between the signals that produce results that can only guessed at! Close frequencies which are mixed will produce beating, the shift registers "chop" the signals by sampling data inputs based on shift clock inputs and there is a kind of second order to this where the store clock is used. Then there are stroboscopic effects possible with the blanking input. I am sure I have only scratched the surface of what might appear at certain settings!<br />
<br />
Here is a schematic of an earlier noise matrix build. The new one is very similar except the display is driven with transistor arrays on both the high and low sides and each LED has a series resistor. There are also now 6 oscillators and two noise generators, with all the signals patchable to matrix.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS97tI4ovbUOmySMjmBFg50PNdzW-A9ef0mViCrkHVwjrOxDlZAYGLMDu_LNzj4aTLhG5KXGOF47Aq68iia36g-yhdPqM-1tRdc6q9YgcEOLfiwfRx54nPNA4o54RgUZV2d-n-0PY8FiQ/s1600/matrix.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS97tI4ovbUOmySMjmBFg50PNdzW-A9ef0mViCrkHVwjrOxDlZAYGLMDu_LNzj4aTLhG5KXGOF47Aq68iia36g-yhdPqM-1tRdc6q9YgcEOLfiwfRx54nPNA4o54RgUZV2d-n-0PY8FiQ/s320/matrix.png" width="320" /></a></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com2tag:blogger.com,1999:blog-8909459762367220480.post-5003543020145639532015-09-27T13:53:00.001-07:002015-09-27T14:07:11.659-07:00Novation Release Custom Firmware API for Launchpad Pro!The Novation Launchpad music controller has been around for several years in various form; it is a USB MIDI grid controller which is primarily designed to work with the Ableton Live program but can also be used as a MIDI controller on its own.<br />
<br />
I am not a user of Live but I have always seen the potential of the Launchpad as part of a standalone MIDI sequencer, like a cheaper Monome. I bought my first Launchpad years ago and immediately got to work writing code to run against it.<br />
<br />
The original Launchpad showed up as a MIDI device (assuming you have Novations drivers installed) and you could open it using your programming language of choice (I was using C++ on Windows MIDI API).<br />
<br />
Then when you press buttons you receive MIDI messages (notes for the grid and CC's for the menu buttons). Sending the same messages back to the controller turns the lights on and off. And it is pretty much that simple!<br />
<br />
My real aim was to get something that could run MIDI sequencers that were not tied to a PC, so I started looking at USB hosting from a microcontroller. The original Launchpad was not USB MIDI class compliant (that came with the Launchpad S) but used a custom interface based on interrupt endpoints. I pulled the descriptors and used an FTDI VNC2 USB host chip to implement sequencer sketches, which did work, but I had some issues with the early versions of FTDI's toolchain for the VNC2 and kind of ran out of steam.<br />
<br />
Later on I started working on an Arduino shield where the VNC2 would just have the USB hosting duties, with the Arduino running the sequencer sketch. That project is still in the pipeline, but what I always thought to myself what would be REALLY good is if Novation opened up the Launchpad with a firmware API so developers like me could actually load custom firmware for sequencers, etc, into the Launchpad itself (in fact I've been wishing the same for lots of musical hardware – are you listening Arturia, Korg etc.. :)<br />
<br />
Anyway just last week I heard that they have actually gone and done it a couple of months back, with a custom firmware API for the Launchpad Pro!!! I immediately had the credit card in my hand and was unpacking a brand new Launchpad Pro the next day.<br />
<br />
Check out the API here<br />
<a href="https://github.com/dvhdr/launchpad-pro" target="_blank">https://github.com/dvhdr/launchpad-pro</a><br />
<br />
I can't quite express the awesomeness of this move my Novation!!! OK it may be a pretty niche thing right now, but I hope it sets a precedent where a creation of custom firmwares for these types of device really takes off.<br />
<br />
Anyway, I got started trying to make a version of one of the sequencers I originally built on the original Launchpad and the FTDI VNC2.
Novation 's API provides a simple set of callbacks that you implement in your “app”. These are an initialisation routine and handlers for incoming MIDI messages, button presses etc. Plus there is a simple set of hardware abstraction functions for controlling the lights behind the buttons, sending MIDI etc.<br />
<br />
The architecture is 32-bit ARM and Novation helpfully provide a Ubuntu Virtual Machine image of a configured development environment using Eclipse and GNU C for ARM. A default firmware project is provided which it is pretty easy to start playing with. The make process invokes a utility to convert the output HEX files into a MIDI SYSEX which can be sent to the Launchpad Pro over USB.<br />
<br />
In order for the device to take new firmware it needs to be set into a bootloader mode (by holding the Setup button when powering on). I quickly discovered an issue; after uploading custom firmware, the Launchpad was not enumerating as a USB MIDI device any more (in fact it was lost to USB until put back into bootloader mode). After trying to work out what I was doing wrong, I contacted the Novation development team via Github and raised an issue which they have acknowledged and will hopefully soon fix.<br />
<br />
Luckily the LPPro does have a “real” MIDI connection in the form of a pair of 3.5mm jack sockets which break out to standard 5-pin MIDI connectors via supplied cables. This “hard” MIDI connection does work, so I have been able to use this for now to get output from my sketch to play an external synth.<br />
<br />
When you load new firmware into the LPPro you are actually replacing the factory firmware. The SYSEX file for the factory firmware is supplied with the SDK so you can easily switch back to it, however there is no source code available for the factory firmware. Maybe this is not so surprising, but it does mean you have to take an “all or nothing” approach to customising the LPPro. There is no option to “tweak” the factory functionality without rewriting it yourself first! I hope Novation address this – maybe it would need the high level functionality of, say, the factory “drum” and “note” modes to be ported to the custom firmware API so the source for those could be released for customisation without having to open up all the proprietary low level stuff.<br />
<br />
I am using a Windows 7x64 machine and I did find that sometimes the VirtualBox VM / VAGRANT package was getting in a funny state such that my VM login could not access the source code projects in Linux (probably something I was doing wrong). Also there was the annoying need to copy the output SYSEX file from VM out to host OS on every build so I could upload it to MIDI. I eventually decided to install the GCC-ARM compiler and Eclipse IDE natively on Windows, but that was not too hard and Novations VM package was invaluable to see how the setup should work.<br />
<br />
Another thing that gets a bit tiresome is the procedure for putting the LPPro into bootloader mode (a process which needs a manual power cycle of the LPPro and needs USB to re-enumerate, so the LPPro device needs to be re-selected in MIDI-OX before the SYSEX can be sent). When debugging you do this a lot and it gets annoying, not to mention putting extra wear and tear on the power switch.
A nice feature would be a special SYSEX command to put the LPPro into bootloader mode without a power cycle and ideally without any USB re-enumeration. Then the SYSEX loader could set bootloader mode before uploading and all the steps included in a makefile (maybe this bootloader command could be “unlocked” via a physical button combination if there is a worry about unwanted firmware updating)<br />
<br />
Anyway, I am not going to complain any more. I applaud Novation for releasing this API and I hope other manufacturers of music and/or other devices follow suit. Interesting times!
<br />
<br />
This is my first sequencer project, I expect to be doing lots more like this over the coming weeks and months :)<br />
<br />
You can get my code (forked repo) here<br />
<a href="https://github.com/hotchk155/launchpad-pro" target="_blank">https://github.com/hotchk155/launchpad-pro</a><br />
<br />
Or if you just want the sysex<br />
<a href="https://github.com/hotchk155/launchpad-pro/blob/master/build/launchpad_pro.syx" target="_blank">https://github.com/hotchk155/launchpad-pro/blob/master/build/launchpad_pro.syx</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/OWO5yih11nE/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/OWO5yih11nE?feature=player_embedded" width="320"></iframe></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com3tag:blogger.com,1999:blog-8909459762367220480.post-83543461216270000082015-08-24T01:43:00.001-07:002015-08-24T01:43:46.474-07:00Hammer Pong's Last Stand?After several months in storage, Hammer Pong is coming back out for a final moment of glory at the <a href="http://makerfairebrighton.com/tag/bmmf/">Brighton Mini Maker Faire on 5th September </a>
Then unfortunately it'll be stripped down for parts... unless you want it?
<a href="http://www.ebay.co.uk/itm/-/151790857896?">http://www.ebay.co.uk/itm/-/151790857896?</a>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-73665982733245664422014-11-29T12:44:00.000-08:002014-11-29T12:44:24.738-08:00A mini mixer for my lovely VolcasI heart the Korg Volca range! If you don't know them already then, chances are you never will, however - they are a set of self-contained, affordable and (mostly) analog synth/sequencer modules. There is a drum machine, 303-ish bassline synth, and a versatile 3-voice synth (they tease us with a currently unavailable sampler unit too). I love 'em .... but this isn't a review of them so Google as required..!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl6MdZDurK_xsdwDOTz_UEmL4Yc4fisYwV-Mnjr-7Z7YmBOxP70LV7oZyMKtVqgNRlexmA9USgbfgrmls3SH-qtCirygxlx9H1MEOnASMv2tWwrUctl_RPh7Tgi-xTEfibuldD3tgp2wc/s1600/DSC06431.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjl6MdZDurK_xsdwDOTz_UEmL4Yc4fisYwV-Mnjr-7Z7YmBOxP70LV7oZyMKtVqgNRlexmA9USgbfgrmls3SH-qtCirygxlx9H1MEOnASMv2tWwrUctl_RPh7Tgi-xTEfibuldD3tgp2wc/s1600/DSC06431.JPG" height="240" width="320" /></a></div>
<br /><br />
Anyway, if you have Volcas you'll need some kind of mixer to combine their audio output for your listening pleasure, Even if you do have one (and I do own a Mackie mini mixer) the spontaneous mini-scratchpad style of the Volca's really needs something simple and lightweight that does not take a lot of setting up, so I decided to make my own passive mini mixer that I could keep set up with my Volcas. I keep my Volcas set up on a guitar pedalboard case so I wanted something I can keep, ready to roll, in there too.<br />
<br />
A simple passive mixer would do trick (i.e. just a bunch of sockets and resistors with no power needed) and a Hammond diecast aluminium stompbox enclosure would fit nicely in my setup.<br />
<br />
I used stereo sockets, pots and wiring - although I think the Volcas are all mono, so maybe I overdid it there, still - it keeps options open. My design has 4 stereo input channels which are combined into a single stereo output. The passive design works pretty well with the Volcas (the outputs are for headphones so they are pretty hot, an active mixer would be wasting time I think)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAKOh7WgtZ4U3z6MWH1e5TujMwedS1vQ1gHIg4JDwVk3bLiqjxycVYyFufW3DgOHpebWg925mtuThHAg5pSY4szboKd9oYjeSNVpW3fJPVWpd8we76UIVA941hKlfcRjqZFJEKP96FAWE/s1600/schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAKOh7WgtZ4U3z6MWH1e5TujMwedS1vQ1gHIg4JDwVk3bLiqjxycVYyFufW3DgOHpebWg925mtuThHAg5pSY4szboKd9oYjeSNVpW3fJPVWpd8we76UIVA941hKlfcRjqZFJEKP96FAWE/s1600/schem.png" height="289" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN4qsE93nLirelmnHZt00ao-i9xA5lpsUCqzAhdk5V2fVliGCfOv_hNVJLWDrb5Z7D9WRiwRpUbAR0tVPSpN_KbFRFbclGrYWr3ZcEW0lXaS8eDejb0zP8ScNo5o9mW8fDb7_zdnd713U/s1600/DSC06420.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN4qsE93nLirelmnHZt00ao-i9xA5lpsUCqzAhdk5V2fVliGCfOv_hNVJLWDrb5Z7D9WRiwRpUbAR0tVPSpN_KbFRFbclGrYWr3ZcEW0lXaS8eDejb0zP8ScNo5o9mW8fDb7_zdnd713U/s1600/DSC06420.JPG" height="240" width="320" /></a></div>
<br />
</br>
I jazzed up the enclosure using a piece of yellow/black 2-layer acrylic laminate which I laser-etched with a lo-fi pic of a good old C-60 (mix tape / mixer, geddit?)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCoqOJEyRVBFyu_b7W7QSf0sa-gdraYWElQGo1OosoCryvT0pFA54BJRCb9Zom3Jb5U60m3tAoGug_CxqDAUyKP6LLUzudjHB0IxYrUtrUyviSHW02TR6WhGFMCJhLS5yUoJf-VAlq1tM/s1600/DSC06419.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCoqOJEyRVBFyu_b7W7QSf0sa-gdraYWElQGo1OosoCryvT0pFA54BJRCb9Zom3Jb5U60m3tAoGug_CxqDAUyKP6LLUzudjHB0IxYrUtrUyviSHW02TR6WhGFMCJhLS5yUoJf-VAlq1tM/s1600/DSC06419.JPG" height="240" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmpCv2rllf9WBWgfnEslj0BNZ0U4Ekv792TkyElPi3b7-iVo0X_dt_Ud3ENmDVEOhBrC2CJHUsm-K2VswMci4Y1WvaifdsoawdPiJuzEvt02jUQQqjEbdLzbmea7JZA-pHx-N9nJQXcZ8/s1600/DSC06436.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmpCv2rllf9WBWgfnEslj0BNZ0U4Ekv792TkyElPi3b7-iVo0X_dt_Ud3ENmDVEOhBrC2CJHUsm-K2VswMci4Y1WvaifdsoawdPiJuzEvt02jUQQqjEbdLzbmea7JZA-pHx-N9nJQXcZ8/s1600/DSC06436.JPG" height="240" width="320" /></a></div>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com15tag:blogger.com,1999:blog-8909459762367220480.post-52734256817382656362014-09-15T13:58:00.001-07:002014-09-15T14:02:04.266-07:00Sound Art and Non-compliant SeagullsJust had an amazing day at the <a href="http://fortprocess.co.uk/">Fort Process</a> sound and art festival at Newhaven Fort!<br />
<br />
It's the first festival I've seen run at the fort, but with its labrynths of tunnels, staircases, passages and caverns it turned out to be the perfect venue. It was rather like being at a mad scientist convention in the dungeons of some Bavarian castle, all resonating with otherworldly chimes, lush drones and earsplitting bursts of static, never being sure what you'll find around the next corner. Often sublime, occasionally ridiculous, sometimes frankly terrifying.<br />
<br />
My involvement was with <a href="http://fortprocess.co.uk/sara-jane-glendinning/">Sara Jane Glendinning's</a> project; The Landing. The concept was that the local seagulls would get involved by landing on a surface made up of sixteen large switch pads on the roof on one of the old gun emplacement towers, enticed by food of course. The pads were set up to trigger arrays of spoken word samples, field recordings and musical sounds when stepped on. These sounds were mixed with the live sound from a microphone on the roof and played to the audience at the base of the tower. A camera on the roof also relayed live images of the pads.<br />
<br />
We used a Teensy (Arduino clone) to read all the switches and send MIDI over USB to a Mac running Propellerheads Reason. And it all seems to be working beautifully... except the gulls didn't want to play ball. We tried chips, fish heads, fish guts, our best gull impressions, but they resolutely stayed hovering high above and didn't come anywhere near our tower. Usually in these parts (or at least on Brighton beach) the gulls will gather round to terrorise any al fresco diner like something out of Hitchcock's <i>Birds</i>, or will swoop out of nowhere and make off with the top half of your ice cream. Not the Newhaven gulls though.. they were a bit crap. Or maybe they were just deeply suspicious of a handout. Or maybe they are so used to doughnuts and burgers they have forgotten what a fish looks like...<br />
<br />
It was not all lost though.. it was a windy day and occasionally the pads would trigger by themselves. There was a Dali-esque treat in store for those who wandered over to our monitor screen to see fish heads, arranged over what looked like a big chessboard, apparently chatting to each other ("No No No!", "Over Here!")!<br />
<br />
<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFn7SWCk7SRupSfMehQyCiYvnf_XB4UeUMz9a3-roYTN1YYeKgW53t9O7EzpNAGEsRWXv3wXhGIyOF9QAw2IWWQ2MyEZThPzc9LWbqKglpg_pu6shoEHXgLokzgc8XokZr8l9sxM00CIU/s1600/tower2.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFn7SWCk7SRupSfMehQyCiYvnf_XB4UeUMz9a3-roYTN1YYeKgW53t9O7EzpNAGEsRWXv3wXhGIyOF9QAw2IWWQ2MyEZThPzc9LWbqKglpg_pu6shoEHXgLokzgc8XokZr8l9sxM00CIU/s1600/tower2.jpg" height="222" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The tower</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguOCLu04e8M5K3NWzAhbTJO0j4_FGDow8zDGyTBXv_lpp9j8ObjCSiqh8XykKcMYbrvjnnn0xnOiQIvAdb8c7Ny1zKcBd4QoCOQnfjrJPDG28mjquekxhvQRXyoQlcMvkTHAf_CTIcIlk/s1600/gulls.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguOCLu04e8M5K3NWzAhbTJO0j4_FGDow8zDGyTBXv_lpp9j8ObjCSiqh8XykKcMYbrvjnnn0xnOiQIvAdb8c7Ny1zKcBd4QoCOQnfjrJPDG28mjquekxhvQRXyoQlcMvkTHAf_CTIcIlk/s1600/gulls.jpg" height="150" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The crap gulls</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlGl-NluRGWunIk_9WfGSsxFR1HYxxpLMjlfBSmaTAuCZyHLt1wCDP7RXKf1PTqMbOK5pDyJC0VkMf4VPkSfT_9nSWEY0F5bS_1PRm1rL8t_jo-7iUtZ3dZDfaYZrtVtS-jErWzQnF5Lg/s1600/M4V06061.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlGl-NluRGWunIk_9WfGSsxFR1HYxxpLMjlfBSmaTAuCZyHLt1wCDP7RXKf1PTqMbOK5pDyJC0VkMf4VPkSfT_9nSWEY0F5bS_1PRm1rL8t_jo-7iUtZ3dZDfaYZrtVtS-jErWzQnF5Lg/s1600/M4V06061.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">No no no no!</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
</div>
hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-90486654784581814592014-07-03T14:11:00.004-07:002014-08-30T13:25:27.395-07:00HammerPong #5: We Got There!!<div class="separator" style="clear: both; text-align: center;">
<object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="https://i1.ytimg.com/vi/IiiWKhS2X_o/0.jpg" height="266" width="320"><param name="movie" value="https://www.youtube.com/v/IiiWKhS2X_o?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" /><param name="bgcolor" value="#FFFFFF" /><param name="allowFullScreen" value="true" /><embed width="320" height="266" src="https://www.youtube.com/v/IiiWKhS2X_o?version=3&f=user_uploads&c=google-webdrive-0&app=youtube_gdata" type="application/x-shockwave-flash" allowfullscreen="true"></embed></object></div>
<br />
So... I might have gone a bit quiet over Hammer Pong recently, but that doesn't mean it hasn't taken over my life these last couple of months!<br />
<br />
I've never been much of a handyman - so the most stressful part of this build for me was putting together<br />
the structure of the thing; Things started going wrong from the start when I bought a couple of large MDF sheets from the local DIY store - before realising they wouldn't fit in the back of the car (OK, they were totally bigger than the car). They wouldn't fit in the taxi minibus I called either - so I had to gingerly wheel them back up to the counter for a refund and then order them online, d'Oh!<br />
<br />
I was still having my DIY nightmares a few weeks later trying to paint it all in the back garden (flies, leaves, fur from the pet rabbits getting stuck on everything) as well as trying to find some place to store such the thing in my house without it getting scuffed, scratched and generally messed up (I can see why proper artists have proper studios!)<br />
<br />
Anyway, finally it all came together and after a couple of days getting it installed and operational at Woking Lightbox gallery I can finally breathe a long sigh of relief and let my big clunky baby fly the nest!<br />
<br />
So if you are really interested in how it all works, read on, we have a lot of catching up to do...<br />
<br />
First off I moved all the game code to an Arduino Due since it had the clout (memory space and instruction clock speed) to <a href="http://hotchk155.blogspot.co.uk/2014/05/hammerpong-4-led-strip-refresh-rate.html">drive six WS2812 LED strips in parallel</a> without resorting to assembly language or programmable logic. Although I am not sure it was entirely essential, I also buffered the data lines to the strips through 74HCT541s to get nice solid 5V edges for the WS2812's<br />
<br />
The<a href="http://hotchk155.blogspot.co.uk/2014/05/hammerpong-3-7-segment-display-made-out.html"> large fairground style LED assemblies</a> are all driven from a 24V supply using power transistors to switch on the low side. The transistors are driven by 74HC595 shift registers. I used TIP120's on the large 7 segment display (each transistor switches 3 LED assemblies) but for the single yellow LED assemblies I simplified things by using ULN2803A arrays instead of the TIP120's (At 24V the current is pretty low)<br />
<br />
I also decided to add sound - first off I experimented with the fascinating Mozzi synth library (running on a separate Teensy 2 board that I planned to send MIDI to from the Due). After blowing up one amp module (I don't think class-D amps cope well with unfiltered PWM input signals :\) I tried a different amp and was getting a lot of static (eventually I found out this was because my Mozzi output was very low due to a code issue, and upping the gain on the amp added horrible levels of noise).<br />
<br />
Anyway, I had to give up on Mozzi (a reflection on my lack of time, not the library itself which looks amazing) and did some very basic sounds using the Tone library. These still run on a separate Teensy, since the Due spends so much time updating the strips (with interrupts disabled) it can't generate Audio at the same time. With hindsight, basic bleeps and bloops do fit with the feel of the game. The winner even gets rewarded with a very crude couple of bars of "If I had a Hammer"!<br />
<br />
So all was looking good - I had several components which all tested fine individually and all I had to do was hook them up. Simple!<br />
<br />
Well... first issue - my<a href="http://hotchk155.blogspot.co.uk/2014/05/hammerpong-2-reading-player-inputs.html"> lovely "audio hit to MIDI" converter</a> worked wonderfully, but when hooked up to the serial input of the Due (yes the one that spends all its time bit banging LED strips with the interrupts suspended) about half the MIDI bytes got dropped at the serial input (since the interrupt to buffer them didn't fire before the next byte came in). Quelle suprise! Well, since I wasn't using the hit velocity anyway (I decided it was a bad idea to encourage any additional violence) I swapped the serial connection for a couple of simple HIGH/LOW data lines.<br />
<br />
Except... my PIC that reads the audio input runs at 5V but the Due runs at 3.3V and it's inputs are not 5V<br />
tolerant. So, I decided to configure the PIC output lines as inputs (high impedence) allowing the lines to<br />
float high to 3V3 on the Due's pull-up's and just drive them LOW to signal a hit. Great idea! ...but I managed to mess it up.. when I went to install the piece I hadn't got the latest firmware on the PIC (thats fine I thought, I could flash it from my laptop when I got there)... But the older version of SourceBoost C on my laptop did not support the PIC16F1825 and I didn't have the license key to upgrade it (as it was on my desktop back home) Aaaarghh!!!<br />
<br />
I kludged it in the end. At least I had the foresight to take the soldering iron with me and I moved the signal lines to the indicator LED lines (the LEDs were all working fine). By attaching the Due input to the point where the 1.5K series resistor connects to the LED I believe/hope/pray that the voltage at this point when the high side of the resistor is pulled to 5V is going to be something like 2V and well within the safe limits of the Due inputs. Anyway it works...<br />
<br />
With those dropped character serial problems in mind, I changed the Teensy sound generation code to expect single character messages to trigger sounds, rather than MIDI messages. I struggled a bit with the Teensy Serial.read (yes now I know that Serial1 is the hardware port and Serial is USB!) but eventually I have sounds, inputs and it all seems to be working. Woop!<br />
<br />
Hammer Pong will be showing (among loads of other cool things!) as part of the Giant Electronic Art Show at the LightBox gallery (<a href="http://www.thelightbox.org.uk/the-giant-electronic-art-show-1">http://www.thelightbox.org.uk/the-giant-electronic-art-show-1</a>) in Woking, Surrey UK<br />
<br />
Project source code is available here: <a href="https://github.com/hotchk155/HammerPong">https://github.com/hotchk155/HammerPong</a><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9yjpWw5Ap63OWnZgnsnCrggTKTvLWUxbEiQnX5-kp5ncEY50d4-27udnyvZhUGoaP2x-gYrhU5FlObmcV8qLwmLjMFqGLXpTXts3-MhNF3TD_1sHtNKfPMP3QiI0g0tfAjlwIW8NQsZ0/s1600/DSC04462.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9yjpWw5Ap63OWnZgnsnCrggTKTvLWUxbEiQnX5-kp5ncEY50d4-27udnyvZhUGoaP2x-gYrhU5FlObmcV8qLwmLjMFqGLXpTXts3-MhNF3TD_1sHtNKfPMP3QiI0g0tfAjlwIW8NQsZ0/s1600/DSC04462.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Planning the digits layout (started with a drawing from a data sheet!)</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3GazPE_EpR9-tTyp4GLidnZPApz9eVUyEVN1dkFj3VCldE3QrqBT5bMc_NnrH4i9hGECIvSnpN72Gv09f3UFXBxpgc6gQg8cG_5bOvxKOjkjnGVM8iWp13nTfbTp8bEu1r1veqbKVhiA/s1600/DSC04465.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3GazPE_EpR9-tTyp4GLidnZPApz9eVUyEVN1dkFj3VCldE3QrqBT5bMc_NnrH4i9hGECIvSnpN72Gv09f3UFXBxpgc6gQg8cG_5bOvxKOjkjnGVM8iWp13nTfbTp8bEu1r1veqbKVhiA/s1600/DSC04465.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Back board with digits laid out</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQNN_MfNzuXyvxMk4jUVajzRgt-mR8taAHbb2xoY-nlxVcyrx06c7v7iqDb3MCgt_EY9G6wfXUDDKsvmO0AnsVTvf4C7S9PP6Vav7bnUnkrgg9St_5RbiqDpWZe-XSlHJvY3hHv41PPHQ/s1600/DSC04466.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQNN_MfNzuXyvxMk4jUVajzRgt-mR8taAHbb2xoY-nlxVcyrx06c7v7iqDb3MCgt_EY9G6wfXUDDKsvmO0AnsVTvf4C7S9PP6Vav7bnUnkrgg9St_5RbiqDpWZe-XSlHJvY3hHv41PPHQ/s1600/DSC04466.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">With base, struts and cylinders</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9L7d5N5sBzWHonFwM3CjuVsj8CQGjuBQm7Dt-w_HraoMMe4JxERmlVUyH7qJjfjVeb6k2U-2bqu_ovNBFbLBcODTxia-79_OaNgBBkadSP6XdwvtluxIuTlqhBrNVsD2P-Y7zX6iRMgY/s1600/DSC04474.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9L7d5N5sBzWHonFwM3CjuVsj8CQGjuBQm7Dt-w_HraoMMe4JxERmlVUyH7qJjfjVeb6k2U-2bqu_ovNBFbLBcODTxia-79_OaNgBBkadSP6XdwvtluxIuTlqhBrNVsD2P-Y7zX6iRMgY/s1600/DSC04474.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Adding the additional panels</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfivqW881Pak6KULAzSDmhTjKTaa_htD6ze5-fRJ3nsq4Pz48AtXpSE1n3FzJjrHJTVdLK9DZb96f8lhdIFdMIeIpTv2oIwYSm0MvM-eG7cmwcGsm3cA_c9Y8fnb3AV5tRC5LgjL6Ix8w/s1600/DSC04478.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfivqW881Pak6KULAzSDmhTjKTaa_htD6ze5-fRJ3nsq4Pz48AtXpSE1n3FzJjrHJTVdLK9DZb96f8lhdIFdMIeIpTv2oIwYSm0MvM-eG7cmwcGsm3cA_c9Y8fnb3AV5tRC5LgjL6Ix8w/s1600/DSC04478.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">More LED's</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMGIh4_JG4ZXDIWovS5rW4yOzdbgVV-jihQmNQbGHBHKFg_CPGP9UlTsNSGx2rmWoOLt6UvVsP9ydVt8YCn-x54eK7j4BaY3G7S5FFCzBZlENQKgOFa2C2Bc1tYrSRep3Oxf3mhBmz1LI/s1600/DSC04721.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMGIh4_JG4ZXDIWovS5rW4yOzdbgVV-jihQmNQbGHBHKFg_CPGP9UlTsNSGx2rmWoOLt6UvVsP9ydVt8YCn-x54eK7j4BaY3G7S5FFCzBZlENQKgOFa2C2Bc1tYrSRep3Oxf3mhBmz1LI/s1600/DSC04721.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">The big day, in the back of the van</td></tr>
</tbody></table>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAVooWw3j2OqIZLksHZBmdxgcbsKDAOjfE4TV6UWwKAj4OMxvIZn850Gz2OZKzBXWZVy0Y-OgyPPQ1xLpk8LjLhta0OoKdTah3FrSEWWWvli1mSo72F5fSsxPRvIMlRxndMMGJiVar-1I/s1600/DSC04773.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAVooWw3j2OqIZLksHZBmdxgcbsKDAOjfE4TV6UWwKAj4OMxvIZn850Gz2OZKzBXWZVy0Y-OgyPPQ1xLpk8LjLhta0OoKdTah3FrSEWWWvli1mSo72F5fSsxPRvIMlRxndMMGJiVar-1I/s1600/DSC04773.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Installation</td></tr>
</tbody></table>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1T3pcuzaBVh-HVLjVKsSCfpyyVbe2tz6I0dwYCH00oyBVsXjsZ0sbdfF51YAuPC9i4WTxPlk6OBsUD5x0JqhPx6ydZlppWEaYyM-IP0bz-OTaiB_iVMbcMvJd2pV16BOVzs-SMl03-ik/s1600/DSC04723.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1T3pcuzaBVh-HVLjVKsSCfpyyVbe2tz6I0dwYCH00oyBVsXjsZ0sbdfF51YAuPC9i4WTxPlk6OBsUD5x0JqhPx6ydZlppWEaYyM-IP0bz-OTaiB_iVMbcMvJd2pV16BOVzs-SMl03-ik/s1600/DSC04723.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Backplane wiring and LED drivers</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguGPTSDWP7y0lxooRXSEsWJ8W8BADk6OsolMGmjmrP0vQRrjapCVXFZOpfTXYU0cXl9CK1Rpi2-kXL74TEInHUFqJg0jkxcuqEo7qZXq9NtV1hKHwO5_OvEM7DTmKGQLoiw8f5dQlDeJ0/s1600/DSC04755.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguGPTSDWP7y0lxooRXSEsWJ8W8BADk6OsolMGmjmrP0vQRrjapCVXFZOpfTXYU0cXl9CK1Rpi2-kXL74TEInHUFqJg0jkxcuqEo7qZXq9NtV1hKHwO5_OvEM7DTmKGQLoiw8f5dQlDeJ0/s1600/DSC04755.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Power supplies, Due, Teensy, Buffer/Level Shifters, Input Board and Audio Amp</td></tr>
</tbody></table>
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com4tag:blogger.com,1999:blog-8909459762367220480.post-62406773636502736992014-05-13T11:25:00.000-07:002014-07-05T06:52:08.000-07:00HammerPong #4: LED Strip Refresh Rate Headaches<div class="western" style="margin-bottom: 0cm;">
So onwards and upwards (and back down the other side) .... Time to have a go at making the LED strips that will provide the display surface for the game. I'd
already decided I wanted each game strip to be made up of three 5 metre, 150 LED strings mounted side by side and I thought that it might
be nice to stagger the centre strip, placing each of its LEDs midway
between the pairs of LEDs on either side. I thought that this might
help give an illusion of denser pixels and also make it easier to
animate the chevron style shapes I've been thinking about for the
game.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I did some eBay surfing
looking for suitable construction materials and found an adhesive
backed roll of 5mm thick, 75mm wide, solid neoprene rubber tape..
This seemed perfect for mounting the 3 LED strips side by side on the
sticky side with the remaining exposed adhesive and LED strips with a
layer of clear sticky tape. After a bit more searching I decided to
try some signmakers masking tape (100mm wide low-tack adhesive paper
tape) instead since I thought this would give a nice diffusion of the
LED colours.
<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqnRBkx93jAPJq6IxBmNDHS4owwawGAanmmZyMz6EAAsEnSyUvmjZWYvcsoXk5-2a-z05PEpBb6nnj9kDXn7Oljz2HusdGAap63pBw6-3huwg6Y9OaAQRY_T_1Ehm4e63u0yRhd-ceFg/s1600/DSC04016.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJqnRBkx93jAPJq6IxBmNDHS4owwawGAanmmZyMz6EAAsEnSyUvmjZWYvcsoXk5-2a-z05PEpBb6nnj9kDXn7Oljz2HusdGAap63pBw6-3huwg6Y9OaAQRY_T_1Ehm4e63u0yRhd-ceFg/s1600/DSC04016.JPG" height="240" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqEyMjUFZeJVSldNqYzyDSyOO9K0Oeb9fkyUJzvF0IassqBlkGFH0ZsebX9IlHLwU7TqVVNr9H30Zfb9Zw28RYfJilh8iSr_KeEkTscFohClzjfgmf6mU4EdS6KsS_cMTuRGKfFqrgA8/s1600/DSC04017.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiqEyMjUFZeJVSldNqYzyDSyOO9K0Oeb9fkyUJzvF0IassqBlkGFH0ZsebX9IlHLwU7TqVVNr9H30Zfb9Zw28RYfJilh8iSr_KeEkTscFohClzjfgmf6mU4EdS6KsS_cMTuRGKfFqrgA8/s1600/DSC04017.JPG" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Sticking down the LED
strips went really well. I didn't remove their backing tape since
there wasn't much point, they stuck down fine with the backing still in place
and it keeps me a few options open if it all went wrong. Must confess I
did get in a bit of an angry mess with the paper tape, which was
frustratingly difficult to lay down on top of the adhesive in one go and was all too easy to crease or tear. I did end up with some joins,
which I wasn't too happy about, but after applying a layer of clear
sticky tape to the whole strip it didn't look so bad after all, and
once I fired up one of the strips the effect was actually pretty
good!</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5IVcp9PySZsUtKDehdoh1eonBQ469KmGTdNUr_kBqtVeFlKpDFFHC4qy9Y2r9E43O2eLewaqWAyaggvIicUlr9qKqmCYNW6AvYnjlX3RMR45dn4ta5HvCKTX0WDGpRahjh0RkAALWHiQ/s1600/DSC04020.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5IVcp9PySZsUtKDehdoh1eonBQ469KmGTdNUr_kBqtVeFlKpDFFHC4qy9Y2r9E43O2eLewaqWAyaggvIicUlr9qKqmCYNW6AvYnjlX3RMR45dn4ta5HvCKTX0WDGpRahjh0RkAALWHiQ/s1600/DSC04020.JPG" height="320" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigb_zrThoicGle01xPcRo4IdTyhUNL3UjkXsEEI8yD7Iz6EsFMFmJ17ruiftj1q_ZH5SLvNX8F1aME6VD8yGMJtXNSg723KcnnTxxRWI60vaTXzNsjKqcxhL5j81qzF16p47AUCerwNDU/s1600/Dsc04023.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigb_zrThoicGle01xPcRo4IdTyhUNL3UjkXsEEI8yD7Iz6EsFMFmJ17ruiftj1q_ZH5SLvNX8F1aME6VD8yGMJtXNSg723KcnnTxxRWI60vaTXzNsjKqcxhL5j81qzF16p47AUCerwNDU/s1600/Dsc04023.jpg" height="217" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I applied <a href="http://hotchk155.blogspot.co.uk/2014/05/hammer-pong-1-multiplexing-ws2812b.html">themultiplexing approach I described before</a>, using a modified version of
the Adafruit Neopixel Library running on an Arduino Uno. I had
replaced my original Toshiba 4514 multiplexer chip with a higher
speed Texas Instruments CD74HC4514EN and it seemed to work fine
driving the 3 strips together. I had fun trying some nice particle
system sketches before having a go at some graphics for the Hammer
Pong game.</div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dx8ZnVPd_2dx0riFiDEzgNGCZNmS7qQgAyZKewJomIk3ETB3GhtVaH1_nDR-nKr83InDsoklTzbYRnijdnAdg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I tried animating a “puck”
shooting along the strip, which all seemed to work fine.... except I
was a little bit disappointed with the maximum speed I was getting. I
could not see any problems in the code, so I got out the calculator:</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
150 pixels per strip</div>
<div class="western" style="margin-bottom: 0cm;">
x 24 bits per pixel</div>
<div class="western" style="margin-bottom: 0cm;">
x 3 strips</div>
<div class="western" style="margin-bottom: 0cm;">
x ~1.25us per bit</div>
<div class="western" style="margin-bottom: 0cm;">
= ~13.5ms to refresh
all three strips</div>
<div class="western" style="margin-bottom: 0cm;">
= ~74 frames per second</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Hmm....</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
OK, for video, 74fps
would be pretty good! However moving the puck one pixel at a time
means the fastest it can tun the length of the 150 pixel strip is
about 2 seconds. It gets even worse if we add in the other strip the maximum frame update
rate would be halved, and the distance doubled.. That would mean 8 seconds for the
puck to reach the opposing player if it moved 1 pixel distance per
frame. A bit slow. Hmmmmmm...</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Yeah of course this is
easily solved by making the puck image move more than one pixel between
frames, which would be the usual way of doing things. The problem is
that the LEDs are very bright - just like I want them to be - and
persistence of vision effects make position jumps between the frames really obvious - you see the image frozen in several locations
along the strip, spoiling the sense of fluid movement. I really want
single pixel per frame motion to make it look smooth, dang!</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
So what to do about
it? Well the WS2812 protocol sets some base restrictions: The data
rate is fixed at 800kbps, so we cannot update faster than 1.25us per bit. Also
we have to refresh the entire strip at once due to the serial nature
of the load operation (we can't just load pixels that have changed
and leave the others). So updating a 150 LED strip will always take a minimum of 4.5ms and
there is nothing we can do about that (other than cutting the strip
into smaller lengths and addressing them separately maybe... but I don't
want to go there!).
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
But, we do have the
possibility of loading the data to all the strips in parallel - so
there is no specific reason why we can't load all 6 strips in the
same 4.5ms cycle. So, what could stop us doing this?
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Well firstly we will
need to render all the data into a memory buffer before the strip
update (at this data rate we will not have the time to render images
on the fly) . Yikes.. thats going to be a lot of memory (by
microcontroller standards).. 6 strips x 150 pixels x 3 bytes per pixel
= 2700bytes... already more than the 2k RAM on the Atmega328
microcontroller (sad face)</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
We could reduce this
using a lookup table (“palette”) of colour values and storing
the palette index for each pixel instead of the 24 bit RGB colour.
Lets say we have an 8 bit palette index (up to 256 colours) with
perhaps 64 colours actually defined in that 8 bit colour-space.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
6 strips x 150 pixels x
1 byte per pixel = 900bytes</div>
<div class="western" style="margin-bottom: 0cm;">
plus palette; 64
colours x 3 bits per colour = 192bytes
</div>
<div class="western" style="margin-bottom: 0cm;">
=1092 bytes total</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
This is much more
doable - and we can save more memory by avoiding storing the palette
in RAM.. e.g. by using PROGMEM data stored in the much more spacious
32k FLASH. However the next problem is processing speed...</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
To be honest I have
never had to be so concerned about performance at this level before,
ever. But when we are talking about bit-banging at 800kHz every CPU
cycle counts. For an ATMEGA328 running at 16Mhz each clock cycle is
62.5ns. Now that *is* pretty fast, but we have to bang these bits
pretty fast too. Reading the assembly language code for the Neopixel
library really shows how careful the timing of this stuff needs to be.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
However, if we can
update a single strip by writing LOW and HIGH byte values to an 8 bit port
register at this data rate, there is really no reason we cannot
update 6 strips (or even 8 - one for each port bit) at the same time ithout breaking
a sweat.. same number of bits to load, right? The extra overhead will
be preparing the next port byte value, where we'll need to load data from 6 different memory addresses (one per strip) instead of just one - and might need an palette lookup
for each one too.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Reading from this
really useful blog post (<a href="http://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/">http://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/</a>) we do have up to 9us of idle time to play
with between bits. This might make it all possible
on an ATMEGA328 with some tight assembly language code, but you know
what, maybe its time to look at something with a bit more grunt. Like
an ARM board....</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<br />
<div class="western" style="margin-bottom: 0cm;">
I've ordered an Arduino
Due as a start. I may yet try to get it working on the Uno, but the comparatively huge amount of memory and much faster CPU speed of the Due
does cure a few headaches. Just need to wait for it to arrive now -
watch this space.....</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dzGL_nLJ7HtqwrBR4is78z8q7PTG85rcULZ6pcFWYMtWDqu0tWsdNXSmJHGRn5Fl306r28MwMwNu1uh7ImSYw' class='b-hbp-video b-uploaded' frameborder='0'></iframe>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com5tag:blogger.com,1999:blog-8909459762367220480.post-61523649305867845082014-05-10T11:44:00.001-07:002014-05-10T12:08:56.296-07:00HammerPong #3: 7-Segment Display Made Out Of Fairground Lights<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="western" style="margin-bottom: 0cm;">
This is the third post in my diary of building my "Hammer Pong" game. </div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
After a visit with the kids to a local fun fair a couple of weeks ago, I thought some
fairground-style lights would look good to jazz up the fascia of my game! I started looking on eBay for used ones, but eventually</div>
decided to buy some new ones.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZTEajXZiEPuNUOk0DjQoXyY4-wleQG5EXKaSYFGSDzutju30G2qzp6EHaNNkK6iOcgXWVbwvVHojVNh_qwqg_XOAHg9Gx0lnZcFlrN3AbZUpm5EZec2bLRMJPWuWvRo1nUzl6g3BW63g/s1600/Dsc03990.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZTEajXZiEPuNUOk0DjQoXyY4-wleQG5EXKaSYFGSDzutju30G2qzp6EHaNNkK6iOcgXWVbwvVHojVNh_qwqg_XOAHg9Gx0lnZcFlrN3AbZUpm5EZec2bLRMJPWuWvRo1nUzl6g3BW63g/s1600/Dsc03990.jpg" height="236" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Loads of LED stuff :o)</td></tr>
</tbody></table>
At first I was thinking of using a row of individual lights to mark the score, but then I got this crazy
idea of making a giant 2 digit, seven segment display!<br />
<br />
First of all I needed
some kind of board to attach the display to for a proof of concept. My neighbour was
throwing out a big sheet of cardboard from a packing case, so I was
happy to take if off his hands.<br />
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
These lights use LED modules in place of filament bulbs, which give a nice clean white light behind the coloured plastic lenses. The LED modules run on
24V and are rated for 1.2W which means they only need 50mA current,
which isn't too challenging to switch. </div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGPJNA4GInRbumKo9OjPIbd2ov4UdfAnTsGgsLHsPY2H5i6xFv2phCv85xZUDmiRr5YVejSgZJuYj9SsKI6XW5eWw4uSwDAG4rjzPcSbIsy6REGucWTWqXQ6YAICtwSaNYyDZDjzNoXB4/s1600/DSC04024.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGPJNA4GInRbumKo9OjPIbd2ov4UdfAnTsGgsLHsPY2H5i6xFv2phCv85xZUDmiRr5YVejSgZJuYj9SsKI6XW5eWw4uSwDAG4rjzPcSbIsy6REGucWTWqXQ6YAICtwSaNYyDZDjzNoXB4/s1600/DSC04024.jpg" height="252" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Bits of a light</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
I decided to use 3 light units
for each segment of my display, so for each segment I'd be switching 150mA at 24V. For
this I went for TIP120 Darlington power transistors as I had a few of
them lying about and I know them pretty well. </div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I wanted to keep my
options open for PWM fading and thought that if I used FETs I
might need additional FET driver ICs to PWM switch the FETs. Anyway, a bit of
experimenting on breadboard shows that a TIP120 could switch and PWM
fade a set of 3 lights, wired in parallel, without breaking a sweat.
For that test I connected the base of the TIP120 to a PWM pin of an
Arduino Uno, via a 1k Ohm resistor. The TIP120 switches on the low
side, so my lights were wired to the +24V line and their GND line was
connected to the TIP120 collector, with the emitter connected to the
GND of the 24V supply. Applying a voltage to the base makes the lights come on.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Now, I don't want to have to
use an Arduino pin for every one of my display segments, so I decided
to use a 74HC595 shift register to control the lights for the seven segment display. One nice feature of the 595 is
the Output Enable pin. Usually I hard wire this to ground to
keep the outputs enabled, but here I have it connected to a PWM pin
on the Arduino. I thought this would let me fade the brightness of
the entire 7 segment display and it seems to work superbly - just
need to remember it is an active low signal, so analogWrite(0) is
full on and analogWrite(255) is full off.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Each output of the
74HC595 is connected via a 1K resistor to a TIP120. Add a bit of code
to load the shift register, define the numeric digits are we're ready
to roll with a 7 segment display test!</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie1qfHUEV7zpjU3Z12Lvz_RGpmBaRNkPTeAIoDkilt6IpFy08jq3iuGpmaZR0bqWr6GmW2ZPolTNXe98p4nZJcgwQE6tYWSVOp749enxHlLnPbTkO6CPX0QGN0dGlumhyphenhyphenp4Lbp4iEh4nI/s1600/DSC04009.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEie1qfHUEV7zpjU3Z12Lvz_RGpmBaRNkPTeAIoDkilt6IpFy08jq3iuGpmaZR0bqWr6GmW2ZPolTNXe98p4nZJcgwQE6tYWSVOp749enxHlLnPbTkO6CPX0QGN0dGlumhyphenhyphenp4Lbp4iEh4nI/s1600/DSC04009.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Shift register/TIP120 driver board</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The lights use a
screw-on base which forces some sharp terminals through the
insulation of the cabling. This makes it nice and quick to wire up
without soldering. I used a common 24V supply rail and wired together
the ground connections of the three lights on each segment, then
connected to the appropriate TIP120 collector terminal. A quick
Arduino sketch and I have digits counting, with a bit of a fade in
and out around a change of digit.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKKWdLwgf2CpT48VWfHSUaBpV_OlwdTTOxfvRnAOLHXUXAFsOh11H2cIZxJIRfW8h7TRKdZKgMz_cyv5-qEk8lGDwbZTCkOG2xJiIbIMGa3GXzuYbfceMpw-Z5JU31beOoYeDuxRT2PW0/s1600/DSC04007.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKKWdLwgf2CpT48VWfHSUaBpV_OlwdTTOxfvRnAOLHXUXAFsOh11H2cIZxJIRfW8h7TRKdZKgMz_cyv5-qEk8lGDwbZTCkOG2xJiIbIMGa3GXzuYbfceMpw-Z5JU31beOoYeDuxRT2PW0/s1600/DSC04007.jpg" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Quick'n'dirty build</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I think I made my digit
a bit tall for it's width, but the visual effect seems to work. Now I
just need to make sure I have enough space on the fascia of my game
for 2 of these - they are quite big! I hope they aren't too big to read properly from a playing distance... hmmmm.... only one way to find out.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUZVfgR84rGXAuQFC8WR_ZrCAhdigKE4D4tJgQgXezksiQzPK0-4us45OpR-WLSaNAWET3WzOGfBcX2AjpQ7rMJCwkmeVkEcFZ8PFZaov7GOJqiU2GF8ijKBHtXHlEntRoa0U7pPw3IMs/s1600/Dsc04000.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUZVfgR84rGXAuQFC8WR_ZrCAhdigKE4D4tJgQgXezksiQzPK0-4us45OpR-WLSaNAWET3WzOGfBcX2AjpQ7rMJCwkmeVkEcFZ8PFZaov7GOJqiU2GF8ijKBHtXHlEntRoa0U7pPw3IMs/s1600/Dsc04000.jpg" height="320" width="307" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">In action</td></tr>
</tbody></table>
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dyM0jX_OONx4M17c9VAkAn-YCtn3p20WbJxnZNm_kqgh4giKG2Dc6DTQwUPn6d9EsfSgEbUoyK2mVX5z0PmSQ' class='b-hbp-video b-uploaded' frameborder='0'></iframe>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-54639282817393686442014-05-08T12:50:00.001-07:002014-05-09T02:09:25.145-07:00HammerPong #2: Reading Player Inputs<div class="western" style="margin-bottom: 0cm;">
The next step in the build of my Hammer Pong game was to read the user input - when they whack something with a big ol' hammer.. I wanted to give the
game some kind of “velocity sensitivity” so that different levels
of force would trigger different behaviours in the game (but maybe a
very hard hit would not always be to player's advantage - perhaps if
the opponent manages to return a fast shot it comes back at
ridiculous speed:)</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Since I can see this part of the build taking a lot of punishment, I wanted to avoid
anything with moving parts that were likely to break with prolonged
use. My idea was to use a piezo disk as a contact pickup, and design in some way to detect the force of a hit (tell the difference between
different volume levels). For robustness and safety reasons I thought
using a foam hammer with a foam block as the target. Burying the
piezo disk deep in the block should protect it.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I'd seen the EVA foam
blocks that are sold by gym shops as exercise aids and thought they
would be good to try, being pre-shaped and finished, tough and quite
dense with a small amount of “give” to them.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I had originally
anticipated getting some kind of off-the-shelf toy hammers, made out
of foam or rubber, but I could not find anything that looks very suitable.
Most of them were very soft light foam, too small, or inflatable, so
I decided to try and make my own using EVA foam blocks. For the
hammer handle I bought some fibreglass broom handles (thinking they
would be lighter and safer than wood, but still hold up to some
abuse).</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I still need to give
the construction of the hammers some thought, but for my tests I used
an EVA foam “yoga block” as the head and a length of broom
handle. I used a standard holesaw, intended for timber, to bore a
hole into the side of the block (I fully expected it to rip the foam
to pieces, but it actually cut the cylindrical hole perfectly!).
Again still experimenting I used generous amounts of cyanoacrylate
superglue (set off with activator spray) to join the handle to the
head. Superglue is brittle, so I thought it might crack with use, but
I tried very hard to break it by hammering things or shear it by
twisting the handle... suprisingly the glue join held up to all the
abuse I gave it so there is definite potential.</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDqnhQUTtZ0vqgC_6KWeOzF7hnYeraXfmfydw90tMYPeUrq6R6CH3bzN42odjwhvBx_6G-IhSZZ4M43GnpUXAaMO2LRjGfa1i1ab0TM4Q43hyphenhyphenWDLcviUb9lwkOY8p-OqjkVHeuBoQAMMQ/s1600/DSC03974.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDqnhQUTtZ0vqgC_6KWeOzF7hnYeraXfmfydw90tMYPeUrq6R6CH3bzN42odjwhvBx_6G-IhSZZ4M43GnpUXAaMO2LRjGfa1i1ab0TM4Q43hyphenhyphenWDLcviUb9lwkOY8p-OqjkVHeuBoQAMMQ/s1600/DSC03974.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Hammer Prototype</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I wrapped the piezo in duct tape and buried it in the middle of an EVA foam cylinder. The only downside is
that the “slap” of the two foam surfaces hitting each other is
very loud.. maybe too loud. I might experiment with covering the
target with fabric later on..</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDK-v7268VczSVrnUrgKBSAkeII42VqmLNBPU8KMbgST30vmBqlWB-ReYp6ZVDxoWK4_SClmy9gB46xZYLaIUyCnTy9nmvRpdNVluXBauVQ30Y8mPb5lhwVnQKBSZNHePR15cwczn80uM/s1600/DSC03973.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDK-v7268VczSVrnUrgKBSAkeII42VqmLNBPU8KMbgST30vmBqlWB-ReYp6ZVDxoWK4_SClmy9gB46xZYLaIUyCnTy9nmvRpdNVluXBauVQ30Y8mPb5lhwVnQKBSZNHePR15cwczn80uM/s1600/DSC03973.JPG" height="320" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Foam Cylinder With Piezo</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
So on to the
electronics... I know from experience that a piezo disk can throw out
a pretty high voltage spike if you hit it hard. Since I wanted to be
able to get a measure of how hard the target was hit, I had to use
an analog measurement of the piezo output voltage. But, now the
microcontroller I am using runs at 5V power, any input voltage higher
than 5V would be clipped at 5V on my analog input (I could use a
higher analog reference voltage, but lets keep it simple) reducing
the range of input levels I can tell apart so middling hits and hard hits would be indistinguishable.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
So, I need some kind of
attenuation (scaling down) of the input voltage level, for which I used a simple 10k trim pot. I also thought some low-pass
filtering would help separate the main impact impulse from other
noise. Something else I noticed with an oscilloscope was that the
negative voltage peak coming from the struck piezo was substantially
higher than the preceding positive peak (not sure why that should
be..). </div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Anyway, all of the factors led me to using an op-amp to make an active lowpass filter (which also inverts and buffers the input). The trimpot gives a variable
attenuation of the raw piezo output to bring it within the range of the opamp input. The opamp output can then be fed directly to an
analog input pin on the microcontroller where it can be measured.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBvVBNWcFxrsDSOf1RRHB-W117NcjxXT_pVKTaYuZeGOTUlZjXXZKO-51uBL0SAXkGUj_w5Z8XyvuMjZtKCizoCYbqA7tOuxEnaw8byNaJ-lynW2FbTyRlA6SwvCQPEOHjP-94TqV9RMs/s1600/InputBoard.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBvVBNWcFxrsDSOf1RRHB-W117NcjxXT_pVKTaYuZeGOTUlZjXXZKO-51uBL0SAXkGUj_w5Z8XyvuMjZtKCizoCYbqA7tOuxEnaw8byNaJ-lynW2FbTyRlA6SwvCQPEOHjP-94TqV9RMs/s1600/InputBoard.png" height="280" width="640" /></a></div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
While I am planning to
use an ATMega328 for the main processor on this project, I decided to
offload the input monitoring to a second MCU, I think this is particularly important given the main processor could be blocked for a short time updating the LED strips and might possibly miss input pulses. I used a PIC16F1825 for my little helper as
I am familiar with this chip and have a ton of them.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
</div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Qy5_Xq5D7NgagjWhk73Akyi6A0Fm7US0L2ERgVnzgs19W6VG7UermIwMJzJDb-fk9ohyuhtby0uPHGKOFj6q7YOMLdqJ8NzM5eKsgxLYsmcyPvrkcJQsZbwuot3vWPPuGi-T4tYUJGI/s1600/DSC03977.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7Qy5_Xq5D7NgagjWhk73Akyi6A0Fm7US0L2ERgVnzgs19W6VG7UermIwMJzJDb-fk9ohyuhtby0uPHGKOFj6q7YOMLdqJ8NzM5eKsgxLYsmcyPvrkcJQsZbwuot3vWPPuGi-T4tYUJGI/s1600/DSC03977.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Circuit On Stripboard</td></tr>
</tbody></table>
<div class="western" style="margin-bottom: 0cm;">
My PIC code monitors
two analog inputs (one for each hammer target) in parallel. When an
input reading exceeds a trigger threshold, the PIC samples the input
over a short period, storing the maximum value (the idea
being to get the peak value of the trigger pulse). This information is then
transmitted as a serial message and the
PIC waits holds off for period of time to allow the sound to fade
before going back to listening. See the code here <a href="https://github.com/hotchk155/HammerPong/blob/master/InputListener/InputListener.c">https://github.com/hotchk155/HammerPong/blob/master/InputListener/InputListener.c</a></div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I used MIDI for the
serial protocol. Some people might say I use MIDI for everything,
but I love it for a lot of sensible reasons :)</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
- It is very simple to
implement, with most messages being only 3 bytes long</div>
<div class="western" style="margin-bottom: 0cm;">
- It has a nice easy
synchronisation scheme (bit 7 set means start of new message - simple
as..) that stops your sender and receiver getting out of step</div>
<div class="western" style="margin-bottom: 0cm;">
- It is perfect for
this kind of thing (transmitting simple “note” events with a
velocity) - it is pretty much what it is designed for.</div>
<div class="western" style="margin-bottom: 0cm;">
- The best bit... if
you have some MIDI gear and utilities then you already have all the
test tools you need! I can test my input reader before I have the
main game program written by simply playing notes through a
synthesizer. When I test the game I can fake input using a MIDI
keyboard. And I already have a bunch of MIDI cables I can used to connect things together.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Next to get some big flashing lights working!</div>
hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-62264451614888027642014-05-05T12:03:00.000-07:002014-05-06T00:43:46.214-07:00Hammer Pong #1 - Multiplexing WS2812B addressable LED stripsMy 1-D Pong game was accepted to be part of an electronic art exhibition this summer.. Yay!! 1-D Pong was a project of mine from a couple of years back, which uses a 5M addressable LED string as the display surface for a game based on the classic PONG. Since the LED string is one dimensional, you can't "miss the ball" in the conventional sense so the gameplay is all about timing; you press a footswitch at exactly the right moment to return the ball. Despite being so basic it works pretty well as a game, and the pace accelerates with each return to keep it challenging.<br />
<br />
As this will be my first gallery installation I decided I really wanted to improve and build on the original (which is, to be honest, getting a bit tatty) and do something a bit more ambitious. In speaking with the curator a few weeks back I learned that the venue has a 7 metre high ceiling, and that the exhibition would have a fairground theme. Wouldn't it be great to orient the 5m strip vertically up the wall, I thought. That got me thinking about those old "high striker" / "test your strength" fairground side shows.. you know the ones with the big hammer to whack a puck up a tube and ring a bell? Well.. combine that with the 1-D Pong and Hammer Pong was born!<br />
<br />
Two players will whack it out against each other, hitting their foam mallets against foam block "triggers" to shoot a pulse of light up a vertical LED strip, where it will cross over and return down the opponents strip. The opponent needs to hit their block at just the right time to fire the pulse back as it reaches the base of the strip. Miss the timing and you lose.<br />
<br />
A simple concept, but technically a little bit more challenging build than the original 1-D Pong. I will be building it over the next few weeks and will post my progress on this blog, which might be of interest to anyone who wants to know about the build after it is complete. So let's get started...<br />
<br />
Challenge number one is that I need to drive multiple LED strips. My original 1-D Pong project was created a couple of years ago when addressable LED strips were new (and rather more expensive) and my strip used an obscure controller called a yds600 for which I had to write my own support library. Due to the way the strip required the SPI communications clock to keep "ticking" after the data was latched, to keep its PWM going, those strips would be hard to drive in multiple.<br />
<br />
However, these days most strips use the WS2812 controller - I find these things amazing; the controller chips is actually inside the LED!!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgigTR2OxZKptNMjTEgumACzOwaNgu8inWSBDlFtqTJ52IS0J0j1GZ6GcGetSfsHeV3hquwsgtkrfI8f5cZFG2v9MBTHwVDQTs2ohlQjDfOb-7ib263wAU38E0WrErXs8GtGS7E8N3l0Uc/s1600/DSC03982.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgigTR2OxZKptNMjTEgumACzOwaNgu8inWSBDlFtqTJ52IS0J0j1GZ6GcGetSfsHeV3hquwsgtkrfI8f5cZFG2v9MBTHwVDQTs2ohlQjDfOb-7ib263wAU38E0WrErXs8GtGS7E8N3l0Uc/s1600/DSC03982.JPG" height="240" width="320" /></a></div>
Just think about that for a moment... a single WS2812 LED is a tiny package about 5mm square, containing not just red, blue and green LED elements but a tiny silicon chip with a serial data controller, internal oscillator, three 8 bit PWM channels and current management circuitry. They can be had for less than 20 cents each but are more usually bought in flexible strings (usually 30 or 60 LEDs to a metre) where the LED data in and data out pins are chained together as a giant shift register so a single data pin on your microcontroller can drive them all. I think that's amazing!<br />
<br />
Also, these days it is easy to find ready made code to drive the strips. Adafruit sell WS2812 LED assemblies under their NeoPixel brand and their Arduino library code seems pretty well written, so I have been working with that. One potentially nice point about the Neopixel library code is that it "bit-bangs" the data (the output pin is explicitly toggled on and off by code rather than using a built in serial hardware peripheral on the AVR) so the strip is not confined to specific output pins.<br />
<br />
This means that two strips could be connected to different output pins using the NeoPixel library. However I was already getting a bit more ambitious than that... when I bought my strips I bought a job lot of ten x 5m WS2812B strips with 30LEDs/m so I could get the price down to just over US$30 a strip including shipping from China. This means I have quite a few strips to play with :)... so why not make each of my 2 players "tubes" actually made up of 3 LED strips side by side, giving each a 3x150 pixel matrix to allow some simple animations and effects, and increase the brightness... Oooh!<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZa6ZcGHc_jklm_FcRZIKssgfHJuEAG9cu5s-097VjnWxVl5BQAV_fom9QeFEgzuHrpHiHj8QBUdGpfM9SlCkrFf2rCDxX-HEpXdhYlxDNfXgbaaKi-yu2k54Ou0kpIhujs9J5mP2uswE/s1600/DSC03980.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZa6ZcGHc_jklm_FcRZIKssgfHJuEAG9cu5s-097VjnWxVl5BQAV_fom9QeFEgzuHrpHiHj8QBUdGpfM9SlCkrFf2rCDxX-HEpXdhYlxDNfXgbaaKi-yu2k54Ou0kpIhujs9J5mP2uswE/s1600/DSC03980.JPG" height="320" width="240" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ten 5 metre addressable LED strips</td></tr>
</tbody></table>
To run the total 6 strips needed I could use 6 output pins and 6 instances of the NeoPixel library object, or I could potentially chain the strips together and use a single pin by treating them as a single 900 (150 x 6) pixel strip. However, I think this would mean the library keeping an image of the 3 byte colour data for each of the 900 pixels in memory at the same time, which would not even fit in the Atmega328's 2k of RAM!<br />
<br />
So... I need to be a bit creative. Firstly there isn't really a need in my game to keep an image of the display contents in memory.. All the required display content can be recalculated at every frame then dumped to the strips and latched into them. There is no need for me to refer back to the display content afterwards (e.g. collision detection is not relevant).<br />
<br />
Also the WS2812 data protocol is very timing critical, so the transmit code needs to be tight and run without interruption (I am pleased to see Adafruit coded the important parts in assembly language in their library). This means that it is not possible to send data to multiple strips in parallel, you must send the full set of data to each strip in turn (unless they are chained together and a single send can address all strips, but this needs the full 900 pixel content to be buffered for send, so is a no-no)<br />
<br />
So, I decided I need a way to update one strip at a time, making sure I required only a single 150 pixel buffer in memory. I guess two options are possible<br />
<ul>
<li>Dynamically reconfigure the NeoPixel library to direct the data from a single library object and 150 pixel buffer to 6 different digital output pins in turn, re-rendering image into the data buffer for each new strip. This would need to use 6 output pins. It may also need some changes to the library code to allow the output pin to be efficiently reconfigured on the fly. </li>
</ul>
<ul>
<li>Use a digital multiplexer IC (I have some TC4514BP's available, which should fit the bill) to connect a single output pin to each of the 6 strips in turn, re-rendering image into the data buffer for each new strip. This would need to use 4 output pins (one for the data and 3 for the selection between strips). I'd need to make sure the multiplexer chip would not skew the output pulses (which for the WS2812 are timing critical). I thought this approach could work without changes to the library code, but read on...</li>
</ul>
<br />
I went for the second option... some simple tests on a breadboard showed it worked, but I did need to modify the NeoPixel library code to allow the data output to be inverted (so that when it would usually output HIGH it output a LOW and vice-versa). I'll explain the reason...<br />
<br />
The 4514 digital multiplexer has 16 outputs (more than I need, but I have a load of these chips lying about so..). You have 4 Address pins which you use to select which of the 16 outputs will be set to a HIGH value (all the other 15 show LOW).<br />
<br />
There is also an Enable pin which must be held low for the selected output to show HIGH. If the Enable pin is HIGH then all of the 16 outputs are LOW. This allows the Enable pin to be used to toggle the selected output pin between LOW and HIGH, BUT the logic is inverted. If you want the selected output to be HIGH then Enable must be LOW and vice-versa. Therefore if we want the output from the NeoPixel library to drive the Enable pin we either need some kind of Inverter chip, or we can hack the library code to enable inverting of the logic. I went for the second option :)<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJGiuYQjpBq36bsB7kQBL8zawAAeCxiez_swajq27K7sNli47emDbsecIqXv71bPn3rN6uOe9TguKvM-7u79hedq9lQoijhwr0ASqO1EHgoGoWXI4-TBldQ2DIlV2Oi92R4j4MoZRqZBA/s1600/DSC03928.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJGiuYQjpBq36bsB7kQBL8zawAAeCxiez_swajq27K7sNli47emDbsecIqXv71bPn3rN6uOe9TguKvM-7u79hedq9lQoijhwr0ASqO1EHgoGoWXI4-TBldQ2DIlV2Oi92R4j4MoZRqZBA/s1600/DSC03928.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">TC4514BP 1-of-16 Digital Multiplexer</td></tr>
</tbody></table>
<br />
Some simple tests on breadboard and it seems to be working fine. I was concerned about the gate lag on the multiplexer impacting the time-critical WS2812 protocol (ICs have a small but possibly significant "propagation delay" between changing an input and seeing the output change) however as long as the delay is symmetrical and rising and falling edges are delayed by a similar amount of time then it should not be a problem for my application. The data sheet shows this is within the WS2812 +/-150ns tolerance.<br />
<br />
Another good thing about this multiplexer is that unselected outputs are driven LOW rather than floated. This means that the WS2812 "Latch" command (pulling the data line low for an extended period of time) can take place after we have deselected the strip and moved on to the next one, making things ever so slightly faster.<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEu8u0U-ULh_LPF1KvR4LObrNbqtJ7SDSZzfB9TAIWfjbfR64h5SJT_5vkUB3hZ4GmS8f89kJ2jXcrda8I6B6Nm4NrOtmd_pe6ej3dqRL-F1ajSaz4ZBpw6IasbAHAPD5I3VQ5vNs-koQ/s1600/DSC03929.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEu8u0U-ULh_LPF1KvR4LObrNbqtJ7SDSZzfB9TAIWfjbfR64h5SJT_5vkUB3hZ4GmS8f89kJ2jXcrda8I6B6Nm4NrOtmd_pe6ej3dqRL-F1ajSaz4ZBpw6IasbAHAPD5I3VQ5vNs-koQ/s1600/DSC03929.JPG" height="240" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Simple test with 2 strips</td></tr>
</tbody></table>
<br />
In case you want to use the same approach, here is the change I made to the NeoPixel library. First off I added a flag field activeLow (I wanted to make it switchable in case I needed to toggle during trouble shooting)<br />
<blockquote class="tr_bq">
class Adafruit_NeoPixel {<br />
:<br />
private:<br />
#ifdef __AVR__<br />
<b><span style="color: red;">uint8_t<br /> activeLow; // Set to 1 to use ACTIVE LOW output pulses </span></b></blockquote>
<blockquote class="tr_bq">
#endif<br />
};</blockquote>
<div>
<br /></div>
I initialise the flag to 1<br />
<blockquote class="tr_bq">
Adafruit_NeoPixel::Adafruit_NeoPixel(uint16_t n, uint8_t p, uint8_t t) : numLEDs(n), numBytes(n * 3), pin(p), pixels(NULL)<br />
,type(t)<br />
#ifdef __AVR__<br />
,port(portOutputRegister(digitalPinToPort(p))),<br />
pinMask(digitalPinToBitMask(p))<b><span style="color: red;">,</span></b><br />
<b><span style="color: red;"> activeLow(1)</span></b><br />
#endif</blockquote>
The library implementation uses conditional compilation directives for the many Arduino boards, so you need to look through and find several places where the bit masks lo and hi are defined. This is a pre-calculation of values used later to toggle specific bits in the port registers. hi is usually set to the current port value with the target bit set and lo to the value with the bit cleared. We simply calculate these in the opposite sense if activeLow is needed<br />
<blockquote class="tr_bq">
<span style="color: red;"><b> if(activeLow)<br /> {<br /> lo = PORTD | pinMask;<br /> hi = PORTD & ~pinMask;<br /> }<br /> else<br /> {</b> </span></blockquote>
<blockquote class="tr_bq">
hi = PORTD | pinMask;<br /> lo = PORTD & ~pinMask;<br /><b><span style="color: red;"> }</span></b></blockquote>
<br />
<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-75836981351884818252013-06-07T14:29:00.001-07:002013-06-07T14:33:12.270-07:00The Making of Ant Attack!<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/RdrgBwSH9W8?feature=player_embedded' frameborder='0'></iframe></div>
<br />
Someone sent me this clip and wow, what memories came flooding back.<br />
<br />
Ant Attack on the ZX Spectrum was the first computer game that not only totally hooked me, but made me think "I wanna be able to do that". At one point, circa 1984, I could even beat the "hall of fame" high scores published in Personal Computer Games (PCG) magazine, though I was much too shy to write in about it.<br />
<br />
One of the dubious joys of the Spectrum was getting to actually hear programs loading. Games could take upwards of 20 minutes to load from cassette tape - which meant you made damn sure you made the effort to enjoy them - and as they loaded you could hear the whistles, chirps and drones of the bits and bytes of game code.<br />
<br />
Every game had its signature loading sound and I can still immediately recall the last few clicky seconds of Ant Attacks loading before it launched into the beepy tune that accompanied the blocky title screen.<br />
<br />
Ant Attack was my first hacking experience. I worked out how to break into the tape loader and get access to the BASIC program that controlled the machine code routines, then I started messing with it to move things about about, such as the characters you're supposed to rescue (the positions were all coded in DATA statements in the BASIC code)<br />
<br />
I moved on to searching through the programs memory image, looking for the data for the "city" that was the game area, then printing it out in long strips on my Alphacom 32 toilet roll printer and sellotaping them together into a map which I proudly blu-tacked to my bedroom wall.<br />
<br />
Some 10 years later I created my own version of the game for the PC, written in C and inspired by a superb Manic Miner port. I found a cassette tape image file for Ant Attack somewhere on the early internet and tracked down and pulled out the bitmaps for the game graphics and the city map. I got the movement and display routines all working but unfortunately didn't get the game play finished off :-(<br />
<br />
Anyway it was a joy for me to see this interview with Sandy White, the creator of Ant Attack. i had no idea what he even looked like before seeing this, and I only remember his name from the big "(C) SW" laid out in bricks on the city map in the game, which I remember noticing when I printed out the map.<br />
<br />
I was pleased to see Sandy White HAND ASSEMBLED all the machine code for the game.. now this really does bring back memories as I used to do this myself, on a much simpler scale, armed only with the list of Z80 assembly language instructions that were printed alongside the character set at the back of the ZX Spectrum manual. Top stuff! Hey I even used to hand assemble Z80 machine code without a reference list, just by remembering all those opcodes from looking them up so many times. I really should have got out more.<br />
<div>
<br /></div>
hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-25104314824378789752013-03-25T14:20:00.001-07:002013-03-25T15:26:14.653-07:00ARPIE - Arduino based MIDI arpeggiator kit<br />
Since I made my first Arduino-powered MIDI arpeggiator a couple of years back I have been meaning (and promising) to get a kit together so others can build their own. Today I listed my first "fundraiser" on Tindie. Hopefully that will raise enough cash get the PCBs made up for 50 of these little beasties!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/mk7zSJ8mq2A?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
These ARPIE kits are made up of 2 PCBs which stack up with 25mm standoffs and connect together using a 2x10 way long pin header strip, so there are no ugly wires. The top board is the control surface, packed with 29 tactile switches and 20 LEDs which together provide all the user-interface you get (or need)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDK-kmub0-rodc4EBz3Dxedj5ZCO0jw8C-EAQsiGo8_lYntVTmWI5AofSIXFYkTRlWRzhDO01hw1t1GJY7gmemI4bpoZXPzEMpWWQJCa4YMKFY3dWTgiXKMe7LmotGY559TpjehbFozf8/s1600/Dsc01715.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDK-kmub0-rodc4EBz3Dxedj5ZCO0jw8C-EAQsiGo8_lYntVTmWI5AofSIXFYkTRlWRzhDO01hw1t1GJY7gmemI4bpoZXPzEMpWWQJCa4YMKFY3dWTgiXKMe7LmotGY559TpjehbFozf8/s320/Dsc01715.jpg" width="320" /></a></div>
<br />
I wanted to preserve the look of my original arpeggiator build, which was in a bright yellow case with black Dymo embossed tape labels. I went for a "Dymo" feel to the PCB silkscreen in this latest build. I made them up in a drawing package and imported them into EAGLE as .bmp files. Although my initial prototype PCBs are standard PCB green, I hope to go for bright yellow soldermask (boards) and black silkscreen (text) in the production run.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFPAJB_rNq9CDnylPTwkJzG8eBQdsdJQ2CWUF7ndKGrr0C0DdpWyGXik4ZQng0iRAfd4cNzBAyNRDu5iwaSkJwH5OFQJFLBS2IB7Nk46-xYBn14DAbt6X255C8KToEBxI57_FhZgQLLSc/s1600/Dsc01747.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFPAJB_rNq9CDnylPTwkJzG8eBQdsdJQ2CWUF7ndKGrr0C0DdpWyGXik4ZQng0iRAfd4cNzBAyNRDu5iwaSkJwH5OFQJFLBS2IB7Nk46-xYBn14DAbt6X255C8KToEBxI57_FhZgQLLSc/s320/Dsc01747.jpg" width="320" /></a></div>
<br />
On the back of the control surface PCB are two 74HC595D surface mount shift registers. When I release the kit I will solder these myself, leaving just the easier through-hole stuff to be added.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2RoWLnQNhyphenhyphenvDSNWwUsQ5eLlLGcyOx3qxD8_5xGQ3Qc-8egUlJjwIk_RF_FPFkvI24VTdkIEpBOGRXHw6F7lYd7HQ5Alc57FiFJv8zk5kWAeqRBvMg9DECBfityzzaTAds-ZaBjGAd6xE/s1600/Dsc01740.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2RoWLnQNhyphenhyphenvDSNWwUsQ5eLlLGcyOx3qxD8_5xGQ3Qc-8egUlJjwIk_RF_FPFkvI24VTdkIEpBOGRXHw6F7lYd7HQ5Alc57FiFJv8zk5kWAeqRBvMg9DECBfityzzaTAds-ZaBjGAd6xE/s320/Dsc01740.jpg" width="320" /></a></div>
<br />
The shift registers are used to scan the switches and drive the LEDs so that only 5 digital I/Os (3 ouputs and 2 inputs) are needed to drive the sixteen blue LEDs and poll the sixteen 6x3mm "Data Entry" tactile switches and the twelve 6x6mm "Menu" tactile switches. The low side of the LEDs is controlled by a 2N3904 transistor. By switching an LED on then off "early" in its refresh cycle we can get multiple brightness levels.. a kind of "poor man's PWM". The scan cycle is controlled by a timer interrupt.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZlsJFdz9TXbwFDq6AgfzLpfV4WKE_fyimKLswqVcY8aF35ZWRJFlf-lA-KLaIl2SzXlHggeoaRhDthBWO9VxA_MHZTVgkvDDl9hI8K3BXyG7Qdkr2WckdoLVVnoqzUCs38Kcd8suqQ-8/s1600/DSC01737.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZlsJFdz9TXbwFDq6AgfzLpfV4WKE_fyimKLswqVcY8aF35ZWRJFlf-lA-KLaIl2SzXlHggeoaRhDthBWO9VxA_MHZTVgkvDDl9hI8K3BXyG7Qdkr2WckdoLVVnoqzUCs38Kcd8suqQ-8/s320/DSC01737.JPG" width="320" /></a></div>
<br />
Although there is no actual Arduino board used - this is an Arduino project - with Atmega328 and 16MHz crystal on board. As with most Arduino projects, all the clever stuff happens in the firmware. We send MIDI simply using the Serial port (31250 baud rate). The MIDI spec tells us to optically isolate the serial input to avoid possible grounding issues between equipment so a 6N139 opto-isolator IC sits on the MIDI input.<br />
<br />
A feature of the ARPIE is to be able to "slave" to a MIDI SYNCH source which is different to the MIDI input where the notes are being received. For example we might have a keyboard on MIDI IN but want to get our SYNCH from a drum machine.<br />
<br />
MIDI SYNCH is achieved through special "tick" messages which arrive at a MIDI input in real time (24 ticks for every beat) so we need a second serial interface to receive these. Since this is rather crucial for timing synchronisation, rather than "soft serial" I decided to add a second microcontroller (PIC12F1822) to manage synch. The PIC listens for the incoming MIDI synch messages and "interrupts" the Atmega328 by pulsing its INT pin each time a tick message comes in. The PIC has its own 6N139 isolator. Apart from the battery and voltage regulator stuff, that is pretty much it for the hardware.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxI4d6ZAkisW9Y889ytfV7X_OEeJRA4AI6arjS8ORVjVRMZW5u9hoSHakSCll5bu2UNMY4gdcpsakbBLOsYmIkKqUvHEGqNCak2pTEOJIuvFUMdhKXJ3udCfVffnnMDdYNGxKXggPMOIQ/s1600/Dsc01723.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="242" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxI4d6ZAkisW9Y889ytfV7X_OEeJRA4AI6arjS8ORVjVRMZW5u9hoSHakSCll5bu2UNMY4gdcpsakbBLOsYmIkKqUvHEGqNCak2pTEOJIuvFUMdhKXJ3udCfVffnnMDdYNGxKXggPMOIQ/s320/Dsc01723.jpg" width="320" /></a></div>
<br />
I am quite pleased with the usability of this box - despite the minimality of the user interface it is mostly intuitive once you get used to it (OK so there are some exceptions, like the need to set the tempo in binary coded decimal :o). For most operations you press a menu button, which changes the meaning of the LEDs and data entry buttons for that function. After a period of inactivity it always goes back to "pattern" mode.<br />
<br />
Apart from making the Arduino sketch open-source to enable hacking of the firmware, I wanted to make the hardware friendly for customisation (for example to put the device in a proper case or give it a more spacious control surface). To this end the pin header which connects the two boards can easily be replaced with a 20 way IDC socket so you can run a ribbon cable to an customised control surface. Two unused I/O lines are routed through the header for custom use. Case mounted DIN sockets can be wired in place of the PCB mount DIN sockets supplied. Both micro-controllers have broken out programming headers (FTDI style for the AVR)<br />
<br />
Find the Arduino sketch source code, and the hardware design files at<br />
<a href="https://github.com/hotchk155/arpie">https://github.com/hotchk155/arpie</a><br />
<br />
I am currently running ARPIE as a fundraiser on tindie.com<br />
<a href="https://tindie.com/shops/hotchk155/arpie-midi-arpeggiator-kit-1/">https://tindie.com/shops/hotchk155/arpie-midi-arpeggiator-kit-1/</a><br />
Back ARPIE and get your own kit for $59<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com2tag:blogger.com,1999:blog-8909459762367220480.post-13564152666136038532012-11-23T09:21:00.002-08:002012-11-23T09:41:20.252-08:00Building an Arcade Button Monome-likey<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJRmoX8yWb4hT5rW8oc8hdUJ1r5UjkyjF7XNQ6gfDcjoZlF_1Z-fFhmuExEd2tSXa04cyxIO6FX_yvSO94IqXziOLQbDo6f-34xxA_tz19rHCT3my1E-WQEjRQNjw3FtWMKi7kkCAwHdU/s1600/DSC01263.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJRmoX8yWb4hT5rW8oc8hdUJ1r5UjkyjF7XNQ6gfDcjoZlF_1Z-fFhmuExEd2tSXa04cyxIO6FX_yvSO94IqXziOLQbDo6f-34xxA_tz19rHCT3my1E-WQEjRQNjw3FtWMKi7kkCAwHdU/s320/DSC01263.JPG" width="320" /></a></div>
<br />
I've had quite a lot of fun with the Novation Launchpad, building interactive MIDI sequencers and control surfaces. For a while I've had the idea in mind of making an Arduinome (an Arduino powered DIY Monome MIDI controller)<br />
<br />
When I was working with Will Nash on the Noisy Table, I really got to like the micro-switched arcade buttons that we fitted to the table to control the sounds. And so it was I hatched a plan to make a Monome style grid controller using arcade buttons. I soon found<a href="http://www.defcon6.com/?cat=15"> it had been done before</a>, but it looked so cool it just encouraged me more.<br />
<br />
I bought the switches quite a long time before I really decided exactly how I was going to use them. They have translucent white plungers with an LED holder in the microswitch clip at the base. The supplied LEDs were white and resistored up for 12V (I guess as a drop in replacement for filament bulbs in arcade machines). I decided to replace them with RGB LEDs, but I needed to make sure I had a decent scheme for doing this, since I needed to wire up 80 of these switches and didn't want to end up making the same mistake 80 times!<br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_dAIwKNfF9yRvONJRCaFPvmW3zpn5zC96fDlHJRfGcsi0m5cSpbpQIx7qbGCkdGxPAmaWJxt2j1aRdx4Wb34b1dCuTFCI3tCVj8Nl0SRlY5tAIkVYOwGawZ6Yavr_a6uWjdn0x-Zo-cs/s1600/DSC01270.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_dAIwKNfF9yRvONJRCaFPvmW3zpn5zC96fDlHJRfGcsi0m5cSpbpQIx7qbGCkdGxPAmaWJxt2j1aRdx4Wb34b1dCuTFCI3tCVj8Nl0SRlY5tAIkVYOwGawZ6Yavr_a6uWjdn0x-Zo-cs/s320/DSC01270.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">12V LED modules and sockets</td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFy8kogZ8a0PTrPUUatJzLv1kIF2yO2yUCYQ-SVxft8ek8PZBGLq4E8JAK1X6L8MPOaICWP5vGajfr_8TWkDpN4p6ennoYb6rcMvkTsBdHJMvr26cIZbs5h88GTH86QqeWztaxymh4mGU/s1600/DSC01257.JPG" imageanchor="1" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFy8kogZ8a0PTrPUUatJzLv1kIF2yO2yUCYQ-SVxft8ek8PZBGLq4E8JAK1X6L8MPOaICWP5vGajfr_8TWkDpN4p6ennoYb6rcMvkTsBdHJMvr26cIZbs5h88GTH86QqeWztaxymh4mGU/s320/DSC01257.JPG" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Microswitch heaven!</td></tr>
</tbody></table>
<br />
What I ended up with was breaking a matrix board into little squares, so I could thread the leds of the 5mm RGB LED through the holes and slide the board into the socket in place of the white LEDs modules. This worked nicely to connect the common anode and one of the cathodes to the LED socket. I was then faced with somehow getting a connection through to the other two cathodes while not interfering with the operation of the switch.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPq96P3ZHc3TwEZzjyjNXiAei29-RfbBsXxhNtR-VHflyGQprep1_XI7_CQv7Bd7Qx-b5ku06vSa9MZGYh9NrxBIWalfk5iprAtLl2qUoC2vzIBa8nzD0HKafo_BXJG2pOeYcnDBB9e4E/s1600/DSC01245.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPq96P3ZHc3TwEZzjyjNXiAei29-RfbBsXxhNtR-VHflyGQprep1_XI7_CQv7Bd7Qx-b5ku06vSa9MZGYh9NrxBIWalfk5iprAtLl2qUoC2vzIBa8nzD0HKafo_BXJG2pOeYcnDBB9e4E/s320/DSC01245.JPG" width="320" /></a></div>
<br />
I have a big roll of Kynar wrapping wire that comes in very handy for this kind of thing. Kynar wire is a single core wire with a very thin insulation layer, so it easily gets through the tiniest of holes and gaps. I could solder two wires to the remaining LED cathodes and thread them down through the socket and out between socket and switch. Since the thin single core wire can be brittle I used little blobs of superglue to anchor the ends after soldering (Its amazing how much more useful superglue becomes if you get a spray can of activator, which sets the glue off instantly - even in blobs)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1liwrfcABUbotPum0NICS6E-ui_3V2ds9P6hc-fSDSN3uFn6507wzF_rHugODNsiB4xTQ682iFg8XmbU11BH6xWmXh4FlWe_dCgH5QAGkIf1RefYXHTJyZs_VJWp2WgeTEuyc5il8zBg/s1600/DSC01250.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1liwrfcABUbotPum0NICS6E-ui_3V2ds9P6hc-fSDSN3uFn6507wzF_rHugODNsiB4xTQ682iFg8XmbU11BH6xWmXh4FlWe_dCgH5QAGkIf1RefYXHTJyZs_VJWp2WgeTEuyc5il8zBg/s320/DSC01250.JPG" width="320" /></a></div>
<br />
I am driving my LEDs with LPD6803 chips, which I have a big batch of from an eBay bargain. These are chainable 3-channel, constant current, self-running PWM controllers with a 2 wire serial interface. They allow 5 bits per channel of PWM resolution (Maybe the 8-bit PWM WS2801 would have been better, but I think these LPD6803's are good enough, and they are what I had)<br />
<br />
Every single LED needs its own controller chip... thats 80 chips... how to fit them all in? I considered putting an LED driver board on every button but quickly decided that wasn't going actually to make life any easier. In the end I decided to put 8 driver ICs on a PCB and have one PCB per grid column (so 10 boards). There would be a lot of wire in there, but it seemed the most straightforward way to build it.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCbM700ICVO52M7kjDP0ICI8blXsFlUad9d1sV7iyBJIPlAExNrDlhhyphenhyphenWmFZojVkejCB_ziHVVqhWnb61JCo-znejE6A59SeK_jvBntKmLSPKk_jtOwDWNOaIVg62gFrNukYpdJNPcQOU/s1600/DSC01237.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCbM700ICVO52M7kjDP0ICI8blXsFlUad9d1sV7iyBJIPlAExNrDlhhyphenhyphenWmFZojVkejCB_ziHVVqhWnb61JCo-znejE6A59SeK_jvBntKmLSPKk_jtOwDWNOaIVg62gFrNukYpdJNPcQOU/s320/DSC01237.JPG" width="320" /></a></div>
<br />
I've recently started getting small batches of PCBs made up by a supplier in China (ITEAD), and these driver PCBs are only the second batch I have ordered. Just getting the thing wired up to see if it worked (or if I had badly messed up my PCB design) took a long time and the suspense was killing me - but finally I was able to connect up an Arduino to send some data to it... and it worked!!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5er7QVvBsGQMLDfXkp0HTKSAfPugR1_9z3xxLyRGee3FpyclmsWySyBxGSgLM9Bv2uy4C0JicjWyQEbwJv_D8jYD5chhTlKr6QPwlsqygKxwoR22izCm-f3z9D4O5rYmJyTn7zUqnveo/s1600/DSC01267.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5er7QVvBsGQMLDfXkp0HTKSAfPugR1_9z3xxLyRGee3FpyclmsWySyBxGSgLM9Bv2uy4C0JicjWyQEbwJv_D8jYD5chhTlKr6QPwlsqygKxwoR22izCm-f3z9D4O5rYmJyTn7zUqnveo/s320/DSC01267.JPG" width="320" /></a></div>
<br />
As well as the 8 x LPD6803 chips the PCB contains a 74HC165 parallel input shift register for reading the switches. I wasn't going to count my chickens until I'd also tested the input part. Wooo, that worked too! (Eventually the input and output driver chips for all the boards will be chained together so the last test will be whether that all works)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfrS_TuVShB0ggbgk8pv_isjxMUNXGLv2mR7y1QHoR8ipJahLHGj2ztQOVG_-U9bFvMFhav9GREuKg3AkMsMzM8LgHnLEOHc5yesyXmtDId0nXj0ECfiunG6io8uPMb6yCOgGrxD3f3o0/s1600/DSC01268.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfrS_TuVShB0ggbgk8pv_isjxMUNXGLv2mR7y1QHoR8ipJahLHGj2ztQOVG_-U9bFvMFhav9GREuKg3AkMsMzM8LgHnLEOHc5yesyXmtDId0nXj0ECfiunG6io8uPMb6yCOgGrxD3f3o0/s320/DSC01268.JPG" width="320" /></a></div>
<br />
The console for the grid is laser-cut 5mm acrylic. I had considered making a box completely out of acrylic, but wondered how sturdy it would be. Eventually I settled on building the box into a flight case and thought cases designed to house 19" rack-mount mixers would be perfect. The one I got is a Reloop case from eBay, where if cost about £75. Not the cheapest way of getting a housing, but it should be good for a few knocks.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwvPN6Dj-Z5d1iXaz7c6XE7i_5ptdlPLjnxhrRKoLMV94n9JUQj99t5RvzeXn7nv2qs1SjuywfQKiAz0z4gjCp8ji4RQPnrJOJ4-3kxT-OQSCVTg6xb6FdP_4WPkgW1F7vZAGZqViZjy0/s1600/DSC01181.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwvPN6Dj-Z5d1iXaz7c6XE7i_5ptdlPLjnxhrRKoLMV94n9JUQj99t5RvzeXn7nv2qs1SjuywfQKiAz0z4gjCp8ji4RQPnrJOJ4-3kxT-OQSCVTg6xb6FdP_4WPkgW1F7vZAGZqViZjy0/s400/DSC01181.JPG" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
So... looks like I have a lot of wiring to do! I am still not certain how I will drive it when its finished, but most likely I will use an Arduino.<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxV9Zs3WmkoAu4bLcZiwUI1lRQCf1VWToVO-pMK8mh2lBsIS-XDavrbco56DG4hSNGwo6ZnJeTmid0qMpCCaUVwiIWIpHgBBubeeOm9CfyUg0j-mexlFvvl01KQqzK2M_Py8b6e6GRq9I/s1600/DSC01259.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxV9Zs3WmkoAu4bLcZiwUI1lRQCf1VWToVO-pMK8mh2lBsIS-XDavrbco56DG4hSNGwo6ZnJeTmid0qMpCCaUVwiIWIpHgBBubeeOm9CfyUg0j-mexlFvvl01KQqzK2M_Py8b6e6GRq9I/s320/DSC01259.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivT4jQRODhLaWKQ-slWPoo6z488bHj7EaWYJJ8ggfLA32_gTRryYZyN6l-pEOcKZ6mwWJuD42uolbWqfAxo_LSNefZharY6DnJhrjykau2VbkyPrl53G3TqnKm7S_iSxpIg_TJMgYRi7k/s1600/DSC01265.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivT4jQRODhLaWKQ-slWPoo6z488bHj7EaWYJJ8ggfLA32_gTRryYZyN6l-pEOcKZ6mwWJuD42uolbWqfAxo_LSNefZharY6DnJhrjykau2VbkyPrl53G3TqnKm7S_iSxpIg_TJMgYRi7k/s320/DSC01265.JPG" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dyR0oa8Ya7yzCoEhiQGa9ZHSeWuXjGiKR13fPkCvVp-3K98bDN2x86Td_-_yiJi8NpRj2lawvssckx2ioAawA' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>
<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-16122008978754960562012-09-29T02:41:00.003-07:002012-09-29T08:04:37.846-07:00Making a POV globe<div class="western" style="margin-bottom: 0cm;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvpsV-5Z3SFXSh6G96SnCsuj_yL68CaJVaUE4w3UQq6iyfscfMXuNombsiYKwQN6-s613je3dCbmP00rC8UR-IXS84l6BUEnTbQ3dLqm5yOH1ECkRyqn9NfEXladZj1WqYfvhru3fRnA/s1600/DSC00991.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKvpsV-5Z3SFXSh6G96SnCsuj_yL68CaJVaUE4w3UQq6iyfscfMXuNombsiYKwQN6-s613je3dCbmP00rC8UR-IXS84l6BUEnTbQ3dLqm5yOH1ECkRyqn9NfEXladZj1WqYfvhru3fRnA/s320/DSC00991.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0LVuKpjCdmZwmJ3iCCYdHpURxeBSbkHF2iPRkyP4wCzfN2UM73sHdwX1l15ekgZFTI0hN79QggtH5iWR0K6TMUHC6_8z2VDwhPFcSqHw_5AMBPlOjmxG8l5LKzAKpdbX4W8C4oceEUU0/s1600/DSC01007.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0LVuKpjCdmZwmJ3iCCYdHpURxeBSbkHF2iPRkyP4wCzfN2UM73sHdwX1l15ekgZFTI0hN79QggtH5iWR0K6TMUHC6_8z2VDwhPFcSqHw_5AMBPlOjmxG8l5LKzAKpdbX4W8C4oceEUU0/s320/DSC01007.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
I've wanted to make a
“globe POV” for a while after seeing a totally amazing hi-res one
on YouTube a while back. The mechanical side of it (motor drive and
power supply) always put me off a bit – while I think I can design
a PCB and feel pretty confident it's going to work, motors, gears and
bearings are still a matter of kludge and guesswork for me.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I decided to make a 24
LED proof of concept project using the largest size board my free
version of EAGLE would let me work to. I originally intended to use
0805 SMT LEDs mounted on their sides but when I realised what a bitch
they are to solder like that I decided to go with good 'ole 3mm thru
holes of which I have – ahem – about 3,000 blue ones (don't ask).</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The electronics was
pretty straightforward – since I have made a few similar things
before (basically this was an Arduino project with a custom designed
PCB) The 24 LEDs are driven by 3 x 74HC595D shift registers through
100 ohm 0805 resistors. I used an Atmega328 in QPF32 package with a
miniature (Nano styley) resonator.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I usually use an FTDI
USB-TTL serial lead for in circuit programming, so I simply added
pads for the the six ICSP connections I needed for burning the
bootloader and temporarily soldered wires to them. In the past I have
routed in a proper 2x3 ICSP header but I don't think I'll bother any
more - after all, burning the bootloader is a one-off procedure and
routing in the header is a pain.<br />
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmmSV4ZNBmD-CTUXDBh984_nEV6hEbMuGAPWDPxl0sppAFDwUVwDmE5uHK6t14kWzT0Yu_Oow7kn1zCw62l7cTSvcReCRm_VWilw5GqZ-9i8bHox4YnGvnD_fx2Env0qdUqHJffF_KLGc/s1600/DSC00978.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmmSV4ZNBmD-CTUXDBh984_nEV6hEbMuGAPWDPxl0sppAFDwUVwDmE5uHK6t14kWzT0Yu_Oow7kn1zCw62l7cTSvcReCRm_VWilw5GqZ-9i8bHox4YnGvnD_fx2Env0qdUqHJffF_KLGc/s320/DSC00978.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjegpU_kSfB2SplzOFn0EMKoSsZUTVDSjsw1F7JccyXSEYjt1sOlb77F6pzKqPGCibZ-o3oriNBQma0uQU9AaNy9d6Q3ue-6u_iOScIyHU70GpIEwEDw4_ircdwHap9_m997QXl0b7tqeE/s1600/DSC00980.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjegpU_kSfB2SplzOFn0EMKoSsZUTVDSjsw1F7JccyXSEYjt1sOlb77F6pzKqPGCibZ-o3oriNBQma0uQU9AaNy9d6Q3ue-6u_iOScIyHU70GpIEwEDw4_ircdwHap9_m997QXl0b7tqeE/s320/DSC00980.JPG" width="320" /></a></div>
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The board is single
sided FR4. After etching and drilling it I tinplated the tracks (I do
this with all my boards now as it makes soldering easier, looks
cooler, doesn't take long, and isn't so expensive). After adding the
wire jumpers to the back I worked in stages to add the components and
test things.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I think its always a
good idea to test at each stage in case you need to junk the board
due to a design problem. First I soldered in the Atmega and the
resonator and burned the bootloader. When that worked I added the
serial programming header, diagnostic LED and resistor and made sure
I could get sketches to run on the Atmega. Only then did I add all
the other components when was confident the brain was alive. I
soldered all the components with an iron, with the exception of the
resonator where I put solder and flux on the pads and used a hot air
tool make the joints.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The rest of it I made
up as I went along, convinced it might go wrong at any moment. I
shaped the board to a disk with a stanley knife, steel rule, pliers
(for snapping) and sandpaper (for smoothing). Then I added in the
slots, top and bottom, to accept a 2mm drive shaft using my new
diamond edge cutting disk on my Proxxon table saw (in retrospect this
blade is fricking awesome and I should have used it to cut out the
circular PCB... you live and learn).
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Aligning the 2mm drive
shafts top and bottom was pure guesswork. I both soldered them and
used copious quanitites of cyanoacrylate superglue (with activator
spray) to hold them in place, with the help of a couple of plastic
hub wheels from a model kit supplier.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The drive shafts go
through miniature model bearings in my crudely fashioned frame (made
from MDF I salvaged from an old CD rack, cut with a plain old Bosch
jigsaw) and at the bottom there is a simple reduction gear from a DC
motor to drive it. There is a crude joinery job holding it all
together - I am not proud of it,</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
What I am more pleased
with was the electrical transfer method I used. In a previous project
I <br />
“borrowed” (saw it on a Youtube video) the idea of using an
axially mounted, graphite-lubricated, 3.5mm jack plug/socket
connection to take power to the rotating LED board while also acting
as a bearing. This time I used some chunky graphite brushes (intended
for drill equipment I think) and drilled a 2.5mm hole in each and
passed the 2mm drive shafts through them, then crudely superglued the
end of the brush springs to my frame. And it worked! In fact it works
rather well and I think I will be using this approach again.</div>
<div class="western" style="margin-bottom: 0cm;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYuFVsPUqHep8I5kECXpSkTUZqnZFXkqrnf8xxguaP47iQ6fydufF3eQ1fXWUE0pSb0_dylLaT4ZaaSy5qyjgjRGCSlRcOfXFkncJvOnYNPS7zpBE1FjSvfaZN2f2pfdQgT5oWOyepwaU/s1600/DSC01017.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYuFVsPUqHep8I5kECXpSkTUZqnZFXkqrnf8xxguaP47iQ6fydufF3eQ1fXWUE0pSb0_dylLaT4ZaaSy5qyjgjRGCSlRcOfXFkncJvOnYNPS7zpBE1FjSvfaZN2f2pfdQgT5oWOyepwaU/s320/DSC01017.JPG" width="240" /></a></div>
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
As I expected, some
balancing was needed. I superglued a couple of nuts to the back of
the board to counterbalance the LEDs on the opposite edge. Its not
perfect but it was a big improvement.</div>
<div class="western" style="margin-bottom: 0cm;">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP74K0RcTvcbnFbN9VparkAruAFGUtVFtD27sJ3YCi-Cc4s0lyOR_BMv95LT4f-K6N_h3mmcvCeKiTkOOdfEa6XtLimkbhEwc_257B1zZA3DL6p9J57EZso_bk3zDJIEKsXezU3ZgyFP4/s1600/DSC01019.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP74K0RcTvcbnFbN9VparkAruAFGUtVFtD27sJ3YCi-Cc4s0lyOR_BMv95LT4f-K6N_h3mmcvCeKiTkOOdfEa6XtLimkbhEwc_257B1zZA3DL6p9J57EZso_bk3zDJIEKsXezU3ZgyFP4/s320/DSC01019.JPG" width="320" /></a></div>
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I saved soldering the
Hall Sensor until the board was mounted in the frame, so I could make
sure I cut the legs to the right length. A small Neodymium magnet
triggers the sensor.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
In hindsight it might
have been better to somehow mount the magnet on the front of the
frame (opposite the vertical part of the frame, so 180 degrees around
the axis from where it is now). The reason is that when the sensor
passes the magnet, a new drawing cycle starts. So this is the point
where the previous draw cycle might be ended early or overrun
(depending on rounding errors due to the timer resolution and
variations in spin speed). With the position of the magnet in my
design these display “glitches” happen right at the front of the
globe and are quite easy to see – it would be better to hide them
around the back by moving the trigger point through 180 degrees, or
by placing the Hall sensor on the same edge as the LEDs rather than
opposite them.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
There is a voltage
regulator on the board and I power the motor and board from a common
supply of about 10 volts. Something that surprised me was that when
plugged the USB lead in to the programming header on the board, the
motor received power and span up. I didn't think the current could
cross the regulator in the opposite direction so it was a bit of a
nasty suprise (and presumably it does the regulator no good either).
A 1N4001 rectifier diode on the +10V supply going to the board brush
solved the problem. I was very glad I found this issue before the
motor was attached to the frame or I could have smashed the board.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
When it was all fitted
together I tested it out with a simple set of vertical and horizontal
lines, rendering as a wireframe globe, and it looked great. Next I
wanted to display a pixellated map of the world... to get this done I
found a suitable Mercator projection image on Google images and
resized down to the target 24 x 64 pixels in PaintShop Pro (still my
drawing tool of choice for its easy work with small bitmaps). Quite a
bit of manual tweaking was then needed to get a decent recognisable
monochrome image.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmbfitLRImJHjef3UpzdRd-1VWX_CVoro3GP8J5h6DCp65t3Bml8tuo_555XViOh7-LP0IBpIjMy3eZCJmV6argTrjAco6w4nQNzUQ3Hb7AuoP4hludFDXTpF1_dS9N0EcbP_DXDrGCwI/s1600/Image2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmbfitLRImJHjef3UpzdRd-1VWX_CVoro3GP8J5h6DCp65t3Bml8tuo_555XViOh7-LP0IBpIjMy3eZCJmV6argTrjAco6w4nQNzUQ3Hb7AuoP4hludFDXTpF1_dS9N0EcbP_DXDrGCwI/s320/Image2.gif" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmZ9K9e-Mu_ZnHgrU0oSE3GNGF5-t9JsJ3dfdYh-jTEh-qcyCypjqKR7qRTTKLJy6YC9zUMCLgG66MGzFppKwupgnL3pKxfZ1ncMonqsjD85gMnUUIFQoKTWeFyfegoYlyImQAJ-3skk/s1600/Image3.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMmZ9K9e-Mu_ZnHgrU0oSE3GNGF5-t9JsJ3dfdYh-jTEh-qcyCypjqKR7qRTTKLJy6YC9zUMCLgG66MGzFppKwupgnL3pKxfZ1ncMonqsjD85gMnUUIFQoKTWeFyfegoYlyImQAJ-3skk/s320/Image3.gif" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
The next step was to
calculate the bitmap values to insert in the code. I needed data as 3
bytes for each vertical scan column through the image (64 x 3 bytes
of data) and I needed the low bit positioned at the vertical top of
each byte.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I usually use a
spreadsheet to do this kind of thing (OpenOffice). I wondered how I
might import the mono bitmap image data directly into the
spreadsheet, but as I was in a hurry and the image was small I just
retyped it manually. To help keep track I divided the image into 8x8
squares and highlighted them chessboard fashion in yellow. This meant
I could work one square at a time and it only took 15 minutes or so
to enter the data into the spreadsheet and use formulas to calculate
the bitmap values I needed.
</div>
<div class="western" style="margin-bottom: 0cm;">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKEGlw7YwmPldFYnEne8LJoFyOg2QVWtPoC9eSlW7JbIvpZvcolfPhUCZ0kizvYJwhFNOYNxqNQXmafb-Ff-Ndd3wS9TsnHmbSYx4XHsQIIia6KmWNpFOVRQOddB0syTFbaGHKrPqq9xQ/s1600/Image1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKEGlw7YwmPldFYnEne8LJoFyOg2QVWtPoC9eSlW7JbIvpZvcolfPhUCZ0kizvYJwhFNOYNxqNQXmafb-Ff-Ndd3wS9TsnHmbSYx4XHsQIIia6KmWNpFOVRQOddB0syTFbaGHKrPqq9xQ/s320/Image1.gif" width="320" /></a></div>
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I copy/pasted the
values from the spreadsheet into the Arduino sketch, programmed the
globe and fired it up – and it worked first time! The Pacific
looked a bit empty though, so I went back and added Hawaii.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
I put a 32kbit I2C
EEPROM on the board so that I can store a decent set of image data to
make animations possible. I haven't done anything with it yet.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Here is a brief
description of how the code works. Almost all the POV projects I've
made work in this way...</div>
<div class="western" style="margin-bottom: 0cm;">
The sketch sets up the
Atmega328's internal timers 1 and 2 to run at the same rate (1/64 of
full clock speed). This means they are counting at a very high rate
(I think it works out as 62500 counts a second).</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The sketch uses
“interrupts” – an interrupt is a way for a specific hardware
event (like a pin changing value or an internal timer reaching a
certain threshold) to cause a specific piece of program code (called
a “service routine”) to be run immediately. This means the
program does not need to keep “polling” things like inputs and
timers, which would not be very accurate at these timescales.
Interrupts are really the only way to get the consistent timing
accuracy we need.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
We use two interrupts,
one is called when the hall sensor fires and the value on pin 2
(Interrupt 0 pin) changes. The service routine for this interrupt
captures the value of timer 1 and resets the timer. This value is the
number of timer ticks in one complete rotation of the board.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
Now we divide this up
to get the number of timer ticks in a single “sector” (vertical
scan column width). Although there are 64 columns in the image, I
actually insert an artificial blank column between every pair of
image columns to cleanly seperate the “pixels” rather than
letting them run together into streaks (it just looks nicer) so I
treat the image like it has 128 columns.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
So the timer count is
divided by 128 and the result is put into the timer 2 “period
register”. Now when timer 2 reaches the value of the period
register it is automatically reset and another interrupt fires. The
service routine for this interrupt will therefore get regularly
called 128 times on each revolution – perfect! Now we just need to
load values from the image data into the LEDs. We need to keep a
count of how far round the revolution we are and we can add an
incrementing offset to make the image appear to spin. It is also here
that we turn off all the LEDs on every other call to add the gaps
between the pixels.</div>
<div class="western" style="margin-bottom: 0cm;">
<br /></div>
<div class="western" style="margin-bottom: 0cm;">
The LEDs are loaded by
simple shift register stuff (Check the Arduino tutorials if you don't
know what a shift register is) . Speed is of the essence, so the
three shift registers are loaded in parallel using 3 data lines and
common clock lines. I avoid using digitalWrite() to drive the output
pins on anything like this and go direct to the port registers since
it's an order of magnitude faster!<br />
<br />
*** Source code, EAGLE files and image data available at<br />
<a href="https://github.com/hotchk155/PovGlobe">https://github.com/hotchk155/PovGlobe</a><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/rZQHkbexKrc?feature=player_embedded' frameborder='0'></iframe></div>
<br /></div>
hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com37tag:blogger.com,1999:blog-8909459762367220480.post-68445755136832725992012-06-06T13:19:00.001-07:002012-06-06T13:19:41.828-07:00Stomp box clone (Big Muff)At the BuildBrighton hackspace we have a workshop planned for DIY stompbox builders. We'll probably be concentrating on a Fuzzface clone since thats nice and simple. Just to make sure we knew what we're doing we put together a couple of Fuzz face circuits last week, and they worked!<div>
<br /></div>
<div>
Inspired by this, and being a lover of the Line5 "Fuzz Pi" (Emulation of the Electro Harmonix Big Muff Pi) model for bass and guitar, I decided to try to make a Bigmuff clone of my own - complete with a proper case et al. I worked from (and fully credit) the following online schematics</div>
<div>
<a href="http://fuzzcentral.ssguitar.com/schematics/bigmuffpischem.gif">http://fuzzcentral.ssguitar.com/schematics/bigmuffpischem.gif</a> </div>
<div>
<a href="http://www.generalguitargadgets.com/diagrams/bmpsc.gif">http://www.generalguitargadgets.com/diagrams/bmpsc.gif</a> </div>
<div>
<br /></div>
<div>
I also added a bypass and a three-state indicator LED showing "standby" (guitar connected, effect bypassed) as a dim glow and "on" as a bright glow (just with 2 different series resistances). This needs a 3PDT switch.<br /><div>
<br /></div>
<div>
I was pretty pleased with the result... a nice edgey fuzz with enough bottom to work well on a bass (my main instrument)</div>
</div>
<div>
<br /></div>
<div>
Eagle files available at <a href="https://sites.google.com/site/skriyl/Home/bigmuff-pi-clone">https://sites.google.com/site/skriyl/Home/bigmuff-pi-clone</a></div>
<div>
<br /></div>
<div>
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/CB6jfqO0sow?feature=player_embedded' frameborder='0'></iframe>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaR2N6KMOV4pFvGgWWxMr9MVLcU2WNl3NiPUidHHKMNbF_V5FDR93NDqlE7XhJ0u2SEay729a_UR0dOKNBiCTexpMi7WXpIuNa-jtJPcarL7fgE1CbxOKNSWDCocUaA9_MLLSZYHrlC78/s1600/DSC00152.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaR2N6KMOV4pFvGgWWxMr9MVLcU2WNl3NiPUidHHKMNbF_V5FDR93NDqlE7XhJ0u2SEay729a_UR0dOKNBiCTexpMi7WXpIuNa-jtJPcarL7fgE1CbxOKNSWDCocUaA9_MLLSZYHrlC78/s320/DSC00152.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN6y4oAkaLRqSbfuB24ZXeOAfYJnhGK6qgp5H94Eyeq18daKs2oH-ALklNgcf2OI1kcEeesalzzOG6eD4cBYbFR_MSP5cB94KgDYdMq6itT2ZBTunM8TbdMu6VY8obfD79vItjrvbeKaY/s1600/DSC00157.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN6y4oAkaLRqSbfuB24ZXeOAfYJnhGK6qgp5H94Eyeq18daKs2oH-ALklNgcf2OI1kcEeesalzzOG6eD4cBYbFR_MSP5cB94KgDYdMq6itT2ZBTunM8TbdMu6VY8obfD79vItjrvbeKaY/s320/DSC00157.JPG" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMjgcIU7NF0jvk6mM_knvwiJMEhvnJPWvgV9v6lpYXqtUDps2fLir8KVSJth-IDxjTdyNK3qCXzLitP4H0QRm1oiMnbiefyha8f0eRZRQGMTTe4VtX0JRFFgFgp974W8kVnuCbkx7vh5w/s1600/DSC00158.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMjgcIU7NF0jvk6mM_knvwiJMEhvnJPWvgV9v6lpYXqtUDps2fLir8KVSJth-IDxjTdyNK3qCXzLitP4H0QRm1oiMnbiefyha8f0eRZRQGMTTe4VtX0JRFFgFgp974W8kVnuCbkx7vh5w/s320/DSC00158.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xlwK_QdkAnkTXAwq1WytpuI9MgOWSHp5L7KAEAl2KGtdFhDLWnZiFa7mxPjesVq0UJl8eETdJF9__ARk2ouVMvQlyF6USZWK9eeAOM74TaVIcSF5NaZNldBGqsqkAjn6RWya8wqqY0I/s1600/DSC00164.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9xlwK_QdkAnkTXAwq1WytpuI9MgOWSHp5L7KAEAl2KGtdFhDLWnZiFa7mxPjesVq0UJl8eETdJF9__ARk2ouVMvQlyF6USZWK9eeAOM74TaVIcSF5NaZNldBGqsqkAjn6RWya8wqqY0I/s320/DSC00164.JPG" width="320" /></a>
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCISbwnrGH_Aq2ST_cIuWJAZybGB40YmZPM1PMDfxdc6L_fQUOK375qgEA0zNm4BQZq5glcxm_xJ8b32M9wKh03q2FgtFewEtw8Ap_sn9Nb8S4ti3MrbA68NwI2lto2eKmzFyKZMjnuo0/s1600/colour.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCISbwnrGH_Aq2ST_cIuWJAZybGB40YmZPM1PMDfxdc6L_fQUOK375qgEA0zNm4BQZq5glcxm_xJ8b32M9wKh03q2FgtFewEtw8Ap_sn9Nb8S4ti3MrbA68NwI2lto2eKmzFyKZMjnuo0/s320/colour.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0VYfeUShUAofEJ4pVB7Qn-VfufkEqPJwiOhaiyb_DSQuyhy7Bml1z1C4o6lJAmLqFoHvXNPr5XHUMUoQSBBKlZqIGg3QyjVeVs39w5nDha7mcgpVnRzQ4_t5yHxEQXzekOdChtZaHRkI/s1600/mono.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0VYfeUShUAofEJ4pVB7Qn-VfufkEqPJwiOhaiyb_DSQuyhy7Bml1z1C4o6lJAmLqFoHvXNPr5XHUMUoQSBBKlZqIGg3QyjVeVs39w5nDha7mcgpVnRzQ4_t5yHxEQXzekOdChtZaHRkI/s320/mono.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrDKWkWJsuAPa_irxGANLxGxCCIYylbfyOgL1tTyK0wbM1gCUv9egiBgPSpDXcK2mVoZO0cxPdExGAEI1rzqCJgZRQq6vTmXO1N9oA-G7XVYhPFMJlcK8PfHwYK3ZkuRbh-jMjHdwfGjo/s1600/schem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrDKWkWJsuAPa_irxGANLxGxCCIYylbfyOgL1tTyK0wbM1gCUv9egiBgPSpDXcK2mVoZO0cxPdExGAEI1rzqCJgZRQq6vTmXO1N9oA-G7XVYhPFMJlcK8PfHwYK3ZkuRbh-jMjHdwfGjo/s320/schem.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div>
<br /></div>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-7207925755933472462012-04-06T09:53:00.000-07:002012-04-06T09:53:06.948-07:00WeenyPOV on Scalextric carMikepea at BuildBrighton is building a Scalextric setup with a difference! One of the many features we're thinking about is a POV display on the roof of a car which will plot out a graphic image as the car moved round the track. The first test was to see if the concept would work (basically are the cars fast enough to get a decent POV effect?). To try this out I made a quick little POV circuit on a 1" square of flexible copper clad. There is a PIC16F688 directly driving 10 green LEDs and there is no trigger or synch on it (it just runs continuously)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvmFq215_t7a8kuatqzBuxPkLwnDDVjH5TqBIrywuacB9LeCLdb6ntz9DXxePaq1sleVOc_rZ3aG-xEHABhGsfDuYBSyt71nKm_FIudsoExr2s4hBxcDNg5WIZFW0QpI8by9yaTmTU0-E/s1600/DSC00009+(4).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvmFq215_t7a8kuatqzBuxPkLwnDDVjH5TqBIrywuacB9LeCLdb6ntz9DXxePaq1sleVOc_rZ3aG-xEHABhGsfDuYBSyt71nKm_FIudsoExr2s4hBxcDNg5WIZFW0QpI8by9yaTmTU0-E/s320/DSC00009+(4).JPG" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt1whvXxiU5ouRDiA4IVNRwkSrQ7AjdukdwWgFS9QgN1yQLAE42V2APgHLJoKSPZBlwYKaEvCaNCEMwWdK7i_116oO3oMdcx_Oz-WENQ5nOfn8lplF4BUxOBjCOwtZzrBdlgAAPSwTsYw/s1600/DSC00013+(4).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt1whvXxiU5ouRDiA4IVNRwkSrQ7AjdukdwWgFS9QgN1yQLAE42V2APgHLJoKSPZBlwYKaEvCaNCEMwWdK7i_116oO3oMdcx_Oz-WENQ5nOfn8lplF4BUxOBjCOwtZzrBdlgAAPSwTsYw/s320/DSC00013+(4).JPG" width="320" /></a></div>
<br />
<br />
For the first try we opened up a car and took our power from the +5V and GND pads of the programming header on the Digital Scalextric controller board inside the car. This seemed to power the POV board fine but the car itself would not work. Unfortunately it still didn't work when the POV was removed... oh crap! not sure exactly what happened there, but Mike was very good about it and offered another car...<br />
<br />
Worried about frying another car, we took a different approach this time and added our own voltage regulator and smoothing caps, taking power directly from the diodes that rectify the AC being picked up from the track. We only had a big 7805 regulator to work with, but actually it looks pretty cool stuck to the hood with a couple of caps. Very 1970's hot rod.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR2a3ZYPw6Ge4TDZuVxhvBX8Q5hpbia-A5CCN-mQIxk067GzathyphenhyphenO0mj8yca6nxlU3MjYEeUGNGjm7JmFX3FQ8tRbe8IXnhY1NppP-waAqJnpaUX7nEGPfuOnmZICJSBojvT7KM-zDqVc/s1600/DSC00044(1).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhR2a3ZYPw6Ge4TDZuVxhvBX8Q5hpbia-A5CCN-mQIxk067GzathyphenhyphenO0mj8yca6nxlU3MjYEeUGNGjm7JmFX3FQ8tRbe8IXnhY1NppP-waAqJnpaUX7nEGPfuOnmZICJSBojvT7KM-zDqVc/s320/DSC00044(1).JPG" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4GZNuYMmz4G-8xA9mr5g74TFGhB1H1w0om5mVfYUyN9sCMyP2FIlTHxej443jLmLPF7nWret-Lw8DrLJ6aPf9cbI-Xj3AY5gGJYMaDb1hP4-Y6aIqHGGMLBltmxT2U3TYi6wccNFWmyw/s1600/DSC00043(1).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4GZNuYMmz4G-8xA9mr5g74TFGhB1H1w0om5mVfYUyN9sCMyP2FIlTHxej443jLmLPF7nWret-Lw8DrLJ6aPf9cbI-Xj3AY5gGJYMaDb1hP4-Y6aIqHGGMLBltmxT2U3TYi6wccNFWmyw/s320/DSC00043(1).JPG" width="240" /></a></div>
<br />
<br />
More importantly it worked.. that is until one time the car rolled and the POV circuit on the roof seems to have got a zap directly from the 12VAC on the track and the PIC died, leaving all 10 LEDs jammed on. Insulation is obviously something to consider for the next time!<br />
<br />
So was the concept proved? it seemed to work pretty well - especially on long exposure photos. I had it displaying some particularly peurile text, but it would probably work better with small graphical images...<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPdz-QVmFHJuexkrcWOEj6YYOlRorc071vn_urzejccxT9UNJeQ8yRemtNLnhoLJOczyTKAKrq1huj-hZR4fqI0eNOgznso2Dl1qylL9kKxuKFreI-fVOsMQbEv3mtzsvB1hfWSLR_dH0/s1600/DSC00031(1).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPdz-QVmFHJuexkrcWOEj6YYOlRorc071vn_urzejccxT9UNJeQ8yRemtNLnhoLJOczyTKAKrq1huj-hZR4fqI0eNOgznso2Dl1qylL9kKxuKFreI-fVOsMQbEv3mtzsvB1hfWSLR_dH0/s320/DSC00031(1).JPG" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPe20Ea6wR48DtCK05PjWqz10wsTIqsXHXgsfh_r0xGT-iBAmXj5InxbF8bH5jf8MUYEIhPfOOsTSFQzXByZVszPmlTpdHseFPJIz97Ey8G1UdeoV95OZ09eQFaHUrrQmhTV156WuowqM/s1600/DSC00038(1).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPe20Ea6wR48DtCK05PjWqz10wsTIqsXHXgsfh_r0xGT-iBAmXj5InxbF8bH5jf8MUYEIhPfOOsTSFQzXByZVszPmlTpdHseFPJIz97Ey8G1UdeoV95OZ09eQFaHUrrQmhTV156WuowqM/s320/DSC00038(1).JPG" width="320" /></a></div>
<br />
<br />hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com1tag:blogger.com,1999:blog-8909459762367220480.post-37382234064444661592012-02-23T14:48:00.003-08:002012-02-24T06:22:37.150-08:00Playing with MIDI ping pong tableWill and I trying out the sensing and early version of MIDI handling on one half of the table.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/9QdFSXRQlRA" width="560"></iframe><br />
<br />
Video by Will Nash. Will's site is at<br />
<a href="http://www.willnash.co.uk/">http://www.willnash.co.uk</a>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com0tag:blogger.com,1999:blog-8909459762367220480.post-33469912270084212452012-02-23T14:39:00.001-08:002012-02-24T08:08:25.490-08:00MIDI Table Top Sensing...It's working!<br />
I thought it was about time to give an update on the MIDI ping pong table sensing stuff. I've spent quite a lot of time on it, been through a few iterations of the hardware, and learned a lot! I started this as a total newbie as far as analog electronics go (Op-amps etc) and now I think I have at least grasped a few basic techniques. I'd like to try to share the lessons I learned, but I'll warn you now that you'll need to be quite interested in this stuff to get through this post :o)<br />
<br />
Going back to the start, my first sensing attempt was to use piezo sensors and an unbuffered inverter (4069) as an amplifier (an idea picked up from Nicholas Collins' book 'Handmade Electronics Music'). I fed the amplified signal into a Darlington transistor which I hoped would give be the logic "hard edge" signal I needed for my timing code. The result was very sensitive, however there were a few things going on that I didn't understand (sometimes the output of the transistor seemed to oscillate without any input). At the time I seemed to be picking up a lot of electrical noise and became convinced the amplifier circuit needed to be closer to the piezo sensor.<br />
<br />
My second iteration used a proper op-amp (An LM358 configured for single supply) which was placed close to the piezo sensor. The circuit was still very sensitive but the "noise" problems thankfully seemed to have gone away. I tried feeding the output of the op-amp to a digital input pin on a PIC but I was finding that the when a pulse was detected the digital input would trigger not just once, but many times over microsecond timescales and this would cause problems for the code (e.g. pin change interrupt fires but the pin state does not seem to have changed)<br />
<br />
At the time I didn't fully understand the reason for the digital input state flipping about like this and could only assume it was some kind of high frequency harmonic component of the actual vibration being picked up (now I know better... see below). However I needed to do something about it so that my microcontroller code would have a decent length pulse it could detect reliably. I added a 555 circuit configured as a "retriggerable monostable" (this was something I read about online). Basically once the first ON pulse come into the 555, no matter how fleeting, the 555 will hold the output HIGH for a controllable timed period, so all the spurious follow-on pulses are masked and we don't need to care about them. The output became nice and clear for the interrupt pins on the MCU and worked reliably.<br />
<br />
So by now I had an LM358 and a 555, plus a bunch of caps, diodes and resistors, that I wanted located right up close to the piezo sensor. I decided to make the circular surface mount boards shown in a previous blog post. I suspected at the time they might be a bit over-engineered, but as long as they worked I didn't care.<br />
<br />
Then I started focusing on the triangulation code and noticed occasional inconsistencies in the sensor timing readings, which I became convinced were due to the differential input levels at which each sensor fired. This makes sense because the "front" of the sound rippling out over a table top is not a hard vertical edge, but rather a slope, with the vibrational displacement ramping up from zero to to its maximum as the wave passes under the sensor. The level at which the sensor "triggers" will depend on its own sensitivity level, but not all 4 sensors will have exactly the same trigger levels. Now, since the speed of sound in dense wood is very high, a small difference in trigger level might translate to a big difference in the calculated position. Damn!<br />
<br />
I was helped here by Matt Waterman, who got in touch with me via my blog and suggested using zero crossing detection as a solution to this. My understanding here is that once the initial wave front passes the sensor and triggers it, the vibrational displacement will reach a positive peak, then fall down to to zero, then reach a negative trough before repeating. At some point the displacement it crosses the "zero" value, and this is a distinct point in time which can be detected without the same sensitivity difference issues (since we're comparing positive level with negative level, not two different positive levels, this can be detected more accurately). Since the positive wave front should have the same front-to-back width across all the sensors, the zero-crossing time measurement should be just as suitable for my purposes as a hypothetical perfect measurement of the arrival time of the wave front (becaise we're working with relative time of arrival at the sensors, not the absolute times of arrival)<br />
<br />
To work with zero crossing I had to remove the 555 from the circuit (since this masked all the input after the initial wave front triggers the sensor, including the initial zero crossing point). I added an LM339 comparator configured for zero crossing detection (based again on internet research), so the Arduino needed to receive digital inputs from the initial pulse (The Op-amp output) and the zero crossing pulse (the Comparator output). The first zero crossing trigger after the wave front trigger would be the point in time we'd be interested in. With the 555 gone, I was of course back with the issues of the crazy pulse trains that it had been hiding from me... Double Damn!<br />
<br />
After more headscratching, Googling, breadboarding and staring at my old CRT oscilloscope and a USB logic analyzer, I tried putting a Schmitt trigger inverter IC in there and Hey Presto!... a perfect clean pulse.<br />
<br />
Now if I'd done this before I would have reached for the Schmitt trigger IC right at the start, but this is all a learning curve, and this was one of the most useful things I learned: When forcing an analog level to a digital level use a Schmitt Trigger! All I'd ever used them for was to make oscillators (like Ray Wilson's excellent WSG noisebox)<br />
<br />
So how does the Schmitt trigger IC help? Well a trace I got from my USB logic analyzer showed what was going on... Think about an analog sine wave being forced to a digital pulse wave. Now, if you simply connected the analog level to a digital pin you'd expect that above a certain threshold the digital level is HIGH and below the threshold the level is LOW right? This is mostly true, but the problem is that round about the threshold level, on the up or down slope, the digital value goes crazy... it flips *really* fast between HIGH and LOW because its in a "grey area" - it really doesn't know if it should be HIGH or LOW and tiny fluctuations and noise push it one way and the other. This goes on until the input voltage changes enough to get out of this fuzzy "no-mans land" range and we get a stable HIGH or LOW<br />
<br />
However, stick a Schmitt trigger in there and there now there are TWO thresholds - one for the rising level and one for the falling level. In the no-mans land between the two, the output of the Schmitt trigger does not change. The result is a nice clean LOW - HIGH - LOW transition. The grey area is gone.<br />
<br />
With a Schmitt trigger, the zero crossing worked! And it worked even with a long wire between the Piezo sensor and the op-amp, so I could put all the electronics on a single board and for all sensors. Not only that, but the direct Schmitt trigger output was now working just as well for timing as the zero crossing comparator output! Removing the comparator now simplifies the whole thing and halves the number of digital inputs needed to read the sensors. Result!<br />
<br />
So, after that long journey I learned quite a lot. If you managed to read this far I hope it helps you too. I would also say never underestimate the value of an oscilloscope - even a battered old CRT one like mine. For digital stuff a cheap USB storage logic analyser (I used a SCANLOGIC built from a 40 Euro kit) is also invaluable for seeing whats going on in that crazy world of the microsecond timescale.<br />
<br />
So, my design now reads 8 piezo sensors (4 for each corner on side of a ping pong table). The sensors are simply wired with screened cable to a central amp box. This has 4 LM358 dual op amps (one channel per sensor) which are now on a 5V dual supply (from a nice board from Futurlec that generates a stable and noise-free bipolar supply from a single input supply). The op amp outputs go through a pair of 74HC14 hex Schmitt trigger inverters and from there to digital inputs of an Arduino Nano.<br />
<br />
The Nano uses interrupt on pin change to simply flag the change of pin state, so that a flag can be polled instead of the port input (in case there is a rapid change and a signal is missed). There are two state machines running timing impulses from each side of the table, and the conversion of time-of-arrival information to coordinates is done using the fast approximation approach I described before.<br />
<br />
The Nano drives a set of diagnostic LEDs - 8 green LEDs representing the sensors and 2 red LEDs which light when there is a misread (not all sensors firing together on that side of table). The coordinate is mapped into an 8x8 grid and sent out as MIDI using the following encoding method:<br />
<br />
MIDI note = 16 * row + col<br />
<br />
where row and col are 0..7<br />
<br />
The two sides of the table are split into two different MIDI channels. These are to be fed into a second Arduino which does some processing of the raw notes to create a more interesting set of MIDI notes and controllers based on some "intelligence" about gameplay (e.g a "rally" is made up of notes alternating between 2 sides of the table and finishes when there are 2 bounces on the same side or no bounce for a timeout period). The MIDI output from the second Arduino will be used to drive a synthesizer to create the eventual sound of the game.<br />
<br />
The note mapping scheme described above is (deliberately) the same as that used in the Novation Lanunchpad. Using MIDI-OX to route MIDI inputs to outputs, this means I can use a pair of Launchpads as a handy display to indicate the detected posiiton of a bounce. It also allows me to use a pair of Launchpads in place of the table while testing the MIDI engine on the second Arduino. I can just alternate pressing buttons on each Launchpad and it things there is a rally going on!<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiefg_8TjZbzGBGVLGAwYMbhlKSraKhwF2FlgW1LlTble5OCciCGwQnIQd0LP-cyoGFTgXlegZoxTHKS13bHkENVTN7Kl-K9wiQqJ_gzHNFyN88A3_Y_dEazj_3F5JheA2tUMQogn74FXw/s1600/DSC00038+%25282%2529.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiefg_8TjZbzGBGVLGAwYMbhlKSraKhwF2FlgW1LlTble5OCciCGwQnIQd0LP-cyoGFTgXlegZoxTHKS13bHkENVTN7Kl-K9wiQqJ_gzHNFyN88A3_Y_dEazj_3F5JheA2tUMQogn74FXw/s320/DSC00038+%25282%2529.JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXR9oZfnfzWpd669MqNkuBYRmftzXBQ8cCIy-_42T6eDKLEalO_qMINt5Kz77WQoCPD6-0UrpS62cTj2h3vTuwDM8XgKoKDfasRjwBfbrR6Pok3OV0sy11RiVUx32NYFWhlnUhMfx6UiY/s1600/DSC00035+(2).JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXR9oZfnfzWpd669MqNkuBYRmftzXBQ8cCIy-_42T6eDKLEalO_qMINt5Kz77WQoCPD6-0UrpS62cTj2h3vTuwDM8XgKoKDfasRjwBfbrR6Pok3OV0sy11RiVUx32NYFWhlnUhMfx6UiY/s320/DSC00035+(2).JPG" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBw6hPYXnmWGMUFAsJ4jVtPWLlj7hDp_fIUP4Mk7KfcnTRENTu1-f_3nb5sLDtrFfftRZI1bOHcM5ZsctGG2me7D672yFMHUEl-m1WcWe44jBoiRrRCN3APkgneSsyAk5QzYLIqGGDPVM/s1600/DSC00031.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBw6hPYXnmWGMUFAsJ4jVtPWLlj7hDp_fIUP4Mk7KfcnTRENTu1-f_3nb5sLDtrFfftRZI1bOHcM5ZsctGG2me7D672yFMHUEl-m1WcWe44jBoiRrRCN3APkgneSsyAk5QzYLIqGGDPVM/s320/DSC00031.JPG" width="320" /></a></div>hotchk155http://www.blogger.com/profile/13452320361660792114noreply@blogger.com2