Warhammer Sorcerer on Disc With Magnetically-Coupled Motor and LEDs
by circuitmage in Circuits > Electronics
3888 Views, 5 Favorites, 0 Comments
Warhammer Sorcerer on Disc With Magnetically-Coupled Motor and LEDs
Want to add some PIZZAZZ to your art projects? Motors and LEDs are the way to go!
Are you a Warhammer gaming enthusiast? This one's for you!
This is my Tzeentch Sorcerer Lord on Disc, revised with added 3 LED's , a motor, a micro (PIC) and small battery.
This instructable covers the completed build and issues.
Are you a Warhammer gaming enthusiast? This one's for you!
This is my Tzeentch Sorcerer Lord on Disc, revised with added 3 LED's , a motor, a micro (PIC) and small battery.
This instructable covers the completed build and issues.
Circuit
First, you may be wondering what this is. This is my custom made miniature for table-top a tabletop wargame called Warhammer. The guy at the top is a regular model from the maker of the game (Gamesworkshop), but the disk and base are all mine. The build for him is the subject of another instructable, so I won't go into that here.
Circuit
The basic idea here was to take a small, 8 pin micro to control 3 LEDs and a motor, with as small a supply as possible.
Use of the "helping-hands", as always, is a good idea. These things have two clips to hold whatever you are working on.
No schematic was needed, as the impementation is very simple;
An 8 pin micro (Microchip PIC) with 3 output pins going straight to LEDs, and 2 output pins going to 1 motor.
The LED's used are a Blue, White and Red surface mount type.
The Motor used was ripped from a broken indoor micro helecopter.
The battery (small Lipo) was also ripped from the heli, but i already plan to use another source for more power.
A switch was added for On/Off.
Circuit
The basic idea here was to take a small, 8 pin micro to control 3 LEDs and a motor, with as small a supply as possible.
Use of the "helping-hands", as always, is a good idea. These things have two clips to hold whatever you are working on.
No schematic was needed, as the impementation is very simple;
An 8 pin micro (Microchip PIC) with 3 output pins going straight to LEDs, and 2 output pins going to 1 motor.
The LED's used are a Blue, White and Red surface mount type.
The Motor used was ripped from a broken indoor micro helecopter.
The battery (small Lipo) was also ripped from the heli, but i already plan to use another source for more power.
A switch was added for On/Off.
Code
The code for the PIC was made to optimize battery life and use many random "events".
In order to have the battery last as long as possible, the circuit had to use the least amount of power I could figure, while keeping the idea alive. So, I decided to reduce the initial activity to an average of 1 LED flash or motor move every 6 seconds.
The code has 12 random "activities" , ranging from 1 LED turning on, the motor turning on for different time periods or directions, to a random wait state. Events vary from 3seconds apart to more than 40 seconds apart, based on the random event generated.
CODE
;===============================================================================
;Disc Controller
;
; -----------
; Vcc-> |1 8| <-Vss
; M<->GPIO5 |2 7| GPIO0 --->LED1
; M<->GPIO4 |3 6| GPIO1 --->LED2
; GPIO3-> |4 5| GPIO2 --->LED3
; -----------
;
;===============================================================================
; Revision History & Notes:
; V1.0 Initial Header, Code 5/19/09
;
;
;(C) 5/2009
;This code may be used for personal learning/application/modification.
;Any use of this code in commercial products violates this freeware release.
;For questions/comments, contact circuit dot mage at yahoo dot com .
;-------------------------------------------------------------------------------
#include P12C672.INC
;===============================================================================
; Defines
;-------------------------------------------------------------------------------
;===============================================================================
; Data
;-------------------------------------------------------------------------------
; Time keeping variables
count1 equ 20
count2 equ 21
delay equ 22
Randlo equ 23
Randhi equ 24
Wtemp equ 25
Temp2 equ 26
rand equ 27
count3 equ 28
;===============================================================================
; Reset Vectors
;
; CHECK CONFIG. BITS BEFORE BURNING!!!
; INTOSC
; MCLR: ENABLED
; PWRUP: ENABLED
; ALL OTHERS: DISABLE!!
;
;-------------------------------------------------------------------------------
RESET_ADDR EQU 0x00
org RESET_ADDR
goto start
;===============================================================================
; Start Here!
;-------------------------------------------------------------------------------
start
; Config I/O ports
bcf STATUS,RP1
bsf STATUS,RP0
movlw h'08' ;RA<0-7> Outputs, PGIO3 always input
tris GPIO
movlw h'07' ; Set GPIO to Digital mode
movwf ADCON1
; Set internal timer
movlw h'CF' ; Tmr0 Internal source, prescale TMR0 1:256
movwf OPTION_REG
movlw h'00'
movwf INTCON ; Disable TMR0 interrupts,
bcf STATUS,RP0
; Initialize Registers
clrf GPIO
clrf count1
clrf count2
movlw 045h
movwf Randlo
movlw 030h
movwf Randhi
;wait 1 sec.
call debounce ; 0.2 sec
call debounce
call debounce
call debounce
call debounce
;===============================================================================
; Main
;-------------------------------------------------------------------------------
main
call twosec ; 2 secs min between each action
rrf Randhi,W
xorwf Randlo,W
movwf Wtemp
swapf Wtemp
rlf Randhi,W
xorwf Randhi,W ; LSB = xorwf(Q12,Q3)
xorwf Wtemp
rlf Wtemp
rlf Randlo
rlf Randhi
movfw Wtemp ;strip random 16 down to 7
andlw 0x0F
movwf rand
; random routine selection
xorlw 0x00 ; 0?
btfsc STATUS,Z
goto flash1 ; Yes. Call 0th
movfw rand
xorlw 0x01 ; 1?
btfsc STATUS,Z
goto flash2 ; Yes. Call 1st
movfw rand
xorlw 0x02 ; 2?
btfsc STATUS,Z
goto flash3 ; Yes. Call 2nd
movfw rand
xorlw 0x03 ; 3?
btfsc STATUS,Z
goto flashall ; Yes. Call 3rd
movfw rand
xorlw 0x04 ; 4?
btfsc STATUS,Z
goto movels ; Yes. Call 4th
movfw rand
xorlw 0x05 ; 5?
btfsc STATUS,Z
goto movell ; Yes. Call 5th
movfw rand
xorlw 0x06 ; 6?
btfsc STATUS,Z
goto movers ; Yes. Call 6th
movfw rand
xorlw 0x07 ; 7?
btfsc STATUS,Z
goto moverl ; Yes. Call 7th
movfw rand
xorlw 0x08 ; 8?
btfsc STATUS,Z
goto moveburst ; Yes. Call 8th
movfw rand
xorlw 0x09 ; 9?
btfsc STATUS,Z
goto Wait1 ; Yes. Call 9th
movfw rand
xorlw 0x0A ; A?
btfsc STATUS,Z
goto Wait2 ; Yes. Call Ath
movfw rand
xorlw 0x0B ; B?
btfsc STATUS,Z
goto Wait3 ; Yes. Call Bth
goto nothing ; 1/4 the time, do nothing for 10 secs.
flash1
bsf GPIO, 0
call debounce
bcf GPIO, 0
goto main
flash2
bsf GPIO, 1
call debounce
bcf GPIO, 1
goto main
flash3
bsf GPIO, 2
call debounce
bcf GPIO, 2
goto main
flashall
bsf GPIO, 0
bsf GPIO, 1
bsf GPIO, 2
call debounce
call debounce
bcf GPIO, 0
bcf GPIO, 1
bcf GPIO, 2
goto main
movels
bsf GPIO, 4
bcf GPIO, 5
call debounce
bcf GPIO, 4
goto main
movell
bsf GPIO, 4
bcf GPIO, 5
call debounce
call debounce
bcf GPIO, 4
goto main
movers
bcf GPIO, 4
bsf GPIO, 5
call debounce
bcf GPIO, 5
goto main
moverl
bcf GPIO, 4
bsf GPIO, 5
call debounce
call debounce
bcf GPIO, 5
goto main
moveburst
bcf GPIO, 4
bsf GPIO, 5
call debounce ; move right 3 times, short bursts.
bcf GPIO, 5
call debounce
call debounce
bsf GPIO, 5
call debounce
call debounce
bcf GPIO, 5
call debounce
call debounce
bsf GPIO, 5
call debounce
bcf GPIO, 5
call debounce
call debounce
call debounce
call debounce
bsf GPIO, 4 ; move left 3 times, short bursts.
bcf GPIO, 5
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
bsf GPIO, 4
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
bsf GPIO, 4
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
goto main
Wait1 ; Wait 1 seconds
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
goto main
Wait2 ; Wait 0.6 seconds
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
goto main
Wait3 ; Wait 4 seconds
call twosec
call twosec
goto main
nothing
movlw .50 ; Delay for 10 seconds Total
movwf count3
nothing_loop
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
decfsz count3,F
goto nothing_loop
goto main
;===============================================================================
; 2 second wait
;-------------------------------------------------------------------------------
twosec
movlw .10 ; Delay for 2 seconds Total
movwf count3
twosec_loop
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
decfsz count3,F
goto twosec_loop
return
;===============================================================================
; Debounce signal
; 4 cycles to load and call , 2 cycles to return.
; 4Mhz Tc :: count2=255 -> 0.2 sec
;-------------------------------------------------------------------------------
debounce
movlw .127 ; Delay for 1/10 second debounce.
movwf count2
call pon_wait
return
;-------------------------------------------------------------------------------
; count1=255d :: 775 cycles to 0, + 3 cycles to return.
;-------------------------------------------------------------------------------
pon_wait
big_loopS
movlw .255
movwf count1
short_loopS
decfsz count1,F
goto short_loopS
decfsz count2,F
goto big_loopS
return
end
In order to have the battery last as long as possible, the circuit had to use the least amount of power I could figure, while keeping the idea alive. So, I decided to reduce the initial activity to an average of 1 LED flash or motor move every 6 seconds.
The code has 12 random "activities" , ranging from 1 LED turning on, the motor turning on for different time periods or directions, to a random wait state. Events vary from 3seconds apart to more than 40 seconds apart, based on the random event generated.
CODE
;===============================================================================
;Disc Controller
;
; -----------
; Vcc-> |1 8| <-Vss
; M<->GPIO5 |2 7| GPIO0 --->LED1
; M<->GPIO4 |3 6| GPIO1 --->LED2
; GPIO3-> |4 5| GPIO2 --->LED3
; -----------
;
;===============================================================================
; Revision History & Notes:
; V1.0 Initial Header, Code 5/19/09
;
;
;(C) 5/2009
;This code may be used for personal learning/application/modification.
;Any use of this code in commercial products violates this freeware release.
;For questions/comments, contact circuit dot mage at yahoo dot com .
;-------------------------------------------------------------------------------
#include P12C672.INC
;===============================================================================
; Defines
;-------------------------------------------------------------------------------
;===============================================================================
; Data
;-------------------------------------------------------------------------------
; Time keeping variables
count1 equ 20
count2 equ 21
delay equ 22
Randlo equ 23
Randhi equ 24
Wtemp equ 25
Temp2 equ 26
rand equ 27
count3 equ 28
;===============================================================================
; Reset Vectors
;
; CHECK CONFIG. BITS BEFORE BURNING!!!
; INTOSC
; MCLR: ENABLED
; PWRUP: ENABLED
; ALL OTHERS: DISABLE!!
;
;-------------------------------------------------------------------------------
RESET_ADDR EQU 0x00
org RESET_ADDR
goto start
;===============================================================================
; Start Here!
;-------------------------------------------------------------------------------
start
; Config I/O ports
bcf STATUS,RP1
bsf STATUS,RP0
movlw h'08' ;RA<0-7> Outputs, PGIO3 always input
tris GPIO
movlw h'07' ; Set GPIO to Digital mode
movwf ADCON1
; Set internal timer
movlw h'CF' ; Tmr0 Internal source, prescale TMR0 1:256
movwf OPTION_REG
movlw h'00'
movwf INTCON ; Disable TMR0 interrupts,
bcf STATUS,RP0
; Initialize Registers
clrf GPIO
clrf count1
clrf count2
movlw 045h
movwf Randlo
movlw 030h
movwf Randhi
;wait 1 sec.
call debounce ; 0.2 sec
call debounce
call debounce
call debounce
call debounce
;===============================================================================
; Main
;-------------------------------------------------------------------------------
main
call twosec ; 2 secs min between each action
rrf Randhi,W
xorwf Randlo,W
movwf Wtemp
swapf Wtemp
rlf Randhi,W
xorwf Randhi,W ; LSB = xorwf(Q12,Q3)
xorwf Wtemp
rlf Wtemp
rlf Randlo
rlf Randhi
movfw Wtemp ;strip random 16 down to 7
andlw 0x0F
movwf rand
; random routine selection
xorlw 0x00 ; 0?
btfsc STATUS,Z
goto flash1 ; Yes. Call 0th
movfw rand
xorlw 0x01 ; 1?
btfsc STATUS,Z
goto flash2 ; Yes. Call 1st
movfw rand
xorlw 0x02 ; 2?
btfsc STATUS,Z
goto flash3 ; Yes. Call 2nd
movfw rand
xorlw 0x03 ; 3?
btfsc STATUS,Z
goto flashall ; Yes. Call 3rd
movfw rand
xorlw 0x04 ; 4?
btfsc STATUS,Z
goto movels ; Yes. Call 4th
movfw rand
xorlw 0x05 ; 5?
btfsc STATUS,Z
goto movell ; Yes. Call 5th
movfw rand
xorlw 0x06 ; 6?
btfsc STATUS,Z
goto movers ; Yes. Call 6th
movfw rand
xorlw 0x07 ; 7?
btfsc STATUS,Z
goto moverl ; Yes. Call 7th
movfw rand
xorlw 0x08 ; 8?
btfsc STATUS,Z
goto moveburst ; Yes. Call 8th
movfw rand
xorlw 0x09 ; 9?
btfsc STATUS,Z
goto Wait1 ; Yes. Call 9th
movfw rand
xorlw 0x0A ; A?
btfsc STATUS,Z
goto Wait2 ; Yes. Call Ath
movfw rand
xorlw 0x0B ; B?
btfsc STATUS,Z
goto Wait3 ; Yes. Call Bth
goto nothing ; 1/4 the time, do nothing for 10 secs.
flash1
bsf GPIO, 0
call debounce
bcf GPIO, 0
goto main
flash2
bsf GPIO, 1
call debounce
bcf GPIO, 1
goto main
flash3
bsf GPIO, 2
call debounce
bcf GPIO, 2
goto main
flashall
bsf GPIO, 0
bsf GPIO, 1
bsf GPIO, 2
call debounce
call debounce
bcf GPIO, 0
bcf GPIO, 1
bcf GPIO, 2
goto main
movels
bsf GPIO, 4
bcf GPIO, 5
call debounce
bcf GPIO, 4
goto main
movell
bsf GPIO, 4
bcf GPIO, 5
call debounce
call debounce
bcf GPIO, 4
goto main
movers
bcf GPIO, 4
bsf GPIO, 5
call debounce
bcf GPIO, 5
goto main
moverl
bcf GPIO, 4
bsf GPIO, 5
call debounce
call debounce
bcf GPIO, 5
goto main
moveburst
bcf GPIO, 4
bsf GPIO, 5
call debounce ; move right 3 times, short bursts.
bcf GPIO, 5
call debounce
call debounce
bsf GPIO, 5
call debounce
call debounce
bcf GPIO, 5
call debounce
call debounce
bsf GPIO, 5
call debounce
bcf GPIO, 5
call debounce
call debounce
call debounce
call debounce
bsf GPIO, 4 ; move left 3 times, short bursts.
bcf GPIO, 5
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
bsf GPIO, 4
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
bsf GPIO, 4
call debounce
call debounce
bcf GPIO, 4
call debounce
call debounce
goto main
Wait1 ; Wait 1 seconds
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
goto main
Wait2 ; Wait 0.6 seconds
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
goto main
Wait3 ; Wait 4 seconds
call twosec
call twosec
goto main
nothing
movlw .50 ; Delay for 10 seconds Total
movwf count3
nothing_loop
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
decfsz count3,F
goto nothing_loop
goto main
;===============================================================================
; 2 second wait
;-------------------------------------------------------------------------------
twosec
movlw .10 ; Delay for 2 seconds Total
movwf count3
twosec_loop
movlw .255 ; Delay for 2/10 second debounce.
movwf count2
call pon_wait
decfsz count3,F
goto twosec_loop
return
;===============================================================================
; Debounce signal
; 4 cycles to load and call , 2 cycles to return.
; 4Mhz Tc :: count2=255 -> 0.2 sec
;-------------------------------------------------------------------------------
debounce
movlw .127 ; Delay for 1/10 second debounce.
movwf count2
call pon_wait
return
;-------------------------------------------------------------------------------
; count1=255d :: 775 cycles to 0, + 3 cycles to return.
;-------------------------------------------------------------------------------
pon_wait
big_loopS
movlw .255
movwf count1
short_loopS
decfsz count1,F
goto short_loopS
decfsz count2,F
goto big_loopS
return
end
Parts
This picture shows how small I had to get the components to fit under this guy.
1 8-pin Microchip (PIC)
3 SMT LED's (Blue, Red, White)
1 Motor from an indoor micro heli.
1 LIPO battery from same heli.
1 power switch
1 2.5mm wooden dowel (2" long)
2 1mm rare earth magnets
1 8-pin Microchip (PIC)
3 SMT LED's (Blue, Red, White)
1 Motor from an indoor micro heli.
1 LIPO battery from same heli.
1 power switch
1 2.5mm wooden dowel (2" long)
2 1mm rare earth magnets
Build
First a center of mass for the whole thing was found. This would be the motor mount area. The motor was mounted using goop called Greenstuff (used in the miniatures world).
The 3 LED's were prewired.
The micro was superglued in an out of the way area, not too close to the edge.
The power switch and battery were mounted to offset the (small) weight of the micro, to keep balance.
The wires were soldered on.
The really cool part is next.
Superglue on the tip of the rotor gear on the motor (this would be facing down later) a rare earth magnet was mounted. A short (~2") length of 2.5 diameter wooden dowel was drilled out (using hand and bit) for a 5mm deep 1mm diameter hole. In this hole another 1mm rare earth magnet was glued.
Now, my base for the figure is magnetically coupled to the rotor of the motor. When the motor spins, from it's center of balance, it turns the whole top portion of the figure.
A red straw was cut to cover the motor and wooden dowel. This was premeasured before the wooden dowel was mounted, to ensure it matched.
The LIPO battery output is currently reading 3.4V without recharge. This is enough to spin the motor and light the LEDs, but with the figure mounted on the base, it is not spinning itself. My next version will use a 12V remote battery with 5V regulator for more power!
The 3 LED's were prewired.
The micro was superglued in an out of the way area, not too close to the edge.
The power switch and battery were mounted to offset the (small) weight of the micro, to keep balance.
The wires were soldered on.
The really cool part is next.
Superglue on the tip of the rotor gear on the motor (this would be facing down later) a rare earth magnet was mounted. A short (~2") length of 2.5 diameter wooden dowel was drilled out (using hand and bit) for a 5mm deep 1mm diameter hole. In this hole another 1mm rare earth magnet was glued.
Now, my base for the figure is magnetically coupled to the rotor of the motor. When the motor spins, from it's center of balance, it turns the whole top portion of the figure.
A red straw was cut to cover the motor and wooden dowel. This was premeasured before the wooden dowel was mounted, to ensure it matched.
The LIPO battery output is currently reading 3.4V without recharge. This is enough to spin the motor and light the LEDs, but with the figure mounted on the base, it is not spinning itself. My next version will use a 12V remote battery with 5V regulator for more power!