Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

ADC math won't cooperate?? why??

Status
Not open for further replies.

MrDEB

Well-Known Member
Doing an ADC temperature conversion and had an algebra teacher show/solve the correct formula
This formula is correct until I add the subtract 42.51 into the equation.
the total before multiplying by 1.41 is 79.794,Multiply by 1.41 = 112.509. Subtract the 42.51 =69.99 which is the amount I am after. Seems like any thing I try I still end up with 112.07 w/wo the subtraction.
I tried several different things but when it comes to algebra I AM LOST
It was suggested to use integers???WHOLE NUMBERS?? but would it change anything??
Code:
 Function sensor() As Word
    result = (ADC.Read(0)+1) *5000 / 1024*1023/5*1.41-42.51  
    End Function
the formula I have is temp = 1.41(ADC COUNT) - 42.51
the ADC count is 79.794.
Do it all on a caculator and it works out right
 
Toooo much for a word.... Suppose 141 from the ADC then * by 5000 (oh dam!!, There is only 65k available you have 705k).

The biggest value you could use would be 13.

result = (ADC.Read(0)+1) *5000 / 1024*1023/5*1.41-42.51
How does this figure in your equation..
Also.... you can't mix floating point numbers with integers

try this 141 * adc_count ( adc_count should be a whole number ie..798 ) / 10 - 4251 this comes out at 7000.
 
I am using integers now but?

I am using the ADC amounts directly
room temp = 7
melting point = 25 these are the adc readings
Code:
 Function sensor() As Word
    result = (ADC.Read(0)*1023)/ 5 *81-45//1024 is divide by  tip sensor  0.07 at RT .25 melt
     //1024 is divide by  temp ref desired
    End Function
the result with ADC of 7 is supposed to be 70degrees
with a reading of 25 the temperature is 370
Do I need to use a LONGWORD because I tried that??
 
this is not correct why?

Been working on this most of the day (Not real keen on algebra to begin with)
This posted snippet displays .09 on my LCD
maybe I have the LONGWORD in the wrong place?


Code:
 Function sensor() As Word
    result = (ADC.Read(0)*1023)/ 5 *(81/1000)-45//1024 is divide by  tip sensor  0.07 at RT .25 melt
     //1024 is divide by  temp ref desired
    End Function


Code:
 Device = 18F4520
    Clock = 8
    // some LCD options...
    #option LCD_DATA = PORTD.4
    #option LCD_RS = PORTD.2
    #option LCD_EN = PORTD.3
    // uses LCD and AD libraries...
    Include "LCD.bas"
    Include "ADC.bas"
    Include "convert.bas"
    Include "InternalOscillator.bas"
    Include "math.bas"
    Dim ADVal As Word
    Dim LED_g As PORTC.0
    Dim LED_r As PORTC.1
    Dim opti As PORTE.0
    //Dim Vref, Vsensor As longWord
    Dim Vref, Vsensor As Integer
    //Dim tiptemp As Integer
    // Read the AD port and scale for 0.00 - 5.00 volts...
    Function REF_V() As Word
    result = (ADC.Read(1)+1)*5000/1024   //1024 is divide by  tip sensor
    End Function
    Function sensor() As Word
    result = (ADC.Read(0)*1023)/ 5 *(81/1000)-45//1024 is divide by  tip sensor  0.07 at RT .25 melt
     //1024 is divide by  temp ref desired
    End Function

    // Start Of Program...
    Input(PORTA.0)                  // temp ref voltage desired temp
    Input(PORTA.1)                  // tip sensor
    Low (LED_g)                     //set lEDs OFF
    Low (LED_r)
    High(opti)
    ADCON1 = %10000000              //set up ADC regesters
    ADCON0.7 = 1
    ADCON0.6 = 1

    DelayMS (150)
    LCD.Cls
       


        // main program loop...
        While true
            // call function REF_V() and assign the result to word variable 'Vref'
            Vref = REF_V()                // desired temp
            LCD.MoveCursor (1,1)
            LCD.Write("REF_V = ", DecToStr(Vref/100), ".", DecToStr(Vref, 2), " ")
            DelayMS(250)
           
           
            // call function sensor() and assign the result to word variable 'Vsensor'
            Vsensor = sensor()          // tip sensor
            LCD.MoveCursor (2,1)
            LCD.Write("sensor = ", DecToStr(Vsensor/100), ".", DecToStr(Vref, 2), " ")
            DelayMS(250)
           
            // compare Vsensor and Vref values
            If Vsensor < Vref Then      // not hot enough
                LED_r=1
                LED_g=0
                opti=0                  // turn on opti couplier by going low
            Else                        // Vsensor must be >= Vref, so desired temperature
                LED_g=1
                LED_r=0
                opti=1                  // turn off opti couplier by going high
            End If
        Wend
 
Why not do a table lookup? Compute your table with your calculator and load it into an array. Use your ADC as the array index.
 
The one thing I keep looking at..
Function REF_V() As Word
result = (ADC.Read(1)+1)*5000/1024 //1024 is divide by tip sensor
End Function

The integer math will try to multiply the ADC reading with 5000 BEFORE dividing by 1024.. A word variable can only be 65535... With the ADC possible value fro 0 to 1024.. Doesn't work.
 
I took out the 5000 (see my code snippet post)
I think I have the LONGWORD designated to the wrong variable. Should be on sensor and not Vsensor. Might try on both.
 
The integer math will try to multiply the ADC reading with 5000 BEFORE dividing by 1024.. A word variable can only be 65535... With the ADC possible value fro 0 to 1024.. Doesn't work.

Normally, that would be true, but MrDEB is failing to tell you what compiler he's using (Swordfish), and there that works since it will use 32-bit multiply/divide for that expression.
 
Swordfish is using a longword and even if you cast it to a word it will do the math as longword then cut that off at a word and gives you most significant bits
Unlike many other BASIC compilers, Swordfish does allow variables of different types to be used in the same expression. For example, an unsigned byte can be multiplied by an integer and assigned to a variable declared as floating point. However, this practice should be avoided if possible, as the code automatically generated by the compiler needs to convert one type into another in order to compute the correct result. This will result in a larger code footprint than would otherwise be generated if all of the variables used had been declared as the same type.
 
Last edited:
Am contemplating going with a look up table (CONST array) for the ref voltage (desired temperature)
here's the formula I worked out for the tip temperature. Still need to confirm if it actually works. It computes on a caculator as well as for RT.
"(300/18*(ADC.Read(0)))-46(ADC.Read(0)))
My actual ADC(x) readings are ADC.READ(0) =7 -25 (70degrees to 370 degrees)
the ref readings (adjustable ADC.READ(217-1019)
The ref readings are not say we say linear?
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top