NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Sensors, Actuators, and Robotics » Sensor interdependence
February 11, 2012 by lsoltmann |
I am trying to build a temperature controller and am having some trouble with what seems to be a coupling between two ADC pins. I have a 10K thermistor connected to PC0 using a voltage divider, an LED connected to PC1, and a 5K potentiometer connected to PC2. The code is as follows
I have taken out some of the code (stuff to do with the LED) to home in on the problem. If I run the code as is, the temperature reads a reasonable value. When I start to turn the potentiometer the value of "setpoint" does not change and the temperature goes up by about 3 degreesF. If I turn the pot the other way the temperature goes down by about 3 degreesF. If I apply heat to the thermistor the temperature goes up as expect but the setpoint value also goes up by about 2 degreesF. Rotating the pot seems to only affect the temperature value not the setpoint. I hooked up a voltmeter to the voltage regulator to ensure the voltage was not dropping as I was turning the pot and it remained steady. I also noticed that if I add a averaging loop (as was done with the temperature) the setpoint value reads correctly and changes with the rotation of the pot. However, the temperature still undergoes the odd increase or decrease as mentioned above. My questions are... why does the temperature change when I rotate the pot? why must I average the potentiometer readings for it to work instead of just taking one sample? |
---|---|
February 12, 2012 by Rick_S |
Try commenting out line 35 in the above program. Then move line 44 beteween lines 38 & 39. What you are seeing could be caused by the "pre-read" configuration the NerdKit guys used in their original tempsensor program. In that program, they start the ADC read at the end of the initialization and at the end of each call to adc_read. The problem when running two is that the reading you get is from the prior call to adc_read, not the current call. Thus if you set ADMUX to 0, then call adc_read, you get the result from the prior call then it starts a new conversion for ADMUX=0. If you then call it with ADMUX=2, you get the results from the earlier ADMUX=0 and fire a conversion for ADMUX=2. See if what I suggested helps, Rick |
February 12, 2012 by lsoltmann |
That fixed it! I'm still new to microcontrollers and programming so I would never have caught that. Thanks for the help. |
February 12, 2012 by Rick_S |
No problem, glad it worked out for you. Rick |
July 02, 2012 by wisc4ever |
I am glad that you got your code working. I am wondering if someone could explain line 50 to me? I have 30+ years of programming experience (and am probably a code snob, but I do know that my way is not always the best). I am curious about the constants and why it was coded that way. I have been trying to get a thermistor working for a couple of weeks now and am too pigheaded to ask for help, but I enjoy seeing what other people have done and learning from my mistakes. |
July 02, 2012 by lsoltmann |
Line 50 exemplifies my lack of coding knowledge. I wanted to apply a fifth order polynomial fit that I obtained from the data sheet but was not able to figure out how to raise a value to another value. I googled exponents in C but the examples given for some reason would not work for me. The compiler kept giving me an error on that line. So instead of asking for help, I brute forced it. Not very efficient but it gets the job done. If anybody knows how to do exponents in C that would be very helpful. Lars |
July 02, 2012 by pcbolt |
Lars - Did you try the 'pow(x, y)' function in the <math.h> library? Both variables need to be "doubles" and it is x raised to the y power. One problem that can come up is a 'double' in AVR is only good for 7 significant digits. |
July 02, 2012 by lsoltmann |
I did try the pow function ,but now that you mention it I did forget to add the math.h library. Just ran a test case and it did work. Guess I'm too used to MATLAB where all these function are built in ... |
July 02, 2012 by wisc4ever |
Lars - As you found out pcbolt is correct with the Pow function in the math library. There is nothing wrong with your code, you are trying to learn as I am. One thing you might want to consider is store ((adc0/1024.0)*5.0) in a variable. For example:
The reason for this is because it takes quite a bit of time to multiply and divide doubles. A lot of my experience was from writing drivers for SCSI and USB controller boards, so performance was always a big issue. Some compilers will optimize it, but I never take that for granted. What are the constant values you are using. i.e. -0.494, 6.8723, -39.559, etc? |
July 03, 2012 by lsoltmann |
That does make sense and makes it look better. I'll definitely go back and change that in the code. I appreciate the help. The constant values in the equation are just the coefficients for each the terms to shape the polynomial. I obtained them from the calibration curve that I generated from the data sheet. The 5th order fit is overkill but it does provide a perfect fit, at least within the region I am interested. If anyone is interested, I got the thermistors from DigiKey http://www.digikey.com/product-detail/en/B57861S0103F040 |
July 11, 2012 by lsoltmann |
wisc4ever - I tried the block of code you suggested,
but I keep getting errors when I compile. I ran some tests and it appears that I can not use an exponent higher than 2 if my base is not an integer. Is this a limitation of the pow function or am I just doing something wrong? |
July 11, 2012 by wisc4ever |
I will try a couple of tests, but <math.h> pow function should handle a double in both parameters and should return a double. Send a code snippet when you get the chance, I will try the test right away. |
July 11, 2012 by lsoltmann |
This compiles...
This does not...
I can string them together and it works as long as the exponent is less than or equal to 2. The error i'm getting is this nom27883d:rims_controller lsoltmann$ make make -C ../libnerdkits make[1]: Nothing to be done for `all'. avr-gcc -g -Os -Wall -mmcu=atmega168 -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt -lm -o erims.o erims.c ../libnerdkits/delay.o ../libnerdkits/lcd.o ../libnerdkits/uart.o /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/libc.a(inverse.o):../../../libm/fplib/inverse.S:50: relocation truncated to fit: R_AVR_13_PCREL against symbol `__divsf3' defined in .text section in /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/avr5/libgcc.a(_div_sf.o) /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/libc.a(log.o):../../../libm/fplib/log.S:94: relocation truncated to fit: R_AVR_13_PCREL against symbol `__addsf3' defined in .text section in /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/avr5/libgcc.a(_addsub_sf.o) /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/libc.a(log.o):../../../libm/fplib/log.S:98: relocation truncated to fit: R_AVR_13_PCREL against symbol `__addsf3' defined in .text section in /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/avr5/libgcc.a(_addsub_sf.o) /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/../../../../avr/lib/avr5/libc.a(modf.o):../../../libm/fplib/modf.S:87: relocation truncated to fit: R_AVR_13_PCREL against symbol `__subsf3' defined in .text section in /usr/local/AVRMacPack-20080721/lib/gcc/avr/4.3.0/avr5/libgcc.a(_addsub_sf.o) make: *** [erims.hex] Error 1 |
July 11, 2012 by wisc4ever |
Your pow function call should not be causing these errors. From what I see (I will continue looking in case I am wrong) is being caused in the make command and not your code, but it appears your code is making it happen. What development system are you using (computer/OS)? Check your include for math.h is it: #include <math.h> I did a cut and paste of the original snippet I posted and it works fine, but my dev system is a Mac running OS 10.4. |
July 11, 2012 by lsoltmann |
I am running the code on a MacBook Pro with OS 10.6. I checked to make sure that I had the #include <math.h> in the code. I assuming that the make file did not need any modifications when I added the math.h library. I appreciate the help. |
July 11, 2012 by wisc4ever |
For what you are doing you should not have to change your make file. Your C compiler and libraries should be the same as mine, so that should not be a problem. Try the following: 1) Get your code to compile (even if you comment out the offending code). 2) Copy and paste the following snippet. Including the '{' and '}'. 3) Try to compile it. This should isolate the pow function into a chunk of code with everything defined locally and no external resources being used with the exception of the pow function. 4) Let me know what happens. { uint16_t aTemp; double vTemp; double Temp; aTemp = 1; vTemp = ((aTemp/1024.0)*5.0); Temp = -0.494*pow(vTemp,5); } |
July 11, 2012 by wisc4ever |
|
July 12, 2012 by lsoltmann |
That did compile. |
July 12, 2012 by wisc4ever |
Since the code you just tried used the power of 5, we can assume the pow function is correct. The next step is to check your declarations of adc0, volts, and ctemp. adc0 should be a uint16_t. volts and ctemp should be double.
|
Please log in to post a reply.
Did you know that you can see each keypress on a computer keyboard on an oscilloscope? Learn more...
|