Shop OBEX P1 Docs P2 Docs Learn Events
Stupid Do While question — Parallax Forums

Stupid Do While question

Lone_huskyLone_husky Posts: 13
edited 2009-07-04 23:42 in BASIC Stamp
I have a reasonably dumb question that I know is simple but for some reason I can't figure it out.

I have two conditions based on a light sensor that starts at a baseline value, decreases and then returns near that baseline.
1. a running differential that is positive when is goes below a certain threshold, aka, stops changing very much
2. a particular ratio that returns back near to a previous baseline

I want the program to detect either one of these conditions and then mark the time. I designed it this way because while the ratio returning to the previous baseline is more accurate, it sometimes never returns, based on some uncontrollable factors so I wanted an independent method that would trigger the conditional when the sensor output is not varying too much

so the following code is supposed to accomplish this, but I think I have my conditional statement fouled up and can't seem to make it so that either statement when true (or false) exists the Loop.


DO WHILE (diff > diff_min AND baseline < ratio)
GOSUB Acquire
GOSUB differential

LOOP

I think that the DO WHILE loop continues while the statement is true, so I thought the above code would work, because the conditional statement is only positive when both are positive and as soon as one become negative, the loop terminates and the program proceeds. Does this make sense????? Is there a better way to do this? Any help would be appreciated.

Thanks

-Vassilios

Comments

  • $WMc%$WMc% Posts: 1,884
    edited 2009-07-01 02:52
    -Vassilios

    Your problem might be in your subroutines. You didn't post them So we may never now?
    What I'm getting at is a little more info might help.

    ______________$WMc%_____

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Truth is out there············································ BoogerWoods, FL. USA
  • Lone_huskyLone_husky Posts: 13
    edited 2009-07-01 03:08
    Here are the subroutines....in order to keep within the memory limit of the BSpx24p I needed to do some stuff with starch memory and sometimes used devAddr as a dummy variable. In my previous post I changed it to Baseline for ease of understanding but in reality the conditional loop is

    DO WHILE (diff > diff_min AND devAddr < ratio)
    GOSUB Acquire
    GOSUB differential

    LOOP

    The subroutines are as follows

    Acquire:
    ' will acquire light readings for 518nm and 660nm and then average
    ' Uses a smoothing function which is an accumulator stored into memory
    
        HIGH LED660  'turn 660nm LED on
        LOW LED518  'turn 518nm LED off
          PULSIN TSL230,1,light1 ' light reading for 660nm
        'PAUSE 1
    
    
        HIGH LED518    'turn 518nm LED on
        LOW LED660     'turn 660nm LED off
          PULSIN TSL230,1,light2  ' light reading for 518nm
        'PAUSE 1
    
    
    'now proceed to calculate ratio
    I=light1/light2
    '---------binary division loop-----------
    FOR J=15 TO 0               ' 16 bits
    light1=light1//light2<<1                   ' remainder*2
    F.BIT0(J)=light1/light2              ' next bit
    NEXT
       '----------------------------------------
    F=F**1000                  ' normalize F*10000/65536
    
    
        IF sw2 = 0 THEN          ' This portion calculates the ratio and stores it in
          ratio = (I*1000)+(F)   ' memory to be used by the average subroutine
          PUT mem_idx, WORD ratio
          mem_idx=mem_idx+2
    
          'DEBUG " ratio= ",DEC I, ".",DEC3 F, " stored as ", DEC ratio,CR
    
        ENDIF
    
    
        IF sw2 = 1 THEN
          ratio = (I*1000)+(F)
    
          GET smooth_mem, WORD light1
          ' light1 = light1 ** 61441 + ratio         '<---- time constant=16 iterations
           light1 = (light1 ** 57345) + (ratio*2)  '<---- time constant=8 iterations
           'light1 = (light1 ** 49153) + (ratio*4)  '<---- time constant=4 iterations
    
          light2 = light1/16
          ratio = light2
          PUT smooth_mem, WORD light1
          'DEBUG DEC ratio ," "
    
          PUT 0, WORD ratio
    
          IF compression  = 0 THEN
            SEROUT LCD,N9600,[noparse][[/noparse]cmd,$45, $40,DEC ratio]
          ENDIF
    
        ENDIF
    
    
    RETURN
    
    
    
    differential: 'subroutine that calculates average of last 10 data points and creates value for
          'comparison with current value for recovery of reflectance
    
        GET 2, WORD F
        GET 4, WORD I
        'DEBUG "mem2 ", DEC F, "mem4 ", DEC I," "
      diff = ratio-I
      diff = ABS diff
         PUT 2, WORD ratio
         PUT 4, WORD F
      'DEBUG DEC diff," " ,CR
    RETURN
    
    
    
    
    
  • Tracy AllenTracy Allen Posts: 6,662
    edited 2009-07-01 04:32
    Have you debugged the values that are going into the conditional? Just before LOOP insert,
    DEBUG DEC diff, TAB, DEC diff_min, TAB, DEC devAddr, TAB, DEC ratio,CR
    That could help a lot to see why the condition is not met. The logic of the WHILE statement seems correct. That is, it will drop out of the loop when either condition is no longer true.

    I see what you are doing in the acquire subroutine, but not in the differential subroutine. Average of 10 samples? It looks more like it is comparing the current ratio (smoothed) with the ratio two iterations before (also smoothed).

    But to reiterate, please show us some DEBUG data with 4 fields. The something is off with the numbers.

    The value of I has to stay within the limits of 0 to 64.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
  • unknownunknown Posts: 10
    edited 2009-07-02 05:13
    I believe thal it is
    DO
    (commands)
    LOOP WHILE (condition)
    not DO WHILE.
  • dev/nulldev/null Posts: 381
    edited 2009-07-02 09:28
    You can use either DO WHILE or LOOP WHILE.
    Which one you use depends on if you want to run the code block before evaluating stuff.
  • $WMc%$WMc% Posts: 1,884
    edited 2009-07-03 06:37
    -Vassilio

    Your way of code is a little different than the norm.This could be a compiler confused issue.What does Your Main look like?

    ____________$WMc%____________

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    The Truth is out there············································ BoogerWoods, FL. USA
  • Lone_huskyLone_husky Posts: 13
    edited 2009-07-04 23:42
    Here is the main code

    Main:
    
    SEROUT LCD, N9600, [noparse][[/noparse]cmd, $51] ' clear LCD
    SEROUT LCD,N9600,[noparse][[/noparse]" PLEASE PLACE",cmd, $45,$40, " PROBE ON SKIN"]
    
    DO WHILE (start_sw =0) ' wait for start button to be pressed
    LOOP
    
    PAUSE 800
    SEROUT LCD,N9600,[noparse][[/noparse]cmd, $51, "Acquiring",cmd, $45,$40, "Baseline"] ' start acquiring baseline
    
    'acquire one data one for the smoothing acculumator
    GOSUB acquire
    devAddr=F*16
    PUT smooth_mem, WORD devAddr
    
    'Acquires 6 data points and calculates average for baseline reflectance
    DO WHILE (mem_idx <= avg_mem_stop)
    GOSUB Acquire
    'DEBUG "memory location= ", DEC mem_idx
    LOOP
    GOSUB Average
    
    
    SEROUT LCD,N9600,[noparse][[/noparse]cmd,$51, "Compress Skin",cmd,$45,$40,"When Ready"]
    
    'Now compress the skin and signal time of skin compression
    DO WHILE (sw =0)
    LOOP
    
    sw2=1
    compression =1
    SEROUT LCD,N9600,[noparse][[/noparse]cmd,$51, "Please wait"]
    
    'Compress the skin for 4s
    FOR idx = 4 TO 0
    
    FOR idx2 = 1 TO 10
    GOSUB acquire
    GOSUB differential
    NEXT
    PAUSE 500
    SEROUT LCD, N9600, [noparse][[/noparse]cmd,$45, $40, DEC idx]
    NEXT
    
    compression = 0
    GET baseline_mem, WORD devAddr
    SEROUT LCD,N9600,[noparse][[/noparse]cmd,$51, "Release Skin",cmd,$45,$4a,DEC devAddr]
    devAddr = 0
    DO WHILE (sw=1)
    GOSUB Acquire
    GOSUB differential
    LOOP
    
    'Set clock to 0s
    
    hundreths = $00
    secs = $00
    control = 0 ' disable SQW output
    
    GOSUB Set_Clock
    GET baseline_mem, WORD devAddr
    FOR idx =1 TO 3
    GOSUB Acquire
    GOSUB differential
    NEXT
    idx=1
    idx2=0
    
    DO WHILE (diff > diff_min AND devAddr < ratio)
    GOSUB Acquire
    GOSUB differential
    
    SEROUT LCD,N9600,[noparse][[/noparse]cmd,$45, $40,DEC ratio," "]
    
    LOOP
    
    
    GOSUB Get_Clock
    
    PUT time_idx, secs
    PUT time_idx+4, hundreths
    
    IF secs<1 AND hundreths<10 THEN
    SEROUT LCD, N9600, [noparse][[/noparse]cmd,$51, cmd,$45,$05,"FAILED",cmd,$45,$42, "MEASUREMENT"]
    
    ELSE
    
    SEROUT LCD, N9600, [noparse][[/noparse]cmd, $51, "CRT = ",HEX secs, ".", HEX hundreths,"s"]
    
    FOR idx =70 TO time_idx STEP 1
    GET idx, secs
    GET idx+4, hundreths
    'DEBUG HEX secs, ".", HEX hundreths,"s",CR
    IF idx = 70 THEN
    SEROUT LCD, N9600, [noparse][[/noparse]cmd, $45, $40 ,HEX secs, ".", HEX hundreths,"s"]
    ELSEIF idx =71 THEN
    SEROUT LCD, N9600, [noparse][[/noparse]cmd, $45, $46 ,HEX secs, ".", HEX hundreths,"s"]
    ELSEIF idx =72 THEN
    SEROUT LCD, N9600, [noparse][[/noparse]cmd, $45, $4c ,HEX secs, ".", HEX hundreths,"s"]
    
    ENDIF
    
    NEXT
    ENDIF
    
    
    IF time_idx<72 THEN
    time_idx=time_idx+1
    PAUSE 2000
    ELSEIF time_idx = 72 THEN
    PAUSE 6000
    time_idx = 70
    ENDIF
    
    LOW LED518
    LOW LED660
    
    SEROUT LCD,N9600,[noparse][[/noparse]cmd, $51]
    
    
    
    GOSUB initial
    
    
Sign In or Register to comment.