PDA

View Full Version : Delayed output 10 secs



lilimike
- 28th May 2009, 03:22
Hi,

I am relatively new at this and I need a little help.
I am using a 16F883
Portb with pull ups as input, portc as instantaneous output and porta as delayed output.
When I press switch 1 (low), it will toggle portc.1 (on)
if I maintain switch 1 (low) for 3 seconds it will branch to another section.
if I press switch 1 again it will toggle portc.1 (off)
So far so good, my program is working fine but I want to add porta.1 which will trigger approx 10 seconds after portc.1

Keeping in mind that the explaination above is for 1 switch / 1 output portc / 1 output porta but it will endup having 6 of each.

Here is my code:



start:
if sw1 = 0 then Bdelay1
goto start

Bdelay1:
pause 25 ; debounce
if sw1 = 0 then
if ld1 = 0 or swstat = 1 then
high ld1
pause 500
swstat = 1
l=l+1
if l => 5 then Bprog1
goto bdelay1
else
low ld1
pause 500
wait1: if sw1 = 0 then wait1
endif
endif
swstat = 0
goto start


Thank you

Mike

lilimike
- 30th May 2009, 02:08
Well I guess this must be a tough one as no one commented or maybe I didn't explain clearly my issue.
I have been doing lots of browsing and searching and I figured what I might need is to use a timer with interup but I am confused. If I have 6 switches on (portb) 6 Leds on (portc) each switch trigering its respective led and then again a respective led on porta will be triggered 10 seconds later.

Sinse there is a chance that a user press switch1, switch2, switch3 and switch4 and even possibly all 6 of them (all within 10 seconds)

If I could have 6 timers and 6 interupt routines I would manage easily but how can I control my 6 events with just one timer?

If anyone can help me out, I don't bite!

Thanks

Mike

Darrel Taylor
- 30th May 2009, 02:56
Well I guess this must be a tough one as no one commented or maybe I didn't explain clearly my issue.
I think it's just one of those, "you can't get there from here" kind of things.
Trying to time things with pauses makes it so you can't do anything else at the same time, so 6 buttons would be difficult with the example given.

However, if you do it a little differently, it's a piece of cake.
Using a timer to measure even 1ms time periods, and running the main loop freely (without pauses), you can do it like this...
<font color="#008000"><b>CLEAR
DEFINE </b></font><b>OSC </b><font color="#800000"><b>20
</b></font><font color="#008000"><b>INCLUDE </b></font><font color="#FF0000">&quot;AllDigital.pbp (http://www.picbasic.co.uk/forum/showthread.php?t=11100)&quot; </font><font color="#0000FF"><b><i>; Disable Analog functions

</i></b></font><b>SW1 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>0
</b></font><b>SW2 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>1
</b></font><b>SW3 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>2
</b></font><b>SW4 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>3
</b></font><b>SW5 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>4
</b></font><b>SW6 </b><font color="#008000"><b>VAR </b></font><b>PORTB</b>.<font color="#800000"><b>5

</b></font><b>LED1 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>0
</b></font><b>LED2 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>1
</b></font><b>LED3 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>2
</b></font><b>LED4 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>3
</b></font><b>LED5 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>4
</b></font><b>LED6 </b><font color="#008000"><b>VAR </b></font><b>PORTC</b>.<font color="#800000"><b>5

</b></font><b>Counters </b><font color="#008000"><b>VAR WORD</b></font>[<font color="#800000"><b>6</b></font>] <font color="#0000FF"><b><i>; 6 words, for 6 buttons
</i></b></font><b>DelayTime </b><font color="#008000"><b>CON </b></font><font color="#800000"><b>10000 </b></font><font color="#0000FF"><b><i>; 10 seconds
</i></b></font><b>T0IF </b><font color="#008000"><b>VAR </b></font><b>INTCON</b>.<font color="#800000"><b>2 </b></font><font color="#0000FF"><b><i>; TMR0 overflow flag
</i></b></font><b>X </b><font color="#008000"><b>VAR BYTE

</b></font><b>OPTION_REG </b>= <font color="#800000"><b>%01010100 </b></font><font color="#0000FF"><b><i>; WPU on, TMR0 1:32 prescaler, internal clk
</i></b></font><font color="#008000"><b>PAUSE </b></font><font color="#800000"><b>50 </b></font><font color="#0000FF"><b><i>; let everything settle

</i></b></font><b>Main</b>:
<font color="#008000"><b>WHILE </b></font>!<b>T0IF </b>: <font color="#008000"><b>WEND </b></font><font color="#0000FF"><b><i>; wait for timer to overflow
</i></b></font><b>TMR0 </b>= <font color="#800000"><b>100 </b></font><font color="#0000FF"><b><i>; load timer for 1ms
</i></b></font><b>T0IF </b>= <font color="#800000"><b>0 </b></font><font color="#0000FF"><b><i>; reset the overflow flag

</i></b></font><font color="#008000"><b>IF </b></font><b>SW1 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>0</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED1
</b><font color="#008000"><b>IF </b></font><b>SW2 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>1</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED2
</b><font color="#008000"><b>IF </b></font><b>SW3 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>2</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED3
</b><font color="#008000"><b>IF </b></font><b>SW4 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>3</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED4
</b><font color="#008000"><b>IF </b></font><b>SW5 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>4</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED5
</b><font color="#008000"><b>IF </b></font><b>SW6 </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>then </b></font><b>Counters</b>[<font color="#800000"><b>5</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED6

</b><font color="#008000"><b>FOR </b></font><b>X </b>= <font color="#800000"><b>0 </b></font><font color="#008000"><b>to </b></font><font color="#800000"><b>5 </b></font><font color="#0000FF"><b><i>; cycle thru counters
</i></b></font><font color="#008000"><b>IF </b></font><b>Counters</b>(<b>X</b>) &gt; <font color="#800000"><b>0 </b></font><font color="#008000"><b>THEN </b></font><font color="#0000FF"><b><i>; if counter is counting
</i></b></font><b>Counters</b>(<b>X</b>) = <b>Counters</b>(<b>X</b>) - <font color="#800000"><b>1 </b></font><font color="#0000FF"><b><i>; decrement counter
</i></b></font><font color="#008000"><b>IF </b></font><b>Counters</b>(<b>X</b>) = <font color="#800000"><b>0 </b></font><font color="#008000"><b>THEN </b></font><font color="#0000FF"><b><i>; if counter timed out
</i></b></font><font color="#008000"><b>SELECT CASE </b></font><b>X </b><font color="#0000FF"><b><i>; turn off the appropriate LED
</i></b></font><font color="#008000"><b>CASE </b></font><font color="#800000"><b>0 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED1
</b><font color="#008000"><b>CASE </b></font><font color="#800000"><b>1 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED2
</b><font color="#008000"><b>CASE </b></font><font color="#800000"><b>2 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED3
</b><font color="#008000"><b>CASE </b></font><font color="#800000"><b>3 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED4
</b><font color="#008000"><b>CASE </b></font><font color="#800000"><b>4 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED5
</b><font color="#008000"><b>CASE </b></font><font color="#800000"><b>5 </b></font>: <font color="#008000"><b>LOW </b></font><b>LED6
</b><font color="#008000"><b>END SELECT
ENDIF
ENDIF
NEXT </b></font><b>X
</b><font color="#008000"><b>GOTO </b></font><b>Main
</b>

No Interrupts required.

HTH,

Darrel Taylor
- 30th May 2009, 04:50
I should add ... the counters in the previous example are retriggerable. So the delay would be from the Last button Release.

If the delay should be from the first press, wait 10 seconds, non-retriggerable,
then replace the switch test lines with these ...
<font color="#000000"> <font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>0</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW1</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>0</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED1
</b><font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>1</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW2</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>1</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED2
</b><font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>2</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW3</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>2</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED3
</b><font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>3</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW4</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>3</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED4
</b><font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>4</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW5</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>4</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED5
</b><font color="#008000"><b>IF </b></font>(<b>Counters</b>[<font color="#800000"><b>5</b></font>]=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>AND </b></font>(<b>SW6</b>=<font color="#800000"><b>0</b></font>) <font color="#008000"><b>THEN </b></font><b>Counters</b>[<font color="#800000"><b>5</b></font>] = <b>DelayTime </b>: <font color="#008000"><b>HIGH </b></font><b>LED6</b>

lilimike
- 30th May 2009, 04:54
Thanks for the quick response Darrel,

I tried your code and I feel like I am getting closer but...
first the delay was over 1 minute so by making DelayTime CON 1500 it is close to 10 seconds. Not sure if it is because I am using the internal oscilator and it is not as accurate as it should be but this is no isue.

Instead of turning off LEDs 1-5 after 10 seconds I need to turn on another set of Leds so I added TR1 VAR PORTA.0 up to TR6 VAR PORTA.5 and I used those in the select case and so far its all good.

I now face the following issues:
if I hold down any of the switches (SW1 to SW6) for 3 seconds, it should cancel the Delaytime that was going to turn on TRx and branch to a different label to do something else.

If I press and release a switch, 10 seconds later TRx turns on, I need to be able to press and release the same switch to turn off LEDx and TRx at once.

Another aspect I didn't mention because I will deal with it later is that when TRx turns on, if I don't manually press and release the switch to turn them off, after a set timed period (written in EEPROM) it will eventually turn off both LEDx and TRx

I have a feeling I am going to spend a few months on this...

Darrel Taylor
- 30th May 2009, 06:26
I tried your code and I feel like I am getting closer but...
first the delay was over 1 minute ... Not sure if it is because I am using the internal oscilator ...
OK, not a problem. You didn't specify an OSC earlier so I chose 20mhz.

Let's go with 8Mhz internal.
Change the OSC define and add this line ...
DEFINE OSC 8
OSCCON = %01110001 ; 8Mhz Internal


And change TMR0 = 100 to ...
<font color="#000000"> <b>TMR0 </b>= <font color="#800000"><b>193 </b></font><font color="#0000FF"><b><i>; load timer for 1ms</i></b></font>

And put DelayTime back to 10000.

The values for different OSC and Timer reload periods can be found easily with ...

PicMultiCalc - (Timer Helper)
http://www.picbasic.co.uk/forum/attachment.php?attachmentid=2957&d=1225550328

My example was trying to show how to deal with 6 different timers without needing 6 Timers.

I'm affraid the "Instead of"'s will be your job. :)
<br>

lilimike
- 30th May 2009, 12:09
Fair enough,
This has brought me to a level beyong what I had expected and its given me tons of ideas for the rest.

Thank you for your help.

Mike

lilimike
- 1st June 2009, 03:11
Darrel,

I was able to mix the code example you provided with my previous code and I have almost completed my project. I have one final step to acomplish and it is to trigger off LED1 to 6 based on a time period. the time period is between 1 to 12 hours and can occur only every 60 minutes from the time LEDx was set high.

I came accros your example "Elapsed Timer" using Timer1 and I think this is suitable for what I need to do. I have saved the 3 files "DT_INTS-14.bas", "ReEnterPBP.bas" and "Elapsed_INT.bas" and used your example but I am getting the following errors:

[224] local directive only for use in macro
[225] undefined symbol 'iflafreg'
[226] numeric constant or symbol name expected
[201] ')' expected
[300] too many errors

Could it be that chip 16F883 is not supported with this code ?
I am using PBP 2.50c

Thanks

Mike

Darrel Taylor
- 1st June 2009, 03:15
You need to use MPASM for the assembler.

It doesn't work with PBP's default PM assembler.
<br>

lilimike
- 1st June 2009, 03:28
I did a bit of code in ASM with MPLAB but If I create a project with MPLAB using MPASM, it will not compile my .bas code. I have tried using PBP within MPLAB but its not working.

Can you give me an overview (or a link) of how to do this?

Thanks

Mike

Darrel Taylor
- 1st June 2009, 03:31
If you have the latest MPLAB it could be a problem.

See the note on this page at meLabs (01/26/2009) ...
http://melabs.com/support/mplab.htm

Added: If you are using MicroCode Studio, don't worry about all the steps to integrate PBP into MPLAB, you won't need them.
Just point MCS to the correct folder, and tell it to use MPASM.
<br>

lilimike
- 1st June 2009, 03:43
I have the propper version 8.15a, it came on the PBP CD (purchased 2 weeks ago)
If I have to use MPLAB I will manage to figure it out but if you can just point me in the right direction I would appreciate.
Do I need to use PBP Tool Suite from within MPLAB?
Otherwize, if I use MPASM Tool Suite how would it compile the .bas section?

Sorry about all my questions...

Darrel Taylor
- 1st June 2009, 03:55
Maybe this will help ...

http://www.picbasic.co.uk/forum/showthread.php?p=47079#post47079
<br>

lilimike
- 1st June 2009, 04:33
Its all good now!

Thanks

Mike

lilimike
- 2nd June 2009, 23:44
Hi,

Trying out the "Elapsed Timer" I am observing these issues:

Beeing that I don't have an LCD module, I am trying to write the values in EEPROM and then read back using a PICKit2.

I know the code is working because LED1 is blinking and the rate seems to be good.

My first write is succesful
then trying to write the value for "Seconds" is always 00
trying to write the value for Minutes is always FF (even after a few minutes)



INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
INCLUDE "Elapsed_INT.bas" ; Elapsed Timer Routines
LED1 var portc.0
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, _ClockCount, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor

INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
ENDASM

GOSUB ResetTime ' Reset Time to 0d-00:00:00.00
GOSUB StartTimer ' Start the Elapsed Timer

write 5,3 ; this is working fine.

Main:
IF SecondsChanged = 1 THEN
SecondsChanged = 0
toggle led1
T1CON.0 = 0
write 0,Minutes ; this is always showing 00
write 1,Seconds ; this is always showing FF
'LCDOUT $FE,2, DEC Days,"d-",DEC2 Hours,":",DEC2 Minutes,":",DEC2 Seconds
ENDIF
GOTO Main

Am I missing something?

Thanks

Mike

lilimike
- 3rd June 2009, 00:21
I tried adding DEFINE WRITE_INT 1 but still getting same results :mad:

Darrel Taylor
- 3rd June 2009, 00:37
The T1CON.0 = 0 line is turning off the Timer.
So it never counts again.

At the start of the program, the SecondsChanged bit is set so that programs will display the initial 00:00:00.

So it stops counting before the first second passes.
<br>

lilimike
- 3rd June 2009, 01:34
Some days I feel dumber than others and today is one of those!

I tried joining this code with my code and things are not going so well... I have a piezo beeping on the press of the swithes and when I added this code it is more like rigning than beeping and also I have a feeling I need something short and simple but I am trying to use something big and complex.

All I really need is to have a counter that counts the minutes up to 720 and then cycle to 0 and start over endlessly. I don't need an interupt as I can test compare by branching from the main loop (in one minute I have plenty of time to test) Accuracy is not really important + or - 10 minutes over 720 is ok. I am already using timer0 so I guess I need to use timer1 or timer2.

Do you have any simple and quick advice or link to suggest?

I feel I have taked already too much of your time and I apologize for that.

Mike

Archangel
- 3rd June 2009, 01:55
Some days I feel dumber than others and today is one of those!


All I really need is to have a counter that counts the minutes up to 720 and then cycle to 0 and start over endlessly. I don't need an interupt as I can test compare by branching from the main loop (in one minute I have plenty of time to test) Accuracy is not really important + or - 10 minutes over 720 is ok. I am already using timer0 so I guess I need to use timer1 or timer2.
Mike
Hi Mike,
Welcome to My World!


counter var byte
minutes var word
clear ' zero variables at start
loop:

PortB = %00000000
TRISB = %00000000
counter = counter + 1
Pause 1000
If counter >= 60 then minutes = minutes + 1 : counter = 0

if minutes >= 720 then gosub action
goto loop

Action:
minutes = 0
Toggle PortB.1 ' change this to do what you need done
return


A great clock this will not be, it does (should do) what you asked, you may need to juggle the numbers if you have a bunch of code to stuff in.

lilimike
- 3rd June 2009, 02:14
Thank you Joe,

Unfortunately the PAUSE 1000 within my main loop is making the response too slow.
This is my main loop ( added your example) when I press on any of the 6 switches it needs to react faster than a second later. This is why I am thinking I probably need to use timer1.


Main:

l=0: y=0
WHILE !T0IF : WEND ; wait for timer to overflow
TMR0 = 193 ; load timer for 1ms
T0IF = 0 ; reset the overflow flag


IF (SW1=0) THEN Counters[0] = DelayTime : goto Channel1
IF (SW2=0) THEN Counters[1] = DelayTime : goto Channel2
IF (SW3=0) THEN Counters[2] = DelayTime : goto Channel3
IF (SW4=0) THEN Counters[3] = DelayTime : goto Channel4
IF (SW5=0) THEN Counters[4] = DelayTime : goto Channel5
IF (SW6=0) THEN Counters[5] = DelayTime : goto Channel6

FOR X = 0 to 5 ; cycle thru counters
IF Counters(X) > 0 THEN ; if counter is counting
Counters(X) = Counters(X) - 1 ; decrement counter
IF Counters(X) = 0 THEN ; if counter timed out
SELECT CASE X ; turn on the appropriate LED
CASE 0 : if led1 = 1 then gosub StartCharge1
CASE 1 : if led2 = 1 then gosub StartCharge2
CASE 2 : if led3 = 1 then gosub StartCharge3
CASE 3 : if led4 = 1 then gosub StartCharge4
CASE 4 : if led5 = 1 then gosub StartCharge5
CASE 5 : if led6 = 1 then gosub StartCharge6
END SELECT
ENDIF
ENDIF
NEXT X
;-------------------------------------------------/
; update counter /
;-------------------------------------------------/
counter = counter + 1
Pause 1000
If counter >= 60 then minutes = minutes + 1 : counter = 0

; trigger off if it is time

if minutes >= 720 then minutes = 0

GOTO Main

Darrel Taylor
- 3rd June 2009, 02:15
Some days I feel dumber than others and today is one of those!
Well, that in itself implies there are days when you don't feel that way ...
Only prior instances of feeling "Smart" can make you recognize the "dumb" when it comes around. :)
Let's see if we can't make tomorrow a little better.

At first I was trying to make it easy with an example Without Interrupts.
Then you found my interrupt program, and the Elapsed Timer.
Combining the two has no doubt created the headaches.

I've tried to figure out what you were doing from the previous posts, and failed.

If I could see what you had so far, I might be able to combine things using only DT_INTS.
Who knows?
<br>

lilimike
- 3rd June 2009, 02:45
Ok so in many occasions I felt like just putting up all my code but then I felt embarassed knowing how many people wil laugh...
But here it is.

This is what I am trying to do:
I have 6 switches SWx, 6 LEDs LEDx and 6 Optoisolator (which will trigger TRIACS) TRx

Normal mode:
if I press SW1, it will turn on LED1 and wait 10 seconds before turning on TR1.
The 10 seconds is just to wait in case I wanted to get in program mode.

Program mode:
Happens if I keep SW1 pressed for about 5 seconds. LED1 will blink 11 times and the program is waiting for user input on SW1 during 5 seconds. each press of SW1 will blink LED1 once. after 3 seconds of inactivity of SW1, LED1 wil blink the amount of time SW1 was pressed during program mode. if pressed 5 times during program mode LED1 will blink 5 times and it will save value 5 in EEPROM address 0. After this, going back to normal mode, if I press SW1, LED1 will go high, 10 seconds later TR1 will go high.
If I press SW1 again LED1 and TR1 will go low. If I don't press SW1, LED1 and TR1 will go low after 5 hours (value in EEPROM)
My default time value is 3 hours, minimum is 1 and max is 12 (720 min.)

At this point my code is (seams to be) working perfectly with the exception that I don't know how to test when the time is up. of course I need to keep track of 6 TR.

I ment to narrow down my code using indexes for all ports but my testing didn't go as planned so I have everything repeated 6 times.

PLease don't laugh:confused:

CLEAR
INCLUDE "AllDigital.pbp" ; Disable Analog functions
DEFINE OSC 8
OSCCON = %01110001
SW1 VAR PORTB.0
SW2 VAR PORTB.1
SW3 VAR PORTB.2
SW4 VAR PORTB.3
SW5 VAR PORTB.4
SW6 VAR PORTB.5

LED1 VAR PORTC.0
LED2 VAR PORTC.1
LED3 VAR PORTC.2
LED4 VAR PORTC.3
LED5 VAR PORTC.4
LED6 VAR PORTC.5
PZ VAR PORTC.6 ; piezo (beep)

TR1 VAR PORTA.0
TR2 VAR PORTA.1
TR3 VAR PORTA.2
TR4 VAR PORTA.3
TR5 VAR PORTA.4
TR6 VAR PORTA.5

SwStat Var bit ; used to control toggle of SWx
L var byte ; count SWz time hold
I VAR byte ; general use in for next

Counters VAR WORD[6] ; 6 words, for 6 buttons
ChargeTime VAR WORD[6] ; charging time in hours
DelayTime CON 10000 ; 10 seconds
T0IF VAR INTCON.2 ; TMR0 overflow flag
X VAR BYTE
Y var byte

OPTION_REG = %01010100 ; WPU on, TMR0 1:32 prescaler, internal clk
PAUSE 50 ; let everything settle
;------------------------------------------------------------------------/
; First time use, check if Charging time is configured. /
; if not, set defaults to 3 hours. (EEPROM 0 to 5 =3 and 6=0x25 /
;------------------------------------------------------------------------/
read 6,y ; if not 0x25 then it is the first time
if y <> $25 then
for I = 0 to 5: write i,3: next i: write 6,$25
endif
;------------------------------------------------------------------------/


Main:

l=0: y=0
WHILE !T0IF : WEND ; wait for timer to overflow
TMR0 = 193 ; load timer for 1ms
T0IF = 0 ; reset the overflow flag


IF (SW1=0) THEN Counters[0] = DelayTime : goto Channel1
IF (SW2=0) THEN Counters[1] = DelayTime : goto Channel2
IF (SW3=0) THEN Counters[2] = DelayTime : goto Channel3
IF (SW4=0) THEN Counters[3] = DelayTime : goto Channel4
IF (SW5=0) THEN Counters[4] = DelayTime : goto Channel5
IF (SW6=0) THEN Counters[5] = DelayTime : goto Channel6

FOR X = 0 to 5 ; cycle thru counters
IF Counters(X) > 0 THEN ; if counter is counting
Counters(X) = Counters(X) - 1 ; decrement counter
IF Counters(X) = 0 THEN ; if counter timed out
SELECT CASE X ; turn on the appropriate LED
CASE 0 : if led1 = 1 then gosub StartCharge1
CASE 1 : if led2 = 1 then gosub StartCharge2
CASE 2 : if led3 = 1 then gosub StartCharge3
CASE 3 : if led4 = 1 then gosub StartCharge4
CASE 4 : if led5 = 1 then gosub StartCharge5
CASE 5 : if led6 = 1 then gosub StartCharge6
END SELECT
ENDIF
ENDIF
NEXT X

GOTO Main


my code is too long, the rest is in the next message

lilimike
- 3rd June 2009, 02:46
here is the rest...


Channel1:
pause 25 ; debounce
if sw1 = 0 then
if led1 = 0 or swstat = 1 then
if led1 = 0 then sound pz,[123,10]: high led1
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led1: sound pz,[123,10]: pause 50: next i
goto Bprog1
else
goto Channel1
endif
else
low led1: low tr1: sound pz,[123,10]
pause 100
while sw1 = 0: wend
endif
endif
swstat = 0
goto main

Channel2:
pause 25 ; debounce
if sw2 = 0 then
if led2 = 0 or swstat = 1 then
if led2 = 0 then sound pz,[123,10]: high led2
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led2: sound pz,[123,10]: pause 50: next i
goto Bprog2
else
goto Channel2
endif
else
low led2: low tr2: sound pz,[123,10]
pause 100
while sw2 = 0: wend
endif
endif
swstat = 0
goto main

Channel3:
pause 25 ; debounce
if sw3 = 0 then
if led3 = 0 or swstat = 1 then
if led3 = 0 then sound pz,[123,10]: high led3
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led3: sound pz,[123,10]: pause 50: next i
goto Bprog3
else
goto Channel3
endif
else
low led3: low tr3: sound pz,[123,10]
pause 100
while sw3 = 0: wend
endif
endif
swstat = 0
goto main

Channel4:
pause 25 ; debounce
if sw4 = 0 then
if led4 = 0 or swstat = 1 then
if led4 = 0 then sound pz,[123,10]: high led4
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led4: sound pz,[123,10]: pause 50: next i
goto Bprog4
else
goto Channel4
endif
else
low led4: low tr4: sound pz,[123,10]
pause 100
while sw4 = 0: wend
endif
endif
swstat = 0
goto main

Channel5:
pause 25 ; debounce
if sw5 = 0 then
if led5 = 0 or swstat = 1 then
if led5 = 0 then sound pz,[123,10]: high led5
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led5: sound pz,[123,10]: pause 50: next i
goto Bprog5
else
goto Channel5
endif
else
low led5: low tr5: sound pz,[123,10]
pause 100
while sw5 = 0: wend
endif
endif
swstat = 0
goto main

Channel6:
pause 25 ; debounce
if sw6 = 0 then
if led6 = 0 or swstat = 1 then
if led6 = 0 then sound pz,[123,10]: high led6
pause 300
swstat = 1
l=l+1
if l => 5 then
for i = 1 to 11: toggle led6: sound pz,[123,10]: pause 50: next i
goto Bprog6
else
goto Channel6
endif
else
low led6: low tr6: sound pz,[123,10]
pause 100
while sw6 = 0: wend
endif
endif
swstat = 0
goto main

Bprog1:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(0) > 0 THEN Counters(0) = Counters(0) - 1
IF Counters(0) = 0 THEN
if y = 0 then y = 3
if y > 12 then y = 12
write 0,y
for I = 1 to y: high led1:sound pz,[123,10]:pause 50:low led1: pause 50: next i
goto main
endif
if sw1 = 0 then
pause 25 ;debouce
if sw1 = 0 then
Counters[0] = DelayTime
high led1: sound pz,[123,10]: pause 25
y = y + 1: low led1
Counters[0] = DelayTime
endif
endif
goto bprog1

Bprog2:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(1) > 0 THEN Counters(1) = Counters(1) - 1
IF Counters(1) = 0 THEN
if y = 0 then y = 3
if y > 12 then y = 12
write 1,y
for I = 1 to y: high led2:sound pz,[123,10]:pause 50:low led2: pause 50: next i
goto main
endif
if sw2 = 0 then
pause 25 ;debouce
if sw2 = 0 then
Counters[1] = DelayTime
high led2: sound pz,[123,10]: pause 25
y = y + 1: low led2
Counters[1] = DelayTime
endif
endif
goto bprog2

Bprog3:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(2) > 0 THEN Counters(2) = Counters(2) - 1
IF Counters(2) = 0 THEN
if y = 0 then y=3
if y > 12 then y = 12
write 2,chargetime(2)
for I = 1 to y: high led3:sound pz,[123,10]:pause 50:low led3: pause 50: next i
goto main
endif
if sw3 = 0 then
pause 25 ;debouce
if sw3 = 0 then
Counters[2] = DelayTime
high led3: sound pz,[123,10]: pause 25
y = y + 1: low led3
Counters[2] = DelayTime
endif
endif
goto bprog3

Bprog4:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(3) > 0 THEN Counters(3) = Counters(3) - 1
IF Counters(3) = 0 THEN
if y = 0 then y = 3
if y > 12 then y = 12
write 3,y
for I = 1 to y: high led4:sound pz,[123,10]:pause 50:low led4: pause 50: next i
goto main
endif
if sw4 = 0 then
pause 25 ;debouce
if sw4 = 0 then
Counters[3] = DelayTime
high led4: sound pz,[123,10]: pause 25
y = y + 1: low led4
Counters[3] = DelayTime
endif
endif
goto bprog4

Bprog5:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(4) > 0 THEN Counters(4) = Counters(4) - 1
IF Counters(4) = 0 THEN
if y = 0 then y = 3
if y > 12 then y = 12
write 4,y
for I = 1 to y: high led5:sound pz,[123,10]:pause 50:low led5: pause 50: next i
goto main
endif
if sw5 = 0 then
pause 25 ;debouce
if sw5 = 0 then
Counters[4] = DelayTime
high led5: sound pz,[123,10]: pause 25
y = y + 1: low led5
Counters[4] = DelayTime
endif
endif
goto bprog5

Bprog6:
WHILE !T0IF : WEND
TMR0 = 225
T0IF = 0

IF Counters(5) > 0 THEN Counters(5) = Counters(5) - 1
IF Counters(5) = 0 THEN
if y = 0 then y = 3
if y > 12 then y = 12
write 5,y
for I = 1 to y: high led6:sound pz,[123,10]:pause 50:low led6: pause 50: next i
goto main
endif
if sw6 = 0 then
pause 25 ;debouce
if sw6 = 0 then
Counters[5] = DelayTime
high led6: sound pz,[123,10]: pause 25
y = y + 1: low led6
Counters[5] = DelayTime
endif
endif
goto bprog6

StartCharge1:
high TR1:
return

StartCharge2:
high TR2:
return

StartCharge3:
high TR3:
return

StartCharge4:
high TR4:
return

StartCharge5:
high TR5:
return

StartCharge6:
high TR6:
return

Archangel
- 3rd June 2009, 02:58
Ok so in many occasions I felt like just putting up all my code but then I felt embarassed knowing how many people wil laugh...



Now that's just wrong headed, I make people laugh all the time. <b>GO FOR IT !</b> You join in here, you're family.

Darrel Taylor
- 3rd June 2009, 03:10
Like you said, you've only had PBP a couple weeks ...
Laughing would only be Rude.

Thanks for the code!
I think I can do something with it.

But first I'd like to point out the WORST Basic statement ever devised.
PAUSE xx
It turns an amazingly fast processor into a "thumb twiddling idiot".
Spending most of it's time doing nothing.
If I were that chips Boss, I'd fire it. :eek:

Granted, there are a few instances when PAUSE is required. But if at all possible, avoid PAUSE at all costs.

Working on it ....

Archangel
- 3rd June 2009, 03:21
Like you said, you've only had PBP a couple weeks ...
Laughing would only be Rude.

Thanks for the code!
I think I can do something with it.

But first I'd like to point out the WORST Basic statement ever devised.
PAUSE xx
It turns an amazingly fast processor into a "thumb twiddling idiot".
Spending most of it's time doing nothing.
If I were that chips Boss, I'd fire it. :eek:

Granted, there are a few instances when PAUSE is required. But if at all possible, avoid PAUSE at all costs.

Working on it ....

I guess I took his 720 min out of context, pretty much thought it was a stand alone app, please allow me to take For Next, Ugh Pause, and pull up my pants :D, . . . "thumb twiddling idiot "!, careful Darrel, that's getting pretty close to home . . . :eek: , But Darrel <B> IS ,</b> right.

Darrel Taylor
- 3rd June 2009, 03:54
But Darrel <B> IS ,</b> right.
I got this lady ... could you repeat that to her? :D

Mike,

Are you stuck with the SOUND command, or do you just want a beep from the piezo?
I'm gonna have problems with PBP's SOUND command and interrupts.
<br>

lilimike
- 3rd June 2009, 04:04
The beep doesn't have to come from the sound command, I didn't know it could be generated another way! as long as it goes beep when LEDx changes state is good.

I will learn from this project but I have a couple of other projects I will impress you with!

Thank you soooooo much for your help.

Mike

Darrel Taylor
- 6th June 2009, 04:56
Yowwwsaaaa!

I saw something interesting floating thru the forum's waters, and I grabbed at it.
Ummm, excuse me ... can I give it back? :D
It looked like a piece of Tuna, I didn't know there was a Hook in it!

Oh OK, I guess not.

So many timers and conditions and beeps,
I'm just going to gnaw on this a little more ...
see if I can't work that hook out of my cheek before I hit surface. :)
<br>

lilimike
- 6th June 2009, 11:37
I was kind of fiddling with part of your timer code and part of what I had and I was able to get all the timings, highs and lows at the right place but the beep with the sound command is really lowsy, instead of beep it goes brererererep!
Of course If I had an scope I might see other strange things!

Darrel Taylor
- 6th June 2009, 21:54
You can probably just turn off the Interrupts (INTCON.7) during the beeps.

It'll stop keeping time during the beep, but in the scope of several hours charge time, you'll never notice.
<br>

Darrel Taylor
- 7th June 2009, 06:36
OK, well now that you already have it working ... :o

I finally got mine working too.
This one doesn't use interrupts, and is essentially the example I gave in post#3, expanded to meet the other requirements.

May not be any help to you, but it might give some more ideas.
View Highlighted code (http://www.pbpgroup.com/files/Charge-6.htm)

CLEAR
INCLUDE "AllDigital.pbp" ; Disable Analog functions
DEFINE OSC 8
OSCCON = %01110001

SW1 VAR PORTB.0
SW2 VAR PORTB.1
SW3 VAR PORTB.2
SW4 VAR PORTB.3
SW5 VAR PORTB.4
SW6 VAR PORTB.5

LED1 VAR PORTC.0
LED2 VAR PORTC.1
LED3 VAR PORTC.2
LED4 VAR PORTC.3
LED5 VAR PORTC.4
LED6 VAR PORTC.5
PZ VAR PORTC.6 ; piezo (beep)

TR1 VAR PORTA.0
TR2 VAR PORTA.1
TR3 VAR PORTA.2
TR4 VAR PORTA.3
TR5 VAR PORTA.4
TR6 VAR PORTA.5

;---[Adjustable delay times]------------------------------------------------
DebounceTime CON 25 ; (ms) button debounce time
ChargeDelay CON 10000 ; (ms) delay before it starts charging
ProgDelay CON 5000 ; (ms) time to hold button for program mode
ProgHold CON 3000 ; (ms) of inactivity to end Program Mode
MaxCharge CON 12 ; (hours) Maximum Charge Time [MAX 18]
;---------------------------------------------------------------------------
Counters VAR WORD[6] ; 6 words, for 6 buttons
ProgCounter VAR WORD[6] ; counts buttom time to enter Program Mode
Debounce VAR BYTE[6] ; debounce counters
ChargeTime VAR BYTE[6] ; counts charging time (hours) in Prog mode
ChannelStates VAR BYTE[6] ; Channel state flags
ChannelState VAR BYTE
LastState VAR ChannelState.0 ; state of SW pin during last loop
Pressed VAR ChannelState.1 ; Button has been pressed
ProgramMode VAR ChannelState.2 ; indicates currently in program mode
ChargeMode VAR ChannelState.3 ; indicates currently in charge mode

T0IF VAR INTCON.2 ; TMR0 overflow flag
I VAR BYTE ; general use in for next
X VAR BYTE
TempW VAR BYTE
OneSecond VAR WORD
SecondsChanged VAR BIT
PinState VAR BIT

OneSecond = 1000
OPTION_REG = %01010100 ; WPUon, TMR0 1:32 prescaler, internal clk

DATA @0, 3, 3, 3, 3, 3, 3 ; set default Charge Time to 3 hours

sound pz,[123,10] ; beep on power-up

;----[Main Loop]------------------------------------------------------------
Main:
WHILE !T0IF : WEND ; wait for timer to overflow
TMR0 = 193 ; load timer for 1ms
T0IF = 0 ; reset the overflow flag
OneSecond = OneSecond - 1 ; count off 1 second intervals
IF OneSecond = 0 THEN ; for charge timers
OneSecond = 1000
SecondsChanged = 1
ENDIF
;-----------------------------------
FOR X = 0 to 5 ; cycle thru Channels
ChannelState = ChannelStates(X) ; get this channels state flags
GOSUB GetSWState ; get the current state of the SW
IF PinState != LastState THEN ; debounce the pin
LastState = PinState
Debounce(X) = DebounceTime
ENDIF
IF Debounce(X) > 0 THEN ; If debouncing
Debounce(X) = Debounce(X) - 1 ; decrement the counter
IF Debounce(X) = 0 THEN ; when it gets to 0
Pressed = !PinState ; button is stable, get the state

IF Pressed THEN ;==== Button Pressed Event =========
IF ChargeMode THEN ; If we're in charge mode
ChargeMode = 0 ; cancel charge mode
Counters(X) = 0 ; clear the counter
GOSUB TriacOFF ; turn off the triac
ELSE
IF ProgramMode THEN ;---- Program Mode------------------
IF ChargeTime(X) < MaxCharge THEN ; limit to Max charge time
Counters(X) = ProgHold ; reset Prog mode Timeout
ChargeTime(X) = ChargeTime(X) + 1 ; increment # of hours
GOSUB Beep ; beep on each button press
ELSE ; If Max has been reached
sound pz,[123,10] ; funky beep
sound pz,[50,10]
ENDIF
ELSE ;---- Normal Mode ------------------
ProgCounter (X) = ProgDelay ; start program detect delay
IF Counters(X) = 0 THEN ; if not counting yet
Counters(X) = ChargeDelay ; Set Delay before Charge mode
' READ X, ChargeTime(X) ; get charge time from EEPROM
' for i = 1 to ChargeTime(X) ; beep once for each hour
' GOSUB Beep ; so user knows current
' next i ; charge time before it starts
GOSUB LEDON ; turn on LED
ENDIF
ENDIF
ENDIF
ELSE ;---- button released --------------
ProgCounter (X) = 0 ; stop looking for program press
ENDIF
ENDIF
ENDIF


IF ProgCounter(X) > 0 THEN ;---- Program Delay counter --------
ProgCounter(X) = ProgCounter(X) - 1
IF ProgCounter(X) = 0 THEN ; when it times out
Counters(X) = 0 ; stop the Charge Delay period
Counters(X) = ProgHold ; reset Program inactivity Timeout
ChargeTime(X) = 0 ; clear the hour counter
for i = 1 to 11 ; beep 11 times as requested
GOSUB Beep
next i
ProgramMode = 1 ; -- Enter Program Mode --
ENDIF
ENDIF

IF Counters(X) > 0 THEN ;---- Main Delay Timers------------
IF ChargeMode THEN ;** In Charge Mode, time counts
IF SecondsChanged THEN ; in seconds **
Counters(X) = Counters(X) - 1
IF Counters(X) = 0 THEN ; End of Charge Time
GOSUB TriacOFF ; turn off the Triac
ChargeMode = 0 ; cancel charge mode
ENDIF
ENDIF
ELSE
Counters(X) = Counters(X) - 1 ;** Normal mode counts ms **
IF Counters(X) = 0 THEN ; if counter timed out
IF ProgramMode THEN ; and already in prog mode
ProgramMode = 0 ; End Programming Mode
GOSUB LEDOFF ; everything OFF
GOSUB TriacOFF
IF ChargeTime(X) > 0 THEN ; if user entered a charge time
WRITE X, ChargeTime(X) ; save it to EEPROM
ELSE ; if user didn't enter charge time
READ X, ChargeTime(X) ; restore time from EEPROM
ENDIF
for i = 1 to ChargeTime(X) ; beep once for each hour
GOSUB Beep
next i
ELSE ;---- End of delay before charge --
ProgCounter(X) = 0 ; Stop looking for program press
GOSUB LEDOFF ; LED OFF
GOSUB TriacON ; Triac ON - Start Charge
READ X, TempW ; Get charge time from EEPROM
Counters(X) = TempW * 3600 ; seconds to charge
ChargeMode = 1
ENDIF
ENDIF
ENDIF
ENDIF

ChannelStates(X) = ChannelState ; save channels state flags
NEXT X ; Do the next channel
SecondsChanged = 0 ; clear SecondsChanged notification
GOTO Main

;----I/O for each channel---------------------------------------------------
GetSWState:
SELECT CASE X ; get state of this channels pin
CASE 0 : PinState = SW1
CASE 1 : PinState = SW2
CASE 2 : PinState = SW3
CASE 3 : PinState = SW4
CASE 4 : PinState = SW5
CASE 5 : PinState = SW6
END SELECT
RETURN

LEDON:
SELECT CASE X ; turn ON the appropriate LED
CASE 0 : HIGH led1
CASE 1 : HIGH led2
CASE 2 : HIGH led3
CASE 3 : HIGH led4
CASE 4 : HIGH led5
CASE 5 : HIGH led6
END SELECT
RETURN

LEDOFF:
SELECT CASE X ; turn OFF the appropriate LED
CASE 0 : LOW led1
CASE 1 : LOW led2
CASE 2 : LOW led3
CASE 3 : LOW led4
CASE 4 : LOW led5
CASE 5 : LOW led6
END SELECT
RETURN

TriacON:
SELECT CASE X ; turn ON the channels Triac
CASE 0 : HIGH TR1
CASE 1 : HIGH TR2
CASE 2 : HIGH TR3
CASE 3 : HIGH TR4
CASE 4 : HIGH TR5
CASE 5 : HIGH TR6
END SELECT
RETURN

TriacOFF:
SELECT CASE X ; turn OFF the channels Triac
CASE 0 : LOW TR1
CASE 1 : LOW TR2
CASE 2 : LOW TR3
CASE 3 : LOW TR4
CASE 4 : LOW TR5
CASE 5 : LOW TR6
END SELECT
RETURN

;----Beep-------------------------------------------------------------------
Beep:
GOSUB LEDON ; flash LED when beeping
sound pz,[123,10]
GOSUB LEDOFF
pause 50
RETURNThere are a few commented lines in the "Normal Mode" section that will beep the number of hours when entering the "Delay before Charge" time. I thought it was handy to know how long it was set for before it starts charging.

HTH,

lilimike
- 7th June 2009, 13:23
Like I was saying I was just fiddling with my code (nothing close to final version)

Now my code has 444 lines and yours has 234 and it does the same thing!

Its just like when my wife tells me a story and then I tell the same story...

This is helping me out a great deal (not my wife's stories but your version of the code) in fact everyone of your posts in this thread and in other threads have helpd me understand better.

I can't figure out if you are 65 years old and you have done this all your life or if you are 16 and living in a bubble filled with pics but you are a master at what you are doing, you where very helpful and I appreciate everything you did. Not only for me but also for others.

Thanks Darrel, you are the best!

Darrel Taylor
- 8th June 2009, 05:17
I can't figure out if you are 65 years old and you have done this all your life or if you are 16 and living in a bubble filled with pics
All of the above.
16 Inside, 65 outside, and chronologically hitting the big five-OH this year. :(
If I'm not playing with PICs, I'm playing video games online.
OK, maybe it's 14 inside.


Its just like when my wife tells me a story and then I tell the same story...
No wifey, but I can totally relate ... :D

Let me know how it all ends up.
<br>

Leonardo
- 9th June 2009, 01:54
Excellent!

Greetings

fratello
- 13th October 2011, 19:32
Please, Mr.Darrel, put again code from #3 (and#4) ? I don't understand nothing there, and I need something like this ...in one non-retriggerable button.
Thanks in advance !

Darrel Taylor
- 13th October 2011, 20:50
See post #32

fratello
- 14th October 2011, 06:28
Thank You !