Matt Reid
Electronics Design Specialist
1.0 PREAMBLE
The idea for this project came to me when friend, who is a tattoo artist, and I were talking about some of the limitations on existing supplies and features she’d like to eventually see. Then I thought I’d be able to build something with some of her specs in mind.
1.1 Some Background on Tattooing
Often when artists are tattooing someone, they need two different needles: one for lines, and one for shading. When you use either, the voltage and the way the gun(also called the tattoo machine) is tuned are slightly different which makes it a bit of a hassle if you want to quickly switch between drawing lines and filling in colors. Most artists will have two or more machines on hand, each loaded with the correct needle needed for the piece they are drawing. This is why some tattoo power supplies have multiple voltage presets you can save. However, most of these power supplies only have one physical output, meaning you have to unplug the current machine you are using and plug in the one you want to use.
Another feature some power supplies have is a screen which tells you the duty cycle and the frequency the machine is running at. The duty cycle is basically the amount of time the coils are energized vs the amount of they are not. There is an armature bar which makes contact with an adjustable screw completing the circuit which energizes the coils. Since the coils act as an electro magnet the armature bar is pulled towards the coils and the circuit is disconnected because the armature bar no longer makes contact with the screw and the bar returns to its original position. This happens over a hundred times a second and this is what creates the buzzing sound. The needle is secured to the end of this armature bar and the needle is then able to puncture your skin. Depending on the kind of lines the artist wants to do, they need to tune the machine by adjusting the screw and adjusting the DC voltage to the machine.
1.2 Key Features
The artist I was designing the supply for wanted to have multiple outputs each with their own adjustable settings. The reason for this being she was that she did not want to have to fiddle with cables when working on a client. She thought it would make the process more efficient if both machines were plugged in all the times and you simply selected between which machine you wanted to operate with the push of a button.
The other request was that she had a large latching button to turn on and off the machine. She was annoyed by the fact that most supplies needed a pedal to turn on and off the machine and she found it would be much easier to only have to plug in the machines and not have any pedals to deal with. She also wanted push buttons to adjust the voltage settings. Since the power supply is covered in plastic during all tattoo sessions, trying to turn a potentiometer just wasnt practical for her. Lastly, we thought it would be neat if we added a bluetooth speaker to the unit. Since she doesnt like to use headphones when tattooing, we thought this feature would let her and the client be able to listen to music without having the extra set up of another speaker.
Custom Tattoo Machine Power Supply
3.0 THE HARDWARE...
I found the enclosure at a local electronics parts store. It was important to the artist that she could operate the power supply with only one hand so having a slanted front panel would keep the power supply from sliding back when the buttons were pressed. The plastic panels and PCBs were machined on a CNC mill. For the "brains" of this circuit, I chose to use the PIC16F88 which I programmed in Picbasic Pro. See code attached at the bottom.
The front panel was made by painting one side of some clear acrylic and machine the logo and words backwards. I then filled in the words with white paint.
4.0 CIRCUIT DESIGN
4.1 Voltage Control
To control the voltage to the output channels, I decided to use only one regulated source rather than have one for each output. The reason for this is because there was only ever going to be one output being used at any given time. Having a regulator for each output means I would of had to add twice the amount of control circuitry so having only one simplified things. To direct the regulated voltage I used two mosfets controlled by the microcontroller. I still used a latching push button to turn the outputs on or off. I could of also controlled that using the microcontroller but I didn't want to completely rely on the software for that part partially because I wanted a way to be able to shut off the output quickly in case of any software hang ups.
If you look at section D2 of the schematic you can see I used a digital potentiometer to control an output voltage to a op amp. I did this for a couple of reasons...You can't run a digital potentiometer at voltages above its voltage rail, and since I needed the output to go up to at least 14 or 15 volts this wouldn't work(the potentiometer chip is powered using 5 volts). Also the digital potentiometer could only handle small amounts of current so that's another reason I needed to use an Op-amp. I could of also used a digital to analog converter for this but I happened to have a bunch of these chips on hand and I wanted to use them for a project.
4.2 Voltage Output Display
To measure the voltage with the microcontroller and display it I had to use a voltage divider since the Pic is powered by 5 volts and I wanted it to measure voltages up to 15 or 16 volts. What I ended up doing was recording the A to D value every 1 volt up to 15 volts. I then found the slope and intercept using excel. Using some integer math, I was able to accuratly measure the output voltage within .1 Volts. Not super accurate, but for this application it was accurate enough.
4.3 Duty Cycle Measurement
To measure the duty cycle I used an INA138 high side current monitor. The maximum voltage this chip could withstand is 36 volts so since the operating range of a tattoo machine is well under that this chip was a perfect fit. R27 is the what sets the gain of this chip. I tried to set the gain as high as possible so the signal clips every time the coils are energized so the output of the INA138 is almost a square wave. I then used a comparator to turn the signal into a true square wave. One thing I found was that every time the coils were on, the output square wave from the current monitor wasn't constant. There were small blips in the signal so I used a 555 timer in monostable mode to get rid of those. At the output of the 555 timer now you have a solid square wave every time the coils are active. This signal is then routed to the pic microcontroller. The pic waits for a rising edge and turns on timer0 as long as the square wave pulse is high. As soon as it returns to zero the timer is stopped and that timer value is saved to the variable "pulsehigh" and the timer is cleared and restarted. The timer then measures how long the pulse is in a low state. When the signal rises the timer is stopped and the timer value is saved in another variable called "pulselow". Some math is then done to convert the timer values saved into duty cycle and frequency.
PICBASIC PRO CODE:
*note* Code is best viewed from a computer. When viewed on mobile the spacing is off.
'****************************************************************
'* Name : Tattoo_machine_PS.BAS
'* Author : Matthew Reid
'* Notice : Copyright (c) 2016 [select VIEW...EDITOR OPTIONS]
'* : All Rights Reserved
'* Date : 9/14/2016
'* Version : 1.0
'* Notes :
'* : external oscillator 16MHz
'****************************************************************
include "modedefs.bas"
#CONFIG
__config _CONFIG1, _EXTCLK & _WDT_OFF & _MCLR_OFF & _BODEN_OFF & _LVP_OFF
#ENDCONFIG
trisb = %10101001
trisa = %11000011
OSCCON = %00001000
CMCON = $07' disable comparators
ANSEL = %00000001
'--------a to d stuff---------------
Define ADC_BITS 10 ' Set number of bits in result
Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS
adval Var Word
counter var byte: counter = 0
ADCON0.7 = 1
'------------------------
'-------------- digi pot stuff
plus var porta.6
minus var porta.1
Rst var porta.4:Rst = 0
clk var porta.3:Clk=0
dq var porta.2:Dq=0
I var byte
Wiper0 var byte
Wiper1 var byte
ch1_pot var byte
ch2_pot var byte
'read eeprom previously saved values
read 5, ch1_pot
read 6, ch2_pot
'150 = 10.21 volts , 50 = 4.27
Wiper0= 50
Wiper1=50
'-----------------------------
'define external oscillator frequency
Define OSC 16
'vout input to micro
vout var portb.5
'channel change stuff
ch1 var portb.1: ch1 =1
ch2 var portb.2: ch2=0
sel var portb.0
current_channel var bit
'read current channel from eeprom
read 7, current_channel
last var bit
'timing measurement variables
pulsehigh var word
pulsehigh1 var word
pulselow var word
pulselow1 var word
duty var word
freq var word: freq = 100
dummy var word
signalinput var portb.3
t1on var t1con.0
gosub intro_screen
gosub cleartimer
gosub set_pot
mainloop:
'minus 2 to wiper variable by pressing plus
if minus = 0 then
'checks which channel unit is currently on
if current_channel = 0 then
'keep integer from rolling over
if ch1_pot>5 then
ch1_pot= ch1_pot -2
endif
else
if ch2_pot>5 then
ch2_pot= ch2_pot -2
endif
endif
'write values into eeprom
write 5, ch1_pot
write 6, ch2_pot
endif
'add 2 to wiper variable by pressing plus
if plus = 0 then
if current_channel = 0 then
'keep integer from rolling over
if ch1_pot<250 then
ch1_pot= ch1_pot +2
endif
else
if ch2_pot<250 then
ch2_pot= ch2_pot +2
endif
endif
'write values into eeprom
write 5, ch1_pot
write 6, ch2_pot
endif
gosub set_pot
'the following code waits for a square wave, it is set up so if the vout is
'on, and all the buttons are untouched it will properly get square wave,
'other wise it exits while loop. pressing plus or minus exits the loop
while signalinput=1 && vout=1 && plus = 1 && minus = 1 : wend
while signalinput=0 && vout=1 && plus = 1 && minus = 1 : wend
t1on=1
while signalinput=1 && vout=1 && plus = 1 && minus = 1 : wend
t1on=0
pulsehigh.highbyte=tmr1h
pulsehigh.lowbyte=tmr1l
pulsehigh= pulsehigh/4
gosub cleartimer
while signalinput=0 && vout=1 && plus = 1 && minus = 1 : wend
while signalinput=1&& vout=1 && plus = 1 && minus = 1 : wend
t1on=1
while signalinput=0 && vout=1 && plus = 1 && minus = 1 : wend
t1on=0
pulselow.highbyte=tmr1h
pulselow.lowbyte=tmr1l
pulselow= pulselow/4
gosub cleartimer
'if there is power display duty and freq, if not display zero
if vout=1 then
if plus = 1 && minus = 1 then 'need this otherwise freq and duty are set incorrectly
pulsehigh1=pulsehigh/100
pulselow1=pulselow/100
duty=pulsehigh/(pulselow1+pulsehigh1)
freq= 10000/(((pulselow+pulsehigh)/100))
endif
else
duty=0
freq=0
endif
'only updates LCD every 6 loops to allow for smoother display
if counter = 6 then
serout PORTB.4,N9600,[$fe,$c0] 'put curser on second line
serout PORTB.4,N9600,[#freq, " CPS "]
serout PORTB.4,N9600,[$fe,$c8]
serout PORTB.4,N9600,["Duty ",#duty,"% "]
gosub get_ad
if current_channel = 0 then
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["CH 1"]
ch1=1
ch2=0
else
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["CH 2"]
ch1=0
ch2=1
endif
counter = 0
else
counter = counter + 1
endif
gosub set_channel
Goto mainloop
cleartimer:
tmr1l = 0
tmr1h = 0
return
set_channel:
'make sure power is off before switching banks
if vout=0 then
'push button has pull ups, checks for high to low transition
if sel = 0 && last= 1 then
current_channel= ~current_channel
'read current channel from eeprom
write 7, current_channel
endif
last = sel
endif
return
get_ad:
ADCIN 0, adval
adval=adval*4286
dummy= div32 10000
dummy= dummy+129
serout PORTB.4,N9600,[$fe,$86]
serout PORTB.4,N9600,[#(dummy/1000),".", #((dummy//1000)/10)]
serout PORTB.4,N9600,[$fe,$8a]
serout PORTB.4,N9600,[" VOLTS "]
counter = 0
return
intro_screen:
'intro screen
pause 1000
serout PORTB.4,N9600,[$fe,$1] 'clear everything
serout PORTB.4,N9600,[$1b,$2a,255] ' set LCD backlight
serout PORTB.4,N9600,[$fe,$1]
serout PORTB.4,N9600,[" BLAKE WOOD "]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,[" INK "]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["* BLAKE WOOD *"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["* INK *"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["** BLAKE WOOD **"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["** INK **"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["***BLAKE WOOD***"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["*** INK ****"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["***BLAKE WOOD***"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["**** INK *****"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["***BLAKE WOOD***"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["***** INK ******"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["***BLAKE WOOD***"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["******INK *******"]
pause 500
serout PORTB.4,N9600,[$fe,$80]
serout PORTB.4,N9600,["***BLAKE WOOD***"]
serout PORTB.4,N9600,[$fe,$c0]
serout PORTB.4,N9600,["******INK********"]
pause 500
serout PORTB.4,N9600,[$fe,$1]
return
set_pot:
if current_channel = 0 then
wiper1= ch1_pot
else
wiper1=ch2_pot
endif
pause 1
'start transition
Rst = 1
pause 1
'stack select
Dq=1
pause 1
Clk=1
pause 1
Clk=0
pause 1
'first wiper
For i = 0 to 7
'dq= ~dq
Dq=wiper0.7
'wiper0 = wiper0<<1
if i = 0 then
dq = wiper0.7
elseif i = 1 then
dq = wiper0.6
elseif i = 2 then
dq = wiper0.5
elseif i = 3 then
dq = wiper0.4
elseif i = 4 then
dq = wiper0.3
elseif i = 5 then
dq = wiper0.2
elseif i = 6 then
dq = wiper0.1
else
dq = wiper0.0
endif
Clk=1
pause 1
Clk=0
pause 1
Next i
'second wiper
For i = 0 to 7
if i = 0 then
dq = wiper1.7
elseif i = 1 then
dq = wiper1.6
elseif i = 2 then
dq = wiper1.5
elseif i = 3 then
dq = wiper1.4
elseif i = 4 then
dq = wiper1.3
elseif i = 5 then
dq = wiper1.2
elseif i = 6 then
dq = wiper1.1
else
dq = wiper1.0
endif
Clk=1
pause 1
Clk=0
pause 1
Next i
'end transition and set resistance
Rst = 0
pause 1
return
2.0 OPERATION INSTRUCTIONS
2.1 Turning on Unit
Flipping the switch titled "PWR" in the back turns on the power supply. You should see a start up splash screen animation that says "BLAKE WOOD INK". To turn on the bluetooth speaker, flip the switch titled "BT". The blue tooth speaker is wired in series with the PWR switch so if you turn on the Bluetooth switch without first turning on the PWR switch, nothing will happen. Turn on the bluetooh transmitter on your phone and search for any new devices in the area. There is no password so it should pair right away.
2.2 Setting Channel Voltage
The unit will start up on whichever channel was last used. The red lights on the front will illuminate to show will channel the button on top will control(the active channel). Pressing the up and down arrows will respectively increase or lower the voltage on that channel. Pressing the ☆ button toggles between the two channels. The unit writes the voltage settings to the internal EEPROM every time the up or down button is pressed. This is so if the power to the unit is cut unexpectedly, the voltage on both channels will be the same.
2.3 Turning on Active Channel
Pressing the large latching button on top turns on the tattoo machine connected to the active channel. The white LEDs on top will illuminate to indicate the machine connected to the active channel should be on and running. Note that if the machine is on and the white LEDs and lit, you are unable to press the ☆ to switch channel. You must first turn press the large to turn off the machine to be able to switch between channels. This was done to prevent you from accidentally turning on a machine that is resting on a table.