Using analogRead(0) or analogRead(A0)?

The Arduinoreference can be a bit obscure about the proper use of pin numbers on the analog pins. Should you for example use analogRead(0), or analogRead(A0), afterall if u use “0” wouldn’t that refer to the digital pin ‘0’?

Well, no worries about that: analogRead(0) and digitalRead(0) will read from two different places. The former will read from analog channel 0 or A0 and the latter will read from pin 0 which happens to be a digital pin. The Arduino KNOWS the difference between digitalRead(0) and analogRead(0) because of the difference in commands.

However, the analogpins can also be used as digitalpins and in that case ofcourse the Arduino doesnt see the difference between ‘0’ and ‘0’ (nor can you) so in that case you should use digitalRead(A0) or its ‘digital’ pin number as in digitalRead(14).

The analog pin definition code for the Arduino Uno can be found in thefile hardware/arduino/avr/variants/standard/pins_arduino.h

static const uint8_t A0 = 14;
static const uint8_t A1 = 15;
static const uint8_t A2 = 16;
static const uint8_t A3 = 17;
static const uint8_t A4 = 18;
static const uint8_t A5 = 19;
static const uint8_t A6 = 20;
static const uint8_t A7 = 21;

So, to summarize, for analogRead you can use the following:

  • analogRead(0); // channel number
  • analogRead(A0); //pin number

for a digitalRead on analogpin A0, you have to use one of the following:

  • digitalRead(A0); // channel number
  • digitalRead(14); // pin number

for digitalWrite on analogpin A0, you should use one of the following:

  • digitalWrite(A0,x); // channel number
  • digitalWrite(14,x);// pin number

The analogWrite command ofcourse is a different story as that only has a function on the PWM pins. The analogWrite() command can be called on any of the pins, but it only does something on the PWM pins. On non-PWM ditial pins and all analog pins, it simply calls digitalWrite(). The analogRead command ONLY has a function on the analog pins.

OK that is clear. A source of confusion however may be the use of constants. For instance if you want to read the value of an LDR on analogpin 0, but you like to use a constant so you can refer to the port by a name like ‘LDRpin’.
Well, again, both of the following definitions will work:

  • const byte LDRpin=0;
  • const byte LDRpin=A0;

and then followed by: analogRead(LDRpin);
The problem however comes when you start using that constant for other commands on that pin, like ‘pinMode’.
It isnt always necessary to set pinMode as usually when you use analogRead your Arduino will understand you are doing a read function, but suppose you want to use the internall pull-up resistor on A0, so you dont need an external resistor for your resistor-LDR voltage divider.
If you would do:

const byte LDRpin=0;
followed by:
pinMode(LDRpin, INPUT_PULLUP);
analogRead(LDRpin);
you will get false readings as you haven’t set the pull up resistor on pin A0, but on pin 0 which is a completely different (digital) pin. You will not only get false readings on A0, but may have completely false function on digital pin 0 as well.
Sure, that would also happen if you are not using a constant, but chances are that when you write pinMode(0,INPUT_PULLUP), you immediately realise something is wrong.

So that is one reason why it is better to always use ‘A0’ ( or A0…A5 for that matter).
ofcourse using
const byte LDRpin=14;
also is not a good idea as that would get the right pin in “pinMode” but not in analogRead. Using the pinnumber “14” is also not a good idea with regard to portability. Yes, 14 refers to pin A0, but not in all arduino’s

For comparaison here is the analog pin definition code for the Arduino Mega:

static const uint8_t A0 = 54;
static const uint8_t A1 = 55;
static const uint8_t A2 = 56;
[…]
static const uint8_t A13 = 67;
static const uint8_t A14 = 68;
static const uint8_t A15 = 69;

 

 

Advertisement

The Arduino and Daylight saving time

wintertijd It is that time of the year again that many countries will end the Daylight Saving Time.
But what about your microcontroller? Many programs on the arduino and other microcontrollers keep time and do that with one of the popular RTC chips such as the DS1307 or the DS3231. They keep time very well (but I prefer the DS3231) and there are a hoist of libraries available for them.
One thing they do not do is to automatically between standard time and daylight saving time (DST). Obviously that would be quite hard as  there are different DST conditions all over the world

Though one could of course reset the RTC chip manually twice a year but that is tedious, especially while it can easily be solved with a few lines of code.

Different parts of the world have different rules for when the daylight saving time takes place and many countries of course have no daylight saving: It only makes sense (if at all) to do it between the tropics and the Arctic circles, so in fact between the tropic of Cancer and the Arctic circle and the tropic of Capricorn and the Antarctic circle.

In Australia daylight saving time is a matter of the states and territories but in general daylight saving time is between the first sunday in oktober and the first Sunday in April (remember, it is down under)

In Canada it largely depends on where you live, some states follow the United states. Newfoundland en Nunavut have their own rule and many of the northern territories do not have daylight saving time

The USA has daylight saving time from the 2nd Sunday of March till the first Sunday of November.

The EU of course has a guideline on it that determines the daylight saving time to start on the last Sunday of March and to end on the last Sunday of October. In the EU the hour to switch is at 01:00 UTC. In practice UTC is equal to GMT (Greenwich Mean Time). UTC itself is not an abbreviation but a compromise between the French abbreviation “TUC” and the English “CUT” (Temps Universel Coordonné resp Coordinated Universal Time).

At 1:59 AM the DST is still OFF (“Uit”), then 1 min later the DST is set and it is 3:00 AM

Catering for your local daylight savings program is usually quite easy:
Let your program check for the proper month and then count the number of Sundays (the change is usually on a Sunday). When you arrived at the
required Sunday check the time and if it is say 2 am, advance the clock an hour (=set it to 3) if DST has to start, or wait till 3 am and reset the clock hours to ‘2’.
Obviously you also need to set a flag to do the clock correction only once.

Simple enough… Unless you live in the EU (or Nunavut). In the EU the switch isn’t made at the first, second, third or fourth Sunday in March resp. October, but at the LAST Sunday of the month.

Well, a month has four Sundays right? Wrong. If for instance October starts on a Friday, Saturday or Sunday, it has 5 Sundays. So what to do?
Well you could of course determine if the first day starts on Friday, Saturday or Sunday and if so, count to 5 and otherwise count to 4. But there is a simpler way, in which you don’t even have to count.

Lets put that in a program for Western Europe, which means that the switch times are 2 and 3 am (that is 1:00 UTC)

Let’s agree that you have an RTC that will keep the “day of week” *as the DS1307 and the DS3231 do). As you set these yourself lets agree that you have set the day of week such that Monday is day 1 and Sunday is day 7. Some people like to start the week on Sunday, but that is just a matter of taste.
Anyway, we have the following variables read from our RTC
dow= day of week (as in 1-7)
mo=month
d=day (as in 1-31)
h=hour
DST is a flag we set when DST starts and that we clear at the end of DST to avoid that the program starts correcting the time for a full hour and even getting in an endless loop when we set the clock back
As October has 31 days, we know that the last Sunday will always fall from the 25th to the 31st
So our check at the end of daylight saving will be as follows:

if (dow == 7 && mo == 10 && d >= 25 && d <=31 && h == 3 && DST==1)
{
setclockto 2 am;
DST=0;
}

As you may be using different libraries the command ‘setclockto 2 am’ is just a place holder for your specific routine to set your RTC to 2 am. I would advise to store the DST flag somewhere in non volatile memory, in case you need to unplug your arduino.
The DS1307 has some on chip Non Volatile RAM where you can store it, the DS3231 does not. Both however usually come as a module with an EEPROM on it as well, otherwise the EEPROM of the Arduino can be used.

Anyway lets do a check if we have the right routine:
Suppose October 1 is a Sunday. That means the 25th is a Wednesday and the 29th a Sunday (the last and 5th Sunday), so the routine will indeed be activated on the 29th as all conditions are met.
Suppose October starts on a Monday. That means there are only 4 Sundays and the last Sunday will fall on the 28th. Again, that is between 25 and 31 so the condition is met.
Suppose October first falls on a Thursday, then the 25th will be a Sunday (the fourth Sunday) and the 31st will be a Saturday, so again the condition will be met for the last (and in this case 4th Sunday).

To start summertime/daylightsaving time on the last Sunday in March is mutatis mutandis the same:

if (dow == 7 && mo == 3 && d >= 25 && d <=31 && h ==2 && DST==0)
{
setclockto 3 am;
DST=1;
}

March also has 31 days so the calculations are the same. This time though we check at 2 am and a reset DST flag and then set the clock to 3 am and set the DST flag to indicate it is done already.

Now if you do NOT use an RTC that keeps the day of week or if you keep track of time and date in some other way than with an RTC, then there is an easy formula to determine the day of the week from the date with Sakamoto’s Algorithm

//gives day of week for a given date Sunday=0, Saturday=6
int dow(int y, int m, int d)
{
static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
y -= m < 3;
return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
}

mind you though that this routine counts from 0 (Sunday) to 6 (Saturday)

So when is it Dark?

I have removed the text that used to be here,in favour of a new post on sunset and sunrise.