problem with ADC

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello.

i never actualy used free running mode of ADC before,
but now i wanted to do it. however i ran into a problem,
which i have problem resolving.

here is my code : http://pastebin.com/m49b823c

its for atmega8535, i'm using v-usb lib.

what it should do ? keep reading ADC pins 0 to 7, saving results in array. on usb request return latest status.

code starts, ISR gets executed, but the problem is
that result of my conversion is always 0.
if i do this in normal mode (set channel, enable, wait, read, .....) it works ok. when i try to move it to free-run, results of my conversion is 0.

i'm sure its just something stupid, but i'm realy out
of luck locating it.

thanks for your support.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So you want to take measurements in all 8 channels, using the free running mode. There is some analysis in the datasheet of how/when to switch from one channel to another, when using the free running mode.
Are you sure you follow the datasheet?

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What advantage do you think you get by using free running mode anyway? If a single channel was involved I could maybe see it but when switching between multiple channels is it really an advantage or a disadvantage? Discuss.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The only advantage of using the free running mode that comes in my mind is to use it for take measurements from 1 channel only, without spending CPU resources.

You could set an interval interrupt to triger rolling measurements, between the needed adc channels. The interrupt period depends on how fast you need to update each adc result.

Michael.

User of:
IAR Embedded Workbench C/C++ Compiler
Altium Designer

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The testBUF variable needs to be declared volatile (not sure if static has the same effect as volatile).

Quote:

testBuf[a] = ADCH;

I am not sure if the order in which you read the ADC value is correct. If I am not wrong you have to read the LSB first and then the MSB. But you can also read the entire value from ADC register as one number and then do the manipulations later.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
not sure if static has the same effect as volatile

No, it does not. Static merely makes it inaccessible from other modules.
Quote:
I am not sure if the order in which you read the ADC value is correct. If I am not wrong you have to read the LSB first and then the MSB.

But the OP is only reading 8 bits, so there is no need to read ADCL at all. However there is a bigger problem in that the OP has not enabled left adjust, so he will only be reading 2 bits.

Also, all readings except the first will be the wrong channel, so the results will be stored one off in the array.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok thanks for all replies, i'm gonna go over all of them right now, and check what results do i get.

first, why i want to use free-running mode:

my device will be pretty simple, reading all 8 ADC
channels into my variable, and sending results to pc
when its requested.

i just tought that free-running would be better, as i
would get my readings more often, but yesterday, after
having no success with free running mode, i switched
back to normal mode where i :
- set adc to fire interupt when its done converting
- in this interupt, i read the value, switch channel,
and then start another conversion (ADEN)

i am only reading ADCH becouse, i have my data left aligned, so the highest 8 bits are in ADCH, i dont care about the other 2 bits.

so if i understood you guys correctly, i wont get any benefit from using free-running mode, so i'm gonna use normal mode.

however i still have some problems, which i'm not sure if they are related to my sensors or my firmware.

it seems that when i connect one sensor it works ok
(if i'+m just reading one adc channel)
when i try to read all 8, values dont seem to be right.

here's my current code: http://pastebin.com/m3d90afd3

however, i'm away for the weekend, so wont be able to test where's my error comming from till monday.

thanks for all your help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why use an interupt? Is the avr 99% busy and you cant afford to wait 100 usec for the a/d to do a conversion? What computation could utilize so much of the computer that 100usec was valuable?

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok i disabled interupts and did it the easy way.
not it works ok,
however there's a problem in my hardwaqre design.

i have 8 plugs to connect my sensonrs to (piezo)
however, if one plug is not connected i'm getting
random readings from it.

how can i fix this ? (so when plug is out i'll get 0, when plug is in i'll get normal readings)

and there's another problem. when i plug in the sensors,
and push on them, i get the readings that i'm expecting,
but then when i dont do anything to the seonsors for a while (half a minute) value starts increasing (constantly, but slow).

thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

how can i fix this ? (so when plug is out i'll get 0, when plug is in i'll get normal readings)

Weak pull-up or pull-down.