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 Query

Status
Not open for further replies.

Dakta

New Member
Hi there, i'm back with a new problem. This should be a lot easier to get resolved as it's got little to do with programming, and more to do with solving a problem.

I want the best approach, in other words.

Right, an introduction, I'm designing an lcd-based boost gauge for my car, which will tap into a 2.5 bar map sensor that also feeds the ecu (do have a seperate sensor of the same type if needs for a seperate sensor be)

I'm using this as a learning exercise, and it's designed to run from a 16f872, as having the three ports help me organise LCD i/o, LCD control and analogue inout (c,b and a respectively). I suppose I could share pins from the same port for multiple purposes by setting the bits individually but i'm not sure i've the confidence to manage this through code effectively yet.


Anyway, I've got things pretty much setup as far as I/O goes, I can read 0-5v in through the adc on the pic, which gives me an 8 bit conversion which I'm happy with (a binary 51 per volt applied), and I have setup routines that can be called to fire individual characters to the LCD, this also works well and I've got a lot of the hard work done.

At the moment though, I'm just a bit lost as to how to tackle taking the result from the adc and calling the correct subroutine to give the right reading on the LCD. I only want it to increment in psi, which is quite a large range of voltage between, so I have made a list of the adc result equivelents for a set psi, which is fine, but I'm still unsure how to proceed.

Let's say I want the lcd to report:

adc result: 12 psi:1
adc result: 24 psi:2
adc result: 36 psi:3
adc result: 48 psi:4
adc result: 60 psi:5

Obviously I'd want to find the closest value the adc output is to, so if I read the adc delivering 13, I'd want to register 1psi.

In all fairness I am happy to round UP in all cases, as it's safer with a tuned engine like mine to assume boost is higher rather than lower, but anyway..

any tips on the best logical approach to working these numbers? I thought of using lookup tables but they don't seem to offer much flexibility for rounding.

cheers
Kris
 

Nigel Goodwin

Super Moderator
Most Helpful Member
any tips on the best logical approach to working these numbers? I thought of using lookup tables but they don't seem to offer much flexibility for rounding.

Use lookup tables, it's the fastest and easiest way, and it gives you total control - FAR more flexible for rounding than any other method.
 

Dakta

New Member
Use lookup tables, it's the fastest and easiest way, and it gives you total control - FAR more flexible for rounding than any other method.

cheers! It certainly is the easiest, my only concern being that I don't want the lcd output to be null should the analogue input pause between references I am looking for.

Maybe what I could do actually is hold the last value in a gpr so if it fails to acquire a reading it can use the last value instead..


i'm deep in thought now LOL
 

Nigel Goodwin

Super Moderator
Most Helpful Member
cheers! It certainly is the easiest, my only concern being that I don't want the lcd output to be null should the analogue input pause between references I am looking for.

How can a lookup table be null?, YOU enter the values you want in it, don't insert any null values.
 

Dakta

New Member
How can a lookup table be null?, YOU enter the values you want in it, don't insert any null values.

Yep I must be misunderstanding something because i'm looking for 25 specific values from a possible 255, and the time will come when it lands somewhere inbetween what i'm looking for.

Unless I made a lookup table for each value. That can wait till the morning I think!

I think you're suggesting that it does not make a decision if the value is not found, which is fine it'l work but considering i'm looking for so few of so many values, wouldn't that make the software slow to update, rather than letting it commit to the nearest value?

Say I let off the gas halfway through building boost, and she sticks at 14.3psi for three seconds, would it be wise to hold the previous value until it hits the next, or to try and round?

If the softwares fast enough to catch all the values as boost builds (very quick), then it won't be so bad, but if for example some of the lcd delays to allow it to write properly etc allow the sensor output to run away from the last value read it might mean holding a a fiarly inaccurate figure.



(don't forget i'm a bit of a n00b. Unfortunately whilst my book goes into detail about lcd's adc's and more, I cannot really find a situation where the adc output is selected on what it is, rather than every adc reading being processed).

If I processed it, even if I could figure it out i'd be dealing with adc outputs for pressures like 14.53psi which really I'm not after, hence my small list of fixed psi voltages, and their respective adc output digital values.

anyway, I don't think i've worded this query well. I've reinterpreted your answer twice already :| I'l try and come up with something mind, and i'l start with these tables.

Definitely need more practice.
 
Last edited:

Nigel Goodwin

Super Moderator
Most Helpful Member
Yep I must be misunderstanding something because i'm looking for 25 specific values from a possible 255, and the time will come when it lands somewhere inbetween what i'm looking for.

How can it?, if your result has 255 possible values, then you have 255 entries in your lookup table - every possible result is referenced to an exact value that YOU decide.
 

Dakta

New Member
How can it?, if your result has 255 possible values, then you have 255 entries in your lookup table - every possible result is referenced to an exact value that YOU decide.


You're going to laugh, but I thought that would waste memory.

I'm definitely getting my coat on this one LOL.

You win, I'l give it a go :D
 

Dakta

New Member
It's not a waste of memory if you're not wanting it for something else - otherwise it's just sat there as completely wasted memory.


I knew i'd regret getting involved in this logic stuff. Clearly don't have the mind for it! ;)

Anyway, your advice was taken on board and today I coded two similar ways around the problem:

Here's the first: (pseudocode, or plain thoughts)

1. Read analog input, store in temporary register
2. move to GPR so next adc input can go in the above register
3. call function lookuptable
- adc value is loaded back into w, and added to PC counter, which in theory steps the program 255 steps (if 5v is present), meanwhile the following lines are structured like this (255 lines in this lookup table:

retlw 0; ;adc value of 0, digital output wants to be 0psi
retlw 0; ;adc value of 1, digital output still wants to be 0psi
retlw 1; ; adc value of 2, digital output is now 1psi

This is how most internet tutorials seem to lay out the theory, my problem being that on testing the code, it compiles fine but the lcd remains blank.

Code example:
; BOOST LOOKUP
BSTLOOKUP ADDWF PC
RETLW .0
RETLW .0
RETLW .0
RETLW .0
RETLW .0
RETLW .0

So I decided to try another approach:

1. Read analog input, store in temporary register
2. move to GPR so next adc input can go in the above register
3. call function lookuptable
4. 255 entires in this look up table - each containining code to XOR literal value (1,2,3-255 etc) with the adc input. The zerobit is then checked and if the xor compared the results as equal it returns the value of psi i am looking for (instead of the adc digital value).

This can then be relatively easy and sorted to call the function to display values on the LCD.

I tested this approach by writing the code to display up to 3 psi for a limited range of voltages, however the lcd printed 0psi1psi2psi all the time regardless of input. My routines for display interfacing are fine as I can alter the code to call functions that send letters to it no problem.

Its getting hard to get across what i've coded now. I doubt anyone can really offer much to specifically help, but any ideas welcome. Surely my logic isn't wrong?
 
Last edited:

Nigel Goodwin

Super Moderator
Most Helpful Member
Are you not aware that a standard table can't cross a 256 byte boundary?, as the PC counter is only eight bits wide.

If you check my LED matrix tutorial, that uses two large tables which show one way to get over the limitation.
 

Dakta

New Member
Are you not aware that a standard table can't cross a 256 byte boundary?, as the PC counter is only eight bits wide.

If you check my LED matrix tutorial, that uses two large tables which show one way to get over the limitation.


That would explain a lot. I wish my books went into a bit more detail. You type out their examples, get it working, modify it, it works. Then you apply it to your own project and you find it's different enough to render what you learnt entirely useless.

I'l have a look at your tutorial ;)
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top