ERROR 21...SUBS and FUNCTIONS cannot be nested...(in PROPBASIC)

dennodenno Posts: 103
edited October 11 in Propeller 1 Vote Up0Vote Down
It does not seem to matter what I do, in the "arrangement of SUB, GOSUB, no SUB at all, I cannot get more then one SUB in a COG. Meaning, I can call a single SUB with the same name, any number of times in a single COG, but if i put another SUB in that same COG, with a different name, I always get the above error message. Yes, I am listing the SUB right after the VARIABLE list like so "getADCdata SUB", but before the DO/LOOP. That SUB does get used 3 times in the DO/LOOP, with three RETURN(s).

Is the problem due to a different SUB, with a different name, being called inside the same above DO/LOOP as the above SUB? "getADCdata SUB"

DennO

Comments

  • 22 Comments sorted by Date Added Votes
  • pmrobertpmrobert Posts: 480
    edited October 11 Vote Up0Vote Down
    Disregard
  • BeanBean Posts: 7,952
    edited October 11 Vote Up0Vote Down
    DennO,
    Please post your code. If you can minimize it as much as you can.

    P.S. I am confused when you talk about putting SUBs in COGs ?
    Do you mean putting SUBs in TASKs ? A "TASK" is not a COG...
    A COG is a processor capable of running a TASK.

    The main code is a TASK (implied), that is run in COG0 at startup.
    A COG can run different TASKs at different times.

    Bean
  • dennodenno Posts: 103
    edited October 11 Vote Up0Vote Down
    Well, I guess I am doing it all wrong. In the code posted, I thought, if I "COGINIT XXXXXXX, 1" ,that would start COG 1 and then I would name a TASK with the same name "TASK XXXXXXX" for COG 1 to run that program. So, in my posted code, (sorry it is a little long), am I running all those TASK(s) in 8 different COG(s) or is all of running in only one COG? I really try to write my code so it is readable...for you..
    TASK voltMeasure is where I have the only SUB routine running...to get data from the MCP3204...by using 3 different single ended channels for 2 different voltages, and 1 temperature measurement using an LM34.
    DennO
    DEVICE P8X32A, XTAL1, PLL16X
    XIN 5_000_000
    '========CONSTANTS============
    baud                   CON "N9600"
    baud2                  CON "T115200" 
    carr_return            CON  13   
    clrLCD                 CON  12          'clear the screen on the lcd
    posCMD                 CON  16          'position the curser command
    hideCUR                CON   4           'hide the curser command
    blinkCUR               CON   6           'blink the curser command
    degreeSYM              CON 223           'the "degree" symbol
    receive_data           CON 255
    backLTon               CON  14          'turn the back light on
    backLToff              CON  15          'turn the back light off
    brightness_ctl         CON  27
    quarter_bright         CON  48
    half_bright            CON  49
    three_quarter_bright   CON  50
    full_bright            CON  51
    beep                   CON   7           'beep command
    right_align            CON  18          'RIGHT ALIGN COMMAND
    start_big_char         CON   2
    end_big_char           CON   3
    astrike                CON  42
    block_char             CON 134
    carReturn              CON  13          'carriage return command
    blank_char             CON  32
    left_arrow             CON 127
    right_arrow            CON 126
    LR_arrow               CON 131
    LL_arrow               CON 128
    UR_arrow               CON 129
    UL_arrow               CON 130
    down_arrow             CON 132
    up_arrow               CON 133
    equal_sign             CON  61
    first_line             CON  64
    second_line            CON 104 
    no_char                CON 0    
    trigger                CON 50'''''20 
    Scale                  CON 205'''''$00CD  ''205=CD in HEX
    inch_conv              CON 889  '*conversion factor, uSec TO inches  (1/74.746) * 65536 using **.
    '======== HUB VARIABLES==============
    longDistance             HUB  LONG 'location of long distance address
    longDistance_tenth       HUB  LONG 'location of long distance tenth/of a foot address 
    compassDegrees           HUB  LONG  'location of LM34 data
    volt_location            HUB  LONG  'location of volt data
    tenth_location           HUB  LONG  
    hunds_location           HUB  LONG
    temp_location            HUB  LONG
    volt_location_12v        HUB  LONG  'location of volt data
    tenth_location_12v       HUB  LONG
    hunds_location_12v       HUB  LONG
    temp_LocationTenths      HUB  LONG
    temp_Location_10         HUB  LONG
    temp_Location_100        HUB  LONG
    distanceLocation         HUB  LONG
    MCPValueLocation         HUB  LONG
    '============= VARIABLES =======================
    
    '========[PIN ASSIGNMENTS]========
    'Assignments of pin go in each COG that is using that pin..
    '========[TASK ASSIGNMENTS]===============
      LCD_1                TASK   
      longDistSensor       TASK
      compass              TASK
      volt_measure         TASK
      LED_blink            TASK
      blinkAnotherLED      TASK
      sonicDistance        TASK
    
    PROGRAM Start      'this is running in COG 0
      Start:
    '========PIN ASSIGNMENTS========
      LED_blue               PIN 16    
    '===============================
      COGINIT sonicDistance, 1        'cog 1
      COGINIT blinkAnotherLED, 2      'cog 2
      COGINIT LED_blink, 3     'cog 3
      COGINIT volt_measure, 4  'cog 4
      COGINIT longDistSensor, 5 'cog 5
      COGINIT compass      , 6 'cog 6
      COGINIT LCD_1, 7         'cog 7
      DO                             
        PAUSE 500
        TOGGLE LED_blue
        PAUSE 500
      LOOP
    END
    '===============================================
    
    
    TASK sonicDistance   'RUNNING IN COG 1
    '========[PIN ASSIGNMENTS]=====================
      PingPin   PIN 14 LOW     ' Connected to Sig pin on Ping module
    '========[VARIABLES]===========================
    inDistance     VAR LONG
    valueStr3 HUB   string(4)
      DO
        PAUSE 100
        PULSOUT PingPin, 5 ' Trigger PING
        PAUSEUS 5
        PULSIN PingPin, 1, inDistance ' Measure PING pulse
        inDistance = inDistance / 2  'divide by 2 for one way
        inDistance = inDistance * 100 'multiply by 100 for interger math
        inDistance = inDistance / 7374 'divide by 73.74 uSec/1 inch...7374
        WRLONG distanceLocation, inDistance
    '   valueSTR3 = STR inDistance,4,5
    '   SEROUT 30, baud2, valueSTR3
    '   SEROUT 30, baud2, 10
      LOOP
    ENDTASK sonicDistance
    '============================================
      
    
    TASK longDistSensor         'this TASK is running in COG 5...a simple math problem   
    '========[PIN ASSIGNMENTS]=====================
      triggerPin   PIN  10 OUTPUT
      sensorPin    PIN  11 INPUT
    '========[VARIABLES]===========================
      target           VAR  LONG
      target_dist      VAR  LONG
      target_tenth     VAR  LONG
      valueTargetDist  HUB   string(7)
      'valueTargetDistTenth  HUB  string(1)
      DO
        sensorPin  =  0
        PULSOUT triggerPin, Trigger                  '* activate sensor by pulsing HIGH
        PAUSEUS 5
        RCTIME sensorPin, 1, target_dist             '* measure echo pulse..
        target_dist = target_dist / 2
        target_dist = target_dist * 100  'multiply by 100 for interger math
        target_dist = target_dist / 7374 'divide by 73.74 uSec/1 inch...7374...inches to target
        WRLONG longDistance, target_dist
        PAUSE 50
      LOOP
    ENDTASK longDistSensor
    '================================================================
    
    
    TASK compass         'this TASK is running in COG 6   
    '========[PIN ASSIGNMENTS]==========
      CMPS10_PWM           PIN     24
    '========[VARIABLES]===========================
    rawHeading1            VAR       LONG
    rawHeading2            VAR       LONG
    rawHeading3            VAR       LONG
    rawHeadingAve          VAR       LONG
    valueSTR4              HUB       string(4)
    valueSTR               HUB       string(4)
      DO
        PULSIN CMPS10_PWM, 1, rawHeading1
        rawHeading1 = rawHeading1 - 1200
        rawHeading1 = rawHeading1 / 100  ''whole degree
        rawHeading1 = ABS rawHeading1
        PAUSE 50
        PULSIN CMPS10_PWM, 1, rawHeading2
        rawHeading2 = rawHeading2 - 1200
        rawHeading2 = rawHeading2 / 100  ''whole degree
        rawHeading2 = ABS rawHeading2
        PAUSE 50
        PULSIN CMPS10_PWM, 1, rawHeading3
        rawHeading3 = rawHeading3 - 1200
        rawHeading3 = rawHeading3 / 100  ''whole degree
        rawHeading3 = ABS rawHeading3
        PAUSE 50
        rawHeadingAve = rawHeading1 + rawHeading2 
        rawHeadingAve = rawHeadingAve + rawHeading3
        rawHeadingAve = rawHeadingAve / 3
        PAUSE 50
        WRLONG compassDegrees, rawHeadingAve
        valueSTR = STR rawHeadingAve,4, 5
    '    SEROUT 30, baud2, 10
    '    SEROUT 30, baud2, valueSTR
        PAUSE 50
      LOOP
    ENDTASK compass
    
    
    '==================================================
    TASK LCD_1  LMM        'this TASK is running in COG 7   
    '========[PIN ASSIGNMENTS]========
      LCD_data_out             PIN   2   
    '========[VARIABLES]===========================
      VOLT          VAR  LONG
      VOLTtenth     VAR  LONG
      VOLThunds     VAR  LONG
      VOLT_12v      VAR  LONG
      VOLTtenth_12v VAR  LONG
      VOLThunds_12v VAR  LONG
      MCPValue      VAR  LONG
      TEMP_100      VAR  LONG
      TEMP_10       VAR  LONG
      TEMP_tenths   VAR  LONG
      valueSTRtenth  HUB  string(4)
      inDistance     VAR  LONG
      rawHeadingAve  VAR  LONG
      target_dist    VAR  LONG
      target_tenth   VAR  LONG
    '=======================================================================
    'the following DATA statments are to preload the display, the variables are loaded elsewhere in the program.
      LCD_data_0  DATA  clrLCD,beep,backLTon
      PAUSE 100
      LCD_data_1  DATA  posCMD,64,"LDis=",posCMD,74,"TEMP=",0  'LCD...line 1
      LCD_data_2  DATA  posCMD,84,"COMPASS=",posCMD,95,degreeSYM,posCMD,100,"IN'S",0 'LCD...line 2 
      LCD_data_3  DATA  posCMD,104,"VOLTAGE=",posCMD,115,".",posCMD,119,"volts",0
      LCD_data_4  DATA  posCMD,124,"VOLTAGE=",posCMD,135,".",posCMD,139,"volts",0
    
      SEROUT LCD_data_out, baud, LCD_data_0  'clear the screen, beeb, and turn on the back light
      SEROUT LCD_data_out, baud, LCD_data_1  'to print line 1
      SEROUT LCD_data_out, baud, LCD_data_2  'to print line 2
      SEROUT LCD_data_out, baud, LCD_data_3  'to print line 3 
      SEROUT LCD_data_out, baud, LCD_data_4  'to print line 4 
     DO  
    ' A LONG DIATANCE MEASUREMENT
         RDLONG longDistance, target_dist  'reading the temperature data that is in the HUB
         PAUSE 50
         RDLONG longDistance_tenth, target_tenth  
         PAUSE 50
        LCD_data_1a  DATA  posCMD,69,"   ",0
        LCD_data_1a(2) = STR target_dist,3,5
        SEROUT LCD_data_out, baud, LCD_data_1a
    
    ' A COMPASSS ANGLE MEASUREMENT and DISTANCE MEASUREMENT
         RDLONG compassDegrees, rawHeadingAve
         PAUSE 50  'reading the temperature data that is in the HUB
         RDLONG distanceLocation, inDistance
         PAUSE 50
         LCD_data_2a  DATA posCMD,92,"   ",posCMD,96,"   ",0
         LCD_data_2a(2) = STR rawHeadingAve,3,5
         LCD_data_2a(7) = STR inDistance,3,5
         SEROUT LCD_data_out, baud, LCD_data_2a
    ' THIS IS A READING FROM A VARAIBLE 5 VOLT
         RDLONG volt_location, VOLT        'reading the voltage data that is in the HUB
         PAUSE 50'100
         RDLONG tenth_location, VOLTtenth  'reading the voltage data that is in the HUB
         PAUSE 50'100
         RDLONG hunds_location, VOLThunds  'reading the voltage data that is in the HUB
         PAUSE 50'100
    ' THIS IS A READING FROM A LM34
         RDLONG temp_location_100, TEMP_100
         PAUSE 50'100
         RDLONG temp_locationTenths, TEMP_tenths     
         PAUSE 50'100
         LCD_data_1aa  DATA posCMD,79,"  ",posCMD,81,".",posCMD,82," ",posCMD,83,degreeSYM,0
         LCD_data_1aa(2) = STR TEMP_100,2,5
         LCD_data_1aa(9) = STR TEMP_tenths,1,5
         SEROUT LCD_data_out, baud, LCD_data_1aa 
         LCD_data_3a  DATA posCMD,114," ",posCMD,116," ",posCMD,117," ",0
         LCD_data_3a(2) = STR VOLT,1,5
         LCD_data_3a(5) = STR VOLTtenth,1,5
         LCD_data_3a(8) = STR VOLThunds,1,5
         SEROUT LCD_data_out, baud, LCD_data_3a
    ' THIS IS A VOLTAGE MEASUREMENT OF INCOMING SUPPLY VOLTAGE
         RDLONG volt_location_12v, VOLT_12v
         PAUSE 50'100
         RDLONG tenth_location_12v, VOLTtenth_12v
         PAUSE 50'100
         RDLONG hunds_location_12v, VOLThunds_12v
         PAUSE 50'100
         RDLONG MCPValueLocation, MCPValue
         PAUSE 50
         IF MCPValue < 9426 THEN '9828/819 = 12.00 volts...beep warning
           SEROUT LCD_data_out, baud, beep
           PAUSE 100
         ENDIF 
         LCD_data_4a  DATA posCMD,133,"  ",posCMD,136," ",posCMD,137," ",0
         LCD_data_4a(2) = STR VOLT_12v,2,5
         LCD_data_4a(6) = STR VOLTtenth_12v,1,5
         LCD_data_4a(9) = STR VOLThunds_12v,1,5
         SEROUT LCD_data_out, baud, LCD_data_4a
     LOOP 
    
    ENDTASK LCD_1
    '================================================================
    
    TASK volt_measure       'this TASK is running in COG 4
    '========[PIN ASSIGNMENTS]==========
    ADC_Clk                PIN  21 LOW     ' MCP3204.11
    ADC_Dout               PIN  20 LOW     ' MCP3204.10
    ADC_Din                PIN  19 LOW     ' MCP3204.9
    ADC_CS                 PIN  18 HIGH    ' MCP3204.8
    '========[VARIABLES]===========================
    'valueSTR               HUB    string (4)'''VAR    LONG
    MCPValue               VAR    LONG
    VOLT                   VAR    LONG
    VOLTtenthx10           VAR    LONG
    VOLTtenth              VAR    LONG
    VOLThunds              VAR    LONG
    
    VOLT_12v                VAR    LONG
    VOLTtenth_12v           VAR    LONG
    VOLTtenth_12vx10        VAR    LONG
    VOLThunds_12v           VAR    LONG
    voltChannel             VAR    LONG
    
    TEMP_100               VAR    LONG
    TEMPtenths             VAR    LONG  
    TEMPtenthsx10          VAR    LONG
    TEMP_100x100           VAR    LONG
    TEMPremainder          VAR    LONG
    
    getADCdata             SUB
    
     DO
       voltChannel = %11000'voltChannel is used to select the proper channel for the MCP3204 ADC in the SUB ROUTINE..CH0
       GOSUB getADCdata   'this MCPValue is for the variable voltage...0 to 5 volts
       VOLT = MCPValue / 819       '=4                     actual 4 volts
       VOLTtenth = MCPValue//819
       VOLTtenthx10 = VOLTtenth * 10
       VOLTtenth = VOLTtenthx10 / 819
       VOLThunds = VOLTtenthx10 // 819
       VOLThunds = VOLThunds * 10
       VOLThunds = VOLThunds / 819
       WRLONG volt_location, VOLT
       PAUSE 50
       WRLONG tenth_location, VOLTtenth
       PAUSE 50
       WRLONG hunds_location, VOLThunds
       PAUSE 50
    
       voltChannel = %11001  ''CH1  tomeasure input voltage 12 VOLT measure
       GOSUB getADCdata
       MCPValue = MCPValue * 3   'voltage divider...3 10K resistors in series.
       WRLONG MCPValueLocation, MCPValue
       VOLT_12v = MCPValue/819      
       VOLTtenth_12v = MCPValue//819 
       VOLTtenth_12vx10 = VOLTtenth_12v * 10
       VOLTtenth_12v = VOLTtenth_12vx10 / 819
       VOLThunds_12v = VOLTtenth_12vx10 // 819
       VOLThunds_12v = VOLThunds_12v * 10
       VOLThunds_12v = VOLThunds_12v / 819
       WRLONG volt_location_12v, VOLT_12v
       PAUSE 50
       WRLONG tenth_location_12v, VOLTtenth_12v
       PAUSE 50
       WRLONG hunds_location_12v, VOLThunds_12v
       PAUSE 50
    
       voltChannel = %11010  ''CH2  to measure the actual temperature with an LM34 sensor
       GOSUB getADCdata
       TEMP_100 = MCPValue * 100
       TEMP_100x100 = TEMP_100   
       TEMP_100 = TEMP_100x100 / 819'whole degrees..units and tens
       TEMPremainder = TEMP_100x100 // 819
       TEMPtenths = TEMPremainder * 10
       TEMPtenths = TEMPtenths / 819
       WRLONG temp_location_100, TEMP_100
       PAUSE 50
       WRLONG temp_locationTenths, TEMPtenths
       PAUSE 50
     LOOP
    
     SUB getADCdata
       LOW ADC_CS ' Enable MCP3204
       PAUSE 100'''''''''PAUSEUS 100
       SHIFTOUT ADC_Din, ADC_Clk, MSBFIRST, voltChannel\5 ' Select CH0, Single-Ended
       SHIFTIN ADC_Dout, ADC_Clk, MSBPOST, MCPValue\13 ' Read ADC
       HIGH ADC_CS ' Disable ADC
       LOW ADC_Clk
     RETURN 
    
    ENDTASK volt_measure
    
    '====================================================
    
    
    TASK LED_blink    'this task is running in cog 3
       LED_white    PIN 17
        DO                             
          PAUSE 100
          TOGGLE LED_white
          PAUSE 100
        LOOP
    ENDTASK LED_blink 
    '========================================================
    
    
    TASK blinkAnotherLED  'RUNNING IN COG 2
        LED_blue_2  PIN 15
        DO
          PAUSE 50
          TOGGLE LED_blue_2
          PAUSE 50
        LOOP  
    ENDTASK blinkAnotherLED   
    
    '======================================================
    
    
    
  • Your code compiled fine for me ???

    The only thing I see wrong is you do NOT put the task name after ENDTASK. But I don't think that causes an error, but it might confuse the compiler.

    Bean
  • The SUB getADCdata definition is missing ENDSUB.
  • jones wrote: »
    The SUB getADCdata definition is missing ENDSUB.

    Ah, good catch. I didn't see that...

    Bean
  • Denno, try adding ENDSUB at the end of the getADCdata subroutine, then add another subroutine (also with ENDSUB).

    If you have more than one SUB without the ENDSUB, I suspect the compiler interprets that as defining a subroutine within a subroutine.

    Bob
  • dennodenno Posts: 103
    edited October 11 Vote Up0Vote Down
    Wow...thank you everyone. I will try the ENDSUB. However, I thought that RETURN was required at the end of a SUB routine. As shown in the "Rules of PROPBASIC 1.48": How does the SUB that is called, know where to return too, with out the RETURN. And in the definition of RETURN, below, what is the "value" argument? Guess I am still thinking along the lines of PBASIC..
    RETURN
    Return from a subroutine or function.
    RETURN value{,value{,value{,value}}}
    

    Bean, the code in the above thread does compile and run with no errors. The problem I was having was using another SUB routine in the same task and then getting ERROR 21. I will try as jones suggested. Also, Bean, I believe I do have the task name after each (7 of them) ENDTASK(s). I double checked....anyways...thanks again...DennO

    Addendum: jones...I just installed a practice SUB in the same TASK as the first SUB and declared it, and the program compiled. So, that was my problem...I was using RETURN, as in PBASIC with the Stamp...thanks again to all....
  • RETURN causes the return to the caller, but there could be more code after the RETURN in a subroutine.
    So ENDSUB tells the compiler that is the end of the SUBROUTINE.

    For example you might do:
    SUB Test
    
    DO
      RDLONG hubVar, A
      IF A = 1 THEN
        RETURN
      ENDIF
    LOOP
    
    ENDSUB
    

    Bean
  • @Bean

    Wasn't GOSUB obsoleted ? I seem to remember this was stated in the doc's.
    PropBASIC ROCKS!
  • Thank you Bean for explaining RETURN, makes perfect sense. As far as the GOSUB, as Mickster mentioned, personally, I like to use the word GOSUB, because I use it with caps, and it shows up in BOLD letters, which helps me find the call to the subroutine, in a large program, otherwise, it is just small letters, like most of the variables and constants...so I am guessing that GOSUB has not been obsoleted?

    On another note, does anyone know why my Windows 7, will not stop downloading the same ZIP file. It goes crazy, and i have to back out of Chrome, or reboot by holding the off button down for 5 seconds. Then I have to open my download files, and delete 20 of the same ZIP file. It will not stop after one... Just thought I would ask, as some of the PROPBASIC examples are in ZIP format...

    DennO...also the dog's name is Lincoln...
  • Maybe it was ON GOSUB?
    PropBASIC ROCKS!
  • If you use GOSUB I don't think you can use parameters.
    I'd have to check the source code to be sure...

    Bean
  • kwinnkwinn Posts: 7,979
    edited October 12 Vote Up0Vote Down
    denno wrote: »
    .........On another note, does anyone know why my Windows 7, will not stop downloading the same ZIP file. It goes crazy, and i have to back out of Chrome, or reboot by holding the off button down for 5 seconds. Then I have to open my download files, and delete 20 of the same ZIP file. It will not stop after one... Just thought I would ask, as some of the PROPBASIC examples are in ZIP format...

    It's Microsoft Windows. Who knows why it does anything? I switched to Linux Mint a while ago and have not regretted it in spite of having to hunt for Linux versions of several apps. IMPNSHO it's past time to abandon Windows and switch to open source software.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • dennodenno Posts: 103
    edited October 13 Vote Up0Vote Down
    Thanks kwinn, for your input. But, right now, I am trying to teach myself PROPBASIC, and my feeble brain can only handle one problem at a time...LOL

    Bean, is there anyway to preform integer math with PROPBASIC, with more then one operator on one line...please see attached code to obtain tens, units, tenths, and hundreds of a volt...
       voltChannel = %11001  ''CH1  tomeasure input voltage 12 VOLT measure
       GOSUB getADCdata
       MCPValue = MCPValue * 3   'voltage divider...3 10K resistors in series to keep voltage below 5 volts max for the MCP3204 or MCP3208.
       WRLONG MCPValueLocation, MCPValue
       VOLT_12v = MCPValue/819      
       VOLTtenth_12v = MCPValue//819 
       VOLTtenth_12vx10 = VOLTtenth_12v * 10
       VOLTtenth_12v = VOLTtenth_12vx10 / 819
       VOLThunds_12v = VOLTtenth_12vx10 // 819
       VOLThunds_12v = VOLThunds_12v * 10
       VOLThunds_12v = VOLThunds_12v / 819
       WRLONG volt_location_12v, VOLT_12v
       PAUSE 50
       WRLONG tenth_location_12v, VOLTtenth_12v
       PAUSE 50
       WRLONG hunds_location_12v, VOLThunds_12v
       PAUSE 50
    

    Thanks..DennO
  • BeanBean Posts: 7,952
    edited October 13 Vote Up0Vote Down
    If I follow right, it looks like the ADC value is 819 per volt.

    So just do this:
      ' Convert 819 per volt to 100 per volt
      MCPvalue = MCPvalue */ 8003 ' same as *100 /819
    
      volts10 = MCPvalue / 1000
      volts = __remainder / 100
      tenths = __remainder / 10
      hunds = __remainder
    
    

    Bean
  • dennodenno Posts: 103
    edited October 13 Vote Up1Vote Down
    Bean, again thank you. So, "__remainder" is the same as" //" in a round about way...what you have showed me does use less code. I did read or see the "__remainder" operator mentioned in the 1.48, but not as a binary operator. I did not know what it was used for in PROPBASIC. I always used "//" in PBASIC.

    I will rewrite my code and remember your instructions..and I did, so, 4 lines of code (your help) replaced 7 lines, to do the same thing. Very good....what can I say....other then I am looking for 1.49...LOL

    DennO
  • OK, Bean or anyone, Bean, with your last help on on the post before the last one....
      ' Convert 819 per volt to 100 per volt
      MCPvalue = MCPvalue */ 8003 ' same as *100 /819
    
      volts10 = MCPvalue / 1000
      volts = __remainder / 100
      tenths = __remainder / 10
      hunds = __remainder
    
    
    which does work, and save alot of code space, which I mentioned in my previous post.

    Now, I am using an LM34 temperature sensor, operating on 5 volts supply. I am using the following code to get the temperature reading on the LCD to whole degrees and tenth of a degree. Which does work. Later on, I send it to the LCD using DATA statments.
       GOSUB getADCdata
    
       TEMP_100 = MCPValue * 100
       TEMP_100x100 = TEMP_100   
       TEMP_100 = TEMP_100x100 / 819'whole degrees..units and tens
       TEMPremainder = TEMP_100x100 // 819
       TEMPtenths = TEMPremainder * 10
       TEMPtenths = TEMPtenths / 819
    

    However in trying to get "your"version to work, I cannot seem to duplicate it. I have tried several different ways, with no luck. You converted the 819 ADC units to 100 ADC units per volt. Which gave me the */8003 to use with the MCPvalue. In trying to do the same with 5 volts, I am not having much success. (Need a call to the expert)...the resolution of the MCP3204 is 12 bit for 5 volts. This give us the 891/volt. Would appreciate your thoughts....

    The LM34 outputs 10mvolt/degreeF...I did try to convert to 5 volts by dividing 5 by 819, which gives me a value of .0061. That value * 65536 gives 388 to use with the */MCPvalue. Still no joy...what am I missing? Hope I am making sense to you or the other readers...

    Again thanks....DennO
  • kwinnkwinn Posts: 7,979
    edited October 16 Vote Up0Vote Down
    @DennO

    Temperature calculation with a 12 bit adc and 5V reference would be ADCreading x 500 / 4095.

    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • dennodenno Posts: 103
    edited October 16 Vote Up0Vote Down
    Yes, kwinn, you are right, meaning that 500/4095 = 819 ADCunits/volt. And, yes the LM34 is running on 5 volts, and it will run on 12 volts as well. But the out put is in millivolts....10 millivolts/degree F. My problem, as I finally discovered, I was not converting low enough. What i had to do, (and I had two ways to do it, but the second way uses one less line of code), was divide 1000mVolts by 819 to get millivolts per ADCunit, which is 1.22. Thus, 1.22 * 65536 = 80019 for use with the */, as shown..this gives me whole degrees, and tenths...which I then send to a specific location on the display..
       GOSUB getADCdata  'this SUB gust gets the ADCunits, or as I call them MCPvalue..
      MCPvalue = MCPvalue */ 80019''''''3 ' same as *1000mv /819 = 1.22 * 65536 using the */ binary operator = 80019
      TEMP_100 = MCPvalue / 10''''''''0
      TEMPtenths = __remainder * 10
      TEMPtenths = TEMPtenths / 10
    

    I owe this trick to Bean...
    DennO

  • Yep, yours is the simple way to do that in basic. For Spin I do the calculations using integer math so if I wanted tenths of a degree I would multiply the reading by 122, add 5 to the result for rounding, convert it to ascii, drop the last digit and insert the decimal in front of the lsd. Sounds like a lot of code but takes way less memory and is much faster than using floating point.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • kwinn...I have been doing integer math for almost 20 years with the Basic Stamp. I don't think I know how to do floating point math anymore....LOL. Thank you for your help and input...
    DennO
Sign In or Register to comment.