B4R Question Faster Timer1_Tick

ChocoScope

Member
Licensed User
Longtime User
Is it possible to change the timer prescaler to give a faster Tick? (Arduino UNO/Nano(328)) Or is there a better way to generate regular fast interrupts?

My attempt to change the Timer Control register with RunNative. Didn't work

B4X:
Private Sub AppStart
    Serial1.Initialize(9600)
    Timer1.Initialize("Timer1_Tick", 500)
    Timer1.Enabled = True 'don't forget to enable it
    RunNative("SetT1PS",Null)                            'attempt to change the timer prescaler
    #If C
    void SetT1PS(B4R::Object* o) {
    ULong *TCCR1B = _SFR_MEM8(0x81)                    //address of timer/counter 1B control register
    TCCR1B = 1;
    }
    #End if
End Sub

The program compiled ok and was downloaded to the UNO but it made no difference whether the RunNative code was present or not.
 

ChocoScope

Member
Licensed User
Longtime User
I am trying to update a stepper motor using an interrupt at say 200-500 microsecond intervals. It would be nice if there was a version of Timer which you could initialise in microseconds as well as in milliseconds. Then the period could be adjustable at a faster rate.
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Thank you Erel. I read this post and did not understand how the looper could work for my application. What causes the looper sub to be triggered? How can I trigger it every 200 microseconds? I can see that the time can be read from the last event and the current one but how does this help me decide when to step the stepper? Is there further reading, because I don't understand the workings of the looper?
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Do you mean something like this?

Sub Looper1
if Micros - counter >= 200 Then Call Stepstepper
counter = Micros
End Sub
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Try Again

Sub Looper1
if Micros - counter >= 200 Then
Call Stepstepper
counter = Micros
end if
End Sub

counter would be a global variable pre defined
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
You will also need to keep track of the stepper state!
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Thank you Cableguy. Does this mean that you think my last method was correct? The Stepstepper sub would have several other global variables including counter and stepper rate and any other housekeeping.
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
I tried it with this code and it worked!
with a value of 200, it turned the led on for 218us and a value of 20 gave 47us Not sure how that correlates.

B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Private counter As ULong
    Private testled As Pin
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    AddLooper("Looper1")
    testled.Initialize(13, testled.MODE_OUTPUT)
End Sub

Sub Looper1
   
    If Micros - counter >= 20 Then
        Stepstepper
        counter = Micros
    End If
End Sub

Sub Stepstepper
    testled.DigitalWrite(Not(testled.DigitalRead))
End Sub
 
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
That is the problem with loopers... It tries to run as fast as it cans... But it's affected by the code inside it... And the external calls it may make.
Especially if there's conditional code!
One condition may be quicker to match or check than other's
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
That is why I wanted to speed up the timer1_Tick, but I am going to do a few tests. I am going to try making the counter a Byte instead of a ULong to see how much it cuts down the overheads. I am also going to try turning the led on and off within the same loop, to see what the instruction time is to toggle a pin. I am using a UNO with a 328 chip.
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Well, I did my tests. With some expected results and some unexpected ones. When I changed the counter to Byte, the time went down to 30us (expected) but it stayed there regardless of whatever number I entered into it. I re-ran the original code to see if I had done anything silly, but it was correct! Can anyone explain that? The pin-pulse experiment was amazing! it toggled in 5.8us but increased the cycle time to 36us (expected). Comments appreciated.
 
Upvote 0

ChocoScope

Member
Licensed User
Longtime User
Thank you Erel. The code that way round makes sense. Can you explain why the counter needs to be Ulong? and not byte.
 
Upvote 0
Top