Shop OBEX P1 Docs P2 Docs Learn Events
Replacing manual RxCheck signal with a self generated signal — Parallax Forums

Replacing manual RxCheck signal with a self generated signal

ElkinElkin Posts: 58
edited 2011-11-25 05:31 in Propeller 1
Below is my code where currently I have to press the spacebar on my terminal window to quit the logfile loop and start a new one. I would like to write something simple that can start a new signal with a self generated signal. Any ideas?
PUB Main

    Repeat                                                   '5 runs/hour, 120 runs/day, 840 runs/wk


      OUTA [P0] := 0                                       
      Syringe.Signal                                        




      waitcnt(time += 400_000_000)                           '5 sec


      Valve.Switch                                          


      repeat 24
        waitcnt(time += 800_000_000)                         '240 sec


      Syringe.Signal                                         


      repeat 35
        waitcnt(time += 800_000_000)                         '350 sec


      outa [P11] := 0


      waitcnt(time += 800_000_000)                           '10 sec


      Valve.Switch                                           
[COLOR=#ff0000]  ***SIGNAL NEEDED HERE***                                   'Quit data gathering for this file[/COLOR]


      waitcnt(time += 400_000_000)                           '5 sec


      OUTA [P11] := 1                                        
      OUTA [P2] := 1                                         
      OUTA [P0] := 1                                         
      Syringe.Signal              

PUB SD_main | check, sync, count, ch0, c, len, FileNumber


  ADC.init (CS, CLK, DIO)
  pause(1)


  'term.tx(CLS)
  term.str(string("-- SD Card Datalogger", CR, CR))
  term.rxflush
  'check := term.rx  


  check := \sdcard.mount_explicit(SD_DO, SD_CLK, SD_DI, SD_CS)
  if (check == 0)
    term.str(string("-- sd card mounted", CR))
    
  else
    term.str(string("-- ERROR: sd card failed to mount", CR))
    repeat
      waitcnt(0)                                                  ' stop here 
                                                   
  repeat FileNumber from 1 to 9999                                'maximum number of files allowed (9999)


    ZeroPad(FileNumber, 4, @logfile + 4)
    term.str(@logfile)
    term.tx(13)
          
    check := \sdcard.popen(@logfile, "w")                         ' attempt to create
    if (check == 0)
      term.str(string("-- log file created; logging started", CR))
      \sdcard.pputs(@header)                                      ' column header in CSV 
    else
      term.str(string("-- ERROR: could not create log file", CR))
      repeat
       waitcnt(0)


    term.rxflush


    sync := cnt
    count := 1


    repeat
     read_adc(@ch0)                                              ' get data


      ' write to log file


      \sdcard.pputs(dec2str(count, @sbuf))                        ' write count
      \sdcard.pputc(",")                                          ' separate
      \sdcard.pputs(dec2str(ch0, @sbuf))                          ' write ch0 value
      \sdcard.pputs(@crlf)                                        ' terminate line


[COLOR=#ff0000]      if (term.rxcheck <> -1)                                     ' if key pressed[/COLOR]
        quit                                                      ' abort


      waitcnt(sync += clkfreq/20)                                 ' update every 50 milliseconds (20 Hertz)
      count += 1                                                  ' update readings count


                          
      

Comments

  • pedwardpedward Posts: 1,642
    edited 2011-11-21 01:06
    Your code is missing some context, but I'll take a stab at saying these are running in separate COGs?

    If you are trying to signal between one COG and another, the simplest is either with a shared variable, or using the LOCKxxx commands. These are hardware mutexes that you can use to synchronize operations between multiple cogs.
  • ElkinElkin Posts: 58
    edited 2011-11-21 01:28
    I do have them running on different cogs. In PUB main, SD_main is called using COGNEW
  • ElkinElkin Posts: 58
    edited 2011-11-21 01:33
    The missing code is below. By using variable, do you mean declaring another variable in the VAR block?
    PUB mainDriver | time, Block, sync, count, ch0, X
    
        term.start(DOUT_PIN, DIN_PIN, %0000, 9_600)
        'term.start(RX1, TX1, %0000, 115_200)
        term.str(string("-- Version 3.0", CR))
    
    
        DIRA[0]~~
        DIRA[2]~~
        DIRA[3]~~
        DIRA[4]~~
        'DIRA[5]~~
        DIRA[6]~~
        DIRA[7]~~
        DIRA[8]~~
        DIRA[9]~~
        DIRA[10]~~
        DIRA[11]~~
    
    
        Syringe.Off
     
        time := cnt
    
    
        COGNEW (LP,@Stack[400])
    
    
        repeat 3
          waitcnt(time += 800_000_000)                           '30 sec
    
    
        COGNEW(HP,@Stack[0])                                     'Tell the new cog to run the HP method
    
    
        Syringe.Signal
    
    
         repeat 30
          waitcnt(time += 800_000_000)                           '300 sec
    
    
        OUTA [P0] := 1                                          
        Syringe.Signal
        
    
    
        repeat 6
          waitcnt(time += 800_000_000)                           '60 sec
    
    
        term.str(string("-- SD_ADC prep", CR))
        
    [COLOR=#ff0000]    COGNEW(SD_main, @Stack[150])                             'Flash memory storage program and ADC converter program[/COLOR]
    
    
        term.str(string("-- SD_ADC running", CR))
    
    
        repeat 6
          waitcnt(time += 800_000_000)                           '60 sec
     
        Block := 1
    
    
    
  • Mike GMike G Posts: 2,702
    edited 2011-11-21 05:44
    Elkin, run your logger in a predefined loop like the code below, execute the process for some period of time, or set a counter to create a new file when the counter expires.

    repeat 1000
    
  • ElkinElkin Posts: 58
    edited 2011-11-21 06:06
    Mike, I could do that here, but the fact that the timing needs to be very specific. I have tried that before but it doesnt really work that well. There is actually a lot of variation in when the loop is starting and ending.

    [FONT=Parallax] [/FONT]    repeat     read_adc(@ch0)                                              ' get data
    
    
          ' write to log file
    
    
          \sdcard.pputs(dec2str(count, @sbuf))                        ' write count
          \sdcard.pputc(",")                                          ' separate
          \sdcard.pputs(dec2str(ch0, @sbuf))                          ' write ch0 value
          \sdcard.pputs(@crlf)                                        ' terminate line
    
    
          'if ()
          if (term.rxcheck <> -1)                                     ' if key pressed
            quit                                                       ' abort
    
    
          waitcnt(sync += clkfreq/20)                                 ' update every 50 milliseconds (20 Hertz)
          count += 1                                                  ' update readings count
    
    
    
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-21 07:00
    Elkin,

    I'm sure there's a way to do what you want. What criteria do you want to use to indicate it's time to start a new log?

    Even if the loops don't always take a set amount of time there are other ways to accurately time a log file.
  • ElkinElkin Posts: 58
    edited 2011-11-21 07:18
    Duane, The criteria that I would like this to follow is simply that there is a command or signal that tells the ADC read repeat loop to quit. When this happens, a new log file will automatically open using the Zeropad program that I believe you wrote up! I can try to notate the code to explain. The code in red is where it need to change it.
    PUB mainDriver | time, Block, sync, count, ch0, X
    
    
    
        term.start(DOUT_PIN, DIN_PIN, %0000, 9_600)
        'term.start(RX1, TX1, %0000, 115_200)
        term.str(string("-- Version 3.0", CR))
    
    
        DIRA[0]~~
        DIRA[2]~~
        DIRA[3]~~
        DIRA[4]~~
        'DIRA[5]~~
        DIRA[6]~~
        DIRA[7]~~
        DIRA[8]~~
        DIRA[9]~~
        DIRA[10]~~
        DIRA[11]~~
    
    
        Syringe.Off
     
        time := cnt
    
    
        COGNEW (LP,@Stack[400])
    
    
    
    
        'repeat 3
          waitcnt(time += 800_000_000)                           '30 sec
    
    
        COGNEW(HP,@Stack[0])                                     'Tell the new cog to run the HP method
    
    
    
    
        
        Syringe.Signal
    
    
    
    
         'repeat 30
          waitcnt(time += 800_000_000)                           '300 sec
    
    
        OUTA [P0] := 1                                         
        Syringe.Signal
        
    
    
        'repeat 6
          waitcnt(time += 800_000_000)                           '60 sec
    
    
        term.str(string("-- SD_ADC prep", CR))
        
        COGNEW(SD_main, @Stack[150])                             'Flash memory storage program and ADC converter program
    
    
        term.str(string("-- SD_ADC running", CR))
    
    
        'repeat 6
          waitcnt(time += 800_000_000)                           '60 sec
     
        Block := 1
    
    
    
    
        
        Repeat                                                   '5 runs/hour, 120 runs/day, 840 runs/wk
    
    
          OUTA [P0] := 0                                        
          Syringe.Signal                                        
    
    
    
    
          waitcnt(time += 400_000_000)                           '5 sec
    
    
          Valve.Switch                                           'inject phase
    
    
          'repeat 24
            waitcnt(time += 800_000_000)                         '240 sec
    
    
          Syringe.Signal                                         
    
    
          'repeat 35
            waitcnt(time += 800_000_000)                         '350 sec
    
    
          outa [P11] := 0
    
    
          waitcnt(time += 800_000_000)                           '10 sec
    
    
          Valve.Switch                                           'load phase
    [COLOR=#ff0000]       ***SIGNAL HERE****                              'Quit data gathering for this file
    ***Here is where the command or signal should be to show that this log file should be closed***[/COLOR]
         
    
    
          waitcnt(time += 400_000_000)                           '5 sec
    
    
          OUTA [P11] := 1                                       
          OUTA [P2] := 1                                       
          OUTA [P0] := 1                                       
          Syringe.Signal                                      
    
    
          repeat 36
            waitcnt(time += 80_000_000)          
    
    
          OUTA [P2] := 0                                      
          term.str(string("-- DRV closed", CR))
    
    
          repeat 74                                             
            waitcnt(time += 80_000_000)                          '74 sec
    
    
          Block += 1                                             ' update readings count
          term.dec(Block)
    
    
        \sdcard.pclose
        term.str(string("-- log file closed", CR))
        term.str(string("-- records logged: "))
        term.dec(count)
    
    
        term.str(string(CR, CR, "Done.", CR))
        \sdcard.unmount
        
    
    
    
    
    PUB SyP
    
    
        Syringe.Signal
    
    
    PUB SyP1
    
    
        Syringe.Off
    
    
    PUB SyP2
    
    
      Valve.Switch
    
    
    PUB HP
    
    
      HPLC.Run                                                
    
    
    PUB HFG
    
    
      Detector.Wave_On
    
    
    PUB LP
    
    
      LPregen.LPpump
    
    
    PUB Terminal
    
    
      term.start(DOUT_PIN, DIN_PIN, %0000, 9_600)
      'term.start(RX1, TX1, %0000, 115_200)
    
    
    PUB SD_main | check, sync, count, ch0, c, len, FileNumber
    
    
      ADC.init (CS, CLK, DIO)
      pause(1)
    
    
      term.str(string("-- SD Card Datalogger", CR, CR))
      term.rxflush
    
    
      check := \sdcard.mount_explicit(SD_DO, SD_CLK, SD_DI, SD_CS)
      if (check == 0)
        term.str(string("-- sd card mounted", CR))
        
      else
        term.str(string("-- ERROR: sd card failed to mount", CR))
        repeat
          waitcnt(0)                                                  ' stop here 
                                                       
      repeat FileNumber from 1 to 9999                                'maximum number of files allowed (9999)
    
    
        ZeroPad(FileNumber, 4, @logfile + 4)
        term.str(@logfile)
        term.tx(13)
              
        check := \sdcard.popen(@logfile, "w")                         ' attempt to create
        if (check == 0)
          term.str(string("-- log file created; logging started", CR))
          \sdcard.pputs(@header)                                      ' column header in CSV 
        else
          term.str(string("-- ERROR: could not create log file", CR))
          repeat
           waitcnt(0)
    
    
        term.rxflush
    
    
        sync := cnt
        count := 1
    
    
        repeat
         read_adc(@ch0)                                              ' get data
    
    
          ' write to log file
    
    
          \sdcard.pputs(dec2str(count, @sbuf))                        ' write count
          \sdcard.pputc(",")                                          ' separate
          \sdcard.pputs(dec2str(ch0, @sbuf))                          ' write ch0 value
          \sdcard.pputs(@crlf)                                        ' terminate line
    
    
    [COLOR=#ff0000]      'if (***Here is where the signal should be to tell the ADC read loop to quit)[/COLOR]
    [COLOR=#ff0000]      if (term.rxcheck <> -1) ***here is the current terminator for the ADC repeat loop that I would like to change   ' if key pressed[/COLOR]
    [COLOR=#ff0000]        quit                                                       ' abort[/COLOR]
    
    
          waitcnt(sync += clkfreq/20)                                 ' update every 50 milliseconds (20 Hertz)
          count += 1                                                  ' update readings count
    
    
        
      \sdcard.pclose
      term.str(string("-- log file closed", CR))
      term.str(string("-- records logged: "))
      term.dec(count)
    
    
      term.str(string(CR, CR, "Done.", CR))
      \sdcard.unmount
    
    
    
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-11-21 07:35
    If you don't need a data value and only a signal, pull up my multi core adc object and see how I used a shared signal between the cores for timing and control. It is 0.99 rev, but it uses shared IO lines to distribute the timing and controls from a master timing generator on one cog to syncronize multiple adc/cog channels for simultaneous. Capture.

    Frank
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-21 07:39
    So is the signal a pin state change? Is it the return value of a method?

    If the later, could you use:
      repeat while syringeSignal == 0
    
        syringeSignal := syringe.signal ' assuming it returns zero when you want to continue
    
    
  • pedwardpedward Posts: 1,642
    edited 2011-11-21 13:48
    Look at the manual page for LOCKCLR, it has a clear example of how to use locks to communicate across COGs.
  • frank freedmanfrank freedman Posts: 1,983
    edited 2011-11-21 16:18
    Duane Degn wrote: »
    So is the signal a pin state change? Is it the return value of a method?

    If the later, could you use:
      repeat while syringeSignal == 0
    
        syringeSignal := syringe.signal ' assuming it returns zero when you want to continue
    
    

    I was looking for accuracy in timing, and the ability to capture multiple inputs simultaneously with no time skew between a set of samples. To do this I created a timebase generator in a separate cog. The timebase currently is free running, however due to a code example from one of the the pasm for beginners posted by JAZZED (#345), it could easily be made to stop and run under control of a external command word passed from the master control cog.
    The signals generated are single pin outputs for clk, CSEL, acq. The first two signals are specifically to drive the MCP3201 A/D converter, while the acq tells the acquisition module when to sample the A/D bit. So, no subrs in the way, no returns to worry about, no shared memory issues to add jitter to the timing, just a rock stable clock system based on the cogs counters and some waitxxx to syncronize the stuff with plenty of headroom for a faster A/D device.

    What this clock generator then allows for it to have multiple identical A/Ds tied to their own cog all capturing syncronously. As many cogs as you want to capture from from 1-5 on a single chip, or assuming special handling, processing and logging, maybe fewer on a single chip, but yet expandable by linking the control lines to as many prop chips as you want to gang together. And again the magic in this method is that the only values that were passed to the cogs were the pin and cog assignments. For timing and control, this made the most sense for the project in question.

    So for fast accurate repeatable timing sequences, I used the counters and monitored the outputs and pin assignments to control peripherals. Not the only way to do it, just the way I chose for this application.

    Frank Freedman, CRES

    P.s. Is this device going to be an infusion / syringe pump of a sort?
  • Mike GMike G Posts: 2,702
    edited 2011-11-21 17:31
    Mike, I could do that here, but the fact that the timing needs to be very specific. I have tried that before but it doesnt really work that well. There is actually a lot of variation in when the loop is starting and ending.
    Let's start with defining "specific timing". What are your timing requirements?

    Is timing periodic or dynamic? Is timing dependent on other factors?
  • ElkinElkin Posts: 58
    edited 2011-11-22 00:18
    My timing requirements are that the ADC read loop quits which would start a new logfile when it is signaled to do so. an example of this signal could be something like using the valve.switch which is where I want it to stop. The only problem is that the valve switches twice during every data acquisition period so I dont think that would work. All of these periods should be around the same time (plus minus about a second or 2) but I need to be able to run about 2500 logfiles without the timing being too far off. Also, I need to have the ability to change the total timing within the logfile period (all of the files would be basically the same length but the total acquisition time could vary by several minutes).

    The only thing that I want the Read ADC repeat loop to be dependent on is the repeat loop in the main driver. The signal can be whatever it needs to be as long as it meets this requirement. The file system should look like this at the end:

    ADC_0001.txt
    (after about 12 minutes)
    ADC_0002.txt
    (after about 12 minutes)
    ...
    ADC_2499.txt
    (after about 12 minutes)
    ADC_2500.txt

    I want the freedom to be able to go into the main driver loop and change the timing of that loop so that instead of 12 minutes it could be 10 or 15 minutes between the start of a new logfile (ADC_xxxx.txt).

    I do think that franks idea could work but I feel like there has got to be a more simple solution to this. If rxcheck <> -1 does this exactly like I want, isnt there something that I can replace this with that would quit the current logfile and open a new one? The only thing that I want to do is have a specifically defined point in the mainDriver loop that can tell the read_adc loop to quit sampling, close the current logfile, and open a new logfile.

    This issue has frustrated me for a while but I feel like this is something that is too simple and I am just overlooking it. What does rxcheck actually send (from FullDuplexSerial)? is it possible to just have a free I/O send that same signal to the Rx pin? I know that isnt really the right way to do this but that seems like it would be a simple way to fix this issue.

    Frank, I am running several different types of pumps. The syringe pump program is loaded into the pump and signaled by the propeller with a quick pulse (10th of a second I think) which starts the current pumping program (withdraw or infuse).
  • Mike GMike G Posts: 2,702
    edited 2011-11-22 06:03
    Elkin, your requirements are not clear to me. About 12 minutes? When a valve switches twice?

    Anyway, the write method in the code below increments the "command" byte every 100ms. The Read method samples the command byte every 10ms. Read is looking for the value 0x10. Read triggers a message on the second 0x10 found.

    I usually use memory locks when two processes access the same resource.
    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    DAT
      command     byte    $00
      SemID       byte    $00
    
      
    VAR
      long ReadStack[20]
      long WriteStack[20] 
    
      
    OBJ
      pst           : "Parallax Serial Terminal"  
    
            
    PUB Main
    
      'Start PST
      pst.Start(115_200)
      pause(200)
    
      ' Start the Read and Write processes
      cognew(Write, @WriteStack)
      cognew(Read, @ReadStack) 
    
    
    PUB Read | value
    '' Write to the terminal when
    '' the command equals $10
      value := 0
      repeat 'forever
        'Wait for the lock to clear
        if(command == $10)
          value++
          if(value // 2 == 0)
          pst.str(string("We got a winner!: "))
          pst.hex(command, 2)
          pst.char(13)
          pause(100)
    
        pause(10)
     
    
    PUB Write | i
      repeat  'forever
        command := i++
        pause(100)
    
    
    
    PRI Pause(Duration)  
      waitcnt(((clkfreq / 1_000 * Duration - 3932) #> 381) + cnt)
      return  
    

    I also have a PASM 4 x timer that is accurate to 1/512 of a second and up to 24 days. An associated pin transitions from high to low when the timer reaches zero. You are welcome to the code.. I have to find it.
  • ElkinElkin Posts: 58
    edited 2011-11-22 06:33
    I am going to try this code out, I think this might be something that could work. I will refer to the code in post number 8 here.

    The requirement is that when the sequence in the mainDriver repeat loop reaches a certain point (where I have labeled in red, SIGNAL HERE) the mainDriver directs the read_adc loop in SD_main to quit the loop. When this loop quits, it goes into a bigger loop which will increment the logfile number and open another file with ADC_xxxx.txt where the xxxx is one number greater than the last logfile (this is also labeled in red further down in the code). While the program is running it takes the program about 12 minutes to get get through this main loop each time, hence the 12 minutes. I need to be able to vary that time by changing the waitcnt periods so that is why I need a timed signal from the mainDriver loop to tell the read_adc loop to quit.

    I think what you have posted here will work for me as long as I can get it written in my program correctly. I dont know if the fact that my mainDriver loop and AD_main loop are operating on different cogs will have an effect on this but it doesnt seem like it will since you have your read and write that way here. as long as the stopping of the SD_main loop is dependent on the mainDriver loop a tenth of a second shouldnt be a problem. What I mean by that is at most it is only going to be delayed by 0.1 seconds and that will not be compounded in every run (which was what I was worried about).

    The fact that the program you have written is something that is constantly sampling makes me fell a little bit better about this. That is essentially what the rxcheck was doing here before. If a key was pressed then it was not equal to -1 which meant it would quit the loop. This seem like the same thing. I am going to give it a shot and wee what I can figure out.

    Thanks for the help!
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-11-22 09:11
    Elkin wrote: »
    is it possible to just have a free I/O send that same signal to the Rx pin?

    Elkin, Absolutely this is possible.

    What signal do you want to use to do this? You said somethink about a valve switching twice. Is the Prop controlling this switch or can the Prop monitor the switch. You can certainly have the logfile stop after a set number of switches or a specific time after the second switch. This is what the Prop is for. It's just a small matter of programming.

    Could you post your whole code as an archive? Let me know what signal to use (after how many counts) and what kind of delay, if any, after the signal. This shouldn't be causing you so much grief when you have so many willing to help.
  • ElkinElkin Posts: 58
    edited 2011-11-22 23:51
    The lines of interest here in version 3.2 are 190, 191, 238, 302 and 303. The prop can either send the signal directly or control a switch (Syringe.EndRun).

    If it is possible to completely do away with the Syringe.EndRun pub block (line 238) and replace this with a simple signal that mimics (rxcheck <>-1) then I could use one of the free pins that i have (pin 3 for example) and just do this directly. Rather than me pushing a key, the prop would generate the rxcheck signal at the given time (line 191) and line 303 could stay the same as (IF(term.rxcheck <> -1)). I could just make a small jumper wire from pin 3 to the rx pin and my problem would be solved.

    There really is no counting or delays if pin 3 can be made to send that signal at line 191 of the code.

    I would of course like to make this signal something different so that I dont accidentally try to type something and make 5 new files but that isnt nearly as important as getting this to work correctly.

    Thanks for all the help!
  • Mike GMike G Posts: 2,702
    edited 2011-11-24 08:01
    You are making this excessively complicated. Create getters and setters in the SyringePump object or any object where you want to save the current state. Then simply read and set the state when needed.

    SyringePump.spin
    CON
    
      _clkmode = XTAL1 + PLL16X
      _xinfreq = 5_000_000
    
      P1 = 1         'Main Injection valve
      P8 = 8         'Syringe pump I/O pin
      P3 = 3
    
      'when pin is low, pump is on
    
    DAT
      isEndRun      byte            $0
    
    PUB Signal
    
      DIRA [P8]~~
       
      OUTA [P8] := 0
       
      waitcnt(clkfreq/2 +cnt)
       
      OUTA [P8] := 1
    
      
    '' Set isEndRun
    PUB SetEndRun(value)
      isEndRun := value
      
    '' Get isEndRun
    PUB GetEndRun
      return isEndRun
    
      
    PUB Off
    
      DIRA [P8]~~
      'DIRA [P1]~~
       
      OUTA [P8] := 0
      OUTA [P1] := 0
    
    PUB Switch  'valve switches position when P1 goes high
    
      DIRA [P1]~~
    
        OUTA[P1] := 1
    
        waitcnt(clkfreq +cnt)
    
        OUTA[P1] := 0
    
    PUB EndRun
    
      DIRA[P3]~~
    
      OUTA[P3] := 1
    
      waitcnt(clkfreq/1000 +cnt)
    
      OUTA[P3] := 0
      
      'Set the internal isEndRun member
      isEndRun := -1 ' true == -1
    

    Around line 191 in Version 3.2.spin
          Valve.Switch                                           'load phase
         ' ***I would like the signal here.***                   'Quit data gathering for this file
         'PIN3 sends word or byte that mimics term.rxcheck <> -1 (originally Syringe.EndRun)
          term.str(string("--  file end", CR))
    
          if(Valve.GetEndRun)
            ' Start a new file
            Valve.SetEndRun(0) ' false == 0
    

    There is some added complexity because SyringePump.spin is started twice. The DAT section (isEndRun I added) is created once. A VAR would be created twice, one for each instance of SyringePump. You probably need to create memory locks else there might be unexpected results. However, it's not clear why you have two instance of SyringePump invoking methods in the same code blocks. Essentially both instance of SyringePump are equal, since there are no unique members.
  • ElkinElkin Posts: 58
    edited 2011-11-25 05:31
    Mike, Thanks for the help. I switched some things a little bit and got it to work. I knew that was something that was pretty simple to do but I just couldnt seem to get it to work until I saw something in you code and the idea was there! Now it is counting autonomously and it does it fast too!
Sign In or Register to comment.