NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Tempsensor Variation Problem

May 21, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Hi. I'm new to Nerdkits. I don't know much about C (but I've used Easy-C)and I don't know much about electronics, just pretty basic stuff. I made a change to the tempsensor program to make it display celsius too. Her's the program: http://dylandylanjkjk.kirdahy.googlepages.com/code What's wrong with it?

May 21, 2009
by Guss
Guss's Avatar

I made a similar change when I initially built the Tempsensor project.

I see you have a function

double FtoC{
    return sample * ((temp_avg-32)*5/9=Celsius_temp);
 }

but I don't see where you call it. Also, it does not accept any variables to calculate with.

First, the FtoC function should occur before main() (unless you use a prototype). Next the function should read:

double FtoC(double f)
{
    return ((5.0/9.0) * (f - 32.0));
    // where f is the fahrenheit value
 }

Next, include:

    //convert to Celcius
    Celcius_temp = FtoC(temp_avg);

after the for loop, which reads the sensor and calculates the average temperature (f).

On a side note, general convention in C is to use lower case for function and variable names. Only use capitals for constants (NULL, EOF, etc) and in a few other special cases (a bit rusty on the other rules.)

May 21, 2009
by mcai8sh4
mcai8sh4's Avatar

Welcome, and thanks Guss... I had just finished typing my response, basically saying the same thing as you (but not as clear :P ), then my feed reader popped up showing me that you'd already answered.

Anyway, dylanjkj1997, welcome. I can't really add anything more than Guss has already said, play around and see how you get on. If you get stuck again, I'm sure someone will be able to help.

Once I finished the temperature sensor example, I also added the dipswitch to the board so I could change the display to either deg C or deg F by flicking a switch. I also added a couple of LEDs - to alert me when the temperature was above whatever I had set. The dip switch turned these LEDs on or off (to conserve the battery).

Whilst this sounds quite simple and daft, I found it very useful in practicing programming, following code and getting a better understanding of the electronics. After a short while of being slightly confused, you'll soon get the hang of programming the basic stuff - after that the real fun can begin.

Best of luck

May 21, 2009
by dylanjkj1997
dylanjkj1997's Avatar

It still doesn't work. I updated the file on the webpage. The compiler gives me an error code still. I put a picture of the error and the updated code on that webpage.

Thanks!

May 21, 2009
by Guss
Guss's Avatar

Looking over your new code, and the errors, I see on line 91 you define double celcius_temp (lower case C)

On line 105 you call the function Celcius_temp = FtoC(temp_avg); (uppercase C)

On line 120 you output fprintf_P(&lcd_stream, PSTR("%2f Celcius"), celsius_temp) with the variable celsius-temp (lower case C and an s in the middle.)

G

May 22, 2009
by mcai8sh4
mcai8sh4's Avatar

Also, you seem to have two FtoC() functions. You can remove (or just comment out) the first one.

I've only managed a quick look at your updated code (I should be working), but I would also recommend you move the line :

Celcius_temp = FtoC(temp_avg);

outside (below) of your 'for' loop, this way it reduces the number of calculations. You will then have 100 samples being read and converted to deg F, then once you have your average temp, then you can convert and display. (I hope that makes sense)

Guss has already told you about the spelling and mixed use of capital letters, remember variables and functions are case sensitive.

The final thing I have noticed is the

return 0;

is also within your main while(1) loop, the return 0 should never be reached - I think this is mentioned in the nerdkits guide. So move that outside of the while loop.

You are also missing a '}' to close main(). So at the very bottom of your progam add a final '}' and I think you should be good to go!

(as an alterniative to moving 'return 0;' and adding a final '}', you could just place a '}' on the line above 'return 0;' you would end up with exactly the same code.)

Good luck, let us know how you get on.

May 22, 2009
by Kevin
Kevin's Avatar

to display the temp in degrees C I did the following

// write message to LCD
lcd_home();
fprintf_P(&lcd_stream, PSTR("Temperature: %.1f"), (temp_avg));
lcd_write_data(0xdf);
lcd_write_string(PSTR("F   "));
lcd_line_two();
fprintf_P(&lcd_stream, PSTR("             %.1f"), (temp_avg-32)*.5556);
lcd_write_data(0xdf);
lcd_write_string(PSTR("C   "));
May 24, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Yay! I got it! I did a variation of what Kevin said. Thanks to everyone who helped. I'll post a pic and code ASAP. Here's what I did:

    lcd_home();
    lcd_write_string(PSTR("ADC: "));
    lcd_write_int16(last_sample);
    lcd_write_string(PSTR(" of 1024   "));
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("Temperature: %.2f"), temp_avg);
    lcd_write_data(0xdf);
    lcd_write_string(PSTR("F      "));
    lcd_line_three();
    lcd_write_string(PSTR("Celsius Temp:"));
    fprintf_P(&lcd_stream, PSTR("%.2f"), (temp_avg-32)*.5556);
    lcd_write_data(0xdf);
May 24, 2009
by dylanjkj1997
dylanjkj1997's Avatar

http://dylandylanjkjk.kirdahy.googlepages.com/workingnerdkitpictureandcode is my working setup. And also a question - can I use 12 volts on the voltage regulator? I was using 12 volts (8 rechargeable AAs)through the voltage regulator and I burnt myself on it.I used pliers to put it in the freezer. It REALLY hurt.

May 25, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Never mind that. I have another question. How can I make a blue LED turn on brighter than a red LED if it is cold and the red LED turn on more than theblue LED when it is hotter? I looked around and found that all the ground pins are connected to ground and the +5v is connected to the MCU pins. The problem is that the full color LED I want to use is like this:

________
l      l
l      l
l      l
--------
l 2 3 4
l 2 3 4
l 2 3 4
l 2 3 4
Pin 1 is green ground
Pin 2 is blue  ground
Pin 3 is all =4.5v
Pin 4 is red   ground

So I can't control each color individually. How can I do this if I have all the +4.5v leads together? Oh and how can I make text scroll and flash on the LCD? I'm making a youtube review of my nerdkit and I wanted to do a little advertising for my robot....

May 25, 2009
by wayward
wayward's Avatar

dylanjkj1997,

I got one of those three-color LEDs and used it to write the name of my girlfriend =)

Veronika

This was a simple hue-cycling program; I could paste some of the code, but there's no need, since it's already covered in the NerdKits' Valentine's Heart project. In essence, you keep the intensity per color channel (red, green, blue) as if you had three separate LEDs (which, in a way, is the case) and switch them on and off accordingly in a timed loop. Just get the code for the Valentine's Heart and you'll figure it out.

May 25, 2009
by wayward
wayward's Avatar

As for text effects on an LCD, grab the HD44780 datasheet and look for "display on/off" and "cursor or display shift" commands on page 24 onwards.

May 26, 2009
by dylanjkj1997
dylanjkj1997's Avatar

so what would I do with the 000001S/CR/Lā€”ā€” that I found in the PDF? How would I plug in the LED? Thanks.

BTW That picture looks awesome!

May 26, 2009
by tom8787
tom8787's Avatar

For those interested, I also did this. You can find my code here: http://www.tspforum.com/tempcels.html . I also created a Visual Basic app to capture the stream of the serial port, and then delayed it a bit, so you can monitor the temperature on your PC screen.

May 26, 2009
by wayward
wayward's Avatar

Hi dylanjkj1997,

000001[S/C][R/L] is the command you send to the LCD to tell it to move the cursor or shift the display. Further down in the datasheet, it is explained that

  • S/C: should be 0 if you want to move the cursor, 1 if you want to shift the display;
  • R/L: should be 0 if you want to move it to the left, or 1 if you want to move it to the right.

To shift the display one character to the left, the command is then:

00000110

which translates to 0x06 hexadecimal. So, somewhere in your code, you'd have:

lcd_set_type_command();
lcd_write_byte(0x06);

which should shift the display when executed. To move it in the other direction, use 00000111, which is 0x07. There are a few gotchas in the datasheet, but play with this for starters :)

Zoran

May 26, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Thanks Zoran! I'll try it and post back when my batteries charged.

PS I got the code to display Kelvin too!

May 26, 2009
by wayward
wayward's Avatar

You know what else is cool? Splice a USB cable and power your NerdKit off it. =) It gives you a clean +5V power source so you don't need a voltage regulator, and you can draw up to 100mA. Only, you're running the risk of frying your laptop if you accidentally short-circuit something on the breadboard (although Mike has cautiously informed me that he had shorted his circuits in the past with no serious consequences, but still...)

I didn't tell you anything. O:)

May 26, 2009
by wayward
wayward's Avatar

Actually, I checked the datasheet and I have to amend myself: you need to send 00011000 (hexadecimal 0x18) to shift left and 00011100 (hex 0x2c) to shift right. The rest is the same:

lcd_set_type_command();
lcd_write_byte(0x18);   // or 0x2c
May 27, 2009
by dylanjkj1997
dylanjkj1997's Avatar

The LCD scrolling didn't work. Where in my code am I supposed to put it? After, say,

lcd_line_four();

or after the text? Thanks.

PS I'll try that;^). Sounds like a much better way to get power. Just gotta make sure my laptop is plugged in.

May 27, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Got the USB thing working! Thanks, that really helped!

May 29, 2009
by dylanjkj1997
dylanjkj1997's Avatar

So where do I type in the lcd command? Is there way to associate the brightness of an LED with a value? Thanks! :^)

May 29, 2009
by wayward
wayward's Avatar

You're trying to scroll the LCD at some fixed rate, right? So you need to shift the text once every N milliseconds, where N determines the speed. For starters, try this:

// output some text
lcd_write_string(PSTR("Testing scrolling"));

// scroll it away
int i;
for (i = 0; i < 20; i++) {
  delay_ms(100);   // 100 ms delay per column
  lcd_set_type_command();
  lcd_write_byte(0x18);
}

As for the LEDs, did you take a look at the Valentine's Heart project?

Cheers, Zoran

May 29, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Thanks wayward, but how can I get just one line to scroll? ( I'm trying to get the bottom line to scroll so I can type in more than 20 characters of info about the temp sensor) Thanks! It scrolled!

May 29, 2009
by dylanjkj1997
dylanjkj1997's Avatar

PS for some reason the top line is on the third line and the third line is on top and the 2nd and last lines have switched too when it scrolls.

May 29, 2009
by wayward
wayward's Avatar

Hehe, well yes, those things about how it scrolls are explained, I think, in the datasheet. If you want to scroll just one line, you can't use hardware scrolling -- you'll have to do animation! :)

Suppose you have a longish text that you want to scroll:

char text[] PROGMEM = "This is a longish text that we are going to scroll across the display.";

If you write it to the LCD:

lcd_write_string(text);

you will get this (naturally):

[This is a longish te]

We wrote the string to the LCD starting from the first character. But we can also write it starting from any arbitrary character, too. "text" stores an address to the first character in the array, so when you do lcd_write_string(text), you are doing the right thing: you're sending the address of the first character to lcd_write_string(). Can we get to the address of the second character? Sure we can, in two ways:

lcd_write_string(text+1);    // this is not advised
lcd_write_string(&text[1]);  // this is

The ampersand & mark above means "address of"; tack it to the left of anything whose address you need. "text" is an address of the first character, but text[0] and text[1] and others are not addresses, they are characters themselves.

Putting it all together, you can try this:

#include <avr/pgmspace.h>  // for strlen_P()

...

#define LCD_COLUMNS   20

char text[] PROGMEM = "*** Long text!  And it scrolls!  Yay! ***"

// scroll it away once -- I'm sure you can figure out how to scroll it back ;)
int i = 0;
int len = strlen_P(text);  // easier than to count them by hand
while (i < len-LCD_COLUMNS) {  // from 0th to 21st character in the string...
  lcd_home();                  // go to first line...
  lcd_write_string(&text[i]);  // ...dump the string from that point onwards...
  delay_ms(100);               // 100 ms delay per column
}

This is a quick and dirty solution. For longer strings, you may have your text start to "bleed" over into the second line. Try it out, and if it works, your next challenge would be to write a function, say lcd_write_string_at_most(char *text, int size) that stops after writing "size" characters, if the string hasn't terminated by then.

Cheers, Zoran

P.S. I haven't tried this. Good luck. ;)

May 30, 2009
by dylanjkj1997
dylanjkj1997's Avatar

I got this error: alt image text

May 30, 2009
by wayward
wayward's Avatar

It looks like you copied the "..." into your program. They just mean that the line above (#include <avr/pgmspace.h>) goes near the top of your actual program, among other #include directives.

Do this instead:

  • Put #include <avr/pgmspace.h> among or below other #includes in your code.
  • Put #define LCD_COLUMNS 20 below #includes.
  • Paste the rest of the code (from "char text[] ..." to the last "}" ) at the end of your main() function (before the final closing brace). Make sure that you don't have any infinite loops above that, or the pasted code will never execute. (Infinite loops look like: "while(1) { ... }" or "for (;;) { ... }").
May 31, 2009
by dylanjkj1997
dylanjkj1997's Avatar

New error error

May 31, 2009
by mcai8sh4
mcai8sh4's Avatar

can you upload you latest code - the errors don't seem to fit the code thats on you site. (or it may just be me :P )

May 31, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Oh, sorry. Got it on!

June 01, 2009
by luisgarciaalanis
luisgarciaalanis's Avatar

dylanjkj1997 I recommend you get the book learn C in 21 days, its a good book. at least it was 15 years ago LOL!

C its not that hard, the book will teach you to do code, you could write the samples and run them on the LCD of the nerds kit. Or get a C compiler for windows, there are several.

a word of caution in come compilers if you multiply by integers it treats everything like an integer, I haven't tried this one to make sure, but "double" is not an integer, integers don't have decimal points so a 1 in integer is 1, 1 in double is 1.0, it has decimals. So its a good practice to do:

((temp_avg-32.0)*5.0/9.0);

instead of

((temp_avg-32)*5/9); <- THIS MIGHT MAKE lose the decimals of temp_avg and the result will be less exact.

June 01, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Thanks Luis. It seems to be displaying decimals on the lcd well. I'll try the code with integers and doubles. I've been thinking about getting a book about C too. The book learn c in 21 days got a good rating on amazon. Maybe I'll try it!

June 01, 2009
by mcai8sh4
mcai8sh4's Avatar

@Dylan : I'm at work at the minute, so I can't really go through it fully. It looks like just a case of re-declaring a variable.

When you type int i; it means you are delclaring variable (in this case called 'i') as an integer (whole number). You only need to declare this once - in your case you have declared it twice (line 120 and line 135). You can simply remove the second occurance and it should be ok.

It's worth noting that you have already got a variable called 'i' that is declared on line 85. For your purposes you could use this and remove the other two declaration (L120 and L135). All your variables should have different names.

'i' is commonly used for an integer (generally as a counter) - where you need more than one at the same time I would usually use 'j' (next letter in the alphabet). For simple variables like counters one letter names are fine. When you have a variable that contains more important data for your program you would give it a 'proper' name (such as last_sample).

As far as a recommendation for c programming, may I suggest the bible (in my eyes) : The C Programming Language, second edition, by Brian Kernighan and Dennis Ritchie (also know as K&R). It's very good for reference - it's always sat next to my chair in the living room. It was the advised book to buy for my course at university - it was quite expensive from what I can remember, but worth it.

So, try commenting out the 2 int i; lines and see if that works. (commenting out is good for things like this as it means you can recover it easily if required).

Hope this helps, if not then I'm sure someone with more experiance than me will solve your problems.

Good luck

June 01, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Ok, I've realized the problem. After looking at the i declarations I noticed that I also had the older scrolling code so I took that out but now it compiles BUT it says "'PROGMEM' attribute ignored". This seems to be a huge problem since the LCD displays random characters (pi, chinese and japanese stuff, symbols, normal letters, double and triple horizontal lines, and spaces)that are always the same and never move.

I always expect faliure in any technical stuff that I do so if it doesn't work it's not frustrating and when it works I'm twice as happy. I think I'll have to expect faliure more often. C seems hard!

June 01, 2009
by wayward
wayward's Avatar

Dylan, I have a book from 1997 called "The Joy of C". It's older than the C99 standard which we follow in our code, but the differences aren't that big. It looks like an in-depth introductory course. If you want, I can mail it to you for free, it's just taking up my precious shelf space.

Just come over to mcai8sh4's IRC channel #nerdkits on irc.freenode.net, I am almost always logged on. But do be quick as I am leaving the country in eight days and won't be back until August. :)

Zoran

June 02, 2009
by dylanjkj1997
dylanjkj1997's Avatar

I'm going to order teach your self C in 21 days because it got pretty good reviews. I asked my dad if he can see if the barnes and nobles near were he works has it or any other books on C. Thanks for the recomendation!

June 04, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Is teach yourself C in 24 hours similar to teach yourself c in 21 days?

June 05, 2009
by TBNK
TBNK's Avatar

Dylan, I think "Teach Yourself C in 24 Hours" will be just fine for programming with the NerdKit. I have seen precious little use in this environment of pointers, linked lists, structures, disk files, memory allocation, and other, more advanced topics that the "21 Days" version has in it. In fact, the "24 Hours" version may well be better suited for MCU programming than the 878 page copy of "21 Days" I have in front of me now.

June 05, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Thanks! I went ahead and opened the CD, Now I'm installing. C in 21 days sounds pretty long. 500 pages is a good enough amount for a middle-schooler! Thanks for the suggestion :)

June 06, 2009
by wayward
wayward's Avatar

Dylan, C in 21 days is actually very fast :) If you manage to go through the book in 21 days, you'll have a working understading of C, but how to put things together is something you just keep learning until you're an old geezer of 30 like me, and onwards. It's very enjoyable, though, so have fun -- and keep us posted on your progress! We're here to help :)

June 06, 2009
by dylanjkj1997
dylanjkj1997's Avatar

Unfortunately, Borland hasn't emailed me back yet. I want to be able compile the programs and test them before I move on. I'm going to try to use the Nerdkit programmer. Some people said Borlan hasn't emailed me back yet.

Thanks Wayward, I'll be sure to post my progress.

BTW I'm actually working on a big project. It's called the Flexx. It was originally called the flexx AIR(autonomous and interactive robot) because of this: this I got this working: here (back then I had a really bad voice on camera and I still do now a bit) Then the next upgrade: here Then this, and finally, we are here lol I know that's a lot. I wanted to show you the last one but put the rest there in case you guys wanted to see them. Forum and website

June 11, 2009
by dylanjkj1997
dylanjkj1997's Avatar

It's been a week and Borland STILL hasn't emailed me the compiler. :^(

December 06, 2009
by pbfy0
pbfy0's Avatar

the finished product should be here

Post a Reply

Please log in to post a reply.

Did you know that 20 LEDs can be controlled from 11 microcontroller pins, to make a twinkling heart outline? Learn more...