On/off/on/off timer

Thread Starter

Reza_liaghat

Joined Jun 17, 2016
12
Hi everybody
I want to make a circuit that does the following steps, When power on :
  1. 8 second "on" (closes a relay)
  2. 1 second "off" (opens the relay)
  3. 1 second "on" (closes the relay)
  4. 1.5 second "off" (opens the relay)
Repeat this cycle until power is on.
It would be great if I could change the time on and off (for example 8 to 10 or 1.5 to 3)
 

Thread Starter

Reza_liaghat

Joined Jun 17, 2016
12
Dear bertus
can i do with arduino or attiny mcu ?

Using the MCU has the drawback that for each change of times i have to change the code and reprogram the MCU.
 

bertus

Joined Apr 5, 2008
21,534
Hello,

Yes, a attiny or pic will do.
Changing the timing will need to reprogram in MCU.
They however can be reporgrammed many times.

Bertus
 

upand_at_them

Joined May 15, 2010
766
If accuracy is important and you are going to use Arduino, you should learn how to create your own Arduino with an ATMega328P, crystal, and USB-serial adaptor. I think many Arduino's use a [less accurate] ceramic resonator, not a crystal (which is more accurate). And clones coming from China are likely to be using the cheapest parts possible.
 

sagor

Joined Mar 10, 2019
479
You could change the timing in any ATTiny (or PIC) with an analog input pin with a potentiometer on it. The code could set a minimum/maximum time based on the 0-5V reading. Even on a 8 pin MCU, you could have up to 4 pots setting various time settings, controlled by the programming. Even a typical 12F683 PIC could do this, 4 A/I and one output. That uses up all 8 pins. I'm sure some ATtiny would be similar. Just about any Arduino could do this as well, and may be easier for you to develop with.
 

LesJones

Joined Jan 8, 2017
3,494
Depending on the number of steps you need between the maximum and minimum value each time setting using DIP switches connected to an input port on the microcontroller might be good enough. For example a 4 position DIP switch would give you 16 values. I recently used this method to give 128 timing values in steps of 30 seconds using a 7 bit DIP switch. To give more resolution you could connect a potentiometer to an ADC input on a microcontroller. Some years ago I made sequencer similar to your requirements using a PIC16f88 that had 4 time steps each controlled by a potentiometer that gave a timing from 20 mS up to 5.12 seconds. It would be very easy to change the timing to suit your timing values. I think I still have the code for this. let me know if it is any use to you.

Les.
 

Thread Starter

Reza_liaghat

Joined Jun 17, 2016
12
Hi LesJones
Thank you very much for your explanation. If possible, explain a little more about the sequencer ,i can build my own circuit by changing it a little.
 

LesJones

Joined Jan 8, 2017
3,494
This is a simple description of the way the sequencer works.
There is a subroutine that generates a short delay using timer 1. In my case the delay is 20 mS (There is also code for delays of 50 and 100 mS in the program code.

There is a short section of code for each time slot.
The output for the channel is set to on.
These sections of the code use an ADC input to read the voltage from the slider of the pot for that time slot.
(Each pot has one end of the track connected to ground and the other end connected to +5 volts)
Only the top 8 bits of the reading are used. (So we have a number between 0 and 255)
That number is loaded into a register.
The code then loops delaying 20 mS, decrements the register. It continues looping until the register reaches zero.
At that point it sets that channel output to off.
The code then moves on to the next time slot which does exactly the same for that channel.
At the end of channel 3 code it goes back to channel zero.

This is the code,
Code:
;Sequencer
;
;28/06/16
; Version 01 now being modified for 4 channels (Renamed to Sequencer_02.asm)
;


; I/O port useage

;    RA0    (Pin 17)    Analog in 0
;    RA1    (Pin 18)    Analog in 1
;    RA2    (Pin 1)        Analog in 2
;    RA3    (Pin 2)        Analog in 3
;    RA4    (Pin 3)
;    RA5    (Pin 4)        Vpp for programming
;    RA6    (Pin 15)    
;    RA7    (Pin 16)    

;    RB0    (Pin 6)        Channel 0 out
;    RB1    (Pin 7)        Channel 1 out
;    RB2    (Pin 8)        Channel 2 out
;    RB3    (Pin 9)        Channel 3 out
;    RB4    (Pin 10)
;    RB5    (Pin 11)
;    RB6    (Pin 12)    PGC for programming
;    RB7    (Pin 13)    PGD for programming





    list P=16F88
    #include p16f88.inc

;Program Configuration Register 1
        __CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF  & _INTRC_IO

;Program Configuration Register 2
        __CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

; Define variables at memory locations

;*******************************************************************************
; Constants
;*******************************************************************************


RAM_START       equ     0x20


; The periods are timed with timer1 which is set to run at the internal clock
; rate (4 Mhz) of Fosc/4 or 1.0MHz which is equal to a 1 uS period.


;*******************************************************************************
; File Register Variables
;*******************************************************************************
        cblock  RAM_START

Save_STATUS        ;Save during interrupt
Save_W            ;Save during interrupt
Save_PCLATH        ;Save during interrupt
Save_FSR        ;Save during interrupt    

param1:    1          ; parameter 1    (Used in delay cycles routine)
param2:    1          ; parameter 2    (Used in delay cycles routine)

AD_Delay:    1    ;Delay count to allow AD to sample input

CH_Time:    1

AD_Channel:    1    ;AD channel number

        endc



; start at memory 0

    org    0
    goto    SETUP
    org    4
    goto    INTERRUPT




Init:
SETUP:
    clrf    PORTB        ; port B outputs low
    clrf    PORTA        ; port A output low
    bsf        STATUS,RP0    ; select memory bank 1

; set inputs/outputs
    movlw    B'00000111'    ; comparators off
    movwf    CMCON
    movlw    B'11110000'    ; port B 0 to 3 outputs 4 to 7 inputs
    movwf    TRISB        ; port B data direction register
    movlw    B'00111111'    ; outputs (0) and inputs (1)
    movwf    TRISA        ; port A data direction register
    movlw    B'11000000'    ; settings (pullups disabled TMR0/2)
    movwf    OPTION_REG

; analog inputs, A/D  

    movlw    B'00001111'    ; AN0 to AN3 are analog inputs
    movwf    ANSEL        ;Bank 1
    movlw    B'01000000'    ; left justified A/D result, VCC as ref
    movwf    ADCON1        ;Bank 1

    bcf        STATUS,RP0    ; select memory bank 0
    movlw    B'01000000'    ; Fosc  1/8 for  4MHz system clock  
    movwf    ADCON0        ; Bank 0
    bsf        ADCON0,ADON    ; A/D on
    bsf        STATUS,RP0    ; select memory bank 1
    movlw    B'01101000'    ;  for 4 MHz
    movwf    OSCCON        ; Bank 1


; Initialized Timer 1
    bcf        STATUS,RP0    ; select memory bank 0
    MOVLW    B'00110100'    ;Clock source FOSC, 1:8 prescale, Dedicated Timer1 oscillator circuit disabled, 
                                ;Do not synchronize external clock input, Fosc/4 Timer off
                ;So counter will increment every 8 uS   (4 Mhz clock)
                ; So for overflow after 500 ms (62500 * 8uS ) counter would need to be loaded with 0x0BDC

    MOVWF    T1CON        ;With 4 Mhz clock timer will increment every 500 mS



START:

Main_Loop:

Time_CH0:
    BSF    PORTB,0        ;1 cycle   (Set channel 0 output)
    MOVLW    0x00        ;Select channel 0
    MOVWF    AD_Channel    
    CALL    Read_Analog
    CALL    Channel_Delay
    BCF    PORTB,0        ;1 cycle  (Clear channel 0 output)


Time_CH1:
    BSF    PORTB,1        ;1 cycle   (Set channel 1 output)
    MOVLW    0x01        ;Select channel 1
    MOVWF    AD_Channel    
    CALL    Read_Analog
    CALL    Channel_Delay
    BCF    PORTB,1        ;1 cycle  (Clear channel 1 output)


Time_CH2:
    BSF    PORTB,2        ;1 cycle   (Set channel 2 output)
    MOVLW    0x02        ;Select channel 2
    MOVWF    AD_Channel    
    CALL    Read_Analog
    CALL    Channel_Delay
    BCF    PORTB,2        ;1 cycle  (Clear channel 2 output)


Time_CH3:
    BSF    PORTB,3        ;1 cycle   (Set channel 1 output)
    MOVLW    0x03        ;Select channel 3
    MOVWF    AD_Channel    
    CALL    Read_Analog
    CALL    Channel_Delay
    BCF    PORTB,3        ;1 cycle  (Clear channel 1 output)

    GOTO    Main_Loop






;        -----------------------------------------------------

; Interupt handler      (Interrupts not used.)

INTERRUPT:
;Save various registers

    MOVWF Save_W             ;Save W                            
    MOVF STATUS, W                         
    CLRF STATUS          ;Bank 0 will be selected
    MOVWF    Save_STATUS
    MOVF    PCLATH, W
    MOVWF    Save_PCLATH
    MOVF    FSR, W
    MOVWF    Save_FSR


;Restore registers 

    MOVF    Save_FSR, W
    MOVWF    FSR
    MOVF    Save_PCLATH, W
    MOVWF    PCLATH    
    MOVF    Save_STATUS, W                           
    MOVWF     STATUS      ;Restore STATUS                     
    SWAPF     Save_W, F                          
    SWAPF     Save_W, W     ;Restore W    
    RETFIE

;        -----------------------------------------------------
;Subroutines

Read_Analog:            ;Channel number will be in AD_Channel (Bits 0 - 2)
                ;Result returned in "W"

    RLF    AD_Channel    ;Move bits to required position (Bits 5 -3)    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    BCF    ADCON0, 3    ;1 cycle
    BCF    ADCON0, 4    ;1 cycle
    BCF    ADCON0, 5    ;1 cycle
    MOVF    AD_Channel, W    ;1 cycle
    IORWF    ADCON0, F    ;Select channel    ;1 cycle

    MOVLW    D'40'        ;1 cycle            64 decimal
    MOVWF    AD_Delay    ; acquisition time  1 cycle

Dec_AD_delay:                        ;loop is 3 cycles long (64 x 3 = 192
    DECFSZ    AD_Delay,f    ;1 cycle  (2 on exit)
    GOTO    Dec_AD_delay    ;2 cycles
    BSF        ADCON0,2        ; GO/DONE bit start conversion
WAIT_AD_Ready:
    BTFSC    ADCON0,2        ; conversion complete when cleared ~11 cycles
    GOTO    WAIT_AD_Ready
    MOVF    ADRESH,w
    RETURN        ;2 cycles



Channel_Delay:
    MOVWF    CH_Time    ;1 cycle
    INCF    CH_Time    ;So that AD value of zero does not give maximum time

CH_Loop:
    DECFSZ    CH_Time    ;1 cycle (2 cycles on exit)
    GOTO    CH_Delay
    GOTO    CH_End

CH_Delay:        ;This generates one unit of channel delay
;    CALL    DELAY_100mS    ;100mS * 256 =25.6 seconds
;    CALL    DELAY_50mS    ;50mS * 256 =12.8 seconds
    CALL    DELAY_20mS    ;20mS * 256 = 5.12 seconds

    GOTO    CH_Loop

CH_End:
    RETURN        ;2 cycles



Delay:

DELAY_100mS:
; Value for param = (100000 - 14)/8 = 99986/8 = 12498 = 0x30D2

    MOVLW    0x30        ;    (1 uS)            (1 cycle)
    MOVWF    param2        ;    (1 uS)            (1 cycle)
    MOVLW    0xD2        ;    (1 uS)            (1 cycle)
    MOVWF    param1        ;    (1 uS)            (1 cycle)
    GOTO    delay_cycles

DELAY_50mS:
; Value for param = (50000 - 14)/8 = 49986/8 = 6248 = 0x1868

    MOVLW    0x18        ;    (1 uS)            (1 cycle)
    MOVWF    param2        ;    (1 uS)            (1 cycle)
    MOVLW    0x68        ;    (1 uS)            (1 cycle)
    MOVWF    param1        ;    (1 uS)            (1 cycle)
    GOTO    delay_cycles        ;Not needed as delay_cycles follows on from here.

DELAY_20mS:
; Value for param = (20000 - 14)/8 = 19986/8 = 2498 = 0x09C2

    MOVLW    0x09        ;    (1 uS)            (1 cycle)
    MOVWF    param2        ;    (1 uS)            (1 cycle)
    MOVLW    0xC2        ;    (1 uS)            (1 cycle)
    MOVWF    param1        ;    (1 uS)            (1 cycle)
;    GOTO    delay_cycles        ;Not needed as delay_cycles follows on from here.

;*******************************************************************************
; Function:    delay_cycles
; Description: Delay a specified number of instruction cycles including
;              interrupt cycles.  The function call overhead adds between
;              13 and 16 cycles of delay on top of the specified value.
; With 4 Mhz system clock and 1:8 prescale
;Delay will be  param * 2 uS + (13 * 1uS)  + 0 to 3 uS
;        = param * 8 uS + (13 to16.0 uS)  (Use 14 uS for calculation.)
;   So param = No. of (uS-14)/8
; Parameters:  param1 - least significant byte of 16 bit cycle delay
;              param2 - most significant byte of 16 bit cycle delay
; Returns:     None
;*******************************************************************************
delay_cycles:
        comf    param1,F                ; negate the delay by complementing the        (1 uS)            (1 cycle)
        comf    param2,F                ; low and high bytes                (1 uS)            (1 cycle)
        bcf     T1CON,TMR1ON            ; stop timer 1                    (1 uS)            (1 cycle)
        movf    param1,W                ; move the low byte of the delay into        (1 uS)            (1 cycle)
        movwf   TMR1L                   ; timer 1                    (1 uS)            (1 cycle)
        movf    param2,W                ; move the high byte of the delay into        (1 uS)            (1 cycle)
        movwf   TMR1H                   ; timer 1                    (1 uS)            (1 cycle)
        bcf     PIR1,TMR1IF             ; clear the timer 1 rollover flag        (1 uS)            (1 cycle)
        bsf     T1CON,TMR1ON            ; turn on timer 1                (1 uS)            (1 cycle)
        
tmr1_check:     
        btfss   PIR1,TMR1IF             ; wait for the timer 1 rollover flag to        1 uS while looping     (2 uS) (2 cycle) on exit
        goto    tmr1_check              ; trigger
        return                ;                        (2 uS)    (2 cycle)
 


    END
I have not drawn a schematic as the circuit was so simple. Let me know it it meets your requirements and I can draw a schematic to match up with the way I have used the I/O pins in the code. There is some code that is not used. For example I wrote code to save registers during an interrupts but I decided not to use interrupts.
Let me know if there is anything that is not clear from the comments. In places I have noted the number of instruction cycles to make corrections to the timing.

Les.
 
Top