Deprecated: Assigning the return value of new by reference is deprecated in /home/dirkdirk/public_html/projects/raiden/wp-settings.php on line 472

Deprecated: Assigning the return value of new by reference is deprecated in /home/dirkdirk/public_html/projects/raiden/wp-includes/cache.php on line 103

Deprecated: Assigning the return value of new by reference is deprecated in /home/dirkdirk/public_html/projects/raiden/wp-includes/query.php on line 21
dirk&dirk - Raiden Project » Blog Archive » Control Board Finished

Control Board Finished

We just moved into a new office and since I didn’t have any real work to do I’ve been committing the control board that communicates with the coin hopper. Ironically I haven’t had the internet this whole time I’ve been working on it which makes it extremely frustrating trying to figure stuff out and now that I’ve got it working the internet has come back on!

I read the first couple of chapters of this book…

… which was extremely helpful for understanding how PIC’s work and how they need to be hooked up to a circuit board. Also the data sheet for the PIC16F84A (the chip i used) is pretty gnarly looking at first but after reading it like 50 times it proves pretty useful.

Heres a picture of the control board in its current state:

This is what it does:

- PIC16F84A manages the count of coins inside the machine
- Coin mech switch triggers the increment count function
- Inside the PIC the count is maintained in EEPROM and volatile RAM, this is because it’s easier to manipulate data in the RAM and then update the EEPROM.
- The increment function increments the RAM count then updates the count in the EEPROM to equal the RAM count.
- PIC16F84A have 8 bit registers which means that one register can only count up to 256, since we need to be able to count up to 800 (the amount the hopper holds) we need to use 2 registers, these are COUNT1 and COUNT2. The starting values for 0 coins should be 0 in COUNT1 and 1 in COUNT2. The reason for this is when we are decrementing the count using DECFSZ the program flow will branch depending if the result of the decrement is 0 or not 0. We can assume COUNT1 will always be at least one when it comes time to spit out the coins because the player could not have got to the end of the game without putting in any money, however COUNT2 must start at 1 so when the COUNT2 decrement occurs (ie after COUNT1 reaches 0) we get a 0 instead of a 255.
- The switch connected to RA1 is used to query the number of coins in the machine, this is only used for testing and i haven’t implemented logic to deal with counts over 256. When the switch is pressed the LED on RB0 will flash a number of times equal to the number of coins in the machine.
- The switch on RA2 resets the EEPROM (and the local count) by setting the local COUNT1 AND COUNT2 to 0 and 1 respectively and copying those values to EEPROM.
- The switch on RA3 initiates a payout, i still have to implement some kind of serial or parallel communication with the PC and MAME, currently its just a push button switch.
- The LED connected to RB1 lights up when the EEPROM is being written
- The LED connected to RB3 lights up when a coin is dispensed
- RB2 controls the hoppers motor, 5v for on, 0v for off

Here is a picture of the circuit diagram:

Here is my source code for the PIC so far also, I can’t really be bothered going over it right now, might do a better description later, right now i want to figure out the PC - PIC communication

;**************************************************************************
;*                               COIN COUNTER                              *
;**************************************************************************
;*          (C) DIRK & DIRK,2009  All rights reserved                       *
;*          Hardware & software by Dirk                                        *
;**************************************************************************
;*          Hardw. Rev: 1                 Softw. Rev:  1.01                *
;*          OSC.......: XT 4MHz Max.     POWER.....:  5V DC              *
;**************************************************************************
;==========================================================================
;    Counts coins:
;        - Each coin triggers an update to the EEPROM
;        - Count is maintained in EEBYTE1 & EEBYTE2 and volatile
;          variables COUNT1 & COUNT2
;        - LED connected to RB0 flashes x times; where x is the coin
;          count
;        - NOTE: Querying the count when it's 0 or over 256 will produce
;          odd effects
;        - LED connected to RB1 is on when EEPROM is being written
;        - RA0: Increment count
;        - RA1: Query value of coin count
;        - RA2: Reset EEPROM
;==========================================================================

;==========================================================================
;
;       Configuration Bits
;
;==========================================================================
_CP_ON                       EQU     H'000F'
_CP_OFF                      EQU     H'3FFF'
_PWRTE_ON                    EQU     H'3FF7'
_PWRTE_OFF                   EQU     H'3FFF'
_WDT_ON                      EQU     H'3FFF'
_WDT_OFF                     EQU     H'3FFB'
_LP_OSC                      EQU     H'3FFC'
_XT_OSC                      EQU     H'3FFD'
_HS_OSC                      EQU     H'3FFE'
_RC_OSC                      EQU     H'3FFF'
    __CONFIG        _CP_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC

;==========================================================================
;
;       Register Definitions
;
;==========================================================================
W                            EQU     H'0000'
F                            EQU     H'0001'
;----- Register Files------------------------------------------------------
INDF                         EQU     H'0000'
TMR0                         EQU     H'0001'
PCL                          EQU     H'0002'
STATUS                       EQU     H'0003'
FSR                          EQU     H'0004'
PORTA                        EQU     H'0005'
PORTB                        EQU     H'0006'
EEDATA                       EQU     H'0008'
EEADR                        EQU     H'0009'
PCLATH                       EQU     H'000A'
INTCON                       EQU     H'000B'
OPTION_REG                   EQU     H'0081'
TRISA                        EQU     H'0085'
TRISB                        EQU     H'0086'
EECON1                       EQU     H'0088'
EECON2                       EQU     H'0089'
;----- STATUS Bits --------------------------------------------------------
IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'
;----- INTCON Bits --------------------------------------------------------
GIE                          EQU     H'0007'
EEIE                         EQU     H'0006'
T0IE                         EQU     H'0005'
INTE                         EQU     H'0004'
RBIE                         EQU     H'0003'
T0IF                         EQU     H'0002'
INTF                         EQU     H'0001'
RBIF                         EQU     H'0000'
;----- OPTION_REG Bits ----------------------------------------------------
NOT_RBPU                     EQU     H'0007'
INTEDG                       EQU     H'0006'
T0CS                         EQU     H'0005'
T0SE                         EQU     H'0004'
PSA                          EQU     H'0003'
PS2                          EQU     H'0002'
PS1                          EQU     H'0001'
PS0                          EQU     H'0000'
;----- EECON1 Bits --------------------------------------------------------
EEIF                         EQU     H'0004'
WRERR                        EQU     H'0003'
WREN                         EQU     H'0002'
WR                           EQU     H'0001'
RD                           EQU     H'0000'
;INPUTS
SW1        EQU     H'00'        ;SW1 is triggering RA0 (Increment)
SW2        EQU     H'01'        ;SW2 is triggering RA1 (Flash value of count times on RB0)
SW3        EQU        H'02'        ;SW3 is triggering RA2 (Reset EEPROM)
SW4        EQU        H'03'        ;SW4 is triggering RA3 (Signal payout)
SW5        EQU        H'04'        ;SW5 is triggering RB4 (decrement coin signal)
;OUTPUTS
PO        EQU        H'02'        ;PO is triggering RA4 (switch on coin hopper motor)
;==========================================================================
;
;       RAM Definition
;
;==========================================================================
        __MAXRAM H'CF'
        __BADRAM H'07', H'50'-H'7F', H'87'

;==========================================================================
;
;       Variables
;
;==========================================================================
COUNT1            EQU        H'0C'    ;Local count byte 1
COUNT2            EQU        H'0D'    ;Local count byte 2
DECRM            EQU        H'0E'    ;Stores temp value of count for flashing
TIMER1          EQU     H'0F'   ;Timer 1, Used for general delay
TIMER2          EQU     H'10'   ;Timer 2, used for delay !
FREQCOUNT        EQU        H'11'    ;Frequency counter
;==========================================================================
;
;       EEPROM Variables
;
;==========================================================================
EEBYTE1            EQU        H'00'    ;Stores the first byte of the count in the eeprom
EEBYTE2            EQU        H'01'    ;Stores the second byte of the count in the eeprom

        ORG        0                ;Setting Reset vector, reset vector address is 000h in PIC16F84
        GOTO    RESET            ;Jump to RESET procedure when boot-up PIC device.


;**************************
;*     main routine:      *
;**************************
RESET    BSF        STATUS,RP0        ;Jump to bank 1 of PIC16F84 to access special registers.
        MOVLW    B'00001111'        ;Config Port A, Low nibble = Ra0 are inputs, high nibble not implemented.
        MOVWF    TRISA            ;Set I/O configuration for PORTA
        MOVLW    B'00010000'        ;Rb7...Rb0 are outputs.
        MOVWF    TRISB            ;Set I/O configuration for PORTB
        BCF    STATUS,RP0            ;Jump back to bank 0 of PIC.
        CLRF    PORTA            ;Clear all I/O's of PORTA
        CLRF    PORTB            ;Clear all I/O's of PORTB
        CALL    FETCHEEPROM
                                ;Loop starts here !!!
LOOP    BTFSC     PORTA,SW1        ;See if button 1 is on (increment button)
        CALL    INCREM            ;Increment the count
        BTFSC    PORTA,SW2        ;See if button 2 is down (flash the number of the count)
        CALL    SHOWCOUNT        ;Start flasher
        BTFSC    PORTA,SW3        ;See if button 3 is on (reset eeprom)
        CALL    RESETEEPROM        ;Reset eeprom
        BTFSC    PORTA,SW4        ;See if button 4 is on (payout signal)
        CALL    PAYOUT            ;Begin payout function
        GOTO     LOOP
;*******************
;* Payout function *
;*******************
PAYOUT    CALL    PAYON            ;Switch hopper motor on
        CALL    DELAY
; Probably not the right way to do it but this part checks the switch 5 times to make
; sure it isn't that weird spiking thing.
P1        BTFSS    PORTB,4            ;Is the coin decrement switch on?
        GOTO    P1                ;No
        BTFSS    PORTB,4            ;Is the coin decrement switch on?
        GOTO    P1                ;No
        BTFSS    PORTB,4            ;Is the coin decrement switch on?
        GOTO    P1                ;No
        BTFSS    PORTB,4            ;Is the coin decrement switch on?
        GOTO    P1                ;No
        BTFSS    PORTB,4            ;Is the coin decrement switch on?
        GOTO    P1                ;No
        BSF        PORTB,3            ;Real decr switch occurred, switch light on
P2        BTFSC    PORTB,4            ;Is the coin decrement switch up?
        GOTO    P2                ;No
        BCF        PORTB,3            ;End of decr switch, turn off light
DEC1    DECFSZ    COUNT1,1        ;Decrement first count byte
        GOTO    P1                ;COUNT1 != 0, so go back to P1
        DECFSZ    COUNT2,1        ;COUNT1 == 0, now check COUNT2
        GOTO    DEC2            ;COUNT2    != 0, so set COUNT1 = D'255' then go back to P1
        GOTO    DEC3            ;COUNT2 == 0, hopper is empty, go to DEC3 to halt and clean up
DEC2    MOVLW    H'FF'            ;
        MOVWF    COUNT1            ;Set count back to FF (256)
        GOTO     P1                ;Start checking for clicks again
DEC3    CALL    PAYOFF            ;Switch of the motor
        CALL     RESETEEPROM        ;Reset count to 0 (count1:0, count2:1)
        RETURN

;        BCF        PORTB,3            ;FOO: This is just to check if a switch signal is received from the hopper
;P2        BTFSC    PORTB,SW5        ;Is the coin dec switch off?
;        GOTO    P2                ;No, go back
; Here one switch from the hopper has occurred, now decrement count
; and check to see if we are at 0
;DEC1    DECFSZ    COUNT1,1        ;Decrement first count byte
;        GOTO    P1                ;COUNT1 != 0, so go back to P1
;        DECFSZ    COUNT2,1        ;COUNT1 == 0, now check COUNT2
;        GOTO    DEC2            ;COUNT2    != 0, so set COUNT1 = D'255' then go back to P1
;        GOTO    DEC3            ;COUNT2 == 0, hopper is empty, go to DEC3 to halt and clean up
;DEC2    MOVLW    H'FF'            ;
;        MOVWF    COUNT1            ;Set count back to FF (256)
;        GOTO     P1                ;Start checking for clicks again
;DEC3    CALL    PAYOFF            ;Switch of the motor
;        CALL     RESETEEPROM        ;Reset count to 0 (count1:0, count2:1)
;        RETURN
;TEMPTEMPTEMPTEMPTEMPTEMPTEMPTEMP
;LED4ON    MOVLW    H'01'
;        MOVWF    FREQCOUNT
;ITSON    BTFSS    PORTB,SW5
;        GOTO    STILLON
;        GOTO     GONEOFF
;STILLON    DECFSZ    FREQCOUNT,1
;        GOTO    ITSON
;LOOPER    BSF        PORTB,3
;        GOTO    LOOPER
;GONEOFF    GOTO    P1
;LED4OFF    BCF        PORTB,3
;        GOTO    P1

;PAYOUT    BTFSC    PORTA,SW4        ;Is button down?
;        GOTO    PAYON            ;Yes
;        GOTO    PAYOFF            ;No
;**********************
;* Payout on function *
;**********************
PAYON    BSF        PORTB,PO        ;Set PO pin to high
        RETURN
;***********************
;* Payout off function *
;***********************
PAYOFF    BCF        PORTB,PO        ;Set PO pin to low
        RETURN                    ;
;******************************
;* Count incrementer function *
;******************************
INCREM    BTFSC    PORTA,SW1        ;Make sure they aren't still holding down the button
        GOTO    INCREM            ;
        CALL    DELAY            ;Short delay for mechanical bouncing on the button
        INCFSZ    COUNT1,1        ;Increment COUNT1 register
        GOTO    WRTRET            ;Go to write then return section if COUNT1 didn't click over to 0
        INCFSZ    COUNT2,1        ;Increment COUNT2 register if COUNT1 did click over to 0
WRTRET    CALL     SETEEPROM        ;
        RETURN                    ;
;********************
;* Flasher function *
;********************
;##############################################################################################################
;################ FOO: NEEDS TO BE UPDATED FOR 2 BYTE COUNT ###################################################
;##############################################################################################################
SHOWCOUNT    BTFSC    PORTA,SW2    ;Make sure they aren't still holding down the button
            GOTO    SHOWCOUNT    ;
            MOVF    COUNT1,0    ;Move the count to W
            MOVWF    DECRM        ;Move W to decrm register
MORECOUNT    CALL    LED1ON        ;Switch LED on
            CALL    DELAY        ;Wait
            CALL    LED1OFF        ;Switch LED off
            CALL    DELAY        ;Wait
            DECFSZ    DECRM,1        ;Decrement count
            GOTO     MORECOUNT
            RETURN
;*******************************************************
;* Fetches count from EEPROM, moves to COUNT1 & COUNT2 *
;*******************************************************
FETCHEEPROM    MOVLW    EEBYTE1            ;Grab first byte
            MOVWF    EEADR            ;Address to read
            BSF        STATUS,RP0        ;Bank 1
            BSF        EECON1,RD        ;EE read
            BCF        STATUS,RP0        ;Bank 0
            MOVF    EEDATA,0        ;Copy EEDATA to W
            MOVWF    COUNT1            ;Copy EEDATA (from W) to COUNT1
            MOVLW    EEBYTE2            ;Grab second byte
            MOVWF    EEADR            ;Address to read
            BSF        STATUS,RP0        ;Bank 1
            BSF        EECON1,RD        ;EE read
            BCF        STATUS,RP0        ;Bank 0
            MOVF    EEDATA,0        ;Copy EEDATA to W
            MOVWF    COUNT2            ;Copy EEDATA (from W) to COUNT2
            RETURN
;******************************
;* Reset EEPROM function      *
;* - Sets COUNT1 & COUNT2 to  *
;      0 then writes the EEPROM *
;******************************
RESETEEPROM    MOVLW    H'0'        ;Move 0 into W
            MOVWF    COUNT1        ;Move W into COUNT1
            MOVLW    H'1'        ;Move 0 into W
            MOVWF    COUNT2        ;Move 0 into COUNT2
            CALL     SETEEPROM    ;Now set EEPROM since COUNT1 & COUNT2 are 0
            RETURN                ;Return from reset call
;**************************************
;* Set EEPROM function                *
;* - Writes COUNT1 & COUNT2 to EEPROM *
;**************************************
; Write the first byte
SETEEPROM    CALL    LED2ON        ;Turn on LED 2 to show it's writing
            BCF        STATUS,RP0    ;Bank 0
            MOVF    COUNT1,0    ;Move COUNT1 into EEDATA for writing
            MOVWF    EEDATA
            MOVLW    EEBYTE1        ;Address to read from (EEBYTE1)
            MOVWF    EEADR
            BSF        STATUS,RP0    ;Bank 1
            BCF        INTCON,GIE    ;Disable interrupts
            BSF        EECON1,WREN    ;Enable write
            MOVLW    H'55'        ;Confirm write 1
            MOVWF    EECON2        ;
            MOVLW    H'AA'        ;Confirm write 2
            MOVWF    EECON2        ;
            BSF        EECON1,WR    ;Set WR bit, begin write
            BSF     INTCON,GIE    ;Enable INT's
            CALL     WAITFOREE    ;Wait for EE to be written
; Write the second byte
            BCF        STATUS,RP0    ;Bank 0
            MOVF    COUNT2,0    ;Move COUNT2 into EEDATA for writing
            MOVWF    EEDATA
            MOVLW    EEBYTE2        ;Address to read from (EEBYTE2)
            MOVWF    EEADR
            BSF        STATUS,RP0    ;Bank 1
            BCF        INTCON,GIE    ;Disable interrupts
            BSF        EECON1,WREN    ;Enable write
            MOVLW    H'55'        ;Confirm write 1
            MOVWF    EECON2        ;
            MOVLW    H'AA'        ;Confirm write 2
            MOVWF    EECON2        ;
            BSF        EECON1,WR    ;Set WR bit, begin write
            BSF        INTCON,GIE    ;Enable INT's
            CALL    WAITFOREE    ;Wait for EE to be written
            BCF        STATUS,RP0    ;Bank 0
            CALL    LED2OFF        ;Switch off LED to show stopped writing
            RETURN                ;End of reset EEPROM function
;**********************************
;* Waits for EEPROM to be written *
;**********************************
WAITFOREE    BTFSC    EECON1,WR    ;Check if WR is still 1
            GOTO    WAITFOREE    ;Yes, go back
            RETURN                ;No return
;*******************
;* LED 1 on function *
;*******************
LED1ON    BSF        PORTB,0
        RETURN

;********************
;* LED 1 off function *
;*********************
LED1OFF    BCF        PORTB,0
        RETURN
;*********************
;* LED 2 on function *
;*********************
LED2ON    BSF        PORTB,1
        RETURN
;**********************
;* LED 2 off function *
;**********************
LED2OFF    BCF        PORTB,1
        RETURN
;******************
;* Delay function *
;******************
DELAY    MOVLW   D'250'          ;*    ;Put 150 decimal in the 'TIMER1' register.
           MOVWF   TIMER1          ;*
                                   ;
DELAY2    MOVLW    D'250'            ;Put 150 decimal in the 'TIMER2' register.
        MOVWF    TIMER2
        DECFSZ  TIMER2,F        ;*    ;Timer2 = Timer2 -1, skip next instruction if Timer2 = 0.
                GOTO    $-1     ;*    ;Jump back 1 instruction.

        DECFSZ    TIMER1,F        ;Timer1 = Timer1 - 1, skip next instruction if Timer1 = 0
        GOTO    DELAY2            ;Jump to 'DELAY2' routine
        RETLW   0                ;Return (jump back to main) and load W-reg with 0.
        END                     ;End of source code.

7 Comments

  1. Hobosic Says:

    Hi,
    Interesting, I`ll quote it on my site later.

    Thanks
    Hobosic

  2. Dirnov Says:

    Hi,
    I have already seen it somethere…

    Have a nice day
    Dirnov

  3. admin Says:

    Dirnov: Where have you seen it? I would like see another one!

    Hobosic: Thanks for the comments!

  4. Tania Says:

    Greatings,
    Amazing! Not clear for me, how offen you updating your http://www.dirkdirk.com.

    Thank you
    Tania

  5. admin Says:

    @tania: i admit the whole blog is pretty all over the place! once the project is finished i will try clean it up into a nice tutorial format. I’m not updating dirkdirk as much as i would like too as i am very busy with lab fiftyfive, i think theres a link to it somewhere on the front page

    keep checking back though, i will finish this project one day!

  6. ted Says:

    wow, nice idea, also in the pic firmware, “checking the button 5 times to make sure its not the werid spiky thing” do you mean to debounce the circuit? a hardware built debounce circuit may be more reliable. nice overall though.

  7. admin Says:

    @ted: thanks! and yes, i just googled debounce and that was what i was trying to do. i’m completely new to electronics, i kind of just tried to figure out what i needed for each part without going too deep into any real theory, not for lack of interest, just lack of time. version 2 will be proper!

Leave a Comment