UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« on: May 25, 2012, 10:20:58 am » |
Hi guys, Had an Arduino (Uno) for a while now, but never used these forums. I've got a simple sketch reading the output of an LM35 temp sensor to define the PWM duty cycle of an output to control a fan. I'm also outputting the temperature via serial to the serial monitor. I've got a delay(200) at the end of the loop so that the temp is only sent once every 1/4s, however - I've just noticed, this is holding up the entire loop for that time too. Now - I'm well aware temp sensors take a while to respond, and so waiting such a time isn't actually a problem here at all, the system responds perfectly well... but, for future reference - how do I send the temp via serial at set intervals, yet not hold up the rest of the loop from, well - looping again! Furthermore, as you can see in the code - I've got the temp, and "deg C" on two different prints, followed by a blank println - how can I get these two little snippets to appear on the same line in the serial monitor, with one line of code. I thought maybe Serial.println(temp, "deg C"); may work, but not so. Many thanks in advance! int tempPin = 1; // defines the LM35 input into analogue pin 1 int valFan = 0; // creates an integer used for temperature mapping, this being mapped fan speed - default to 0 int fanPin = 9; // defines the fan output connected to digital pin 5 int onboardLED = 13;
void setup() { analogReference(INTERNAL); // sets ADC ref voltage to internal 1.1v to increase resolution pinMode(fanPin, OUTPUT); // defines fanPin as an output pinMode(onboardLED, OUTPUT); // defines onboardLED as an output digitalWrite(onboardLED, LOW); // turns off onboard pin 13 LED Serial.begin(9600); // initialises serial comms at 9600 baud rate digitalWrite(fanPin, HIGH); // pulses fan output to max delay(250); // waits 250ms digitalWrite(fanPin, LOW); // then switches output to fan off before commencing loop, helps to kickstart sticky fans into motion at low PWM duty cycles }
void loop() { valFan = map(analogRead(tempPin), 0, 500, 0, 255); // used to map valFan between 0 and 255 for PWM, between 2 and 55 degrees C (LM35 output = 0v @ 2deg C, + 10mV/degC) valFan = constrain(valFan, 0, 255); // sets limits of valFan analogWrite(fanPin, valFan); // write PWM to fanPin int temp = (1.1 * analogRead(tempPin) * 100 / 1024); // converts analog reading into degrees C Serial.print(temp); // prints to serial monitor Serial.print(" deg C"); Serial.println(""); delay(200); // updates serial monitor every 200ms (+ miniscule execution time of the rest of the loop) }
|
|
|
|
« Last Edit: May 25, 2012, 10:24:04 am by jtw11 »
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #1 on: May 25, 2012, 10:23:15 am » |
Check the blink without delay example to see how to perform an action at every given interval without using delay(). Furthermore, as you can see in the code - I've got the temp, and "deg C" on two different prints, followed by a blank println - how can I get these two little snippets to appear on the same line in the serial monitor, with one line of code. I thought maybe Serial.println(temp, "deg C"); may work, but not so.
Serial.print("This "); Serial.print("prints on "); Serial.println("the same line!");
|
|
|
|
« Last Edit: May 25, 2012, 10:25:52 am by Arrch »
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #2 on: May 25, 2012, 10:28:50 am » |
Serial.print("This "); Serial.print("prints on "); Serial.println("the same line!"); Sorry, the question was worded a little strange - what I meant is, using the code the way I've written it does print "32 deg C" for example on a fresh serial monitor line each time, I meant is there a command so that I can code it in one line, in the program, itself.
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #3 on: May 25, 2012, 10:31:17 am » |
Sorry, the question was worded a little strange - what I meant is, using the code the way I've written it does print "32 deg C" for example on a fresh serial monitor line each time, I meant is there a command so that I can code it in one line, in the program, itself.
sprintf() function will allow you to format a null terminated char array (string) with variables.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #4 on: May 25, 2012, 10:41:42 am » |
Brilliant, just tested the new code without a delay (set serial output to 20 seconds for test) - and it everything else responds instantly. Thanks very much! Here's the code if you're interested. Will look into cleaning up the serial commands themselves though. int tempPin = 1; // defines the LM35 input into analogue pin 1 int valFan = 0; // creates an integer used for temperature mapping, this being mapped fan speed - default to 0 int fanPin = 9; // defines the fan output connected to digital pin 5 int onboardLED = 13; long previousMillis = 0; long interval = 20000;
void setup() { analogReference(INTERNAL); // sets ADC ref voltage to internal 1.1v to increase resolution pinMode(fanPin, OUTPUT); // defines fanPin as an output pinMode(onboardLED, OUTPUT); // defines onboardLED as an output digitalWrite(onboardLED, LOW); // turns off onboard pin 13 LED Serial.begin(9600); // initialises serial comms at 9600 baud rate digitalWrite(fanPin, HIGH); // pulses fan output to max delay(250); // waits 250ms digitalWrite(fanPin, LOW); // then switches output to fan off before commencing loop, helps to kickstart sticky fans into motion at low PWM duty cycles }
void loop() { valFan = map(analogRead(tempPin), 0, 500, 0, 255); // used to map valFan between 0 and 255 for PWM, between 2 and 55 degrees C (LM35 output = 0v @ 2deg C, + 10mV/degC) valFan = constrain(valFan, 0, 255); // sets limits of valFan analogWrite(fanPin, valFan); // write PWM to fanPin unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { previousMillis = currentMillis; int temp = (1.1 * analogRead(tempPin) * 100 / 1024); // converts analog reading into degrees C Serial.print(temp); // prints to serial monitor Serial.print(" deg C"); Serial.println(""); } }
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #5 on: May 25, 2012, 11:01:49 am » |
Looks good.
As good practice, I would also make the pins and interval constants.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #6 on: May 25, 2012, 11:35:01 am » |
Looks good.
As good practice, I would also make the pins and interval constants.
Sorry - not quite with you. Are you referring to the 'long interval = 20000"? ...and as for the pins?
|
|
|
|
« Last Edit: May 25, 2012, 11:39:03 am by jtw11 »
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #7 on: May 25, 2012, 11:43:09 am » |
Sorry - not quite with you. Are you referring to the 'long interval = 20000"? ...and as for the pins?
Yes. It's not going to make a difference with your current code, but it's good practice to define them as constants if there is no plan to change them within the code.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #8 on: May 25, 2012, 12:22:47 pm » |
Hmm - nope, still not got it!  Do you mean, as opposed to 'long interval', write 'long const interval'? 'const interval' throws an error at me. As for pins, what isn't quite best practice? You'll have to excuse me - before Arduino, I had no experience whatsoever with any C variant.
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #9 on: May 25, 2012, 12:29:33 pm » |
Do you mean, as opposed to 'long interval', write 'long const interval'? 'const interval' throws an error at me.
const unsigned long interval =
As for pins, what isn't quite best practice? Not sure what you mean by that. Something like: const int tempPin = 5; would be best practice. You could also change it to a short, but I don't know which way the compiler handles constant declaration, so I'm not sure if that's necessary.
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #10 on: May 25, 2012, 12:43:50 pm » |
Ah okay, I see where you're coming from. const int tempPin = 1; // defines the LM35 input into analogue pin 1 int valFan = 0; // creates an integer used for temperature mapping, this being mapped fan speed - default to 0 const int fanPin = 9; // defines the fan output connected to digital pin 5 const int onboardLED = 13; long previousMillis = 0; const unsigned long interval = 500; What exactly is the benefit to defining pins and intervals in this way?
|
|
|
|
|
Logged
|
|
|
|
|
Global Moderator
UK
Offline
Brattain Member
Karma: 138
Posts: 19067
I don't think you connected the grounds, Dave.
|
 |
« Reply #11 on: May 25, 2012, 12:47:22 pm » |
If there are lots of references to them, there's only one place to change them if you decide to move a pin, or need a little longer to do something.
|
|
|
|
|
Logged
|
Pete, it's a fool looks for logic in the chambers of the human heart.
|
|
|
|
UK
Offline
Sr. Member
Karma: 1
Posts: 313
|
 |
« Reply #12 on: May 25, 2012, 12:52:21 pm » |
If there are lots of references to them, there's only one place to change them if you decide to move a pin, or need a little longer to do something.
I see what you're trying to say, but using 'int tempPin = 1;' for example, I simply reference tempPin in the program, and if I want to change the pin, I just change the 1 for something else. So why, ' const int tempPin = 1;' instead of the old 'int tempPin = 1;'?
|
|
|
|
|
Logged
|
|
|
|
|
UK
Offline
Edison Member
Karma: 45
Posts: 2260
What a host of balls she had seen: gaity, the brass buttons...
|
 |
« Reply #13 on: May 25, 2012, 12:56:16 pm » |
So why, 'const int tempPin = 1;' instead of the old 'int tempPin = 1;'? The "const" tells the compiler the value will never change. Therefore, instead of allocating a variable and taking up valuable RAM space, and slowing the system down reading and writing from RAM, it just uses the number "1". It's functionally the same as #define tempPin 1
but has the advantage that it is typecast to an int.
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 41
Posts: 1888
|
 |
« Reply #14 on: May 25, 2012, 12:57:00 pm » |
If there are lots of references to them, there's only one place to change them if you decide to move a pin, or need a little longer to do something.
I see what you're trying to say, but using 'int tempPin = 1;' for example, I simply reference tempPin in the program, and if I want to change the pin, I just change the 1 for something else. So why, ' const int tempPin = 1;' instead of the old 'int tempPin = 1;'? If you mess up and change that value somewhere in your code, your code will still compile fine, but you're likely to see logic errors. By defining it as a constant, you're compiler will throw an error if you mess up and try and change the value in the code and it's A LOT easier to debug compiler errors than it is logic errors.
|
|
|
|
|
Logged
|
|
|
|
|
|