Shop OBEX P1 Docs P2 Docs Learn Events
Strange problem - can't figure it out! — Parallax Forums

Strange problem - can't figure it out!

CarlosFandangoCarlosFandango Posts: 67
edited 2008-10-16 12:53 in Propeller 1
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

Comments

  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-15 20:32
    Why are you multiplying milliseconds by 10 first instead of just adding it?

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • CarlosFandangoCarlosFandango Posts: 67
    edited 2008-10-15 20:50
    Hi Phil. Good question. The chip I'm using, M41T81, returns ms x 10 (actually the registers are 0.1s and 0.01s) representing 00-99 'hundred' ms. So the actual values returned have to multiplied by 10 to result in true milliseconds, which is what I'm working with. Hence 1 minute is 60000 milliseconds, and one second is 1000 milliseconds - that's how the calculation is derived. I'm hoping this makes sense, doubt is creeping in as I type...!
  • StefanL38StefanL38 Posts: 2,292
    edited 2008-10-15 20:55
    Hello Carlos,

    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
  • CarlosFandangoCarlosFandango Posts: 67
    edited 2008-10-15 21:20
    I have extensively used serial comms to debug, and the only behaviour I can confirm is as described - specifically, with the 'added' variable it works, without it doesn't. I don't think the hardware is the issue as this seems to be reliable, although who knows - with all of these interactions going on, it's hard to say. Yes, I thought of stack space allocation as well (that's tripped me up several times). I have to confess I don't know how much is likely to be needed, whether it's one stack long per function call, or what. But I increased stack space all the way up to 200 longs (I think this should be, under most circumstances, considered to be a lot?) and still the problem persists. There is no recursion in the code I've written, and the maximum call depth is about 10.

    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 confused.gif 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.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-15 21:31
    I think this line is your problem:

    return startt + (3600000 - startt) + now
    
    
    


    It should be:

    return now + 3600000 - startt
    
    
    


    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • CarlosFandangoCarlosFandango Posts: 67
    edited 2008-10-15 22:07
    Phil - I was in the middle of composing a lengthy reply to your post which basically said "no,
    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 Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2008-10-15 22:13
    CarlosFandango said...
    Quite why it works using the variable, but otherwise not, isn't clear to me right now.
    I'm working on the assumption that that's a red herring, resulting from when you performed the tests. I could be wrong about that, but I am certain about the line of code I cited being in error.

    -Phil

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    'Still some PropSTICK Kit bare PCBs left!
  • CarlosFandangoCarlosFandango Posts: 67
    edited 2008-10-16 12:53
    @Phil: You were right, of course - the change to the line you identified was necessary and this should make the algorithm correct.

    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
Sign In or Register to comment.