Software ADC Comparator?


Closed Thread
Results 1 to 14 of 14

Hybrid View

  1. #1
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    967


    Did you find this post helpful? Yes | No

    Default

    Ryan

    What you're looking for is a derivative function. What you can do is something like this

    Code:
    LastADC  var   word    ' previous error
    CurrADC  var   word    ' current error
    Threshold con  1        ' can be more if you want
    
    loop:
      gosub ReadADC
      Error = CurrADC-LastADC
      if Error < 0 then Error = -Error ' make absolute error
      if Error > Threshold then
        High Output
        pause 1000    ' wait 1 second
        Low Output
      endif
      LastAdc = CurrAdc
      goto loop
    This will more or less achieve what you want to. However, this is pure untested code. Use at your own risk.

    Jerson

  2. #2
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default still not it..

    I tired your code, Jerson, and it didn't seem to work right, say the ADC had 2.5 volts applied, and then i turned the voltage up to 3 volts, the output would turn on and off, over and over, rather than toggle once, to show a change happened, and then stop. i changed the threshold value to account for any instabilty in my input voltage, and still no dice. and like a i said before, i need the circuit to "readjust automatically" so that it only cares that there is a positive increase in voltage by a certain value and reacts once and then resets, it shouldn't care what the original ADC value was, only that the value increased. so it would have to "dynamically" adjust itself. you would figure that you would take a reading, and then some miliseconds later, take another reading, subtract the first value from the second and that number would show a difference (if there is any), which would mean a positive change. if that value was over that of the threshold, then react. you would have to clamp that value to a number between 0 and 1023, so there wouldn't be a negative value and a roll over (or under, in this case) which i think is what Jerson's code showed, and i already tried the same thing, in a slightly different way, and neither work... but i could be, and probably am missing something! i really don't understand absolute values (only their vodka!) and how it applies here, all your saying is that the number can only have a certain maximum value right? so couldn't i use MAX?
    Last edited by Ryan7777; - 13th February 2008 at 05:00.

  3. #3
    Join Date
    Nov 2003
    Location
    Wellton, U.S.A.
    Posts
    5,924


    Did you find this post helpful? Yes | No

    Default

    Like skimask said, you have the code in you explanation of the project.
    Jerson gave an "untested" example to get you started.

    Think about this:
    Code:
    Two VAR : read ADC first : write that value to VAR1 : start LOOP : read ADC :_
    write ADC value to VAR2 : IF VAR2 > VAR1 THEN ? : Now make VAR1 = VAR2_
    GOTO LOOP
    Dave
    Always wear safety glasses while programming.

  4. #4
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default This is what i have.

    This is what i got so far, and im not seeing why it doesn't work.
    please excuse the formatting and what not!

    @ DEVICE pic16F684, HS_OSC, WDT_OFF, PWRT_OFF, MCLR_ON, BOD_OFF, IESO_OFF, FCMEN_OFF

    DEFINE OSC 20
    DEFINE ADC_BITS 10
    DEFINE ADC_CLOCK 2
    DEFINE ADC_SAMPLEUS 11

    CMCON0 = %00000111
    VRCON = %00000000

    ANSEL = %00110100

    ADCON0.6 = 0
    ADCON0.7 = 0

    voltLevBf VAR WORD
    voltLevAf VAR WORD
    voltLevCk VAR WORD
    threshHold VAR WORD
    timOut VAR WORD

    prgSel VAR PORTC.2
    swtOut VAR PORTC.3

    CLEAR

    PAUSE 1000


    autoGainPrg:

    ADCIN 2, voltLevBf

    PAUSEUS 12

    ADCIN 4, threshHold

    PAUSEUS 12

    ADCIN 2, voltLevAf

    PAUSEUS 12

    voltLevCk = voltLevAf - voltLevBf

    IF voltLevCk > threshHold THEN

    HIGH swtOut

    PAUSE 60

    LOW swtOut

    ADCIN 5, timOut

    PAUSEUS 12

    PAUSE timOut

    ENDIF

    GOTO autoGainPrg:

    the ADC acts as if there are two seperate voltage values present at the pin even if the voltage is the same and doesnt change. like on the first reading it should read 3 volts, and the second reading should be 3 volts or close enough! it shouldn't flash the LED sitting on the output, but its does, over and over like a blinky circuit, like the two readings are never close to equal, no matter what threshold is set at! so that would make me think that the difference between the two readings is somehow always larger than threshold.. what i'd like to know is, what did Jerson mean by "if Error < 0 then Error = -Error ' make absolute error" ?

    IF Error < 0 THEN
    Error = Error - Error
    ENDIF
    ??? if so, i tried that version of it, and it didn't work either..

  5. #5
    Join Date
    Nov 2005
    Location
    Bombay, India
    Posts
    967


    Did you find this post helpful? Yes | No

    Default

    Ryan

    You seem to be reading 3 diff adc ports. First of all, you have to tell us what is each one for any of the code I gave to make sense.

    The code I gave wants only 1 adc port to sense the light intensity. So, the other 2 are redundant. And the code I gave should do exactly what you asked for.

    Check your code. You seem to have got it diff from what I have given you.

    in Pseudo code what I have sent you does this

    if CurrentADC != PreviousADC
    Output = high
    Wait 1 second
    Output = Low
    PreviousADC = CurrentADC
    endif

    Jerson

  6. #6
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default ok

    here is where i am now, and it still doesn't work, no matter.. also, if I were to set my current reading and previous readings equal, the next loop through would set them to what ever the ADC says at sample time anyway.. so it would be pointless wouldn't it?
    PreviousADC = CurrentADC ?

    @ DEVICE pic16F684, HS_OSC, WDT_OFF, PWRT_OFF, MCLR_ON, BOD_OFF, IESO_OFF, FCMEN_OFF

    DEFINE OSC 20
    DEFINE ADC_BITS 10
    DEFINE ADC_CLOCK 2
    DEFINE ADC_SAMPLEUS 11

    CMCON0 = %00000111
    VRCON = %00000000

    ANSEL = %00110100

    ADCON0.6 = 0
    ADCON0.7 = 0

    voltLevBf VAR WORD ' variable for first reading or "previous"
    voltLevAf VAR WORD ' variable for second reading "current"
    voltLevCk VAR WORD ' variable for holding the difference
    threshHold VAR WORD ' variable for the threshold
    timOut VAR WORD ' variable for holding the timeout

    prgSel VAR PORTC.2 ' not in use yet
    swtOut VAR PORTC.3 ' output to LED

    CLEAR

    PAUSE 1000


    autoGainPrg:

    ADCIN 2, voltLevBf ' sample voltage on ADC 2

    PAUSEUS 12

    ADCIN 4, threshHold ' get threshold from pot set up as volt. divider on ADC 4

    PAUSEUS 12

    ADCIN 2, voltLevAf ' sample voltage on ADC 2 again, to check for difference

    PAUSEUS 12

    IF lghtlevAf > lghtlevbf THEN ' IF the second reading is higher than the first,

    voltLevCk = voltLevAf - voltLevBf ' subtract the first reading from the second to get the Dif.

    IF voltLevCk > threshHold THEN ' IF there is a difference, and it is greater then threshold

    HIGH swtOut ' set the LED high

    PAUSE 60 ' pause for 60 mS

    LOW swtOut

    ADCIN 5, timOut ' check volt. div pot on ADC 5, use number as time out - 0 to 1023

    PAUSEUS 12

    PAUSE timOut ' Pause for the time out setting, determined by ADC 5

    ENDIF

    ENDIF

    GOTO autoGainPrg:

  7. #7
    Join Date
    Sep 2006
    Location
    Indiana, USA
    Posts
    72


    Did you find this post helpful? Yes | No

    Default Hope this doesn't make anyones head explode!

    just to make sure the problem i need to solve is clear, i will explain what i want yet again.
    I will not be monitoring a sine wave, the signal will not vary that often actually and will never go negative in relation to ground. but for the sake of an example, I will use sinewave.

    Say that there is a sine wave, the frequency of which does not matter, that is 2 Vp-p.
    This Sine wave is "floating" with its zero point at 2 volts above ground, making the lowest peak 1 volt, and the highest peak 3 volts. then we'll say my threshold is set at 1.5V.
    When the sine wave reaches 1.5V above the 1 volt line (not ground!), it triggers a response from my circuit, or flashes the LED once, and then waits.
    Where the sine wave is "floating" (again, floating, not peaking) doesn't matter, it will be anywhere between 0 and 5 volts and is out of my control, it is an independent circuit.
    The PIC circuit only needs to trigger when there is a positive going change in voltage that exceeds a threshold that i will need to have control of. so therefore, the threshold has to follow the 1 volt ( or 2V or whatever!) line automatically, while i can vary the threshold level, it will always be in reference to the 1 volt line! not ground. please see my example.bmp
    (and yes i know that if my threshold is 1.5 volts, and the signal zero reference exceeds 3.5, the threshold will be out of range, and that is fine because 1.5V is only an example.)
    Attached Images Attached Images  

Similar Threads

  1. Stable Adc Reading Routine
    By gebillpap in forum General
    Replies: 27
    Last Post: - 13th May 2015, 02:18
  2. Comparator circuit thoughts....
    By kevlar129bp in forum mel PIC BASIC Pro
    Replies: 15
    Last Post: - 24th October 2009, 06:04
  3. Software Stack
    By yasser hassani in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 18th December 2007, 10:04
  4. ADC value with 2 decimals on an LCD
    By Squibcakes in forum mel PIC BASIC Pro
    Replies: 3
    Last Post: - 2nd December 2005, 15:54
  5. 12F675 ADC 'Issues'
    By harrisondp in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 31st March 2005, 01:55

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