NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Support Forum » temp sensor project
November 17, 2010 by tkopriva |
I am a novice to this and have started with the tempsensor project. I wanted to slow down the rate of temperature readings (ideally to 1 second per reading). I tried modifying the following: while(1) { // take 100 samples and average them! temp_avg = 0.0; for(i=0; i<100; i++) { last_sample = adc_read(); this_temp = sampleToFahrenheit(last_sample);
to: while(1) { // take 115200 samples and average them! temp_avg = 0.0; for(i=0; i<115200; i++) { last_sample = adc_read(); this_temp = sampleToFahrenheit(last_sample);
The program downloaded fine, but did not do anything once running (blank LCD). I re-downloaded the original and it worked again. I also tried 500, 1000, etc. and only the original code seems to work. What am I missing here? |
---|---|
November 17, 2010 by bretm |
The variable "i" in the "for" loop is type uint8_t. A variable of that type can only take on values from 0 to 255, so it will always be less than 500, or 1000, or 115200, and the "for" loop will never complete. Once it reaches 255 and you try in increment it, it will wrap around back to 0. You can change the type to increase the limit. Some types you could choose:
The reason you wouldn't want to use one of the 32-bit types is that on an 8-bit processor manipulating 32-bit values takes more time and more program space. But since you're already doing 32-bit floating-point calculations it shouldn't hurt. |
November 17, 2010 by tkopriva |
thank you, that got it to work! I was able to get readings and see it update in hyperterminal. one thing that seems strange is using 115200 it updates about every 20 seconds. reading the code I would think it should update every second:
Thanks Tom |
November 17, 2010 by tkopriva |
just confirmed it by dividing 115200/20 = 5760, don't know why this is. I realize there are probably better ways of doing this, but would like to understand what is happening here. Thanks Tom |
November 17, 2010 by mrobbins (NerdKits Staff) |
Hi Tom, The ADC clock rate is 115200 Hz, but if you take a look at pages 249 and 250 of the ATmega168 datasheet, you'll see that it takes 13 ADC clock cycles to do a conversion, so that's about 8861 per second. (This is a "successive approximation analog to digital converter", so it needs one ADC clock cycle for each of the 10 bits of its output, plus a few extra for setting things up etc.) If you're now counting up to average over 115200 samples, that should take roughly 13 seconds. Mike |
November 18, 2010 by tkopriva |
Thank You that helps a lot! From what I understand interrupts are the better way to keep time. You have a good example--realtimeclock1.c which I have been learning from. What I do not understand is why I can not change OCR0A – Output Compare Register A to 1439 or 14399 and get a .1 or 1 second clock. I just seem to get the same frequency. See code below where I try to get readings every .1 second and still get a frequecy of .01 second:
|
November 18, 2010 by mrobbins (NerdKits Staff) |
Hi Tom, Timer0 is a 8-bit timer, so just like a uint8_t variable can only count from 0 to 255, the 8-bit timer module can only count to 255 as well. That's why changing OCRA to 1439 or 14399 won't do what you expect. However, Timer1 is a 16-bit timer which can count from 0 to 65535, so you might be able to make that do what you want! Mike |
November 20, 2010 by tkopriva |
Thanks for all the help! I have now successfully created a program to output temperature readings on second intervals. The issue I have is since I am using a mod operator in the while loop, I am rolling the dice whether on when I get a match (see code). What I end up getting is read outs at 9, 21, 35 seconds for example. I realize the issue, but do not know how to fix it. I tried putting the if statement inside:
However, I get errors since the printf statement contains variables that are not yet defined.
Can someone give me some pointers on how to properly use the interrupts to output temp readings on second intervals? Here is the all the code:
|
November 21, 2010 by hevans (NerdKits Staff) |
Hi tkopriva, A solution for your mod time problem is to just keep a separate counter on your code that gets updated at the same time the_time does, however you just reset this one to 0 every time you write out to the serial port. Then do something like:
This way you won't miss your time target by much, Is there a specific reason you are trying to only output the temperature once per second? If all you are doing is trying to have a time stamped temperature reading, I would suggest just sending out the temperature down the serial port as fast you can. Then on the python side you can average those readings and just write them out to the file once per second. This would also allow you to write the time out using your python would would let you get day month year and an accurate time. I'm not trying to discourage your approach if you wanted to do it so you could know how, but it might be easier to do it on the PC side. Humberto |
November 21, 2010 by tkopriva |
I am not particularly attached to doing it on the C side. It sounds like doing it on the PC side is more the better approach. I am brand new to python programming. I have a basic script that writes the serial input to file. Is there a module/function in python that time stamps the serial inputs? or is it better to send in the time with the temperature reading.
The comment I am most intrigued in is averaging the temperature readings over each second. Would this be figured out by some sort of module that works off the PC clock? Or are you thinking along the lines of an algorithm that takes all temperature readings for a given second identified by the serial input (how ever many that may be) and averaging them? My input currently is:
Thanks! Tom |
November 21, 2010 by hevans (NerdKits Staff) |
Hi tkopriva, The datetime module in python that does an awful lot of the time and date manipulations for you. Here are a few examples of how you might use it:
There are also ways to format a time to your liking, check out the strftime() section at the bottom of the documentation page I linked you to.
Would print out the year month day. You can format a time the way you want it, then print it out to the file right before you print out your temperature reading. Hope that helps. Humberto |
November 21, 2010 by tkopriva |
That gives me plenty to work with, thanks you for all the examples! Tom |
December 06, 2010 by tkopriva |
Hi Humberto, I went ahead and created some code to average the temperature readings on the PC side using python. Everything seems to work well for awhile until I get the following traceback error: line 19, could not convert string to float. It is perplexing since it works for awhile before crashing. Can you give me a type how to make my python code more stable (I am using v2.7)? See below for all the related code and some successful output before the inevitable crash:
and the pertinent microcontroller code is:
text file output:
|
December 06, 2010 by tkopriva |
Update: I read that readline() has some issues with pySerial. I used read() instead and am having better success. However, still wary that I may set up an eight hour test just to find out it has crashed several hours into it! In python I changed readline to:
and in my microcontroller program changed the output to:
Tom |
December 07, 2010 by hevans (NerdKits Staff) |
Hi tkopriva, I think your best bet in this situation is to use try/except (exception handling) blocks to just ignore any data that doesn't make sense.
Strictly speaking this is not fantastic programming practice. If you wanted to be good about it you would catch the particular exception you were expecting. For more about exceptions in Python you can check out the official python exception documentation. Hope that helps. Humberto |
December 07, 2010 by tkopriva |
Thanks Humberto! If I didn't want to print or do anything upon an exception, can I leave the except blank?
or will this cause issues? Thanks Tom |
December 07, 2010 by tkopriva |
never mind the last question, I can't think of a case were I wouldn't want feedback when except executes Thanks Tom |
December 08, 2010 by hevans (NerdKits Staff) |
Hi tkopriva, It is generally good practice to print something out somewhere upon exception. You could have a different log file to log errors only. But in case anyone else wanders on this thread with the same question there is a way to have an empty except block in Python with the keyword pass.
|
January 15, 2011 by SirHobbes3 |
Ok, so im doing the tempsensor project and i need some help. Take a look at the screenshot below. I recieve the error shown in the command prompt window, HELP! |
January 15, 2011 by Rick_S |
Nerdkits Guide Pg 42 Step 10b.
|
January 17, 2011 by SirHobbes3 |
ok, i changed the com port in the makefile and it works beautfully! thanks guys! SirHobbes3 |
Please log in to post a reply.
Did you know that one NerdKits customer discovered that his hamster ran several miles in a night using his kit and a Hall-effect sensor? Learn more...
|