3v3 GPIO trigger a set of 5V relays with delays

Thread Starter

*synonymous*

Joined Nov 29, 2013
35
Hello

I have a set of relays that I would like to trigger with a 3.3v GPIO signal.
Please see attached image..

The GPIO signal is but enough to power a small LED.
I have an adequate 5VDC supply to power the relays.
When the GPIO signal goes high, I'd like to have the first relay come on as fast as possible with the second come on after a small (1sec) delay.
When the GPIO signal is removed, I'd like to have the relays remain on for a time of around 10 minutes and both switch off at the same time.

Any help appreciated!
 

Attachments

LesJones

Joined Jan 8, 2017
2,729
For your "FANCY-RELAY-CIRCUIT" use an 8 pin micro such as an ATtiny13A running of 3.3 volts with a transistor driver for each relay. The timing would be simpler to implement with a microconntroller than other timing methods. Do you not have another spare GPIO pin on the original device and implement the timing in software on that device. you would then only need two transistors. One for each relay. (Don't forget to put a diode across the relay coils to protect the driver transistors from back EMF.)

Les.
 

Thread Starter

*synonymous*

Joined Nov 29, 2013
35
Thanks for the reply..
I'm attempting to get this done in a discreet fashion if possible. Technically I could do this in some way of programming, although it's more my intention to omit that aspect as much as possible. Cost is not an issue near as much as anything else..

I've attached another image of something that I've cobbled together..
Any obvious issues that you can see?
I realize that the second relay will disengage before the first, however this is not an issue in the least. The big part is having a slight delay for the second relay on engagement and then a nice long wait before they let go..

Thanks for any improvements or critique
 

Attachments

LesJones

Joined Jan 8, 2017
2,729
the 12 second delay circuit using Q1 and K1 should work but the timing will have poor accuracy. I do not think the 1 second delay will work as R3 and R4 form a potential divider. This means that when Q1 is conducting there will only be 18/28 * 5 volts = 3.2 volts across R4. As Q2 is being used as an emitter follower it will drop about another 0.6 of a volt so you will only get about 2.6 volts across the coil of K2 which will probably not be enough to pull it in. For the 1 second delay I would suggest using an P channel mosfet in a similar configuration to the Q1. Another alternative would be to use a dual comparator such as an LM393 as this would give a better defined switching voltage. You would need to check that the LM393 had a low enough input current rating to work with your very high value 68 meg resistor.

Les.
 

LesJones

Joined Jan 8, 2017
2,729
With that circuit (Post #5) K2 will give the 1 second delay both switching on and switching off. I would use one output from the ATTINY13a to drive K1 and another to drive K2. I would use a 2N7000 for each relay driver.

The code below should give you a good start. The code relating to timing is what you can use You do not need the ADC input code as this is monitoring battery voltage. the device is for timing a battery opperated LRD light. there is just one button to switch it on. it will also switch it off if required before the end of the iming period. If the battery voltage is low it also flashes a warning light to show that the battery needs charging. If the voltage is even lower it shuts down before the timing period.
the line ".equ Shutdown_minutes = 5 ;Time to shutdown in minutes." can be changed to give to give a different number of minutes.
There is also a subroutine "Inc_Sec:" (Increment seconds.) That you can use to control K2
Code:
;
/*
 * Shutdown timer  (Shutdown_timer03)  (To shut off a light after a preset period and also if the battery voltage is too low.)
 *
 *  Created: 03/09/2015
 *  Author: Les
 *  Version 2 being modified by adding low battery warning light
 */
 ;   using ATTINY13
; Fuse bit settings
 ; Low       0x62  (0x6A is also OK)
 ; High      0xFF
 ; Extended    0xFF
 ; Lock       0xFF


 ;
;

;Use internal clock at 9.6 Mhz  (Default value) and divide by 8 by setting CKDIV8 fuse bit (These are the default setting on a new chip.)
; 9.6 Mhz/8 = 1.2 Mhz
;(So Instruction time = 833.3 nS)

; So for 50 uS delay requires 50/0.8333 = 60 instructions

; Burst needs to be 5 mS long. This will be 50 cycles of 10 Khz

;
;**************************************************************************
.nolist
.include   <tn13def.inc>   ; ATtiny 13
.list
.listmac

;***************************************************************************
;*
;* Global Register Variables
;*
;***************************************************************************
; Note register number is in decimal

.def   N200mS     = r17   ;Number of 200 mS
.def   Seconds     = r18   ;Number of seconds
.def   Minutes     = r19   ;Number of minutes
.def   count_L     = r22   ;Used for time delay
.def   Flags     = r23   ;Bit 0 used for battery low warning flag



.equ   Shutdown_volts   = 0xA4   ;battery voltage shutdown value. (164 decimal. Divide battery voltage using a 4.7K resistor to ground and a 10 K resistor to the )
;  (collector ofthe power switching transistor. This gives a ratio of 0.32. So for a cut off voltage )
;  (of 10.0 we need to detect 3.2 volts This is 256 x 3.2/5 = 164 )
.equ   Battery_Low   = 0xB4   ;Battery voltage low warning level. (Set to come on at 11.0 volts so this will be 1.0 * 0.32 = 3.52 volts at ADC input
;                  (This will be a count of 256 * 3.52/5 = 180 = 0xB4 )
;
.equ   Shutdown_minutes = 5   ;Time to shutdown in minutes.
;
;
;******************************** INTERRUPT VECTORS ***********************
.CSEG
.ORG   00
     rjmp   reset
     reti
     reti
     rjmp    TC_overflow   ;Timer/Counter Overflow
     reti
     reti   ;   rjmp   timer1_OVF
     reti
     reti
     reti
     reti
;
;******************************* RESET *************************************
;   
; Initialise the stack-pointer   
reset:
         ldi   R16,low(RAMEND)
         out   SPL,R16


       
   

       
; initialize PORTB
;   Bit 0   Input  (pin 5)  (Input will be low when button is pressed.
;   Bit 1   Input
;   Bit 2   Input  ADC input (Pin 7)
;   Bit 3   Output  (Pin 2)  (Drive to low battery warning LED High for LED on)
;   Bit 4   Output   (Pin 3)  (Drive to power control tansistor base.)
;   Bit 5   Input

           ldi   R16,0x18   ; Bits 3 and 4 as outputs.
           out   DDRB,R16   ;
           ldi   R16,0x10
           out   PORTB,R16   ; PORTB Bit 3 low, bit 4 high


; initialize Flags
           ldi Flags,0x00



;Initialize ADC

           ldi R16,0x84       ;Enable ,  Prescale value 16,  No auto triggering
           out ADCSRA,R16

           ldi  R16,0b00000000
           out  ADCSRB,R16

           ldi R16,0x21   ;Select AD1 (pin 7) input, Select VCC as analogue reference. ADLAR (Left justify result)
           out ADMUX,R16


           ldi R16,0x04   ;Set PB2 as analoge input
           out DIDR0,R16


;Initialize timer / counter


           ldi R16,0x00       ;Normal operation
           Out TCCR0A,R16

           ldi R16,0x05       ;  Prescale value 1024 (Inc counter every 0.8333 uS x 1024 = 853.3 uS  (1171.88 hZ)
           Out TCCR0B,R16       ; Counter will overflow every 218.445 mS  (4,58 hZ)  
                       ; Counting to 234 would give 199.7 mS  ( 256 - 234 = 22 = 0x16)

           ldi R16,0x02       ;TOIE0 (Bit1) : Timer/Counter0 Overflow Interrupt Enable
           Out TIMSK0,R16

;Init time counters
           ldi N200mS,0x05
           ldi Seconds,0x00
           ldi Minutes,0x00

;Wait for button to be released  (Wait for input to go high

Wait_Button_High:
           sbis PINB,0
           rjmp Wait_Button_High

           bset 7     ;Enable global interrupst.

           rjmp main


;Timer/Counter Overflow interrupt handler.
TC_overflow:

           ldi R20,0x16     ;Preset timer so interrupt occures every 199.7 mS
           out   TCNT0,R20

           dec   N200mS ;200mS
           breq TC01
           RETI
TC01:
           ldi N200mS,0x05


Inc_Sec:       

           SBRS Flags, 0
           CBI PORTB,0x03     ;Clear battery low warning LED
           SBRS Flags,0     ;Bat_Warning   ;Skip if battery warning bit is set
           RJMP Inc_S2

           in R20,PORTB
           ldi R21,0x08     ;Bits 3
           eor R20,R21       ; Toggle bit 3 (Pin 2) (Every second)
           out PORTB,R20




Inc_S2:
           ldi R20,0x3C     ;60 decimal

           inc   Seconds       ;Increment seconds counter
           cpse Seconds,R20
           rjmp TC_End
           CLR Seconds

Inc_Min:
           ldi R20,0x3C     ;60 decimal

           inc   Minutes       ;Increment minute counter
           cpse Minutes,R20
           rjmp TC_End
           CLR Minutes

TC_End:
           RETI


;     ------------------------------------- End of interrupt handlers --------------------------------------




;
;  Main program code
;
Main:
       nop
       nop
       ldi R20,Shutdown_minutes
       cpse Minutes,R20         ;Is it time to shutdown ?
       rjmp Not_Time
       cbi PORTB,4             ;Clear PORTB bit 4
       rjmp End_Loop



Not_Time:
       nop
       nop
       nop
;       rjmp Main   ; Just loop waiting for interrupt


;Read ADC input value
           ldi R16,0x84       ;Enable ,  Prescale value 16,  No auto triggering
           out ADCSRA,R16

           ldi R16,0x21   ;Select AD1 input (pin 7) Select VCC as analogue reference, ADLAR (Left justify result)
           out ADMUX,R16

         sbi  ADCSRA,ADSC  ; Start ADC conversion
           nop
Wait_ADC_Ready:
           sbic  ADCSRA,ADSC  ; Wait_ADC_Ready:
           rjmp  Wait_ADC_Ready
           in R20,ADCL       ;Read ADC result L  (Value not used but need to read this register befor high byte.)
           in R20,ADCH       ;Read ADC result H

;Test for battery warning level
           CBR Flags,0x01 ;Bat_Warning       ;Clear battery warning flag

           CLC         ;Clear carry flag
           SBCI R20,Battery_Low
           BRBC 0x00,Test_Shutdown     ;Branch if carry bit is clear
           SBR Flags,0x01 ;Bat_Warning       ;Set battery warning flag bit


;Test for battery shutdown level
Test_Shutdown:
           in R20,ADCH       ;Read ADC result H again
           CLC         ;Clear carry flag
           SBCI R20,Shutdown_volts
           BRBS 0x00,Bat_Low       ;Branch if carry bit is set
           RJMP Bat_OK

Bat_Low:
           CBI PORTB,0x04       ; Shutdown

End_loop:
           NOP
           RJMP End_loop       ; Loop until power removed.



Bat_OK:


Test_button:               ;If button pressed input will be low.
           sbic   PINB,0

           rjmp Main   ; Just loop waiting for interrupt

;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
           rcall Delay_100ms
           sbic   PINB,0   
           rjmp Main
           cbi PORTB,4             ;Clear PORTB bit 4
           rjmp End_Loop








;Test_button:
           sbis   PINB,0
           rjmp   Test_button   ;Loop until button pressed

;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
           rcall Delay_100ms
           sbis   PINB,0   
           rjmp   Test_button   ;Loop until button is pressed


Button_open_loop:
           sbic   PINB,0   ;
           rjmp   Button_open_loop; loop until pedal released








;Subroutines.
;
;
;                 ----------------------------------------------
; Instruction cycle time is 0.83333 uS

; Delay 1mS  Rcall to get here takes 3 instruction cycles. ret instruction takes 4 instruction cycles, ldi takes 1 instruction cycle (total 8)

; For 1 mS (1000 uS) we need 1000/0.83333 = 1200 instructions  so need additional 1192 instructions  5 cycles in loop.


Delay_1_mS:
           ldi    count_L,0xEE   ;Decimal 238  0xEE (Once round the loop is 5 instructions)
D_1mS_Loop:
           dec   count_L     ; Count_L is R22  (1 cycle)
           nop         ;(1 cycle)
           nop         ;(1 cycle)
           brne    D_1mS_Loop   ;If not zero  (2 cycles while looping, 1 on exit)
           ret





Delay_100ms:
           ldi R21,0x64   ;100 decimal
Del_100ms_Loop:
           rcall Delay_1_mS
           dec R21
           brne Del_100ms_Loop
           ret

;  -------------End of subroutines --------------
;
I think that should help you to code your application.

Les.
 

Thread Starter

*synonymous*

Joined Nov 29, 2013
35
Thank you

It'll take a few to look through it and refine it to work for me..

Can you tell me if these things can do an accurate job of comparing analog signals?
I'm reading that they have that capacity more than devices like the RPI etc..
At some point and when, I may be interested in constructing a circuit that can give an indication when identical signals deviate to an extent.

Thanks again Les
Scott
 

LesJones

Joined Jan 8, 2017
2,729
It depends on what you mean by "accurate" The A to D converter has a resolution of 10 bits (That is about 0.1% of the full range value.) You would need to read the data sheet to see if the internal voltage reference for the ADC met your accuracy requirement. I assume by "RPI" that you mean a Raspberry Pi computer. If so I have never checked if they have an analogue to digital converter.

Les.
 

Thread Starter

*synonymous*

Joined Nov 29, 2013
35
Thanks again,

Here's an updated image attachment..

Since going with the AVR, I've added a 'perk' to it, sensing another device. I may add indicator LED's as well.
Any particular reason in using the FET to drive the relays other than the easy BJT?
I've got a supply of the BJT
 

Attachments

LesJones

Joined Jan 8, 2017
2,729
The only reason I suggested ysing the mosfet was to save using a couple of resistors. Your driver circuit in post #9 looks fine. I suggest programming in only the most basic functions first. when they are working add some other features. For example when I wrote the code in post #6 I probably just wrote the timer code and had it toggeling the output of one output pin as a first step. I then would have added the code to divide the basic timming into seconds then the code to divide into minutes and so on.

Les.
 
Top