Wednesday 16 April 2014

Latest Version update...the ringer

The ringer circuit is complicated, quite large and subject to blowing up PICs and H-bridges.

Ringer circuit fitted in a phone

This ringer circuit produces a 50V square wave and pulses the existing solenoids which activate the hammer on the two bell. I have decided that it is too big for the phone so another solution is needed so that I can still use the bells in the GPO phone.

Whilst retaining the bells, I have got rid of the 2 solenoids altogether as they are also quite big. So in order to ring the two bells in the phone I have decided that I need a bicycle bell. Well sort of, the mechanism an old fashioned cycle bell uses to spin round and hit the internal sides of the bell itself. This will be replicated using an electric motor, which will spin the 'dingers' against the sides of the 2 bells.

For this purpose I bought a stepper motor as this can be controlled easily with the outputs from a PIC micro controller, which I will  be using anyway to decode the dialled number from the rotary.

I built a circuit using the PICKit2 demo board - which has a 16f690 installed in it - to send the required pulses to the stepper motor controller.



Once I'd found the PIC16F690 datasheet I decided to program the very simple logic using the native assembly language, this initially proved to be quite tricky. (I spent a few years writing assembly for flight control software as a job, but this was nearly 20 years ago!). After searching for tutorials and rereading the datasheet, I had a "light bulb" moment and it all became fairly straight forward.

Using MPLAB 8, I wrote a simple program that sends a pulse-train to the 4 inputs of the stepper motor, the speed of the pulses and hence the stepper is controlled by the POT on the demo board.

Basically the program does the following:

;  Wire 1 2 3 4 5 6 7 8 Port
;  ORG  x x           x C0
;  YEL    x x x         C1
;  PIK        x x x     C2
;  BLU            x x x C3


This is the pulses that have to be sent to the stepper, so orange, then orange + yellow, then yellow etc. this is the half drive for the stepper.

The ports are the ports on the PIC used for output of the pulse.

Here's the source:

;
#include <p16F690.inc>

    __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _BOD_OFF & _IESO_OFF & _FCMEN_OFF)


; Registers for use with the variable delay loop.
    UDATA
dc1 res 1   ; Reserve 1 byte of data memory and call it dc1
dc2 res 1   ; Reserve 1 byte of data memory and call it dc2
dc3 res 1   ; Reserve 1 byte of data memory and call it dc3


    org 0   ; start vector

Start
    BSF        STATUS,RP0  ; set bit at RP0 in register STATUS to select bank 1
    movlw    0h            ; 00000000 - makes ports C0 & C1 as outputs
    movwf    TRISC         ; moves the 00000000 to TRISC
    BCF        STATUS,RP0  ; clear bit at RP0 in register STATUS to reselect bank 0
    ; Setup the ADC
    ; NOTE: you can set these bits individually using "bsf register,bit"
    movlw    b'001'        ; set the sample rate to /8
    movwf     ADCON1       ; move to ADCON1
    ; The below 2 statements are the same as the 3rd
;    movlw    b'00000001'  ; switch A2D on
;    movwf    ADCON0
    bsf        ADCON0,ADON  ; Sets the ADON bit in ADCON0
Loop
    call A2D
    bsf        PORTC,RC0    ; C0 - using bsf does not alter content of w so means the A2D is detected
    call A2D
;    bsf        PORTC,RC0
;    bsf        PORTC,RC1
    movlw     b'00000011'   ; C0 & C1 - could set ports like this, but done for the above reason.
    movwf    PORTC
    call A2D
    bsf        PORTC,RC1    ; C2
    call A2D
    movlw     b'00000110'   ; C0 & C1 - could set ports like this, but done for the above reason.
    movwf    PORTC
    call A2D
    bsf        PORTC,RC2    ; C3
    call A2D
    movlw     b'00001100'   ; C0 & C1 - could set ports like this, but done for the above reason.
    movwf    PORTC
    call A2D
    bsf        PORTC,RC3    ; C3
    call A2D
    movlw     b'00001001'   ; C0 & C1 - could set ports like this, but done for the above reason.
    movwf    PORTC
    GOTO Loop               ; go to Loop label
   

; 10 millisecond delay loop - altered to speed it up
; setting W to 1 will be a
delay10   
    movwf    dc3       ; move value in w to memory location dc3
dly2
    movlw     .1       ; Repeat inner loop 1 times (was 13) - this speeds it up for stepper motor
    movwf    dc2       ; move .13 to memory location dc2
    clrf     dc1       ; clear dc1
dly1   
    decfsz  dc1,f      ; decrement value at dc1 to 0 then jump
    goto    dly1   
    decfsz  dc2,f      ; decrement value at dc2 to 0 then jump
    goto    dly1
    decfsz  dc3,f      ; decrement value at dc3 to 0 then jump
    goto    dly2
    return


A2D:
    bsf ADCON0,GO     ; start conversion
    btfss ADCON0,GO   

    ; if ADCON0 == 0 then jump (this bit will change to zero when the conversion is complete)
    goto $-1          ; goto previous line
    movf ADRESH,w     ; Copy the value to the w register
    ADDLW     1       ; Add 1 so that the minimum value is always > 1
    call delay10      ; calls the delay script once the value has been read from the POT
    return   

   

   

No comments:

Post a Comment