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.

A little help with ADC and swordish

Status
Not open for further replies.

be80be

Well-Known Member
What I'm trying to do is save two voltage values the first being the highest
and the second the lower seeing ADC is bigger then 8 bits I get a error saying out of bounds when I try it like this
Code:
Dim highvolts As Word
Dim lowvolts As Word
Dim Counter As Word
Dim hold(2) As Word 
Counter = 0
       For Counter = 0 To 1                   // loop 2 times
            While Get_ADC_Sample > 0          // get sample
            Wend
            hold(Counter) = Get_ADC_Sample     // put in hold(1)
            DelayMS(20)                 // small delay
       Next  
     highvolts = hold(1)  [COLOR="Red"]//I get a Constant expression [/COLOR]
     lowvolts = hold(2) [COLOR="Red"]//violates subrange bounds here [/COLOR]
 
That's it I keep forgetting that with swordfish and it's the same in C too Lol it worked.
I set the counter right just not calling it back right thanks 3v0
 
I still have a problem it's putting the same value in both
highvolts = hold(0)
lowvolts = hold(1)
 
Here the whole code
Code:
Device = 18F1220
Clock = 8 // tells the compiler the FOSC speed
Config OSC = INTIO2, WDT = OFF, LVP = OFF, MCLRE = OFF
Include "Utils.bas"
Include "INTOSC8.bas"
Include "ADC.bas"
Dim right1 As PORTA.0
Dim left1 As PORTA.1 
Dim highvolts As Word
Dim lowvolts As Word
Dim Counter As Word
Dim hold(2) As byte  
 Function Get_ADC_Sample() As Byte   // Function to grab the ADC sample
 
   result = ADC.Read(0)             // Grab an ADC sample from channel 0
   //result = result * 2               // Scale the answer up by a factor of 3
  
   End Function
  hold(0) = 0
   hold(1) = 0
 Counter = 0
       For Counter = 0 To 1                    // loop 2 times
            While Get_ADC_Sample > 0          // get sample
            Wend
            hold(Counter) = Get_ADC_Sample     // put in hold()
            DelayMS(20)                 // small delay
       Next 
  
SetAllDigital
TRISB =%00000000 
PORTB =%00000000
Input(PORTA.0)
     
While True 
    highvolts = hold(0)
    lowvolts = hold(1)                        
    
    If highvolts > lowvolts  Then     // checks to see if highvols is higher
    PORTB = %11111111                 // lights up portB
    DelayMS(20)
    Else
    PORTB =%00000000                  // if not higher turns portB off
    DelayMS(20)
    EndIf
                    
Wend
 
Last edited:
You need to have someone who programs in SF to look at this. There are things I have doubts about that may be clear the them.

This is what I see as you main code. You read the ADC just the twice and go into a loop using the same values for hold(0) and hold (1) over and over.

Code:
hold(0) = 0
hold(1) = 0
Counter = 0
For Counter = 0 To 1          // loop 2 times
  While Get_ADC_Sample > 0    // get sampl
    Wend
  hold(Counter) = Get_ADC_Sample // put in hold()
  DelayMS(20)                 // small delay
Next 
  
SetAllDigital
TRISB =%00000000 
PORTB =%00000000
Input(PORTA.0)
     
While True 
    highvolts = hold(0)
    lowvolts = hold(1)                        
    
    If highvolts > lowvolts  Then     // checks to see if highvols is higher
    PORTB = %11111111                 // lights up portB
    DelayMS(20)
    Else
    PORTB =%00000000                  // if not higher turns portB off
    DelayMS(20)
    EndIf
                    
Wend
 
This make the portb flash when the adc value changes but not what i'm trying for.
Code:
Device = 18F1220
Clock = 8 // tells the compiler the FOSC speed
Config OSC = INTIO2, WDT = OFF, LVP = OFF, MCLRE = OFF
Include "Utils.bas"
Include "INTOSC8.bas"
Include "ADC.bas"
Dim right1 As PORTA.0
Dim left1 As PORTA.1 
Dim highvolts As Word
Dim lowvolts As Word
Dim Counter As Word
Dim hold(2) As word 
 Function Get_ADC_Sample() As Byte   // Function to grab the ADC sample
 
   result = ADC.Read(0)             // Grab an ADC sample from channel 0
   //result = result * 2               // Scale the answer up by a factor of 3
  
   End Function
  
       
  
SetAllDigital
TRISB =%00000000 
PORTB =%00000000
Input(PORTA.0)
     
While True 
 Counter = 0
       For Counter = 0 To 1                    // loop 2 times
            While Get_ADC_Sample = 0          // get sample
            Wend
            hold(Counter) = Get_ADC_Sample     // put in hold()
            DelayMS(20)                 // small delay
       Next 
    highvolts = hold(0)
    lowvolts = hold(1)                        
    
    If highvolts > lowvolts  Then     // checks to see if highvols is higher
    PORTB = %11111111                 // lights up portB
    DelayMS(20)
    Else
    PORTB =%00000000                  // if not higher turns portB off
    DelayMS(20)
    EndIf
                    
Wend
I didn't read your post till after mine but that's what's happening
This is what I see as you main code. You read the ADC just the twice and go into a loop using the same values for hold(0) and hold (1) over and over.
but I moved
the for next down in to the while wend loop. So now it's just flashes the leds as it changes.
 
Last edited:
The thing is it's happening so fast if i didn't have the delay you couldn't see it. It's reading
the light bulb flicker in the room. No it's the power supply it's reading I changed it to this. I'm getting two values. I need to figure out how to set a high range and a low range
Code:
While True 
 Counter = 0
       For Counter = 0 To 1                    // loop 2 times
            While Get_ADC_Sample = 0          // get sample
            Wend
            hold(Counter) = Get_ADC_Sample     // put in hold()
            DelayMS(100)                 // small delay
       Next 
    highvolts = hold(0)
    lowvolts = hold(1)                        
    
    If highvolts > lowvolts  Then     // checks to see if highvols is higher
    PORTB = hold(0)                 // lights up portB
    DelayMS(20)
    Else
    PORTB =hold(1)                 // if not higher turns portB off
    DelayMS(20)
    EndIf
                    
Wend
 
Last edited:
I'm not sure what you are trying to do but a few things stand out as possible problems.

You have SetAllDigital when you need analogue pins.
You don't initialise the ADC.

If you can describe what the program is supposed to do then it is much easier to write it.

Mike.
 
Burt,

Here's a little program that lights the Junebug LEDs as you move VR1.

To use it set all DIP switches to ON.
Code:
Device = 18F1320
Clock = 4 // 4MHz clock
Config OSC = INTIO2, WDT = OFF, LVP = OFF

Include "18F1320.bas"

Function ReadADC(Channel As Byte) As Word
Dim GO As ADCON0.1
    ADCON1=ADCON1 And (255-(1<<Channel))
    ADCON0=(Channel<<2)+1
    GO=1
    While(GO=1)
    Wend
    ReadADC=(ADRESH*256)+ADRESL
End Function

Sub InitADC()
    ADCON0 = %00000001      //A2D on and select AN0
    ADCON1 = %11111111      //digital I/O
    ADCON2 = %10110101      //Right justify - Fosc/16    
End Sub

//main code starts here
Dim Result As Word
OSCCON = $62                //select 4MHz internal clock
InitADC
While true
    Result=ReadADC(1)       //read VR1
    If Result<150 Then
        TRISA.7 = 1         //light first LED
        High(PORTA.0)
        Low (PORTA.6) 
    ElseIf Result<350 Then
        TRISA.7 = 1         //light second LED
        Low (PORTA.0)
        High(PORTA.6)      
    ElseIf Result<550 Then
        TRISA.0 = 1         //etc.
        High(PORTA.6)
        Low (PORTA.7)      
    ElseIf Result<750 Then
        TRISA.0 = 1
        Low (PORTA.6)
        High(PORTA.7)      
    ElseIf Result<950 Then
        TRISA.6 = 1
        Low (PORTA.0)
        High(PORTA.7)      
    Else
        TRISA.6 = 1
        High(PORTA.0)
        Low (PORTA.7)      
    EndIf    
Wend

End

The code you will probably find useful is the InitADC and ReadADC subroutines.

Mike.
 
Mike I was using the module in swordfish for the adc . I removed the SetAllDigital. This is what I'm trying to do . Is save the highest adc value as (highvolts) and then when it reads
a value that is lower compare the two so if it is closer to the highvolts portb will read as (0) on all pins if (lowvolts) is lower then(highvolts) by a half volt it will set all pins to (1) on portb . Thanks for the code I'll look at that it has r range of value to light at . That would work I think I'll try it later when I get home.
 
Something like,
Code:
//main code starts here
Dim Result As Word
Dim Upper as Word
Dim Lower as Word
OSCCON = $62                //select 4MHz internal clock
InitADC
Upper=0
Lower=$ffff
while TRUE
    Result=ReadADC(1)       //read VR1
    if Result > Upper then  //is it a new high
        Upper=Result        //yes so update Upper
    endif
    If Result < Lower then  //is it a new low
        Lower=Result        //yes so update lower
    endif
    if(Upper-Result)>(Result-Lower) then
        //code for when result is nearer Lower
    else
        //code for when result is nearer Upper
    Endif    
Wend

Mike.
 
Mike that works for me Thanks what it is doing you set
Upper to 0 and Lower to 1111111111111111
Then you put the value of ReadADC(1) into Result and make it = to Upper
But what keeps Upper from going lower.
Because I have tried it like this and the values would change till they had the same is it this part that keeps it from happen.
Code:
Upper=0
Lower=$ffff
that's the only thing i haven't put in my code.
So if ADC is high it is close to 0
and if it is Low it's closer to 65535 of $ffff
I think that's right thanks agin. Mike
 
To add to what 3v0 posted, think how the variables will get changed first time through the loop.

Say Result is 500, the line
if Result > Upper Then
will result in Upper being set to 500 as 500 is greater than 0.
if Result < Lower Then
will result in Lower being set to 500 as 500 is less than $ffff.

And then second time through the loop.
Say the next reading is 400 then
if Result > Upper Then
will result in no change as 400 is not greater than 500.
if Result < Lower Then
will result in Lower being set to 400 as 400 is less than 500.

And so, Lower will contain the lowest value read (400) and Upper the highest (500).

Mike.
 
Thanks Mike I was close I just never set a value in Lower but 0 and that's why they ended up the same. You have to think in 3D here to make it work lol. It works like a charm
now for the next part. This is what I'm making Interactive LED Panels just one. I was play with ADC and a LDR and out putting the value to portb with 8 leds it looks just like one
row on one of the panels.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top