Tuesday, 16 May 2017

SK001 - in theory... (pt 3)

Now we come to the setup function.  This is where we do all the one-time initialisation, getting everything ready to go...


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void setup()
{

  Serial.begin(9600);         // initialize serial comms at 9600 baud
  lcd.init();                 // initialise the display

  // flash backlight for 1 second on startup
  for (int i=1; i <= 4; i++)
  {
    lcd.backlight();        // may be an alias for lcd.setBacklight(255);  Try adjusting brightness with values 1-254.
    delay(125);
    lcd.noBacklight();      // may be an alias for lcd.setBacklight(0);
    delay(125);
  }

  // turn off cursor options
  lcd.cursor_off();
  lcd.blink_off();
  

  // setup backlight pushbutton
  lightState="off";
  pinMode(lightSwitch, INPUT);
  lightOnTime = 0;

  // write constants to display (Coordinates = col,row)
  lcd.setCursor(2,0);
  lcd.print("Temp now = --.-");
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(2,1);
  lcd.print("Max temp = --.-");
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(2,2);
  lcd.print("Min temp = --.-");
  lcd.print((char)223);
  lcd.print("C");
  lcd.setCursor(2,3);
  lcd.print("5min ave = --.-");
  lcd.print((char)223);
  lcd.print("C");

  // set Analog Input to use internal 1.1V reference rather than VCC 5V
  // this reduces upper limit to 110C, but gives greater resolution of nearly 0.1C vs 0.5C.
  analogReference(INTERNAL);
 
}

Line 4 sets up the ability to have serial communications with the controlling PC.  It isn't really required in this specific sketch, but it is generally a good idea to have this ready for use for troubleshooting  when things go wrong (as they will).  I'll cover troubleshooting in a later post, but in a nutshell, serial communications allow the Arduino to talk to the PC across the USB cable.  This can be as simple as writing the value of a variable out to the serial console (visible in the Arduino programming IDE), or writing data to the hard disk (or reading it from the hard disk), amongst other things.

Line 5 initialises the lcd.

Line 8 through 14 is what is known as a 'for...next loop'.
Line 8 sets up the loop control.  It creates an integer variable called 'i', and starts by setting it to 1. The next part of the loop control sets the ending condition for how many times the loop is run - all the while i is less than or equal to 4, then the loop will keep running.  Finally, at the end of each loop, the value in i is incremented by 1 (that is what i++ does).
The loop itself is all the instructions between the curly brackets.
Line 10 calls a function called backlight from the external code library, via the object called lcd. This switches the lcd backlight on.  Notice in the comment, it appears that you can actually put a brightness level in the brackets as a parameter to the setBacklight command - if that is the case, then a nice touch might be to create another for...next loop with values 0 to 255, and turn the lcd backlight on by incrementally 'fading it up'.
Line 11 sets a delay before the next instruction is started.  The parameter value of 125 is the number of milliseconds for the delay.
Lines 12 and 13 turn the backlight off again, and wait for another 125 milliseconds
So, effectively, one iteration of the loop will take a total of about 1/4 second (250 milliseconds), and the loop will run 4 times.  The upshot of this block of code flashes the backlight on and off 4 times in a second.  It will actually take very slightly more than 1 second as each instruction may take a few milliseconds to execute - and external devices may take some additional time to react.

Lines 17 and 18 make sure the block and underline cursor options are switched off.  I don't want the display to have any cursor at all - just text and numbers that change as required.

Lines 22 to 24 are setting up the pushbutton for the control of the backlight.  First we have a variable which just stores the current state of the light (starting with 'off').  The next line tells the Arduino microcontroller that the pin we are connecting the switch to (pin 8) is to be treated as an input to be read from, as opposed to an output that can be written.  The final line of the three sets up a variable that will be used to store the milliseconds counter at the point the button gets pressed.

Lines 27 to 42 are 4 sets of 4 commands that set the cursor position on the display (char, row); write out a line of text (note - the hyphens will be overwritten with the actual values later); write character #223 from the 256 standard ASCII character set (actually, only 128 characters are official standard characters, followed by 128 unofficial character slots) - I have seen 223 listed as the degree symbol (°) for the character set used in the LCD controller, but also seen 176 used for it elsewhere, so this will need some testing when the actual display comes,  The final line in each group of 4 writes the C for Celsius.

Line 46 - OK, this might take some explaining!
When an analogue input pin is read, it is normal (actually, it is required) for the voltage on that pin to be somewhere in the range of 0 to 5 volts.  As the chip itself is also running from 5 volts, then that is a handy thing for it to be able to use as a comparison for the voltage present at the analogue input.
The voltage seen at the analogue pin is expressed in 1024ths of the reference 5v - i.e. an integer 0 to 1023, where 0 = 0v and 1023 = 5v.  This gives the smallest increment a value of 5v/1024 = 4.9mV.
Since the LM35 produces an output of 10mV per degree C, then this effectively means that our thermometer can only differentiate temperature in half degree increments.  However, also note that our LM35 will only ever put out a maximum of 1.5 volts, and the 'normal' usage range in this instance will have it somewhere between 0 and 0.5 volts - so comparing it with a 5 volt reference with half a degree accuracy is somewhat wasteful.
The great thing is that internally, the chip also has a 1.1v reference available to it.  If that could be used instead of the normal 5 volts, then each of the 1024 increments now becomes slightly over 1mV, meaning that our thermometer can now read in 0.1 degree increments.  However, if the temperature goes above 110C (i.e. the voltage on the analogue pin is higher than 1.1v), then the thermometer will still register it as 110C - that has become the highest recordable temperature.
So analogReference(INTERNAL) is simply telling the chip to use its internal 1.1v reference for analogue inputs, instead of the normal 5v.

NB - there is also an analogReference(EXTERNAL) option, whereby you can provide whatever reference voltage you want (up to 5v max of course) and connect it to the chip's AREF pin.  So, if I had a regulated 1.5v reference, then I could use the full range of the LM35's measuring range, or alternatively, a 0.5v reference would severely constrain the range I could measure, but give a much greater level of granularity with each increment being about half a millivolt!

If you want to read more about the way the analogRead and analogReference are related, then the Arduino Reference is a good place to start (and they explain it far more succinctly than me).

Next up - SK001 - in theory...(pt 4) - the process loop.

No comments:

Post a Comment