# [SOLVED]Time Delay with micro-controller

Status
Not open for further replies.

#### psb64

##### Newbie level 4
I want to keep a relay off for 20hrs and keep it on for 14 hrs using a micro-controller. Please help me by giving the necessary program (in mikroBasic/Assembly) and schematic diagram to do so.

Last edited:

#### alexan_e

I don't think you will find anyone to provide you a ready solution, this is a forum to help with your project when you have a specific problem not do the projects for you.
What you want to do can be achieved using an MCU with a timer, set the timer to work at a specific rate and calculate the times that the timer needs to overflow.
To achieve the delay you want, keep a variable to count the overflows of the timer and when the number matches the one you have calculated change the output.
If you are using an ARM based mcu then you will not need to do an overflow at all because the counter is 32 bit (usually there is at least one 32bit timer) and can be set to count for many days before it overflows, in that case a compare match register set to the correct value will be all that you need.

Alex

Last edited:

#### arbj

##### Full Member level 4
I can give you a hint, you need a micro-controller, and a RTC, I suppose a watch crystal would also do.

Setting up an external watch crystal with the PIC 16F628 is quite easy, the schematic and code for this is available in the datasheet for the device, also there are numerous projects in the internet that use this combination. it should not be difficult to search for a suitable one.

Try searching in google, select a few projects that you think can do the job for you, then post back to this forum for more help.

psb64

### psb64

Points: 2

#### navenmou

##### Full Member level 4
you have to use micro-controller with RTC so that you can get your functionality i.e write a Assembly code or Embedded C code for switching ON-OFF i.e set the ON time and OFF time of relay...I hope this will hep to you

#### psb64

##### Newbie level 4
I want to use the PIC16F84A to do this and the cristal should be 4Mhz

---------- Post added at 21:47 ---------- Previous post was at 21:36 ----------

I found the following circuit in mikroBasic. Will it work?

program timer84EDA

symbol relay = PORTB.B0

const ontime = 43200000
const offtime = 75600000

main:
TRISB = 0
PORTB = 0
relay = 0 'relay off
delay_ms(offtime) 'twenty-one hour delay
relay = 1 'relay on
delay_ms(ontime) 'twelve hour delay
relay = 0 'relay off
while true 'done
wend
end.

#### bigdogguru

I never used MikroBasic, is the delay_ms() parameter a type long?

The 75600000 is quite a large number for MCU, so if the delay_ms() doesn't take a type long that will be a problem.

If it does take a type long, then there is only one way to test it out, compile and program your 16F84A and see.

psb64

### psb64

Points: 2

#### xaccto

##### Full Member level 5
I've never used mikro tools but do have the wiz development environment from PIC C Compilers and development ki...

you can download their demo, and it should go alright for a 16F84 size chip.

whats more you can simulate your solution easily before wiring any hardware
App designer also has ready built application blocks like timers, clocks, ports etc you plug into your application - builds a workable shell
check it out at PIC C Compilers and development ki...

#### psb64

##### Newbie level 4
delay_ms is a long type variable

#### bigdogguru

I want to keep a relay off for 20hrs and keep it on for 14 hrs using a micro-controller. Please help me by giving the necessary program (in mikroBasic/Assembly) and schematic diagram to do so.

I want to use the PIC16F84A to do this and the cristal should be 4Mhz

---------- Post added at 21:47 ---------- Previous post was at 21:36 ----------

I found the following circuit in mikroBasic. Will it work?

program timer84EDA

symbol relay = PORTB.B0

const ontime = 43200000
const offtime = 75600000

main:
TRISB = 0
PORTB = 0
relay = 0 'relay off
delay_ms(offtime) 'twenty-one hour delay
relay = 1 'relay on
delay_ms(ontime) 'twelve hour delay
relay = 0 'relay off
while true 'done
wend
end.

I'm not familiar with MikroBasic, however I believe you placement of the while loop is incorrect.

If you wish to have the relay cycle on/off repeatedly, you may want to use this version instead:

Code:
program timer84EDA

symbol relay = PORTB.B0

const ontime = 43200000
const offtime = 75600000

main:
TRISB = 0
PORTB = 0

while true 'done
relay = 0 'relay off
delay_ms(offtime) 'twenty-one hour delay
relay = 1 'relay on
delay_ms(ontime) 'twelve hour delay
wend

end.

This encloses the portion of the code you wish to repeat continually. Also a little indentation would help you understand the code flow.

Due to the 34 hours cycle period, each new cycle will be offset by 10 hours. So if you power up the MCU at Midnight, the 2nd cycle with start at 10AM day 2, the 3rd cycle at 8PM day 3 and so forth.....

The continually shifting start time makes the use of a RTC unnecessary and somewhat impractical. If the cycle period were equal to or less than 24 hours it would be a practical alternative.

Also your choice of the PIC 16F84A, unless it is what you have on hand, ill fitted for this application. A baseline PIC like the PIC 12F50X family with an internal 4MHz oscillator and low cost would be a better choice. The use of a PIC 12F50X would not only be a less expensive option, it would alleviate the need for an external crystal or RC pair. However if this is what you have on hand, then it is understandable.

Hope the info helps in your endeavors.

psb64

### psb64

Points: 2

#### JayantD

##### Member level 3
You need to be careful about the accuracy of your system clock. Any small error is going to accumulate i.e. add up and show as an inaccuracy at the end of your 20 hours time period. If this cycle is to continue, drift due to ambient temperature also becomes significant. Stray capacitance around the crystal also needs to be tackled by careful routing the tracks on the printed circuit board.

I would suggest decide the upper and lower tolerence limits first, and then go about designing your circuit.

psb64

### psb64

Points: 2

#### cool.man

##### Full Member level 6
const ontime = 43200000
const offtime = 75600000

delay_ms(offtime) 'twenty-one hour delay

If you have no other function to perform then you can use delay_ms() function, but this function is not suitable i think because you are defining a large delay which is in hours,suppose in the delay routine your processor hangs up then what will happens? you have to restart your microcontroller,then the whole process starts again.
you can define delays in terms of loop like "for loop" and in for loop you can use watchdog timer which prevents the microcontroller from restart.

Best regards

psb64

### psb64

Points: 2

#### sankar.m8

If you are using a 4MHz crystal....

The operating frequency will be 4MHz/4 = 1MHz (4 machine cycle constitute 1 instruction cycle)

ie, it will execute 1,000,000 instructions in 1 second.

so to get a 1 second, you have to use a for loops which will consume 1,000,000.

for a minute 60 times the 1second loop

for hour, 60times the 1minute loop..

from this you will get the exact timing...

This will be effective only when your microcontroller is dedicated for this ON/OFF of the relay(you cant give any other work to the microcontroller other than this delay counting)...else you have to use any other methods like Timers,external RTC chip.

psb64

### psb64

Points: 2

#### bigdogguru

If you are using a 4MHz crystal....

The operating frequency will be 4MHz/4 = 1MHz (4 machine cycle constitute 1 instruction cycle)

ie, it will execute 1,000,000 instructions in 1 second.

so to get a 1 second, you have to use a for loops which will consume 1,000,000.

for a minute 60 times the 1second loop

for hour, 60times the 1minute loop..

from this you will get the exact timing...

The only way to achieve timing delays of high accuracy, without exhaustive testing and some accurate test equipment, is to write the delay routines in assembler, accounting for every cycle consumed by each instruction under each circumstance. Using any high level language to directly generate a delay is inherently inaccurate due to the fact the resulting code is highly compiler and optimization dependent.

Delay routines such as delay_ms(), if they have a high degree of accuracy, are typically written in assembler and furnished as relocatable code modules.

Even if these measures are taken, exact timing delays do not exist, due to the inherent inaccuracies of the oscillator/clock and variations due to temperature changes and other factors.

psb64

### psb64

Points: 2

#### sankar.m8

nsec_a:
movlw D'100'
movwf delay1
nsecloop_a:
nop
nop
nop
nop
nop
nop
nop
nop
nop
clrwdt
decfsz delay1
goto nsecloop_a
return

nsec1a:
call nsec_a
decfsz delay2
goto nsec1a
return

msec250a:
movlw D'250'
movwf delay2
goto nsec1a

This is just a sample code to generate delays

If you move the value into the delay2 register and following the above procedure, you will get almost correct delays...
If you are a perfectionist, you need to consider the delays which are taken for the each instructions too....

psb64

### psb64

Points: 2

#### psb64

##### Newbie level 4
I thank everyone who helped me with this project for their help and contribution.:smile:

#### d@nny

##### Full Member level 5
; Delay = 7.56e+007 seconds
; Clock frequency = 4 MHz

; Actual delay = 75600000 seconds = 75600000000000 cycles
; Error = 0 %

cblock
d1
d2
d3
d4
d1_4
d1_5
endc

;75599999999990 cycles
movlw 0xD7
movwf d1
movlw 0x2A
movwf d2
movlw 0xF0
movwf d3
movlw 0x00
movwf d4
movlw 0x4A
movwf d1_4
movlw 0x06
movwf d1_5
Delay_0
decfsz d1, f
goto $+2 decfsz d2, f goto$+2
decfsz d3, f
goto $+2 decfsz d4, f goto$+2
decfsz d1_4, f
goto $+2 decfsz d1_5, f goto Delay_0 ;10 cycles goto$+1
goto $+1 goto$+1
goto $+1 goto$+1

Status
Not open for further replies.