'{$STAMP BS2p} 'Datalog.BSP 'Copyright 2002 Blue Bell Design Inc. 'Demo program for BBDI "Libby" robot board A/D and PC display ' ' comment out the DEBUGGER CON 1 statement to run with a terminal pgm ' or comment out the DEBUGGER CON 0 to work with the Stamp Debug Terminal 'DEBUGGER CON 0 'if debugger is 0, the program uses a terminal ' or PC running a terminal program. DEBUGGER CON 1 'if debugger is 1, the program uses a Stamp debugging window. chan VAR NIB 'Nibble sized variable used for channel number adc_value var word '10 bit A/D value left justified in 16 bit word hi_dig var byte 'whole # of volts SPKR CON 12 'Speaker port on "Libby" LF con 10 'Define Line Feed Character '======================================================================== 'Startup stuff AUXIO 'Select "Aux" I/O pins to get X0-X15 instead of regular ports 'Co-Processor is connected to Aux ports. 'To get back to the regular ports use MAINIO command. GOSUB beepit 'Beep twice to say "Hello!" GOSUB msg1 'Print opening message '======================================================================== 'Main Routine SEROUT 10, 1021, [116] '116 = Reset Co-Processor - send it twice SEROUT 10, 1021, [116] ' in case Co-Proc was expecting data main: FOR chan = 0 to 4 'Read all 5 A/D channels and display values 'Channel 0 is the power supply voltage/2. 'The power supply tap is taken after the Schottky ' anti-droop diode. That is the voltage into the ' low-drop regulator. 'Read the full 10 bits of the A/D from the channel number in chan ' into a 16 bit Stamp word named adc_value. 'The data is left justified so the 6 LS Bits of the lowbyte are 0. SEROUT 10, 1021, [120 + chan] 'Read first byte of A/D command = ' 120(decimal) + channel number SERIN 9, 1021, [adc_value.HIGHBYTE] 'Gets the Most Significant byte first. SEROUT 10, 1021, [85] 'Now read 2nd byte of A/D ' command = 85 (decimal) or $55 (hex) SERIN 9, 1021, [adc_value.LOWBYTE] 'the data coming back is the least significant ' 2 bits but left justified - that is ' they are in most significant 2 bit positions. ' The bottom 6 bits are 0. 'If you only wanted a 1 byte answer, ' just skip the second read. You could then ' make adc_value a byte variable instead of ' a word. GOSUB A2D_msg 'Show what is going on to PC Screen GOSUB display_A2D: 'Scale the above value to 5.00 volts max and print it ' to the PC screen NEXT Pause 5000 GOTO main STOP '======================================================================== ' SUBROUTINES BELOW '======================================================================== beepit: 'Beep the speaker twice freqout SPKR,500,2000,4000 pause 500 'the stamp stops and waits during this time. see timer ' example to see how to keep running doing something ' else during this time. freqout SPKR,500,2000,4000 RETURN '======================================================================== msg1: if (DEBUGGER = 1) THEN bug1 SEROUT 16, 17405, ["Hi There!",CR,LF,LF] RETURN bug1: DEBUG "Hi There!",CR, LF, LF RETURN '======================================================================== A2D_msg: if (DEBUGGER = 1) THEN bug2 SEROUT 16, 17405, ["Channel #", DEC1 chan, " "] SEROUT 16, 17405, ["rcvd hi = " , HEX2 adc_value.HIGHBYTE] SEROUT 16, 17405, [", low = " , HEX2 adc_value.LOWBYTE] RETURN bug2: DEBUG "Channel #", DEC1 chan, " " DEBUG "rcvd hi = " , HEX2 adc_value.HIGHBYTE DEBUG ", low = " , HEX2 adc_value.LOWBYTE RETURN '======================================================================== display_A2D: 'Scale a 16 bit value to 5.00 volts max and print it ' to the PC screen. 'The A/D reads the input as a fraction of the power supply voltage. 'It is only as accurate as the power supply. If you want an absolute ' referenced voltage, measure the supply to the Co=Processor and ' correct the equation accordingly. The drift spec on the regulator ' (20mv/1000hrs typical) is better than the absolute accuracy spec ' 4.75->5.25V over temp or 4.85->5.15 @ 25 C). '1 A/D LSB 5.00/1024 or 4.883mv but we read the 10 bits shifted left 6 bits ' so our max count is FFC0 or 65472 and that corresponds to 5V-4.88mV. ' = 4.995V. 1 volt is then (1/4.995) * 65472 = 13107 hi_dig = adc_value /13107 'Find the integer number of volts 'Max count/Max volts = 65535/5 = 13107 adc_value = adc_value - (hi_dig*13107) 'Get the fractional value only adc_value = adc_value **4883 '** gets high word of 32 bit result 'multiplied by 4883 because we want to ' show millivolts and each bit has a ' value of 4.883 millivolts. ' NOTE: This way was shown as the most straightforward way for instructional purposes. ' In this program we are pausing 5 seconds after each loop anyway. ' If speed is an issue, you could do 4 compares to find out the hi_dig value. ' When you subtract (hi_dig*13107) you would know the 4 possible values without ' calculating them each time in the program. ' That way the divide and multiply can be eliminated. ' The last multiply can be turned into adds and shifts as well. DEC 4883 = HEX 1313 if (DEBUGGER = 1) THEN bug3 SEROUT 16, 17405, [", = ",DEC1 hi_dig, ".", DEC3 adc_value," Volts", CR,LF] SEROUT 16, 17405, [CR,LF] RETURN bug3: DEBUG ", = ",DEC1 hi_dig, ".", DEC3 adc_value," Volts", cr RETURN END