Shop OBEX P1 Docs P2 Docs Learn Events
Does program section order make a difference? — Parallax Forums

Does program section order make a difference?

PlitchPlitch Posts: 39
edited 2010-03-31 15:21 in BASIC Stamp
I have a BASIC Stamp PLC equipped with a Stamp 2e and a MAX 1270 A2D converter (12 bit).· I use this to control and read an ultrasonic ranging device (snow depth measurement).
I have two sections of code that deal with (1) reading the battery voltage using a voltage divider circuit which reduces the battery voltage to 0-5 VDC for the MAX 1270 to interpret and (2) reading the output of the ultrasonic sensor scaled to 0-10 VDC for the MAX1270 to read.

The voltage sensor is on analog input #2 of the and the ultrasonic sensor is on analog input #1 of the PLC.· Both sections of code produce good outputs when used independently, but something weird happens when both are used in the same progarm.

By multimeter measurement, there was 2.5 volts between the analog in #2 pin and analog ground on the stamp PLC, and the raw data from the MAX 1270 showed the variable assigned the value of the data in the SHIFTIN statement has a good value in it if a temporary debug statement is inserted, but after being converted to an ASCII sting value for serial output to a terminal, the variable is apparently zero, and the terminal displays zero.

I reversed the two sections of code that control the power and reading of the ultrasonic sensor and the voltage sensor, and with no other changes, the voltage is now absolutrly correctly displayed on the screen.

There are no interactions between the two sections of code, and no changes were made in moving them except in the order the two sections would execute.· But somehow that makes a difference in assigning a value to a variable for output.· All variables, including all used by both these sections, are defined at the beginning of the program, and no all the variable space is used up as far as I know.·

Question(s):· Is this normal behavior?·confused.gif

Comments

  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-03-29 20:21
    I suggest you post your code so it can be examined. It's pretty hard to evaulate a problem like this without it...
  • PlitchPlitch Posts: 39
    edited 2010-03-29 20:50
    Point well taken! Here's the latest (modified as above):


    '==========[noparse][[/noparse]TITLE}==================================================
    ' File..... StampPLC_snow_xx.BS2
    ' Purpose . Contol StampPLC based ultrasonic snow depth measuring station
    ' Author .. Pieter Litchfield
    ' Copyright 2010 - All Rights Reserved
    'E-mail.... pvcl@plitch.com
    '===================================================================
    '
    '
    [noparse][[/noparse] Program Description ]
    '
    ' This program reads a 0-10 volt input from an SensComp Mini-AE ultrasonic sensor and
    ' converts to a scaled digital value representing the inches of distance
    ' and then converts to inches of snow depth. The resulting snow depth
    ' is transmitted via radio modem to a PC for recording
    ' and reporting.
    '
    ' In addition, the voltage state of the batteries is read and sent at the
    ' same tme as the snow depth is sent.
    ''
    ' The program also controls the power state of the various components
    ' to reduce power use when not engaged in actual measurements. Two relays
    ' provide 24 volt power to the ultrasonic distance sensor and 12 volt DC
    ' power to the modem. One relay shuts off the solar panels used
    ' to charge the batteries while measurements are taken to insure uniform
    ' voltage to the sensor. There is also a relay that controls a voltage
    ' divider circuit for measuring battery voltage.
    ' These are turned On and off before and after readings
    ' to conserve power since the unit is expected to use solar power.
    '
    '
    [noparse][[/noparse] Revision History ]
    ' 0 Just text and formatting, no code
    ' 1 Added code for ADC 4/1/07
    ' 2 Revised ADC code to add PLC volt divider factor and millivolt scale 4/7/07
    ' 3 Added code to store zero depth value in eeprom on key press
    ' 4 Added modem and sensor relay power subroutines
    ' 5 Added long division routine to get snow depth to 4 places
    ' 6 Added code to scale sensor millivolts (0-5000) to battery volts (0-24)
    ' 7 Modified the voltage range to 0 - 50VDC 7/8/07
    ' 8 Changed to a sample of 10 readings from 5
    ' 9 Moved modem power on command to reduce possible electrical noise during sensor reading 7/17/07
    ' 10 Review & tidy up 8/5/07
    ' 11 Changed power up sequence for sensor and modem
    ' 12 Changed volts-per-inch factor to observed value 9-19-07
    ' 13 Longer warm up for sensor and added samples
    ' 14 Moved zero-snow-volts setting routine to seperate program 9-28-07
    ' 15 Trying for 4 hours between readings. no intro text transmitted
    ' 16 Added an equal weight averaging routine - last read & this read/2 10-20-07
    ' Added a comment field for edits on data fle later. 10-28-07
    ' Added an output field for mvolts raw reading 10-28-07
    ' 17 Changed averaging routine to 200 sample moving average with continuous history
    ' 18 Added rounding factor to averaging, changed warm uperiod 11-14-07
    ' Added write and read to eeprom - last sensor average for cold statup data
    ' number of sensor samples reduced to 100 - spreadsheet shows this to be enough
    ' to get a stable moving average
    ' 19 Increased delay between readings to 3 hours
    ' Reduced warm-up time to 3 minutes
    ' 20 modified A/D converter setup to allow 0-10 VDC output. Changed VPI
    ' to reflect 0-10 volts over 6 inches - 240 inches for use with Senscomp sensor.
    ' 21 Added Mvolts to output statement and changed to subtract current reading from
    ' no_snow_volts since sensor voltage is reduced with height using SensComp
    ' mini AE
    ' 22 Removed first CsADC in sensor reading subroutines to better zero readings.
    ' Did Not work, so replaced 02-19-09
    ' changed to favor current reading adresult averaging for test
    ' 23 changed VPI from 438 to 427 (actual is 42.735)
    ' 24 major changes in code to allow for 4 relay board
    ' Stamp digital output port Function
    ' 1 controls solar panel relay (NC)
    ' 2 controls voltage divider circuit (NO)
    ' 3 controls power to US sensor (NO)
    ' 4 controls power to radio (NO)
    '
    '
    [noparse][[/noparse]TEMPORARY PRODUCATION NOTES]
    ' after on site installation, the battery voltage will have to be compared with a meter to verify
    ' that the voltage scale is accurate - it assumes that the divided voltage (0-5)at the stamp is
    ' scaled to 0-50.
    ' Above was resolved by using an adjustable potentiometer in the voltage divider circuit
    ' and comparing the actual terminal voltage (approx 25 VDC) with the reported voltage
    ' and adjusting the potentiometer to get agreement.
    '
    ' Note that the volts-per-inch (constant VPI) is based ON the factory seting of the
    ' ultrasonic sensor that produces a linear change in output voltage (0 - 10 VDC)
    ' over a range of 6 - 240 inches, thereby producing a constant voltage change
    ' per inch of distance to target.
    '
    '
    '
    [noparse][[/noparse] INITIALIZE ]
    '
    ' {$STAMP BS2} ' compiler directive
    ' {$PBASIC 2.5} ' compiler directive
    '
    '
    [noparse][[/noparse] constants ]

    awhile CON 15000 ' PAUSE used TO allow modem to come on line
    a_long_time CON 60000 ' length of a long pause - 1 minute
    a_second CON 1000 ' 1 second pause
    briefly CON 10 ' pause interval when using ADC shifts
    hour CON 10000 ' used to sleep for approx 3 hrs between readings
    version CON 24 ' software version number
    VPI CON 427 ' millivolts-per-inch of sensor scale
    ' 6-240 inches = 0 TO 10 VDC
    Warm_up_minutes CON 05 ' number of minutes sensor on before readings
    samples CON 50 ' number of depth samples per reading
    '
    [noparse][[/noparse] variables ]
    '
    adResult VAR Word ' raw data from analog to digital convers.
    Accum VAR Word ' accumulates voltage readings for average
    depth VAR Word ' snow depth as calculated, integer part
    D VAR Word ' denmonator of long division - volts per in
    F VAR Word ' fractional accumulator of long division in depth
    I VAR Byte ' calc
    J VAR Byte ' index for long dividion loop, depth calc
    Mvolts VAR Word ' depth sensor 0-5000 millevolts corrected
    N VAR Word ' numerator of long division process
    no_snow_volts VAR Word ' stored value for min volts - no snow distance
    ' corrected millivolts
    VoltResult VAR Word ' battery voltage input from ADC
    X VAR Word '.1,.01,.001,.0001 place holder in log division
    '
    '
    [noparse][[/noparse] I/O Definitions ]
    '
    AinAdc PIN 5 ' A/D Data in
    AoutAdc PIN 4 ' A/D Data out
    ClkAdc PIN 0 ' A/D clock
    CsAdc PIN 3 ' Chip Select for ADC
    Dat PIN 2
    Load PIN 1
    modem PIN 13 ' modem power relay is on Dout 4
    sensor PIN 12 ' sensor power relay is on Dout 3
    panel PIN 14 ' solar panels on Dout 1
    divider PIN 15 ' voltage divider on Dout 2
    '
    [noparse][[/noparse] Initialization ]
    ' load zero depth value stored in eeprom one time on startup one time
    '
    READ 6, Word no_snow_volts
    READ 2, Word accum
    '
    ' send reboot message
    '
    GOSUB modemon
    DEBUG ", REBOOT , no_snow_volts is ",DEC no_snow_volts, " , accumulator is ",DEC Accum, CR
    GOSUB MODEMOFF
    '
    '
    '
    [noparse][[/noparse] PROGRAM CODE ]
    '
    ' do forever
    DO
    ' turn solar panel off - do all readings on battery power only
    GOSUB solaroff
    '
    ' set initial value in data accumulator for this round of readings
    READ 2, Word Accum
    ' turn on ultrasonic sensor
    GOSUB sensoron
    '
    FOR j= 1 TO warm_up_minutes 'warm up temp sensor
    PAUSE a_long_time
    NEXT
    '
    ' get a battery voltage reading On analog channel 2
    '
    GOSUB ReadVolts
    '
    ' get a snow depth sensor reading 50 times on analog channel 1
    '
    ' Accum will have saved value from memory or last calculated value
    '
    FOR j = 1 TO samples ' get a set of sensor readings
    '
    PAUSE a_second 'PAUSE FOR a second before another sensor reading
    GOSUB ReadSensor ' get a sensor reading
    Accum = (( 9*adResult)+Accum+ 5)/10 ' average 9 times current plus 1 times history
    ' ' accum value retained for next session
    NEXT
    '
    ' end of sensor reading loop - accum has readings accumulated & averaged
    '
    '
    GOSUB sensoroff 'tuen off power to sensor'
    '
    ' get a battery voltage reading On analog channel 2
    GOSUB divideron 'turn on voltage divider circuit
    '
    GOSUB ReadVolts 'get a reading - no delay required
    PAUSE 10000
    '
    GOSUB divideroff ' turn off voltage divider circuit
    '
    GOSUB solaron 'turn on solar panesl after readings
    WRITE 2,Word Accum ' save current sensor resding in EEPROM
    ' turn on modem
    '
    GOSUB modemon ' in case of restart
    '
    Mvolts = Accum + Accum + (Accum ** 28967) ' x 2.4420 scale 4095 to 10000 millivolts
    '
    ' convert distance to target to snow depth
    ' automatically scales inches per volt depending on no_snow_volts value each time
    '
    D=VPI ' denom. is sensor volts-per-inch of depth const.
    IF Mvolts <= No_Snow_Volts THEN N = No_Snow_Volts - Mvolts ' numerator is volts above whiteboard
    IF Mvolts > No_Snow_Volts THEN N=0 ' no such thing as negative distance - assume it is zero
    '
    N=N*10
    Depth = N/D ' integer result of division
    X = 1000 ' placeholder for .1,.01,.001,.0001
    F=0 ' F is the fractional part accumulator
    '
    FOR J=1 TO 4 ' 4 places
    N=N//D*10 ' remainder *10
    F=N/D*X+F ' accumulate next digit
    X=X/10 ' next place holder
    NEXT
    '
    ' send depth in ASCII character to modem for transmission
    '
    DEBUG ", ",DEC4 mvolts,",", DEC Depth,".", DEC4 F, ", "
    '
    'output battery volts To modem for transmission To PC
    '
    n = voltresult * 10

    ' increase scale to get more sign. digits
    d = 1000 ' scale 0-50000 to 0-50 by using 1000 in denom
    I=N/D ' I = integer result
    X = 1000 ' placeholder for .1, .01, .001, .0001
    F=0
    ' ' F is the fractional part accumulator
    FOR J=1 TO 4 ' 4 places
    N=N//D*10 ' remainder * 10
    F=N/D*X+F ' accumulate next digit
    X=X/10 ' next place holder
    NEXT
    '
    ' send voltage reading in ASCII characters to modem for transmission
    '
    DEBUG DEC I,".",DEC F, ",", DEC version,",", " no snow volts ",DEC no_snow_volts, CR
    '
    ' shut modem off
    GOSUB modemoff
    '
    ' put StampPLC to sleep for a while
    '
    SLEEP hour 'change constant hour to adjust length of time between readings
    '
    ' end do forever
    LOOP
    '
    '
    [noparse][[/noparse] SUBROUTINES ]
    '
    '
    [noparse][[/noparse] Get data from ADC chip from ultrasonic sensor ]
    '
    ReadSensor:
    '
    adResult = 0 ' zero reading variable
    LOW CsAdc
    PAUSE briefly 'select chip
    SHIFTOUT AoutAdc, ClkAdc, MSBFIRST, [noparse][[/noparse]%11111000] 'Ch1 0-10 VDC
    PAUSE briefly
    HIGH CsAdc
    PAUSE briefly 'trigger
    LOW CsAdc
    PAUSE briefly
    SHIFTIN AinAdc, ClkAdc, MSBPRE, [noparse][[/noparse]adResult\12] ' get result
    PAUSE briefly
    HIGH CsAdc
    '
    ' adjust ADC count for PLC input voltage divider
    '
    adResult = adResult + (adResult ** $D6C) MAX 4095 ' x -1.05243
    '
    ' adResult now contains a number from 0 - 4095 which represenst a sensor voltage
    ' adResult still needs to be scaled to 0-10000 millivolts
    RETURN
    '
    '
    [noparse][[/noparse] Get data from ADC chip for battery voltage monitor ]
    '
    ReadVolts:
    '
    VoltResult = 0
    LOW CsAdc
    PAUSE briefly 'select chip
    SHIFTOUT AoutAdc, ClkAdc, MSBFIRST, [noparse][[/noparse]%11100000] 'Ch2 0-5 VDC
    PAUSE briefly
    HIGH CsAdc
    PAUSE briefly 'trigger
    LOW CsAdc
    PAUSE briefly
    SHIFTIN AinAdc, ClkAdc, MSBPRE, [noparse][[/noparse]VoltResult\12] ' get result
    PAUSE briefly
    HIGH CsAdc
    '
    ' adjust ADC count for PLC input voltage divider
    '
    VoltResult = VoltResult + (VoltResult ** $D6C) MAX 4095 ' x 1.05243
    '
    ' adjust voltage (0-5000 mvolts) from scale of 12 bits (0-4095) to 0-5 volts
    '
    VoltResult = VoltResult + (VoltResult ** $3880) ' x 1.2207
    '
    RETURN
    '

    '
    [noparse][[/noparse]turn sensor power ON ]
    '
    sensoron:
    '
    LOW sensor
    PAUSE a_second
    RETURN
    '
    '
    [noparse][[/noparse]turn sensor power OFF]
    '
    sensoroff:
    '
    PAUSE a_second
    HIGH sensor
    RETURN
    '
    '
    [noparse][[/noparse]turn modem power ON]
    '
    modemon:
    '
    LOW modem
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn modem power OFF]
    '
    modemoff:
    '
    PAUSE awhile
    HIGH modem
    RETURN
    '
    '
    [noparse][[/noparse]turn solar power OFF]
    'note: Solar is on a NC relay so turning the relay on turns the panels off
    '
    solaroff:
    '
    LOW panel
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn solar power OFF]
    'note: Solar is on a NC relay so turning the relay off turns the panels on
    '
    solaron:
    '
    PAUSE awhile
    HIGH panel
    RETURN
    '
    '
    [noparse][[/noparse]turn divider power ON]
    '
    divideron:
    '
    LOW divider
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn divider power OFF]
    '
    divideroff:
    '
    PAUSE awhile
    HIGH divider
    RETURN
    '
    '
    [noparse][[/noparse]end of program]
    '
    END
  • Ron CzapalaRon Czapala Posts: 2,418
    edited 2010-03-29 22:13
    Which sections of code were moved around? Only subroutines were swapped correct?
  • stamptrolstamptrol Posts: 1,731
    edited 2010-03-29 23:54
    The only thing I have observed with two-channel adc's ( i was using LTC1298, I believe) was a small amount of interaction between the two channels from time to time.

    I cured it in the end by tieing each channel to ground with 100K resistor. It successfully bled off the coupled signals.

    In your case, by flipping the order of operation, you may have lucked into a situation which minimized or eliminated the coupling.

    While you have found a suitable operating mode, it would be nice to know. Perhaps a test with 100K on each channel and an arbitrary input signal ( perhaps a AA battery ) on each channel would let you run a simple test with both execution modes to compare the results.

    Cheers,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • PlitchPlitch Posts: 39
    edited 2010-03-30 02:03
    Excuse me - I sent the an old test version, not the new. However, here's what I did - the original position of "gosub readvolts" was before the section used to turn on and read the ultrasonic sensor. In the version above, you will find it there. I moved to after the section used to read the US sensor - where it also appears above. Obviouslythis isn't the correct working version, but it does show both the old and new positions of the voltmeter (readvolts) process section. Sorry to cause any confusion.

    I'm not sure I understand the comment about coupling. The two sensors were both physically working right - each had an analog voltage in the correct range present at the correct input pin (by multimeter reading). In addition, the input variable that captures the value from the AD converter was getting the correct value (VoltResult above) in the input routine (sub ReadVolts). From this I deduced the problem was not physical, but logical after the input variable has the correct value. In addition, I believe the input pins in the PLC have a 100k ohm resistor and a small capacitor installed at the factory to reduce noise (according to "an industrial cup o' joe" column #105 Jan 2004 - on this web site site.

    Here's the current code (I hope!):


    '==========[noparse][[/noparse]TITLE}==================================================
    ' File..... StampPLC_snow_xx.BS2
    ' Purpose . Contol StampPLC based ultrasonic snow depth measuring station
    ' Author .. Pieter Litchfield
    ' Copyright 2010 - All Rights Reserved
    'E-mail.... pvcl@plitch.com
    '===================================================================
    '
    '
    [noparse][[/noparse] Program Description ]
    '
    ' This program reads a 0-10 volt input from an SensComp Mini-AE ultrasonic sensor and
    ' converts to a scaled digital value representing the inches of distance
    ' and then converts to inches of snow depth. The resulting snow depth
    ' is transmitted via radio modem to a PC for recording
    ' and reporting.
    '
    ' In addition, the voltage state of the batteries is read and sent at the
    ' same tme as the snow depth is sent.
    ''
    ' The program also controls the power state of the various components
    ' to reduce power use when not engaged in actual measurements. Two relays
    ' provide 24 volt power to the ultrasonic distance sensor and 12 volt DC
    ' power to the modem. One relay shuts off the solar panels used
    ' to charge the batteries while measurements are taken to insure uniform
    ' voltage to the sensor. There is also a relay that controls a voltage
    ' divider circuit for measuring battery voltage.
    ' These are turned On and off before and after readings
    ' to conserve power since the unit is expected to use solar power.
    '
    '
    [noparse][[/noparse] Revision History ]
    ' 0 Just text and formatting, no code
    ' 1 Added code for ADC 4/1/07
    ' 2 Revised ADC code to add PLC volt divider factor and millivolt scale 4/7/07
    ' 3 Added code to store zero depth value in eeprom on key press
    ' 4 Added modem and sensor relay power subroutines
    ' 5 Added long division routine to get snow depth to 4 places
    ' 6 Added code to scale sensor millivolts (0-5000) to battery volts (0-24)
    ' 7 Modified the voltage range to 0 - 50VDC 7/8/07
    ' 8 Changed to a sample of 10 readings from 5
    ' 9 Moved modem power on command to reduce possible electrical noise during sensor reading 7/17/07
    ' 10 Review & tidy up 8/5/07
    ' 11 Changed power up sequence for sensor and modem
    ' 12 Changed volts-per-inch factor to observed value 9-19-07
    ' 13 Longer warm up for sensor and added samples
    ' 14 Moved zero-snow-volts setting routine to seperate program 9-28-07
    ' 15 Trying for 4 hours between readings. no intro text transmitted
    ' 16 Added an equal weight averaging routine - last read & this read/2 10-20-07
    ' Added a comment field for edits on data fle later. 10-28-07
    ' Added an output field for mvolts raw reading 10-28-07
    ' 17 Changed averaging routine to 200 sample moving average with continuous history
    ' 18 Added rounding factor to averaging, changed warm uperiod 11-14-07
    ' Added write and read to eeprom - last sensor average for cold statup data
    ' number of sensor samples reduced to 100 - spreadsheet shows this to be enough
    ' to get a stable moving average
    ' 19 Increased delay between readings to 3 hours
    ' Reduced warm-up time to 3 minutes
    ' 20 modified A/D converter setup to allow 0-10 VDC output. Changed VPI
    ' to reflect 0-10 volts over 6 inches - 240 inches for use with Senscomp sensor.
    ' 21 Added Mvolts to output statement and changed to subtract current reading from
    ' no_snow_volts since sensor voltage is reduced with height using SensComp
    ' mini AE
    ' 22 Removed first CsADC in sensor reading subroutines to better zero readings.
    ' Did Not work, so replaced 02-19-09
    ' changed to favor current reading adresult averaging for test
    ' 23 changed VPI from 438 to 427 (actual is 42.735)
    ' 24 major changes in code to allow for 4 relay board
    ' Stamp digital output port Function
    ' 1 controls solar panel relay (NC)
    ' 2 controls voltage divider circuit (NO)
    ' 3 controls power to US sensor (NO)
    ' 4 controls power to radio (NO)
    '
    '
    [noparse][[/noparse]TEMPORARY PRODUCATION NOTES]
    ' after on site installation, the battery voltage will have to be compared with a meter to verify
    ' that the voltage scale is accurate - it assumes that the divided voltage (0-5)at the stamp is
    ' scaled to 0-50.
    ' Above was resolved by using an adjustable potentiometer in the voltage divider circuit
    ' and comparing the actual terminal voltage (approx 25 VDC) with the reported voltage
    ' and adjusting the potentiometer to get agreement.
    '
    ' Note that the volts-per-inch (constant VPI) is based ON the factory seting of the
    ' ultrasonic sensor that produces a linear change in output voltage (0 - 10 VDC)
    ' over a range of 6 - 240 inches, thereby producing a constant voltage change
    ' per inch of distance to target.
    '
    '
    '
    [noparse][[/noparse] INITIALIZE ]
    '
    ' {$STAMP BS2} ' compiler directive
    ' {$PBASIC 2.5} ' compiler directive
    '
    '
    [noparse][[/noparse] constants ]

    awhile CON 15000 ' PAUSE used TO allow modem to come on line
    a_long_time CON 60000 ' length of a long pause - 1 minute
    a_second CON 1000 ' 1 second pause
    briefly CON 10 ' pause interval when using ADC shifts
    hour CON 10000 ' used to sleep for approx 3 hrs between readings
    version CON 24 ' software version number
    VPI CON 427 ' millivolts-per-inch of sensor scale
    ' 6-240 inches = 0 TO 10 VDC
    Warm_up_minutes CON 05 ' number of minutes sensor on before readings
    samples CON 50 ' number of depth samples per reading
    '
    [noparse][[/noparse] variables ]
    '
    adResult VAR Word ' raw data from analog to digital convers.
    Accum VAR Word ' accumulates voltage readings for average
    depth VAR Word ' snow depth as calculated, integer part
    D VAR Word ' denmonator of long division - volts per in
    F VAR Word ' fractional accumulator of long division in depth
    I VAR Byte ' calc
    J VAR Byte ' index for long dividion loop, depth calc
    Mvolts VAR Word ' depth sensor 0-5000 millevolts corrected
    N VAR Word ' numerator of long division process
    no_snow_volts VAR Word ' stored value for min volts - no snow distance
    ' corrected millivolts
    VoltResult VAR Word ' battery voltage input from ADC
    X VAR Word '.1,.01,.001,.0001 place holder in log division
    '
    '
    [noparse][[/noparse] I/O Definitions ]
    '
    AinAdc PIN 5 ' A/D Data in
    AoutAdc PIN 4 ' A/D Data out
    ClkAdc PIN 0 ' A/D clock
    CsAdc PIN 3 ' Chip Select for ADC
    Dat PIN 2
    Load PIN 1
    modem PIN 13 ' modem power relay is on Dout 4
    sensor PIN 12 ' sensor power relay is on Dout 3
    panel PIN 14 ' solar panels on Dout 1
    divider PIN 15 ' voltage divider on Dout 2
    '
    [noparse][[/noparse] Initialization ]
    ' load zero depth value stored in eeprom one time on startup one time
    '
    READ 6, Word no_snow_volts
    READ 2, Word accum
    '
    ' send reboot message
    '
    GOSUB modemon
    DEBUG ", REBOOT , no_snow_volts is ",DEC no_snow_volts, " , accumulator is ",DEC Accum, CR
    GOSUB MODEMOFF
    '
    '
    '
    [noparse][[/noparse] PROGRAM CODE ]
    '
    ' do forever
    DO
    ' turn solar panel off - do all readings on battery power only
    GOSUB solaroff
    '
    ' set initial value in data accumulator for this round of readings
    READ 2, Word Accum
    ' turn on ultrasonic sensor
    GOSUB sensoron
    '
    FOR j= 1 TO warm_up_minutes 'warm up temp sensor
    PAUSE a_long_time
    NEXT

    '
    FOR j = 1 TO samples ' get a set of sensor readings
    '
    PAUSE a_second 'PAUSE FOR a second before another sensor reading
    GOSUB ReadSensor ' get a sensor reading
    Accum = (( 9*adResult)+Accum+ 5)/10 ' average 9 times current plus 1 times history
    ' ' accum value retained for next session
    NEXT
    '
    ' end of sensor reading loop - accum has readings accumulated & averaged
    '
    '
    GOSUB sensoroff 'turn off power to sensor'
    '
    ' get a battery voltage reading On analog channel 2
    GOSUB divideron 'turn on voltage divider circuit
    '
    GOSUB ReadVolts 'get a reading - no delay required

    '
    GOSUB divideroff ' turn off voltage divider circuit
    '
    GOSUB solaron 'turn on solar panesl after readings
    WRITE 2,Word Accum ' save current sensor resding in EEPROM
    ' turn on modem
    '
    GOSUB modemon ' in case of restart
    '
    Mvolts = Accum + Accum + (Accum ** 28967) ' x 2.4420 scale 4095 to 10000 millivolts
    '
    ' convert distance to target to snow depth
    ' automatically scales inches per volt depending on no_snow_volts value each time
    '
    D=VPI ' denom. is sensor volts-per-inch of depth const.
    IF Mvolts <= No_Snow_Volts THEN N = No_Snow_Volts - Mvolts ' numerator is volts above whiteboard
    IF Mvolts > No_Snow_Volts THEN N=0 ' no such thing as negative distance - assume it is zero
    '
    N=N*10
    Depth = N/D ' integer result of division
    X = 1000 ' placeholder for .1,.01,.001,.0001
    F=0 ' F is the fractional part accumulator
    '
    FOR J=1 TO 4 ' 4 places
    N=N//D*10 ' remainder *10
    F=N/D*X+F ' accumulate next digit
    X=X/10 ' next place holder
    NEXT
    '
    ' send depth in ASCII character to modem for transmission
    '
    DEBUG ", ",DEC4 mvolts,",", DEC Depth,".", DEC4 F, ", "
    '
    'output battery volts To modem for transmission To PC
    '
    n = voltresult * 10

    ' increase scale to get more sign. digits
    d = 1000 ' scale 0-50000 to 0-50 by using 1000 in denom
    I=N/D ' I = integer result
    X = 1000 ' placeholder for .1, .01, .001, .0001
    F=0
    ' ' F is the fractional part accumulator
    FOR J=1 TO 4 ' 4 places
    N=N//D*10 ' remainder * 10
    F=N/D*X+F ' accumulate next digit
    X=X/10 ' next place holder
    NEXT
    '
    ' send voltage reading in ASCII characters to modem for transmission
    '
    DEBUG DEC I,".",DEC F, ",", DEC version,",", " no snow volts ",DEC no_snow_volts, CR
    '
    ' shut modem off
    GOSUB modemoff
    '
    ' put StampPLC to sleep for a while
    '
    SLEEP hour 'change constant hour to adjust length of time between readings
    '
    ' end do forever
    LOOP
    '
    '
    [noparse][[/noparse] SUBROUTINES ]
    '
    '
    [noparse][[/noparse] Get data from ADC chip from ultrasonic sensor ]
    '
    ReadSensor:
    '
    adResult = 0 ' zero reading variable
    LOW CsAdc
    PAUSE briefly 'select chip
    SHIFTOUT AoutAdc, ClkAdc, MSBFIRST, [noparse][[/noparse]%11111000] 'Ch1 0-10 VDC
    PAUSE briefly
    HIGH CsAdc
    PAUSE briefly 'trigger
    LOW CsAdc
    PAUSE briefly
    SHIFTIN AinAdc, ClkAdc, MSBPRE, [noparse][[/noparse]adResult\12] ' get result
    PAUSE briefly
    HIGH CsAdc
    '
    ' adjust ADC count for PLC input voltage divider
    '
    adResult = adResult + (adResult ** $D6C) MAX 4095 ' x -1.05243
    '
    ' adResult now contains a number from 0 - 4095 which represenst a sensor voltage
    ' adResult still needs to be scaled to 0-10000 millivolts
    RETURN
    '
    '
    [noparse][[/noparse] Get data from ADC chip for battery voltage monitor ]
    '
    ReadVolts:
    '
    VoltResult = 0
    LOW CsAdc
    PAUSE briefly 'select chip
    SHIFTOUT AoutAdc, ClkAdc, MSBFIRST, [noparse][[/noparse]%11100000] 'Ch2 0-5 VDC
    PAUSE briefly
    HIGH CsAdc
    PAUSE briefly 'trigger
    LOW CsAdc
    PAUSE briefly
    SHIFTIN AinAdc, ClkAdc, MSBPRE, [noparse][[/noparse]VoltResult\12] ' get result
    PAUSE briefly
    HIGH CsAdc
    '
    ' adjust ADC count for PLC input voltage divider
    '
    VoltResult = VoltResult + (VoltResult ** $D6C) MAX 4095 ' x 1.05243
    '
    ' adjust voltage (0-5000 mvolts) from scale of 12 bits (0-4095) to 0-5 volts
    '
    VoltResult = VoltResult + (VoltResult ** $3880) ' x 1.2207
    '
    RETURN
    '

    '
    [noparse][[/noparse]turn sensor power ON ]
    '
    sensoron:
    '
    LOW sensor
    PAUSE a_second
    RETURN
    '
    '
    [noparse][[/noparse]turn sensor power OFF]
    '
    sensoroff:
    '
    PAUSE a_second
    HIGH sensor
    RETURN
    '
    '
    [noparse][[/noparse]turn modem power ON]
    '
    modemon:
    '
    LOW modem
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn modem power OFF]
    '
    modemoff:
    '
    PAUSE awhile
    HIGH modem
    RETURN
    '
    '
    [noparse][[/noparse]turn solar power OFF]
    'note: Solar is on a NC relay so turning the relay on turns the panels off
    '
    solaroff:
    '
    LOW panel
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn solar power OFF]
    'note: Solar is on a NC relay so turning the relay off turns the panels on
    '
    solaron:
    '
    PAUSE awhile
    HIGH panel
    RETURN
    '
    '
    [noparse][[/noparse]turn divider power ON]
    '
    divideron:
    '
    LOW divider
    PAUSE awhile
    RETURN
    '
    '
    [noparse][[/noparse]turn divider power OFF]
    '
    divideroff:
    '
    PAUSE awhile
    HIGH divider
    RETURN
    '
    '
    [noparse][[/noparse]end of program]
    '
    END
  • stamptrolstamptrol Posts: 1,731
    edited 2010-03-30 10:54
    The coupling, if present, occurs within the a/d chip. Sounds like you have that possibility eliminated.

    ·Is there any relationship to when the radio modem is powered up?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • PlitchPlitch Posts: 39
    edited 2010-03-30 20:24
    I don't know the answer to that one.· The radio modem is not attached, but the relay controlling the power to the radio is on the same relay board as the others and is in use - there's just no radio hooked to it at the moment.· However, I have not changed the position of the modem power relay control code relative to either of the two analog sensor control sections.

    To confirm:· The "normal" sequence of operations in the code after startup is:

    beginning:
    shut off solar panels relay 1 (digital out #1)
    turn on depth sensor power relay 3 (digital out #3)
    take a distance (depth) reading from analog input #1
    turn off depth sensor power
    turn on voltage divider circuit relay 2 (digital out #2)
    take a battery voltage reading with analog inut #2
    turn off voltage divider circuit
    turn on solar panels
    turn on modem power relay 4 (digital out #4)
    transmit readings
    turn off modem power
    go to sleep for 3 hours, then loop to beginning:



    All seems to work normally.· I assume I had some kind of issue relating to variables or values in memory trying to occupy the same space?· But I don't know how to read the memory chart in the stamp terminal/editor, so if I "fixed" it with my moving code around, great!· I recall reading about issues relating to values in memory getting overwritten and was wondering how to test for that.
  • stamptrolstamptrol Posts: 1,731
    edited 2010-03-31 14:29
    As long as its working for you, it can remain one of life's mysteries.

    I loaded your program and looked at the memory map. You still have the equivalent of 4 bytes free in the variable area and lots of room in the program area.

    I noticed the comment for adResult notes the multiplier to be "- 1.05243" and for VoltResult the comment is for "1.05243". so I assume one is a typo as the ** operation is the same in both cases. The equation complies in either case.

    Cheers,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tom Sisk

    http://www.siskconsult.com
    ·
  • PlitchPlitch Posts: 39
    edited 2010-03-31 15:21
    Thanks Tom.· Wow - 4 bytes of variable space left - that kind of reminds me of programming my old Radio Shack TRS-80 (model 1) in Z80 Assembler many many years ago.· I programmed a whole control driver and a loader for the driver for a voice synthesizer, including a look up table for all punctuation pronunciation, into 1000 bytes.· Now it seems that hundreds of millions of bytes are needed to do the same thing.· The Stamp is sort of a return to crude but demanding processors for me.

    The "-" in front of the multiplier is indeed a typo - but never fixed since it was in a comment.· I should tidy up my program a bit.

    I have checked the functioning of both the analog circuits (ultrasonic sensor of analog input #1 and voltage on input #2).· Both seem to be responding correctly to applied voltages using the latest version of the program, so I have reached a "who cares" point. However, it's always better to know why things do or son't work for the next time one tries a similar situation.
    ·
Sign In or Register to comment.