Shop OBEX P1 Docs P2 Docs Learn Events
// Modulus Operator — Parallax Forums

// Modulus Operator

sbotsbot Posts: 19
edited 2012-10-23 05:48 in BASIC Stamp
Hello to All,
I am trying to use the Modulus operator to seperate whole minutes and the remaining seconds from a raw total of seconds.
Like this:
seconds//60
What hapens to the seconds if I start with a number less than 60?
I am afraid I will get 0 minutes 0 seconds
«1

Comments

  • TorTor Posts: 2,010
    edited 2012-10-20 03:45
    Unless the modulus operator is buggy it'll work just fine. 60 mod 60 is 0, 61 mod 60 is 1, 51 mod 60 is 51 and so on.

    -Tor
  • doggiedocdoggiedoc Posts: 2,240
    edited 2012-10-20 03:52
    I suspect your problem is that modulus returns only the remainder. So you need to divide by 60 first to get minutes then use modulus to get the remainder.

    Paul

    EDIT:

    Here's an example:
    ' ----------------------------[ doggiedoc ]------------------------------------]
    '
    '   File......  modulus_test.bs2
    '   Purpose...  example of modulus to convert seconds
    '   Author....  Paul A. Willoughby, DVM
    '   E-mail....  doc@tcah.com
    '   Started...  10/20/2012
    '   Updated...
    '
    '   {$STAMP BS2}
    '   {$PBASIC 2.5}
    '
    ' [----------------------------------------------------------------------------]
    
    remainder VAR Word
    hours VAR Word
    minutes VAR Word
    seconds VAR Word
    rawTime VAR Word
    nextLoop VAR Nib
    
    DEBUG CLS
      DO
        DEBUG "Enter Total Seconds to Convert:"
        DEBUGIN DEC rawTime
        hours = rawTime/3600
        remainder = rawtime//3600
        minutes = remainder/60
        seconds = rawTime//60
    
    
        DEBUG  DEC2 hours, ":", DEC2 minutes,":", DEC2 seconds, CR
        PAUSE 50
        DEBUG "Press any key to continue."
        DEBUGIN  nextLoop
        DEBUG CLS
    
      LOOP
    
  • doggiedocdoggiedoc Posts: 2,240
    edited 2012-10-20 06:30
    Here's the BS2 file. I corrected some of the 'time logic' that I goofed at such an early hour before. :D
  • sbotsbot Posts: 19
    edited 2012-10-20 15:16
    Thanks Paul,

    Yea, I should have attached the code I had already written, and you could have seen I already had a line separating minutes.
    the example you attached was almost exactly what I had. I don't have a stamp here (I'm @ work; in the middle of an oil field; isolated)
    so I couldn't test to see if it did what I wanted.

    I am a Mud-Logger on a Gas Drilling Rig trying to make my job more accurate and easier using a Stamp. You would not believe the archaic methods used to gather the data I need to do my job.

    Thanks,
    Oscar
  • sbotsbot Posts: 19
    edited 2012-10-20 15:32
    Before anyone posts and reams me for using pause to keep track of time elapsed; believe me it's several orders of magnitude above what is being used now. Besides if it works to well I'll be out of a job.
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-10-20 17:52
    I get what you are doing in the code up to the last two lines:
    [FONT=courier new][SIZE=1]SECONDS = SECONDS/2 'divide seconds in half to equal 1 foot of hole drilled
    minutes = SECONDS/60    'divide value of SECONDS by 60 TO get minutes expired
    rsec = SECONDS//60   'The remainder of total elasped seconds devided by 60 equals number of seconds left after whole minutes
    [COLOR=#ff0000]IF rsec<6 THEN thsMins = rsec*0
    thsMins = rsec*100/60     'change seconds TO tenths of minutes[/COLOR][/SIZE][/FONT]
    

    The next to the last line is superceded by the last line, and the last line completely discards the minutes.
  • sbotsbot Posts: 19
    edited 2012-10-20 21:24
    Hello Tracy,
     
    thsMins=rsec*100/60 Avoids an answer I can not use like 1.66, and the line above that drops any seconds below 6; because (5,4,3...*100/60) returns answers I cannot use like 5*100/60*=8.333.....The way I have debug set up it would display as .8 minutes, instead of.08minutes. But that is ok I don't need anything smaller than .1 minutes.
    You are much more experienced at this than I am, but why would the last line completely discard minutes. Minutes, I thought would be calculated by the line 3 lines above (I need to start numbering my lines)
    minutes = SECONDS/60 I mean they are two separate variables with different names . I am sure you are correct, but you are going to have to splain it to me.

    Opps wait a minute: never mind
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-10-20 21:40
    Oh, sorry, I misinterpreted the meaning of the variable thsMins.

    I think you can replace the two red lines by the single statement,
    thsMins = rsec/6

    That integer division is automatically zero for rsec values less than 6, so your tenths of a minute will be minutes.0 for rsec={0..5} up to minutes.9 for rsec={54..59}.
  • sbotsbot Posts: 19
    edited 2012-10-20 21:41
    I always think of things I should have said after I’ve said them. Concerning the line;
    IF rsec<6 THEN thsMins = rsec*0 I’m sure there is a more elegant way to get rid of the remaining seconds I couldn’t use, but multiplying by zero seemed the easiest to me.
    Thanks Tracy,
    Oscar
  • sbotsbot Posts: 19
    edited 2012-10-20 21:55
    Ah Ha, simpler and much more elegant. Thanks so much for your help. I will be setting this up on my next job. Just "TD" here (That's Total Depth)
    I will probably be back with questions about hardware then. Although it should be pretty simple. I'll splice into the line that energizes the electromagnet that makes the pen place a tick mark on the chromatograph paper with a resistor to limit the current. That should give me a high on the input pin starting the count. Thank you all for the help. I'll be back

    Oscar
  • sbotsbot Posts: 19
    edited 2012-10-20 23:07
    Another senior moment, man never mind.
    I love this stuff. Really makes you think. Wish I knew more.
    Thanks,
    Oscar
  • sbotsbot Posts: 19
    edited 2012-10-21 01:42
    OH ,oh

    That integer division is automatically zero for rsec values less than 6, so your tenths of a minute will be minutes.0 for rsec={0..5} up to minutes.9 for rsec={54..59}.[/QUOTE]
    Tracy,
    Wait a minute I just thought of something. If the Modulus returns an answer of zero for anything smaller than the number you are using to mod. The line: rsec = SECONDS//60 will return a zero for any number of seconds smaller than sixty, and that is what I need the most. Fractions of a minute, tenths of minutes.
    I’ll have to and a couple of lines to deal with totals less than sixty
    Maybe after the line:
    SECONDS = SECONDS/2
    Add this line…...................IF SECONDS<60 THEN
    and this one…...................SECONDS = SECONDS+60

    minutes = SECONDS/60 '.....................
    rsec = SECONDS//60'...................
    thsMins = rsec*100/60
    DEBUG "ROP =",DEC minutes,".",DEC thsMins,32,"minutes"
    GOTO RESET

    Will the rest of the program work if I add the two lines above or do I need ELSE and ENDIF statements
    I love this stuff. Really makes you think. Wish I knew more.
    Thanks,
    Oscar
  • TorTor Posts: 2,010
    edited 2012-10-21 01:50
    sbot,
    Have you tested the code? I don't know the stamp, but as I said in my earlier reply a modulus implementation is supposed to handle values lower than the modulus operator just fine. So 51//60 is supposed to return 51, not zero.

    -Tor
  • sbotsbot Posts: 19
    edited 2012-10-21 02:03
    Tor,
    I don't have anything with me to test. However I'll be going home soon and will gather everything for the next job. I hope you are correct.

    Thanks,
    Oscar
  • doggiedocdoggiedoc Posts: 2,240
    edited 2012-10-21 04:43
    Oscar - can you get mail where you are? Sounds like you might work in a remote location. I can send you a BS2 board to have on site if you like. I've got some extras and would happy to give you one.
  • sbotsbot Posts: 19
    edited 2012-10-21 06:19
    Paul,
    Thanks for the offer, but I'll be going home in a few days and I have everything I need there.At this location I'm only about 20 miles from civilization, but some sites like in west Texas are really remote.

    Thanks again,
    Oscar
  • doggiedocdoggiedoc Posts: 2,240
    edited 2012-10-21 06:29
    No problem. I don't use the BS2 nearly as much any more (in favor of the Propeller) and since folks on this forum especially Parallax have been exceedingly generous to me I thought it might be a chance to 'pay it forward' so to speak.

    There's no shortage of good help around here. :D
  • sbotsbot Posts: 19
    edited 2012-10-21 06:32
    Well folks; I will be needing help with the hardware. I thought it was going to be as easy as just hooking one wire to pin 10; but I just checked the voltage of the pluse when the pen strikes a mark. It's 22 volts AC, YIKES!!! I'm going to have to rectify, step it down, and knock the edges off before I can use it.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2012-10-21 07:24
    Depends how fast it has to be.
    You could buy a 24V lamp and couple that to a photocell and use RCTIME.
    You could use a diode to half-wave rectify the 22vac and turn on the IRED (w/ appropriate resistor) in an optocoupler and poll/test that on an INPUT pin.
  • sbotsbot Posts: 19
    edited 2012-10-21 08:03
    It doesn't have to be anywhere near micro-second fast. The fastest drill rate I've ever seen is .4 of a minute/foot and since the pulse I'm going to use is activated every 2 feet, time speed shouldn't be a problem. I like the optocoupler idea.
    Thanks PJ
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-10-21 11:16
    As Tor pointed out, you are okay with seconds//60. It works for seconds<60. For example 43 // 60 = 43. Also (60 + 43) // 60 = 43. And so on (N * 60 + 43) // 60 = 43 for any integer N.

    In your last program post you still had,
    thsMins = rsec*100/60
    That gives 1/100ths of a second. All you need for tenths is,
    thsMins = rsec/6.
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-10-21 11:21
    PJ is right on about the optocoupler. It is like the ring detector to interface a telephone to a computer. The ring signal is a relatively high voltage AC.
  • tonyp12tonyp12 Posts: 1,950
    edited 2012-10-21 14:53
    Would this work (even if seconds is less than 60?)

    minutes= seconds/60
    sec2 = minutes*60-seconds

    print "time is: " + minutes + "Min " + sec2 + "Sec"
  • doggiedocdoggiedoc Posts: 2,240
    edited 2012-10-21 15:07
    tonyp12 wrote: »
    Would this work (even if seconds is less than 60?)

    minutes= seconds/60
    sec2 = minutes*60-seconds

    print "time is: " + minutes + "Min " + sec2 + "Sec"

    I don't think so... if seconds is less than 60 then minutes will = 0.
    So, 0* 60 = 0
    and 0 - seconds = 'negative seconds'
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2012-10-21 16:44
    It should be,
    sec2 = seconds - minutes*60
    because seconds is the larger number.

    That is a valid way to do it, but
    seconds // 60
    works fine.

    By the way, there is a difference between the Stamp and the Propeller in the way they treat the // operator when it has to do with negative numbers. The Prop in Spin recognizes numbers as twos complement, and for example,
    -43 // 60 = -43
    or
    (-43 - N*60) // 60 = -43 ' for any non-negative integer N.
    So the negative numbers mirror the positive numbers with respect to the // operator.
    The Stamp treats numbers always as positive in that context,
    -43 can be written for the Stamp, and printed out as -43 for things like debug, but the math operators treat it as (65536 - 43) = 65493. Under the // operator that works out to,
    -43 // 60 = 33 ' not right!.
    That is not an issue with time values because in this world time is usually not negative. (Be careful though -- around here -- you never know.
  • sbotsbot Posts: 19
    edited 2012-10-21 17:41
    It should be,
    sec2 = seconds - minutes*60
    because seconds is the larger number.

    Clever, I never would have thought of that.
    Tracy,
    I know I said I only need tenths of minutes, but more accurately; I don't need an amount smaller than a tenth of a second. rsec*100/60 makes 45 seconds .75 minutes , which I instantly recognize as 3/4ths of a minute, where .7 would have me scrathing my head for at least .05 minutes.

    PJ,
    I started getting excited about the power of the pollmode operation you mentioned; and wondered why I had never used it. Well, I can't use it. I have a BS2.
    Thank you everybody,
    Oscar
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2012-10-21 18:10
    sbot wrote: »
    I started getting excited about the power of the pollmode operation you mentioned; and wondered why I had never used it. Well, I can't use it. I have a BS2.
    I meant "poll" as - a term of art - checking the state of an input pin.
    pen_volts  PIN  0
    INPUT pen_volts
    
    Main:
      IF pen_volts = 0 THEN pen_ticked  ' 0 = active
      DEBUG "no 22vac", CR
      GOTO Main
    
    pen_ticked:
      DEBUG "pen ticked", CR
      PAUSE 20
      GOTO Main
    

    You just have to get around to checking it periodically.

    If you need to, you can hang a little cap on the end of that half-wave recitifer, like a smoothing cap in a power supply, to provide a little bit of hang-time from the "pen tick".
  • sbotsbot Posts: 19
    edited 2012-10-21 19:28
    Boy, I sorry PJ I'm really new at this. The code you posted has me a little confused. Does pen_volts Pin 0 = pen_volts con Pin 0, and the next line
    Does INPUT pen_volts make Pin 0 an input
    I know this is elementry to you and others with thousands of posts, but I'm not sure what these 2 lines do. The rest of the code I understand except it seems backwards to me. I'm using a postive pulse to activate the start wouldn't 1=active be more logical. I'm probably in error in my thinking but seems like you want to make a 1=0=1
    What is wrong with my original program ? I Define a pin as an input low, then loop and check that pin each loop for a high. I'm not saying I disagree with what you are saying, I'm just not sure what you are saying.
    Thanks again,
    Oscar
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2012-10-22 05:59
    sbot wrote: »
    Boy, I sorry PJ I'm really new at this. The code you posted has me a little confused. Does pen_volts Pin 0 = pen_volts con Pin 0, and the next line Does INPUT pen_volts make Pin 0 an input

    pen_volts PIN 0 makes an "alias" for Pin0 - so it now has a name
    INPUT pen_volts Yes, it makes Pin0 an INPUT
    sbot wrote: »
    The rest of the code I understand except it seems backwards to me. I'm using a postive pulse to activate the start wouldn't 1=active be more logical. I'm probably in error in my thinking but seems like you want to make a 1=0=1. What is wrong with my original program ? I Define a pin as an input low, then loop and check that pin each loop for a high. I'm not saying I disagree with what you are saying, I'm just not sure what you are saying.
    There's nothing wrong with your original. I was just Demo'ing using my general assumption.
    Lots of people get stuck in this on=active=1 abstraction. An active state can be a HIGH or a LOW, depending on the circuit.
    As you move along you may find it more convenient to test for an "active Low", but don't let that impede your progress.
    Comment your code (for your own reference if not others') so that you can remember what your idea was at the time.
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2012-10-22 08:17
    sbot wrote: »
    re. "51//60=51"I hope you are correct.

    It's true! (:
    modulus results.JPG
    591 x 444 - 35K
Sign In or Register to comment.