Shop OBEX P1 Docs P2 Docs Learn Events
Need help using an ADC0831 and the SHIFTIN line in pBasic — Parallax Forums

Need help using an ADC0831 and the SHIFTIN line in pBasic

LockDotsLockDots Posts: 4
edited 2012-12-13 12:14 in Accessories
Hello everyone,

I'm working on a project for school and part of it requires us to use a photo resistor to measure the amount of light in a room. I need to use the voltage read from the resistor to compare to a value from another photo resistor in a different room. The difference between the two will be used in an equation to control a servo. As most of us already know, the voltage read from the photoresistor is analog and therefore I need to convert it to a digital value seeing as how the Basic Stamp does not have a built-in ADC. We were instructed to use an ADC0831.

Can someone sum up how to use the SHIFTIN line in pBasic? I've seen the MSBPOST line/command used in conjunction with SHIFTIN here: http://www.parallax.com/dl/docs/prod/acc/SharpGP2D12Snrs.pdf and was wondering how exactly it's used.
' ========================================================================= '   File...... GP2D12 Demo.bs2 
'   Purpose... Demonstrate GP2D12 
'   Author.... Parallax, Inc. 
'   E-mail.... support@parallax.com 
'   {$STAMP BS2} 
'   {$PBASIC 2.5} 
' ========================================================================= 
' -----[ Program Description ]--------------------------------------------- 
' This program demonstrates reading the distance in centimeters from the 
' Sharp GP2D12 Analog Distance Sensor. 
' -----[ I/O Definitions ]------------------------------------------------- 
Adc0831         PIN     0               ' ADC0831 Chip Select (ADC0831.1) 
AdcClock        PIN     1               ' ADC0831 Clock (ADC0831.7) 
AdcData         PIN     2               ' ADC0831 Data (ADC0831.6) 
' -----[ Constants ]------------------------------------------------------- 
span            CON     5               ' 5 cm Per Data Point 
' -----[ Variables ]------------------------------------------------------- 
result          VAR     Byte            ' ADC8031 Result 
volts           VAR     Word            ' Volts (0.01 Increments) 
cm              VAR     Byte            ' centimeters 
index           VAR     Nib 
test1           VAR     Byte            ' Values For 
test2           VAR     Byte            ' Interpolation 
slope           VAR     Word            ' mV/cm between test points 
' -----[ EEPROM Data ]----------------------------------------------------- 
Vout            DATA    251, 179, 139, 114,  97 
                DATA     85,  76,  67,  62,  57 
                DATA     53,  50,  48,  46,  43 
                DATA      0 
' -----[ Initialization ]-------------------------------------------------- 
HIGH Adc0831                            ' Disable ADC0831
' -----[ Program Code ]---------------------------------------------------- 
  DO 
    GOSUB Read_GP2D12                   ' Read Sensor Value 
    GOSUB Calculate_Distance            ' Convert Value To cm 
    DEBUG HOME, "Distance = ", DEC cm, " cm " 
    PAUSE 100 
  LOOP 
  END 
' -----[ Subroutines ]----------------------------------------------------- 
Read_GP2D12: 
  volts = 0                             ' Reset Sensor Value 
  FOR index = 0 TO 2                    ' Read 3 Times 
    LOW Adc0831                         ' Enable ADC0831 
    SHIFTIN AdcData, AdcClock, MSBPOST, [result\9]  ' Read The Voltage 
    HIGH Adc0831                        ' Disable ADC0831 
    volts = volts + result              ' Add The Values 
    PAUSE 30 
  NEXT 
  volts = volts / 3                     ' Average The Readings 
  RETURN 
Calculate_Distance: 
  FOR index = 0 TO 15                   ' Search DATA Table For Value 
    READ (Vout + index), test2          ' Get Value From DATA Table 
    IF (test2 <= volts) THEN EXIT       ' Found Value 
  NEXT 
  SELECT index 
    CASE 0 
      cm = 10                           ' Set To Minimum Distance 
    CASE 1 TO 14                        ' Calculate Distance 
      cm = 10 + (5 * index) 
      IF (test2 < volts) THEN           ' Estimate Using Interpolation 
        READ (Vout + index - 1), test1 
        slope = (test1 - test2) * 10 / span  ' Calculate Slope 
        cm = cm - ((volts - test2) * 10 / slope) 
      ENDIF 
    CASE 15 
      cm = 80                           ' Set To Maximum Distance 
  ENDSELECT 
  RETURN



I THINK this is how it works, and PLEASE correct me where I'm wrong :)

SHIFTIN AdcData, AdcClock, MSBPOST, [result\9]
AdcData - designates which pin will be used for as the data input
AdcClock, designates which pin will used as the clock output to the ADC0831
MSBPOST - ?????
[result\9] - stores digital value to 'result' not too sure about '\9'

Please help, I'm starting to get desperate.

Thanks in advance!

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2012-12-12 18:40
    Read the description of the SHIFTIN (and SHIFTOUT) statements in the BASIC Stamp Syntax and Reference Manual which you can download here. This describes MSBPOST and the other options (LSBPOST, MSBPRE, and LSBPRE). These tell the Basic interpreter whether the bits come in MSB first or LSB first (Most Significant Bit or Least Significant Bit) and whether the clock pulse comes before or after the data needs to be sampled.

    The same writeup explains the '\9' and has to do with how many bits are produced by the ADC0831. You might look at the datasheet for the ADC0831 (do a web search). This has some nice pictures of the relationship between the clock pulses and the data and what is contained in the data bits.
  • LockDotsLockDots Posts: 4
    edited 2012-12-12 18:58
    Mike Green wrote: »
    Read the description of the SHIFTIN (and SHIFTOUT) statements in the BASIC Stamp Syntax and Reference Manual which you can download here. This describes MSBPOST and the other options (LSBPOST, MSBPRE, and LSBPRE). These tell the Basic interpreter whether the bits come in MSB first or LSB first (Most Significant Bit or Least Significant Bit) and whether the clock pulse comes before or after the data needs to be sampled.

    The same writeup explains the '\9' and has to do with how many bits are produced by the ADC0831. You might look at the datasheet for the ADC0831 (do a web search). This has some nice pictures of the relationship between the clock pulses and the data and what is contained in the data bits.

    First and foremost I would like to thank you for your quick and detailed response. Next, I would like to apologize for my confusion. Looking up SHIFTIN in the Syntax manual explained everything pretty clearly. It's amazing how much things make sense when you click on the right thing you want to learn.......I accidentally clicked something other than SHIFTIN and in my confusion and desperation I didn't realize and just became even more confused :D I was trying to understand SERIN instead of SHIFTIN.......aye aye aye.

    Thanks a bunch Mr. Green!
  • LockDotsLockDots Posts: 4
    edited 2012-12-12 19:39
    Quick question, can the Basic Stamp handle arithmetic with a combination of binary and integers?

    For examples let's say I have two variables both with binary number 1010 stored to them from my SHIFTIN command (I believe if I were to type it in it would have to be %1010). If I wanted to add them and then take 60% of them could I write the following?

    (var1+var2)*(3/5)
  • Mike GreenMike Green Posts: 23,101
    edited 2012-12-12 21:51
    There is no difference (between binary and integers). All numbers (and characters) in the Basic Stamp are treated as 16-bit 2's complement signed numbers. It doesn't matter where the numbers come from ... whether from some I/O device (like an ADC0831) or from the debug window on the PC (via a DEBUGIN statement) or from an RFID reader (via a SERIN statement) or compiled into the program (as a constant). What does matter is how you tell the Basic interpreter to read the value in. You have to tell the SHIFTIN statement how many bits there are so it knows how many clocks to produce. You have to use "formatters" like DEC or HEX or BIN to tell DEBUGIN or SERIN how to interpret input characters to get a number, whether in decimal, hexadecimal, or binary. If you don't use a formatter, then you're getting the code for the character as a number. Things go the opposite way on output ... from number to some external representation.

    So, yes, you can take the number received from the ADC0831 and do any kind of arithmetic on it. Do remember that there are no decimal fractions, so (var1+var2)*(3/5) won't produce what you might want. You'll get more like what you want if you write ((var1+var2)*3)/5.
  • LockDotsLockDots Posts: 4
    edited 2012-12-13 12:14
    Awesome, thanks again!
Sign In or Register to comment.