Pages: 1 [2] 3   Go Down
Author Topic: Serial print refresh time  (Read 2114 times)
0 Members and 1 Guest are viewing this topic.
UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Also, in reply to how to join your strings together into one print - you can use sprintf to build up a string before printing to serial:

Code:
char buffer[80];

// ...

sprintf(buffer,"The temperature is %f degrees C", temperature);

Serial.println(buffer);

where %f is a placeholder for a "float" or "double" variable - there are others for other variable types - plenty of references online.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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

Code:
#define tempPin 1

but has the advantage that it is typecast to an int.

Aha, that's the explanation I was looking for! (thanks to everybody else too!) On that subject, are there any other ways to reduce the program size, as this sketch actually forms part of a complete automated engine dyno control program.
Logged

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
are there any other ways to reduce the program size

Yes.  Write it in assembly instead of C++.

But seriously, some tips:

1. Avoid float / double - the floating point library adds loads of bulk.
2. Don't use variables bigger than you need.  The processor is 8-bit.  Anything bigger than a BYTE or CHAR uses extra instructions to emulate a larger value.
3. Think about the flow of your program.  Write it tight, and the resultant program will be tight.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Having taken snippets and applied them for use in my code from the 'blink without delay' example, could somebody please explain to me the use of 'unsigned long' in place of 'int'? It seems 'int' takes up just a few bytes more, but I'm not sure what 'unsigned long' really is, or indeed why the example uses it. English please?  smiley-grin

Quote
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;
Logged

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The "const unsigned long" is just seen as (and takes up the room of) 500.

However, when it's being used in comparisons, it's being combined with / compared against other values that are unsigned long.  This just helps the compiler to know what it's doing so it doesn't get confused between different length variables.

For example, if you subtract an int from a long, should the result be an int or a long?  If you're putting it in a variable, then it's whatever the destination variable is cast as.  If you're just using it as a comparison, what then?  By telling the compiler it's an unsigned long, it's telling it that the value is of the same type as that returned by the millis() function.

Unsigned long is twice as big (RAM wise) as an int.  As it's a "const" though, it doesn't use RAM.

Byte, char - 8 bits.
Int, short - 16 bits.
Long - 32 bits.
Long long - 64 bits.

(the "unsigned" doesn't affect the size, just the range of the content)

Oh, and
Code:
long previousMillis = 0;

should really be
Code:
unsigned long previousMillis = 0;

to keep the signs the same.
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, I was just about to ask that question - one signed, one unsigned. So, I've changed them to both signed - but embarrassingly, I still don't understand the different between signed and unsigned, i'm aware one can contain neg values whilst the other can't. I can't sit here with a command in my code that I don't really know why it's there, even if it works.

I completely understand why I've made some of 'const', so as to prevent the controller putting things in and out of RAM unnecessarily.

I think maybe i'm confused between bytes, ints & longs. Which do I actually need to use here for the millis and intervals. I can't see why I need to sign, or unsign either.

EDIT: Aha, the table on this page seems to explain it! http://www.cplusplus.com/doc/tutorial/variables/

Well no, not really actually - because surely I can just use a 'short' instead, as the value is between 0 and 65535. Then signed or unsigned is simply a sign convention thing. Correct?

All help up until now greatly appreciated!
« Last Edit: May 25, 2012, 03:55:38 pm by jtw11 » Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Given two values
Code:
unsigned short a = 0xD5;
signed short b = 0xD5;

a is interpreted as 213
b is interpreted as -43

This is important in comparison, multiplication, division operations as well as conversions for stuff like Serial prints because how it's interpreted would affect the result.

Addition, subtraction and bitwise operations don't care as the result (in binary) is the same no matter how it's interpreted.
« Last Edit: May 25, 2012, 04:02:21 pm by Arrch » Logged

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Given two values
Code:
unsigned short a = 0xD5;
signed short b = 0xD5;

a is interpreted as 211
b is interpreted as -43

Am I missing something here, where have the Ds come from?
Logged

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Am I missing something here, where have the Ds come from?
0xD5 is the hex representation of 213 and -43.

Edit: D5 is 213, not 211.
« Last Edit: May 25, 2012, 04:02:56 pm by Arrch » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24322
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The whole example is nonsense.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

New Hampshire
Offline Offline
God Member
*****
Karma: 13
Posts: 779
There are 10 kinds of people, those who know binary, and those who don't.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah, I was just about to ask that question - one signed, one unsigned. So, I've changed them to both signed - but embarrassingly, I still don't understand the different between signed and unsigned, i'm aware one can contain neg values whilst the other can't. I can't sit here with a command in my code that I don't really know why it's there, even if it works.

You should make them unsigned, not signed.  millis() and micros() will never return a negative value.  Look at the reference of a function to see it's return type.  9 times out of 10, that's the data type you want to store the value into.

millis() and micros() return an unsigned long, so you should store the value in an unsigned long.  Otherwise you will eventually run into problems.

Both signed and unsigned long store their values in 4 bytes.  So they have the same storage capacity, but they don't haverepresent the same range of values they can store.  Because unsigned long only stores positive values, it can store twice as many positive values as signed long, because half of signed long's values are negative.

A smaller scale example:
byte is an 8 bit unsigned type, so it can store any value from 0 to 255.  If you try to store the value 256 in it, you will get an overflow and the actual value stored in it will be 0.  If you try to store 257 in it, the actual value stored will be 1.
char is an 8 bit signed type.  It stores values from -128 to to 127.  It still has the same storage capacity, 256 discrete values, but a different range.  However, if you have a function that returns a byte value, and you attempt to store it in a char, if that byte value is greater than 127, it will not be properly represented by the char type.  The bit pattern will be stored exactly the same, but the representation will be different.  Operations on the char value will likely have undesirable results.
« Last Edit: May 25, 2012, 04:18:50 pm by jraskell » Logged


Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24322
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Arch,
You need to show how
Code:
signed short b = 0xD5;
gets sign extended to a negative number to -43.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
God Member
*****
Karma: 1
Posts: 530
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


You should make them unsigned, not signed.  millis() and micros() will never return a negative value.  Look at the reference of a function to see it's return type.  9 times out of 10, that's the data type you want to store the value into.

millis() and micros() return an unsigned long, so you should store the value in an unsigned long.  Otherwise you will eventually run into problems.


Got it, I think! So, can I do the following; use a short for the interval, as the interval is constant at 500?

Code:
unsigned long previousMillis = 0;
const unsigned short interval = 500; // creates 500ms interval in which to update serial

So as for defining pins as ints, can I not define pins as chars, as they are between 0 and 255 - to save space? For example;

Code:
const short tempPin = 1; // defines the LM35 input into analogue pin 1
short valFan = 0; // creates an integer used for temperature mapping, this being mapped fan speed - default to 0
const short fanPin = 9; // defines the fan output connected to digital pin 5

Or is this not seen as best practice, if not - why?

EDIT: Changed my entire code to the following, and tested - works exactly the same, but the program size is exactly the same replacing the ints with shorts. I thought a short was 1 byte, and int was 2 bytes?

Code:
/*
Uses an LM35 to sense temperature, and drive a cooling fan accordingly.
 
by Julian West http://uk.linkedin.com/pub/julian-west/26/a42/a02
*/

const short tempPin = 1; // defines the LM35 input into analogue pin 1
short valFan = 0; // creates an integer used for temperature mapping, this being mapped fan speed - default to 0
const short fanPin = 9; // defines the fan output connected to digital pin 5
const short onboardLED = 13; // defines onboard LED as pin 13
unsigned long previousMillis = 0;
const unsigned short interval = 500; // creates 500ms interval in which to update serial

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(); // count milliseconds and assign to currentMillis
  if(currentMillis - previousMillis > interval) // decides if current millis is greater than interval
  {
    previousMillis = currentMillis;
    short 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("");
  }
}
« Last Edit: May 25, 2012, 04:20:06 pm by jtw11 » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24322
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So as for defining pins as ints, can I not define pins as chars
No, the type accepted by pinMode, digitalWrite etc for pin numbers is unsigned.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

UK
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3969
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I thought a short was 1 byte, and int was 2 bytes?

No, a short is 2 bytes.

It's specifically 2 bytes on all systems regardless of word size.

On a 32-bit system an int is 4 bytes, but a short is still 2 bytes.

On an 8-bit system like the AVR an int is 2 bytes emulated as 2 individual bytes with extra code to operate on both as a single digit.  A short, not surprisingly, is 2 bytes - exactly the same as an int.

As for negative numbers, you need to understand "two's complement", which is how processors and microcontrollers represent negative numbers.

Wikipedia has a page on it here: http://en.wikipedia.org/wiki/Two%27s_complement
Logged

Why not visit my eBay shop? http://stores.ebay.co.uk/Majenko-Technologies
Replacement for the Arduino IDE: UECIDE - Proper serial terminal, graphing facilities, plugins, overhauled internals.
Java isn't bad in itself, but it has enabled morons to write programs.

Pages: 1 [2] 3   Go Up
Jump to: