Sugestions with code


Closed Thread
Results 1 to 8 of 8
  1. #1

    Default Sugestions with code

    Hi all,

    I've finished my experiment circuit to learn how to handle with ADC,capture, processing it and send out it's readings.

    The circuit , using a 16F88 and a LM35 temp sensor reads temp. and voltage and sends the values to a LCD.

    I used 10bit resolution, removed last digit from result and added a constant value to calibrate the temperature ( because i get a difference of +- 4ºC ).

    For the voltage, since i'm reading from 13V, i used 3 resistor as voltage divider. Then again i added a constant value to calibrate the result.

    The code is working and reason for this Thread is only to get feedback from you experient users about the code.

    Please let me know you thoughts and tips if this can be improved

    Thanks

    Here is the code :


    Codestart:

    output portb.7

    low portb.7

    Define osc 4

    ' Define LCD pins
    Define LCD_DREG PORTB
    Define LCD_DBIT 0
    Define LCD_RSREG PORTB
    Define LCD_RSBIT 4
    Define LCD_EREG PORTB
    Define LCD_EBIT 5
    Define LCD_BITS 4

    'variables
    va1 var word
    va2 var word
    a var byte
    b var byte
    c var byte
    d var byte
    e var byte
    f var byte
    g var byte

    pause 200 'init LCD
    lcdout $fe,1 'clear LCD

    lcdout $fe,2," Voltage/Temp" 'lcd intro
    pause 2500

    lcdout $fe,1 'clear LCD

    'Define ADCIN parameters
    Define ADC_BITS 10 ' Set number of bits in result ( 8 or 10 bits )
    Define ADC_CLOCK 3 ' Set clock source (3=rc)
    Define ADC_SAMPLEUS 50 ' Set sampling time in uS


    input porta.0
    input porta.1

    ADCON1 = %00000001 ' Set PORTA analog

    loop:

    ADCIN 0, va1 'Store ADC value to va1
    va1=va1/10 'remove last digit
    ADCIN 1, va2 'Store ADC value to va2
    va2=va2/10 'divide by 10 to get xx,xºc
    va2=va2 - 42 'calibration setting
    va1=va1/10 'remove last digit
    va1=va1*2 'multiply to compensate voltage divider
    va1=va1+0179 'calibration setting


    a=va2 dig 0 ' separate digits
    b=va2 dig 1 ' separate digits
    c=va2 dig 2 ' separate digits

    d=va1 dig 0 ' separate digits
    e=va1 dig 1 ' separate digits
    f=va1 dig 2 ' separate digits
    g=va1 dig 3 ' separate digits

    high portb.7 'Led on indicating code running

    lcdout $fe,2,"VOLTAGE..",#g,#f,",",#e,#d,"V" 'Show values Line 1 - Voltage
    lcdout $fe,$c0,"TEMP.....",#c,#b,",",#a,"C" 'Show values Line 2 - Temperature
    pause 250 'pause between readings

    Goto loop

    End

  2. #2
    Join Date
    Jan 2006
    Location
    Istanbul
    Posts
    1,185


    Did you find this post helpful? Yes | No

    Default

    Suggestion1:

    Remove all these:
    a=va2 dig 0 ' separate digits
    b=va2 dig 1 ' separate digits
    c=va2 dig 2 ' separate digits

    d=va1 dig 0 ' separate digits
    e=va1 dig 1 ' separate digits
    f=va1 dig 2 ' separate digits
    g=va1 dig 3 ' separate digits

    and use this instead:

    lcdout $fe,2,"VOLTAGE..",dec va1 dig 3 ,dec va1 dig 2,",",dec va1 dig 1,dec va1 dig 0,"V" 'Show values Line 1 - Voltage
    lcdout $fe,$c0,"TEMP.....",dec va2 dig 2,dec va2 dig 1,",",dec va2 dig 0 ,"C" 'Show values Line 2 - Temperature
    pause 250 'pause between readings


    Good?
    Bad?
    "If the Earth were a single state, Istanbul would be its capital." Napoleon Bonaparte

  3. #3


    Did you find this post helpful? Yes | No

    Default

    sayzer ,

    good one

    Anything else ?

  4. #4
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    You might want to take a look at this thread also.

    http://picbasic.co.uk/forum/showthread.php?t=4289

  5. #5


    Did you find this post helpful? Yes | No

    Default

    jblackann ,

    thanks for the link.

    But i'm getting a hard time understanding the logic.

    AD_AN3_Volt = (AD_AN3_VALUE */ 500) >> 2

    Using 10Bit resolution:

    5V = 1023 so 2.5V = 511

    ( final reading on LCD should be 2.50V )

    If i have 2.5V the AD_AN3_VALUE = 511

    */ -> get the middle 16bits from the 32 ( divided aftermath )

    511 / 500 = 1,022

    1,022 - the 16 middle bits ???

    Then >>2 means shift 2 positions to the right ( binary ) ??


    And final the DEC2 - this is not included in the PBP manual...
    EDIT: But this last line i understand the logic.

    .
    Last edited by ruijc; - 4th December 2007 at 17:34.

  6. #6


    Did you find this post helpful? Yes | No

    Default

    Can someone help me undestand the code ?

    AD_AN3_Volt = (AD_AN3_VALUE */ 500) >> 2

    thanks

  7. #7
    Join Date
    May 2006
    Posts
    36


    Did you find this post helpful? Yes | No

    Default

    I had a problem understanding this too. Here is another link that you can look at that explains the '*/' operator. http://www.picbasic.co.uk/forum/showthread.php?t=5545

    Quote from Darrel Taylor on Jan 17, 2007.
    ======================
    */ is the MidWord multiplier.

    When you multiply 2 16-bit values together, you'll get up to a 32-bit result (4 bytes). The Midword, is the 2 bytes in the middle.

    For instance, let's say you have an A/D value of 600, and you multiply it times 5000, that gives you 3,000,000. And if you express that in Hexadecimal, it looks like ...
    002D:C6C0

    The MidWord is 2DC6, or 11,718.

    That's the same as (600 * 5000) / 256. The /256 is implied, and happens without the extra time required to do a division. So, it can be allot faster than using DIV32.

    The rest of the formula is, >> 2, or shiftright 2 places. Which is the same as /4. Since the result has already been divided by 256, /4 makes the total divisor equal to 1024 (256*4). And, the result will be 2,929, which represents 2.929 Volts input to the ADC.

    So, the whole formula is really just (600 * 5000) / 1024. But in a way that PBP can handle it with 16-bit numbers.
    --------------------------------------------------------------------------------

    OK, so how to go the other direction...

    Quote:
    I would like to take 0.01 to 0.250V

    You'll need the integer numbers (10 to 250) I'll call it Offset. Then just do the reverse formula.

    AD_Cal = (Offset * 1024) / 5000

    This one doesn't fit in with the */ operator, so you'll need to use DIV32.
    Code:
    Offset = 250 ; 0.250V - Must be a WORD Var
    AD_Cal = Offset * 1024
    AD_Cal = DIV32 5000This gives a result of 51, which can then be added or subtracted from the AD result as necessary.

    HTH,
    __________________
    DT
    =====================

    As for the DEC3 command, I looked in the manual at SEROUT2 command, it has a little bit more explanation. From the manual, a numerical value preceded by DEC will send the ASCII representation of its decimal value. For example, if B0 = 123, then DEC B0 (or DEC 123) will send "123".

    Also BIN, DEC, and HEX may also be followed by a number. Normally these modifiers will display exactly as many digits as necessary, zero blanked (leading zeros are not sent). However, if a number follows the modifier, SEROUT2 will always send that number of digits, adding leading zeros as necessary. It was also trim off any extra high order digits. For exampl, BIN6 8 would send "001000" and BIN2 8 would send "00".

    You can try to do some experimenting with this.

    I believe with the code I supplied
    ======
    TO have precision to three decimal points use:
    AD_AN3_Volt = (AD_AN3_VALUE */ 5000) >> 2
    LCDOUT $FE, 1 ' Clear LCD screen
    LCDOUT "A to D Value"
    LCDOUT $FE, $C0, DEC (AD_AN3_volt/1000) ,".",DEC3 AD_AN3_VOLT ,"VDC"
    =======
    I am using 10 bit A to D, so the max value I could have for AD_AN3_VOLT is 1023. I then use the */ 5000 which is equivalent to *5000 /256 and then I use '>>' (shift right by 2) which is equivalent to dividing by 4. My value is now equal to a max of 4995. I then divide AD_AN3_VOLT by 1000 and get a integer (using the DEC will allow it to display 0 if it needs to). And DEC3 AD_AN3_VOLT will provide a 3 digit value for AD_AN3_VOLT. I believe that I how it works. I did this awhile ago and proved it to myself then. I would suggest you experiment with the code and see that happens. Best of luck.

  8. #8


    Did you find this post helpful? Yes | No

    Default

    jblackann,

    i thank you very much for the detailed explanation

    In fact i did tryed the code and it works 5*****

    i just wasnt undestanding the math...and now i do

    This way we get precise results with less code.


    Thanks

    .

Similar Threads

  1. Reading in Manchester code
    By brid0030 in forum Code Examples
    Replies: 0
    Last Post: - 10th March 2009, 21:55
  2. How much code space do PBP statements use.
    By Darrel Taylor in forum Code Examples
    Replies: 5
    Last Post: - 13th February 2009, 21:31
  3. Loop with two motor and 2 sensors
    By MrRoboto in forum mel PIC BASIC
    Replies: 4
    Last Post: - 8th December 2008, 23:40
  4. Making Program Code Space your playground...
    By Melanie in forum Code Examples
    Replies: 15
    Last Post: - 19th July 2008, 08:26
  5. Re-Writing IF-THEN-AND-ENDIF code?
    By jessey in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 18th August 2006, 17:23

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts