Strange problem - can't figure it out!
CarlosFandango
Posts: 67
Hmm... seem to have a problem that I can't get to the bottom of... I am trying to make this as short as possible,
but it's a bit lengthy to explain (sorry):
I have been working on a prop-based unit that contains several i2c devices, one of which is a RTC. The code that
manages these devices runs in a separate cog, so to get the current time I use a caller function that operates, via
flags to avoid contention, as follows:
clkptr := dm.GetClock ' clkptr is pointer to byte array [noparse][[/noparse]0]=seconds, =minutes ...hour/wkday/date/month/year/(ms x 10)
Where dm is the device manager object. I have tested this object extensively and, as far as I am aware, it functions
100% reliably; certainly my testing has shown this to be the case.
Because I have the RTC I have implemented a timing schema that operates over a maximum period of one hour, or
3600000 milliseconds. In order to utilise the timer (and have multiple concurrent timers) I initially call a function
GetTimeStamp:
PRI GetTimeStamp | clkptr
' Calculates 60000 * minutes + 1000 * seconds + 10 * milliseconds
clkptr := dm.GetClock
return (byte[noparse][[/noparse]clkptr+1] * 60000) + (byte[noparse][[/noparse]clkptr] * 1000) + (byte[noparse][[/noparse]clkptr+7] * 10)
and to get the elapsed time I then use
PRI TimeDiff(startt) | now
now := GetTimeStamp
' Check rollover (going from mins=59 to mins=0)
if now < startt ' rolled over
return startt + (3600000 - startt) + now
else
return now - startt
So, using the timer is (or should be) as simple as
start := GetTimeStamp
..some time passes
elapsed := TimeDiff(start) ' Returns milliseconds
***********
THE PROBLEM:: If I use
***********
repeat while TimeDiff(start) < some_value
..some code
the code will sometimes exit early, that is, WELL before the time difference reaches the value of some_value.
WHEREAS..
start := GetTimeStamp
repeat while var_name < 3000 ' For example!
var_name := TimeDiff(start)
WORKS??....?! Why would using an additional variable here make such a difference? I'm a bit confused. I thought
maybe it was just a fluke, but I ran the above code for two separate one hour sessions today - both of which
crossed the zero boundary - and it didn't fail once. So I look to the collected wisdom of the sages on this forum!
-CF
but it's a bit lengthy to explain (sorry):
I have been working on a prop-based unit that contains several i2c devices, one of which is a RTC. The code that
manages these devices runs in a separate cog, so to get the current time I use a caller function that operates, via
flags to avoid contention, as follows:
clkptr := dm.GetClock ' clkptr is pointer to byte array [noparse][[/noparse]0]=seconds, =minutes ...hour/wkday/date/month/year/(ms x 10)
Where dm is the device manager object. I have tested this object extensively and, as far as I am aware, it functions
100% reliably; certainly my testing has shown this to be the case.
Because I have the RTC I have implemented a timing schema that operates over a maximum period of one hour, or
3600000 milliseconds. In order to utilise the timer (and have multiple concurrent timers) I initially call a function
GetTimeStamp:
PRI GetTimeStamp | clkptr
' Calculates 60000 * minutes + 1000 * seconds + 10 * milliseconds
clkptr := dm.GetClock
return (byte[noparse][[/noparse]clkptr+1] * 60000) + (byte[noparse][[/noparse]clkptr] * 1000) + (byte[noparse][[/noparse]clkptr+7] * 10)
and to get the elapsed time I then use
PRI TimeDiff(startt) | now
now := GetTimeStamp
' Check rollover (going from mins=59 to mins=0)
if now < startt ' rolled over
return startt + (3600000 - startt) + now
else
return now - startt
So, using the timer is (or should be) as simple as
start := GetTimeStamp
..some time passes
elapsed := TimeDiff(start) ' Returns milliseconds
***********
THE PROBLEM:: If I use
***********
repeat while TimeDiff(start) < some_value
..some code
the code will sometimes exit early, that is, WELL before the time difference reaches the value of some_value.
WHEREAS..
start := GetTimeStamp
repeat while var_name < 3000 ' For example!
var_name := TimeDiff(start)
WORKS??....?! Why would using an additional variable here make such a difference? I'm a bit confused. I thought
maybe it was just a fluke, but I ran the above code for two separate one hour sessions today - both of which
crossed the zero boundary - and it didn't fail once. So I look to the collected wisdom of the sages on this forum!
-CF
Comments
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I don't know the reason from just reading your post.
As I don't have your hardware it's hard to test it.
How about debugging via a serial connection to your PC
and logging the received data to a file ?
Then you can look at the file and maybe you can detect some strange things and when they do happen
One Idea right out of the blue sky: Did you reserve enough stackspace in the cognew-commands ?
best regards
Stefan
I've spent more time on this 'simple' problem than I did on modifying Timothy's 8 bit driver for the oled-96 to 65K colours! So you can see how frustrating it's becoming It's very weird. I can fix it by modifying the code such that it all uses this extra var., but that seems somewhat unnecessary to me. Better to determine what the issue is and fix everything globally, although I am close to caving in on that line of thought.
It should be:
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I'm pretty sure the algorithm's OK". But now I think you could be right; I think I missed
a step somewhere.
It's late here so I'm going to have to pick this up in the am... I'll let you know if I sort this
out. Quite why it works using the variable, but otherwise not, isn't clear to me right now.
-Phil
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
'Still some PropSTICK Kit bare PCBs left!
I implemented this change, however the result is still the same. I've come to the conclusion that it's something to do with reading the i2c bus; during the delay periods I am also reading the state of some input buttons connected to another device. Looks like the bus hasn't had time to settle down properly between successive reads, and when I read the clock again it returns something rather undefined. I'm really surprised at that, as the i2c code is all spin (uses Mike Green's Basic_I2C_Driver) and therefore should result in significant delays between reads... well, I could spend another several days tracking this down or implementing some kind of improved error checking, but I'm not going to, instead I'm planning a version of the same thing that uses the prop's internal timers which I'm sure will fix this.
In any case, there's nothing wrong with the prop or the spin compiler / interpreter (I'm hardly surprised at THAT conclusion!)
-CF