Timing in switch statement failing

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Hello all, 

 

I am trying to create an object that will vary the amount of time it takes for the object to be called in the future from within the object. I am using a compare interrupt to generate a 1 ms clock tick. The object is blinking the LED. What it isnt doing is changing based on the amount of time that I add to valve_t_next. Its blinking with a 310us period regardless. Ill try to post all relevant code:

 

 

 

Attachment(s): 

Last Edited: Wed. Jul 27, 2022 - 01:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


 

 

Please tell me the result of rewriting this part.

 

volatile uint8_t ticker = 0;
volatile unsigned int time_stamp = 0;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I see where your head is at! I went ahead and did that and I also changed the valve_t_next to volatile as well. I then varied the number I am adding to the valve_t_next from 10 to 10k and its still the same duty cylce and period of aprox. 310us.

 

 

 

Thank you for the suggestion!

 

edit: it to at*

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Let's fix this as well.

What will be the result?

 

 

 

void valve_fire_timing(void){
    cli();
    unsigned int tmp_ts = time_stamp;
    sei();
    
    if (tmp_ts - valve_t_next >= 1000){
            // omit
            valve_t_next = tmp_ts;
            // omit
        }
    }
}

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Take a look at the other threads to learn how to post code.
If it is an image, it is troublesome to re-enter it, so I will not follow it any more.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Example-

 

https://godbolt.org/z/bq1coz754

 

For starters, you have to access time atomically because it is changing in an isr and the changing var is > 1 byte. You also cannot compare two times as you were doing, as the result of comparing two time to >=0 is always true. You need to get the difference in (unsigned) times, then check the difference with a time rate value.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Something interesting happened. I have attached the oscilloscope picture. 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sgtYumYum wrote:

Something interesting happened.

 

And what might that be?

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#2 Hardware Problem? Read AVR042.

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Replying to Raving Lunatic:

 

The period became two seconds. This agrees with a 50% duty cycle and an if statement >=1000. Given that the time_stamp increments every 1ms. Its relieving to be able to affect some change. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1


I've got it working folks. Thank you all for the insight and help. Feast your eyes.

 

 

The big difference is with the if statement that was comparing time values. You guys are the best. Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What happens when time_stamp has just rolled over?  Say time_stamp = 100 and t_last_run = 65000.

 

Also, you don't need the cli() and sei() around the assignment to t_last_run, since time_now is not shared with the ISR, so it cannot be corrupted during the assignment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In uint16_t, 100-65000 = 636.

This is the correct elapsed time.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kabasan wrote:

In uint16_t, 100-65000 = 636.

This is the correct elapsed time.

Yes, my example was bad.  I was thinking of a different issue, when checking against a pre-computed target time.

Last Edited: Wed. Jul 27, 2022 - 08:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

kk6gm wrote:

kabasan wrote:

In uint16_t, 100-65000 = 636.

This is the correct elapsed time.

Yes, my example was bad.  I was thinking of a different issue, when checking against a pre-computed target time.

To elaborate, I always compare a current time with a target time using a subtraction and test against zero.  This only involves (in the AVR8) two subtract instructions and a branch.  

 

Doing a subtraction and then a compare against a value involves four subtract instructions and another two load instructions, and a branch.  That inefficiency bothers me, especially if the test is happening very often.  I also thing the test against zero is more readable, but that's a style issue.

 

It is when comparing against zero that the rollover must be handled properly, by casting the subtraction result into a signed value.  This causes the compiler to use a signed branch instruction for the test, e.g. bmi.  Without the cast and resultant signed branch instruction, the rollover case will not be handled properly.