Pages: [1]   Go Down
Author Topic: [sorted] delay() & equivalent not working.  (Read 824 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm writing a library at the moment and wanted to change the colour of an object when pressed....

The following function draws a key and by changing the cap colour and text colour it has the appearance of being pressed:

calckey(key number,clrWhite,clrBlack);

The function works perfectly now if I do the following:

calckey(key number,clrRed,clrWhite);
calckey(key number,clrWhite,clrBlack);

It displays the key in red then straight away in white, so fast that you can barely see it in red (as you would expect)....

So now to what I would have done:

calckey(key number,clrRed,clrWhite);
delay(15);
calckey(key number,clrWhite,clrBlack);

The sketch locks up at the delay....  so I tried:

calckey(key number,clrRed,clrWhite);
unsigned long int=now;
while (millis()<now+20){};
calckey(key number,clrWhite,clrBlack);

it also crashes !

any ideas??

confused.com


« Last Edit: May 18, 2013, 06:20:04 am by cowasaki » Logged

East Anglia (UK)
Online Online
Faraday Member
**
Karma: 117
Posts: 4327
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
unsigned long int=now;
Is that really part of your code ?  Please post all of your code.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No it's not really part of my code at all! It was a quick hack to replace the delay() function to see why it was happening! 

I'm still writing it at the moment and it now works because I now change the key top colour until the user takes the stylus away then change it back so it is working without the delay bit.....  The delay bit was only there to test the colour bits and was never staying.  It just seemed weird that it would do that at all!
Logged

East Anglia (UK)
Online Online
Faraday Member
**
Karma: 117
Posts: 4327
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What I was really querying was did that line compile ?
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The sketch locks up at the delay

Can you prove that?
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Offline Offline
Shannon Member
****
Karma: 214
Posts: 12443
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to post the entire sketch so we can work out what's happening.
Logged

[ I won't respond to messages, use the forum please ]

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The sketch stopped at the delay. Its all working now as the delay was only there as a temporary measure.

I just thought it a little strange.

The whole sketch compiles to 64k so probably a bit much listing it all smiley-grin
Logged

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?

Yes, a slow one. Didn't know that was an issue but it does make sense thanks.
Logged

Offline Offline
Edison Member
*
Karma: 19
Posts: 1041
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?

Yes, a slow one. Didn't know that was an issue but it does make sense thanks.
So you're starting to realize why most people ask you to post all of your code rather than just what you think is the problem?
Logged

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?

Yes, a slow one. Didn't know that was an issue but it does make sense thanks.
delay() checks the return value of millis() against a timeout value.  millis() returns the value of a counter variable.  That counter variable is updated once a millisecond by a timer driven interrupt routine.

That interrupt routine cannot run while you are in your interrupt routine, so the counter never increases.

Interrupt routines should be kept as short as possible so that other interrupts have a chance to fire.  The "proper" way of doing what you want is to set a flag (and maybe a couple of variables - x/y coordinates for example) in the interrupt routine, and then watch for that flag being set in the main loop.  Only in the main loop would you do slow and intensive operations like drawing widgets on a screen.

You need to separate the "capturing" of the event and the "reacting to" the event.  The capturing is done in the interrupt by setting a flag that says this event has happened.  The reacting to is done in the main loop by it realising that the event happened recently, so it does what is needed.  The capturing wants to be instant and reliable (interrupt) but the reacting to can be slightly delayed by a few milliseconds without any adverse consequences (and maybe not even being noticable) - the event has already been captured.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?

Yes, a slow one. Didn't know that was an issue but it does make sense thanks.
So you're starting to realize why most people ask you to post all of your code rather than just what you think is the problem?

Sorry, posting 5500+ lines of code would have been silly when this was more out of interest than anything else.  Someone was able to come up with the solution without the code.  I am more than happy to jump in and help others and usually the code is necessary but on this occasion it would have been ott.
Logged

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're not using delay() or millis() from within an interrupt are you ...?

Yes, a slow one. Didn't know that was an issue but it does make sense thanks.
delay() checks the return value of millis() against a timeout value.  millis() returns the value of a counter variable.  That counter variable is updated once a millisecond by a timer driven interrupt routine.

That interrupt routine cannot run while you are in your interrupt routine, so the counter never increases.

Interrupt routines should be kept as short as possible so that other interrupts have a chance to fire.  The "proper" way of doing what you want is to set a flag (and maybe a couple of variables - x/y coordinates for example) in the interrupt routine, and then watch for that flag being set in the main loop.  Only in the main loop would you do slow and intensive operations like drawing widgets on a screen.

You need to separate the "capturing" of the event and the "reacting to" the event.  The capturing is done in the interrupt by setting a flag that says this event has happened.  The reacting to is done in the main loop by it realising that the event happened recently, so it does what is needed.  The capturing wants to be instant and reliable (interrupt) but the reacting to can be slightly delayed by a few milliseconds without any adverse consequences (and maybe not even being noticable) - the event has already been captured.

Thanks for your reply but I actually already understand all this anyway.  My interrupt handler is very short and uses its own interrupt on the Due (checked beforehand to make sure it was clear), if it detects an event it needs to deal with then it halts the interrupt whilst it updates the screen etc then restarts it.


Thanks to everyone who tried to help but majenko got it..


the only thing here I didn't realise was that delay() and millis() didn't work inside an interrupt. 

millis() could have been updated by another interrupt hence me trying to use the loop alternative myself to see if delay() was the issue.

It was only done like this as a quick kludge to check the display before connecting the process to the on button press and on button release events.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, posting 5500+ lines of code would have been silly when this was more out of interest than anything else.  Someone was able to come up with the solution without the code.  I am more than happy to jump in and help others and usually the code is necessary but on this occasion it would have been ott.

I'm certain that it would have been possible to demonstrate the problem in considerably less than 5500 lines of code. Just the act of doing so would probably have been enough for you to spot the problem on your own. In any case, posting a minimal sketch that actually demonstrated the problem would have avoided relying on some inspired guesswork by majenko and would have avoided everyone else looking at this thread from wasting time trying to guess what you were doing. If you had posted a short sketch demonstrating the problem, it would have been blindingly obvious what was causing it.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

UK
Offline Offline
Sr. Member
****
Karma: 7
Posts: 436
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sorry, posting 5500+ lines of code would have been silly when this was more out of interest than anything else.  Someone was able to come up with the solution without the code.  I am more than happy to jump in and help others and usually the code is necessary but on this occasion it would have been ott.

I'm certain that it would have been possible to demonstrate the problem in considerably less than 5500 lines of code. Just the act of doing so would probably have been enough for you to spot the problem on your own. In any case, posting a minimal sketch that actually demonstrated the problem would have avoided relying on some inspired guesswork by majenko and would have avoided everyone else looking at this thread from wasting time trying to guess what you were doing. If you had posted a short sketch demonstrating the problem, it would have been blindingly obvious what was causing it.

I'm sorry but as I didn't know what was causing the problem it makes building a small sketch that recreates the problem quite difficult!

It just seemed odd really and knowing that interrupts stop delay() and millis() working would have made the process of finding the problem instant hence another member knowing what the likely issue was. 

Like I said, the library was never going to keep the delay in anyway so writing the rest of that function negated the need for it but I was curious as to why it was happening.


Anyway I now know what the issue is and anyone reading this will do too so it has been a useful excursion from what I am doing.
Logged

Pages: [1]   Go Up
Jump to: