TAQOZ - ADC using Smart Pin - run in new cog

twm47099twm47099 Posts: 809
edited 2019-01-22 - 02:53:02 in Propeller 2
I had previously been able (with a lot of help) to use a Smart Pin as an ADC to read a voltage from a potentiometer. The program is at this link:
forums.parallax.com/discussion/comment/1461499/#Comment_1461499
I have tried to do the same with TAQOZ. My code is:
---  ------------------------------------------------------
---	**** adcsp.fth
---	UsePin 22 as smart pin in ADC mode
---  ------------------------------------------------------
---	Define Constants
--- ADC_MODE from spin2 program that worked

  %0000_0000_000_100011_0000000_00_01111_0 := ADC_MODE 
   22 := ADC_PIN 
   4096 := ADC_CYCLES

: adcsp  (  --   )
ADC_PIN  PIN  F 		' set pin dir = 0
ADC_MODE WRPIN 
ADC_CYCLES WXPIN 
0 WYPIN
L			' set pin dir = 1
cnt@ ADC_CYCLES + WAITCNT 	' wait ADC_CYCLES
RDPIN . CRLF @PIN . CRLF ;

It doesn't work. I get 0 for RDPIN regardless of the voltage setting.
I think that I don't have to put ADC_PIN on the stack for WRPIN, WXPIN, and WYPIN since I used the PIN word to select the pin to use as a smart pin. However, I have tried a version with ADC_PIN before each of those lines. That also didn't work. I'm also not sure if waitcnt is the best way to stall the program while the smart pin collects the bits.

Help will be greatly appreciated.
Tom

Comments

  • I found one error. I was getting the "???" error when the binary number was entered. I can't have underscores in the binary number.

    But now when I try to run the program I get a mess:
    TAQOZ# adcsp
    .SDSS16G 3665_3133 NO NAME    32k 15,189M
      0: PFTH103      $0000_4040   2016.11.24.17.36   .          .....   0
      1: Bh - c o. l  $1C00_3F80   1980.03.24.00.03   PFTH103    .....   4,294,901,760
      3: THINKI~1.PDF $0000_65C0   2014.02.24.21.27   %PDF-1.3.%.....2   4,499,830
      4: Bd o c  .    $FFC0_3F80   2107.15.24.31.63   PFTH103    .....   4,294,967,295
      6: ANDSOF~1.DOC $0000_6200   2014.01.24.14.37   ................   476,160
      7: B  I n f. o  $1D00_3F80   1980.03.24.00.03   PFTH103    .....   110
      9: SYSTEM~1     $0000_8840   2017.07.24.20.22   .          ..k..   0
     10: 3204GOOD.FTH $0000_8880   2019.01.24.19.21   --  ------------   1,341
     14: EXTEND  .FTH $0000_88C0   2019.01.24.19.21   TAQOZ..{..use th   3,069
     15: _BOOT_P2.BIX $0000_8900   2019.01.24.20.08   X...P2-ES   ....   131,072
    .SDSS16G 3665_3133 NO NAME    32k 15,189MÎÎ0ÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎÎ
    
    In this case (TAQOZ v 1.1) it just prints out the SD directory and a string of nonsense characters.

    Without the boot SD (TAQOZ v1.0) it shows the following which looks like an empty directory

    TAQOZ# adcsp
    ........ 0000_0000            0k 0M
     :|Z    . y  $0000_0000   2049.03.15.12.26   825,499,750
    
    ........ 0000_0000            0k 0M
     :|Z    . y  $0000_0000   2049.03.15.12.26   825,499,750
    2009
     ok
    TAQOZ#
    
    Note for these two prinouts I had changed the last line of ADCSP to:
    RDPIN . CRLF  ;
    
    The value RDPIN puts on the stack is 2009 (it doesn't change regardless of where the pot is set. However, it does change depending on the value of the constant ADC_CYCLES.
  • Peter JakackiPeter Jakacki Posts: 8,429
    edited 2019-01-20 - 08:37:54
    While the ' symbol is a comment in p2asm it is entirely different in TAQOZ. The ' symbol will compile the address of the following word after which it will still be compiling whatever you thought was part of a comment, but it isn't, such as "dir = 0" which is why it does a "DIR". Try using the \ or --- words for comments.

    BTW, the reason the binary number fails is simply because there are too many characters in the number that end up overflowing the word buffer but symbols are fine normally. The next version ROM increases this buffer size.
    TAQOZ# %1011_0011---1111 .l $0000_0B3F ok
    

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    P2 +++++ TAQOZ INTRO & LINKS +++++ P2 SHORTFORM DATASHEET
    P1 +++++ Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    Brisbane, Australia
  • Peter,
    Thanks for the help. I've got to make some cheat sheets for the different languages, so I stop making silly mistakes.
    Here's the code that works. It will continuously measure the voltage and print the raw value. Press the number 1 to stop.
    Next step will be to run it in a newcog. I think I need to use a variable to send the adc value between cogs. Is that correct?
    I want to try some of the other Smart Pin modes to add to this one and the ones in your Intro to TAQOZ document.

    Thanks again,
    Tom
    ---  ------------------------------------------------
    ---
    ---	**** adcsp.fth
    ---	Use Pin 22 as a Smart Pin in ADC mode
    ---  
    ---  ------------------------------------------------
    ---
    ---	Define Constants
    --- ADC_MODE from spin2 program 
    
      %00000000000100011000000000011110 := ADC_MODE 
       22 := ADC_PIN 
       16384 := ADC_CYCLES
    
    : adcsp  ( -- )
    ADC_PIN PIN F 	  \ set pin dir = 0
    ADC_MODE WRPIN 
    ADC_CYCLES WXPIN 
    0 WYPIN
    L 1 ms		  \ set pin dir = 1 to start and delay
    Begin		  \ measure continuously
     RDPIN CRLF . 
     100 ms
    KEY 1 and UNTIL	   \ press 1 to stop
    ;
    
  • twm47099twm47099 Posts: 809
    edited 2019-01-22 - 03:53:51
    Peter,
    I've been able to modify the above program to run in a new cog and print the data to the terminal in the original cog.
    The modifications are shown below.
    After both definitions adcsp and adcdata are loaded, I type:
    1 NEWCOG
    ' adcsp 1 TASK W!
    
    and then adcdata to run the program.

    I tried to put
    1 NEWCOG
    ' adcsp 1 TASK W!
    
    into the definition of adcdata, but that did not work. Is it possible to have to start a newcog and function in a definition and use a variable that can be accessed in any cog?
    ------------------------------------------------------
    ---	**** adcspnewcog.fth
    ---	UsePin 22 as smart pin in ADC mode
    --- 	adcsp runs in cog 1
    --- 	raw data is printed to terminal from cog 0
    ------------------------------------------------------
    ---	Define Constants
    --- ADC_MODE from spin2 program 
      %00000000000100011000000000011110 := ADC_MODE 
       22 := ADC_PIN 
       16384 := ADC_CYCLES
       2696 := CALMIN   13368 := CALMAX  3.30 := VREF 
    
       long vadcspraw         \ variable used to move data between cogs
    
    : adcsp  ( -- )
    ADC_PIN PIN F 	  \ set pin dir = 0
    ADC_MODE WRPIN  \ ADC_MODE
    ADC_CYCLES WXPIN 	\ ADC_CYCLES
    0 WYPIN
    L 1 ms		  \ set pin dir = 1 and delay
    Begin		  \ measure continuously
     RDPIN vadcspraw !
     10 ms
    AGAIN
    ;
    
    : adcdata
    BEGIN
      vadcspraw @ dup CRLF .
      CALMIN - VREF * 10 * CALMAX CALMIN - /
      CRLF .AS" #.### volts "
      100 ms
    KEY 1 and UNTIL	   \ press 1 to stop
    1 COGSTOP
    ;
    
    \ enter next 2 lines and then adcdata <ret>
     1 NEWCOG
    ' adcsp 1 TASK W! 
    \ --------------
    
    
  • I accidentally created VREF as 3.30, but the program works reporting the voltage as 3.3 volts with the pot at one extreme and 20 to 40 mV at the other -- both in agreement with a DVM reading.

    I recall reading in Starting Forth that putting a decimal in a number makes it a double precision number (or something like that), can you explain how this works in TAQOZ?
  • twm47099 wrote: »
    I accidentally created VREF as 3.30, but the program works reporting the voltage as 3.3 volts with the pot at one extreme and 20 to 40 mV at the other -- both in agreement with a DVM reading.

    I recall reading in Starting Forth that putting a decimal in a number makes it a double precision number (or something like that), can you explain how this works in TAQOZ?

    In some Forths they do this but TAQOZ just allows any symbol to be mixed in which also includes commas. Interestingly I was just thinking about which method I might use to enter double numbers but the decimal point is used as position indicator in 32-bit integers that can be read by software to determine scaling. The print routine automatically handles 64-bit numbers and using <D> before any print will cause it to grab the upper 32-bits to be handled internally after which this internal high word is reset to zero again.

    There are however very few double precision operators in TAQOZ, mainly the UM* and UM// and perhaps the */ that uses both of these operators but returns a 32-bit result. I just had a need for it when I wanted to calculate the counter value from the clock rate with:
    : NCOCNT ( hz -- cntval )	CLKHZ 4 << SWAP U/ 0 $10 ROT UM// DROP NIP ; 
    
    The double number is the 0 $10 where the $1.0000.0000 I suppose is scaled up by 4 bits for some extra precision. It would be nice to be able to enter this as a double number, especially for decimal numbers.

    Tachyon Forth - compact, fast, forthwright and interactive
    useforthlogo-s.png
    --->CLICK THE LOGO for more links<---
    P2 +++++ TAQOZ INTRO & LINKS +++++ P2 SHORTFORM DATASHEET
    P1 +++++ Latest binary V5.4 includes EASYFILE +++++ Tachyon Forth News Blog
    Brisbane, Australia
  • This modification uses 2 Smart Pins to measure and print the value of 2 voltage sources. I simply duplicated the original code and use the suffix 1 or 2 for the constant ADC_PIN and the global variable (vadcspraw).
    ---  
    
    ------------------------------------------------------
    ---	**** adcspnewcog2ch.fth
    ---     Read 2 voltage sources (2 channel ADC) 
    ---	Use Pins 22 & 23 as smart pins in ADC mode
    --- 	adcsp runs in cog 1
    --- 	raw data is printed to terminal from cog 0
    ------------------------------------------------------
    ---	Define Constants
    --- ADC_MODE from spin2 program 
    
      %00000000000100011000000000011110 := ADC_MODE 
       22 := ADC_PIN1
       23 := ADC_PIN2 
       16384 := ADC_CYCLES
       2696 := CALMIN   13368 := CALMAX  3.30 := VREF 
    
       long vadcspraw1
       long vadcspraw2
    
    : adcsp  ( -- )  \ this will be run in cog 1
    
    --- Setup Smart Pin P22 for Channel 1
    ADC_PIN1 PIN F 	  \ set pin dir = 0
    ADC_MODE WRPIN  \ ADC_MODE
    ADC_CYCLES WXPIN 	\ ADC_CYCLES
    0 WYPIN
    
    --- Setup Smart Pin P23 for Channel 2
    ADC_PIN2 PIN F 	  \ set pin dir = 0
    ADC_MODE WRPIN  \ ADC_MODE
    ADC_CYCLES WXPIN 	\ ADC_CYCLES
    0 WYPIN
    
    --- Start both channels
    ADC_PIN1 PIN L        \ set pin22 dir = 1
    ADC_PIN2 PIN L 1 ms   \ set pin23 dir = 1 and delay
    
    --- Read Smart Pins store result in global variables
    Begin		  \ measure continuously
     ADC_PIN1 PIN  RDPIN vadcspraw1 !
     ADC_PIN2 PIN  RDPIN vadcspraw2 !
     10 ms
    AGAIN
    ;
    
    : adcdata ( -- )   \ prints ADC data from adcsp
    BEGIN
      CRLF ." Ch #1 "
      vadcspraw1 @ dup  .
      CALMIN - VREF * 10 * CALMAX CALMIN - /
      CRLF .AS" #.### volts "
    
      CRLF ." Ch #2 "
      vadcspraw2 @ dup  .
      CALMIN - VREF * 10 * CALMAX CALMIN - /
      CRLF .AS" #.### volts " CRLF
      200 ms
    KEY 1 and UNTIL	   \ press 1 to stop
    1 COGSTOP
    ;
    
    \ enter next 2 lines and then adcdata <ret>
     1 NEWCOG
    ' adcsp 1 TASK W! 
    \ --------------
    
    
Sign In or Register to comment.