Tuesday, April 30, 2013

16. Infrared Thermometer - MLX90614

The Melexis MLX90614 is a factory pre-calibrated infrared thermopile with integrated signal conditioning and temperature calculation.  It incorporates a low noise amplifier, 17 bit ADC and a powerful digital signal processing unit, leading to high accuracy (0.5C) and precision (0.01C).  Smart - eh?

That's a formal way of describing this very clever, tiny digital non-contact thermometer.  It has a diameter of about 8mm, and a field of view of about  ±20°.  So it can give a true reading as long as the object is within, and fully occupies, that field.

The one I have operates at 3.3V, which is available from my BreadboArduino.  This is what it looks like:

  

Here is mine mounted at the centre of a breadboard to the left of my BreadboArduino:  The BreadboArduino has a red LED indicating power on, and a flashing green LED to indicate that the sketch (see below) is running.


This video gives some idea of what the finished project is capable of:  First I bring a bag of very cold ice down close to the thermopile.  Notice the colour of the RGB LED changing into the blues and greens.  The LED is so bright that it is whiting out its image.  However, you can get an idea of its colour from its light reflected off the surrounding surfaces.  Then I introduce a hot cup of tea, and the LED goes into the reds and whites.


The serial port gives a running list (about every second) of the current measured temperature in Celsius and Fahrenheit:


Note the changing temperature as the bag of very cold ice is placed in front of the thermopile, followed by a hot cup of tea.  (No milk - one sugar).  The code is a little tricky to get going, but there are excellent instructions at: http://bildr.org/2011/02/mlx90614-arduino/

1:  // MLX90614 Program April 2013  
2:    
3:  #include <i2cmaster.h>  
4:    
5:  int led = 13;  
6:  int mappedSensorValue = 0; // maps range of rawSensorVale and constrains it between 0 and 255  
7:  int mSV = 0;  
8:    
9:  int minF = -40; // min range of sensor is -40C = -40F  
10:  int maxF = 257; // max range of sensor is 125C = 257F  
11:    
12:  int REDPin = 6;  // RED pin of the LED to PWM pin 6  
13:  int GREENPin = 5; // GREEN pin of the LED to PWM pin 5  
14:  int BLUEPin = 3;  // BLUE pin of the LED to PWM pin 3  
15:  //int brightness = 0; // LED brightness  
16:    
17:  void setup(){  
18:       Serial.begin(9600);  
19:       Serial.println("Setup...");  
20:         
21:       i2c_init(); //Initialise the i2c bus  
22:       PORTC = (1 << PORTC4) | (1 << PORTC5);//enable pullups  
23:     pinMode(led, OUTPUT);  
24:     pinMode(REDPin, OUTPUT);  
25:     pinMode(GREENPin, OUTPUT);  
26:     pinMode(BLUEPin, OUTPUT);   
27:  }  
28:    
29:  void loop(){  
30:    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)  
31:    delay(100);        // wait   
32:    digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW  
33:    delay(100);        // wait   
34:    digitalWrite(led, HIGH);  // turn the LED on (HIGH is the voltage level)  
35:    delay(100);        // wait   
36:    digitalWrite(led, LOW);  // turn the LED off by making the voltage LOW  
37:    delay(1000);        // wait for a second  
38:      
39:    int dev = 0x5A<<1;  
40:    int data_low = 0;  
41:    int data_high = 0;  
42:    int pec = 0;  
43:      
44:    i2c_start_wait(dev+I2C_WRITE);  
45:    i2c_write(0x07);  
46:      
47:    // read  
48:    i2c_rep_start(dev+I2C_READ);  
49:    data_low = i2c_readAck(); //Read 1 byte and then send ack  
50:    data_high = i2c_readAck(); //Read 1 byte and then send ack  
51:    pec = i2c_readNak();  
52:    i2c_stop();  
53:      
54:    //This converts high and low bytes together and processes temperature, MSB is a error bit and is ignored for temps  
55:    double tempFactor = 0.02; // 0.02 degrees per LSB (measurement resolution of the MLX90614)  
56:    double tempData = 0x0000; // zero out the data  
57:    int frac; // data past the decimal point  
58:      
59:    // This masks off the error bit of the high byte, then moves it left 8 bits and adds the low byte.  
60:    tempData = (double)(((data_high & 0x007F) << 8) + data_low);  
61:    tempData = (tempData * tempFactor)-0.01;  
62:      
63:    float celsius = tempData - 273.15;  
64:    float fahrenheit = (celsius*1.8) + 32;  
65:    
66:    Serial.print(celsius);  
67:    Serial.print(" C ... ");  
68:    
69:    Serial.print(fahrenheit);  
70:    Serial.print(" deg F");  
71:      
72:    Serial.println();  
73:      
74:   // maps range of sensor values to target range between 0 and 255  
75:    mappedSensorValue = map( celsius, 10, 40, 0, 255);  
76:    mSV = mappedSensorValue;  
77:        
78:     if (celsius<10)  
79:    {  
80:     analogWrite(REDPin,  0);  
81:     analogWrite(GREENPin, mSV);  
82:     analogWrite(BLUEPin, (255-mSV));  
83:    }    
84:     else if (celsius>40)  
85:    {  
86:     analogWrite(REDPin,  255);  
87:     analogWrite(GREENPin, mSV);  
88:     analogWrite(BLUEPin, mSV);  
89:    }  
90:     else  
91:   {  
92:    analogWrite(REDPin,  mSV);      
93:    analogWrite(GREENPin, 0);  
94:    analogWrite(BLUEPin,  (255-mSV));   
95:   }   
96:      
97:  }  

In the code, REDPin, GREENPin and BLUEPin refer to the anodes of the RGB LED corresponding to the three colours.

The main part of this code has been taken from http://bildr.org/2011/02/mlx90614-arduino/






Friday, April 26, 2013

15. Programming the ATTiny85 with the BreadboArduino

The ATTiny85 is a tiny 8-legged microcontroller, and it is a surprisingly powerful device.  It has 8kB of Flash memory, 512 bytes of EPROM (Erasable Programmable Read Only Memory) and 512 bytes of RAM (Random Access Memory), can operate up to 20 MHz, has an 8-bit AVR (an architecture developed by the Atmel company) central processing unit, up to 6 available input/output pins, and operates between 2.7 V and 5.5 V. 

Applications range from home climate control to remote health monitoring (Telecare), home appliances, and industrial sensor devices.  You can buy them for about £1.50 each.



You can also program them using an Arduino, with the Arduino IDE software.  So I thought I would have a go at xBacon's Mini RGB Mood Light (http://www.instructables.com/id/ATtiny85-Mini-RGB-Mood-Light/).  The version I decided to build is the Night version, which can detect when it's dark and automatically turn on the cycle of hundreds of colours.  

All the details are given above, but it has a light dependent resistor (LDR) which tells it when the ambient light level is low (night time).  


The Light Dependent Resistor


This is what it looks like:






Also known as a photoresistor, the LDR's resistance decreases as the amount of light falling on it increases.  This behaviour is known as photoconductivity.  Its working element is a semiconductor with high resistance.  Semiconductors work as conductors when something stimulates the electrons bound in its valence band, to jump to the conduction band.  

There are many things that can stimulate this, but in this case, visible ambient light has enough energy to enable electrons to jump to the conduction band.  The resulting electrons in the conduction band, and their associated vacancies (holes) in the valence band, effectively cause the material to become a conductor, which in effect is a lowering of resistance.

Most semiconductor materials are extrinsic as opposed to intrinsic, meaning that they have been doped with miniscule amounts of a chosen impurity, which makes it easier for the electrons to cross the valence band / conduction band energy gap.  This is basically how photocells work.  The labelled diagram above indicates cadmium sulphide as the active semiconductor.

LDRs can be bought for about 25 pence each.

PWM and POV

When LEDs are driven by digital signals (square wave signals with a fixed amplitude) and their output light intensity needs to be changed, the method of Pulse Width Modulation (PWM) can be employed successfully:  

The LED's brightness is not actually going up and down, it's only blinking on and off at the same voltage, but as the duty cycle changes, it appears to fade and glow.  The duty cycle of square waveforms is the ratio of the pulse width to the period.  

This smooth appearance is due to our visual perception - our eye-brain systems are not capable of seeing the very rapid flashing of the LED, and instead we perceive the brightness going up and down.  This effect is known as Persistence of Vision (POV).  The following cartoon has been made from a series of still drawings replayed at 12 frames per second.  Our persistence of vision  makes us think that there is smooth motion.

12 fps actually appears jerky and that's why modern movies work at 24 fps - for smooth persistence of vision.

It is relatively easy to vary the duty cycle with software.

The RGB LED

The Red-Green-Blue Light Emitting Diode is another nice component.  Not only can these show you how your circuit and software are working, but everybody likes them - particularly the multi-coloured ones.


The picture on the left shows the anatomy of a single-colour LED.  They can be produced in various colours, using different semiconductor materials for the diode.  On the right is shown the RGB LED, which is really 3 single colour elements in one - hence the need for two extra legs for the two extra colours.  

One of the legs is a different length from the others, indicating that it is common to all 3 elements ie either the common anode (positive terminal - only one of these needed for all three) or common cathode (negative terminal).  As can be seen in this example, there is a clear plastic cover, allowing white light to be emitted when all three elements are on.

Here is a demonstration of how the three primary colours of light can be combined to give secondary colours:
This shows how full intensity red, green and blue combine, but as the red, green and blue brightnesses change, many other intermediate colours are produced.  

Our lamp will cycle from red to yellow to green to cyan to blue to magenta to red, by smoothly reducing the duty cycle of the first colour while at the same time increasing the duty cycle of the second colour.  This should appear to be smooth as there are 100 steps involved in each transition.

Programming the ATTiny85

Before looking at the connections from chip to chip, let's look at the basic pin numbering convention for integrated circuits.  Here is a general chip:

The pins are numbered in an anti-clockwise direction, starting with Pin 1, indicated by the small spot beside it.  If the spot isn't there, there's still usually a half-moon mark on one end, which shows the end that Pin 1 is on.

This can be done by connecting the two chips as follows:

ATMega 328 (Hobbytronics.co.uk type label)



Connect the ATMega 328 chip's pins to the ATtiny as follows:

                              ATMega 328 Vcc (+5V)           --->  ATtiny85 Pin 8 (VCC)
                              ATMega 328 Ground (GND)    --->  ATtiny85 Pin 4
                              ATMega 328 Pin D10              --->  ATtiny85 Pin 1 (Reset)
                              ATMega 328 Pin D11              --->  ATtiny85 Pin 5
                              ATMega 328 Pin D12              --->  ATtiny85 Pin 6
                              ATMega 328 Pin D13              --->  ATtiny85 Pin 7

Then follow this link http://hlt.media.mit.edu/?p=1695 for instructions on how to download files, and use the Arduino ISP software.

The sketch comes straight from http://www.instructables.com/id/ATtiny85-Mini-RGB-Mood-Light/  The essence is that the 6 methods redtoyellow()  through to magentatored() run in a continuous loop until the detected ambient light level (analogRead(sensor) exceeds a pre-defined value.  At that point it turns the LED off until the room gets dark again.

The methods (sections of code beginning with void) select the pins involved in powering the LED elements and fade up in 100 steps,  one colour, by flashing it on and off for varying amounts of time, effectively increasing that colour's duty cycle. At the same time, the duty cycle of a neighbouring colour is gradually decreased, and the result is a pleasing transition from the first colour to the second. 

Here is the instructables.com sketch code again for convenience:

1:  //ATtiny85 RGB color fading Mood Light NOW WITH LIGHT SENSING CAPABILITIES!!!  
2:    
3:  const int redPin = 2;   
4:  const int grnPin = 1;   
5:  const int bluPin = 0;  
6:  const int sensor = 3;  
7:    
8:    
9:  void setup()  
10:  {  
11:   pinMode(redPin, OUTPUT);    
12:   pinMode(grnPin, OUTPUT);    
13:   pinMode(bluPin, OUTPUT);  
14:   pinMode(sensor, INPUT);  
15:  }  
16:    
17:  void loop() {  
18:   if (analogRead(sensor) <= 200)  
19:   {  
20:    redtoyellow();  
21:    yellowtogreen();  
22:    greentocyan();  
23:    cyantoblue();  
24:    bluetomagenta();  
25:    magentatored();  
26:   }  
27:   else if (analogRead(sensor) >= 201)  
28:   {  
29:    digitalWrite(redPin, LOW);  
30:    digitalWrite(grnPin, LOW);  
31:    digitalWrite(bluPin, LOW);  
32:   }  
33:  }  
34:    
35:  void redtoyellow()  
36:  {  
37:   digitalWrite(redPin, HIGH);  
38:   digitalWrite(bluPin, LOW);  
39:    
40:   // fade up green  
41:   for(byte i=1; i<100; i++) {  
42:    byte on = i;  
43:    byte off = 100-on;  
44:    for( byte a=0; a<100; a++ ) {  
45:     digitalWrite(grnPin, HIGH);  
46:     delayMicroseconds(on);  
47:     digitalWrite(grnPin, LOW);  
48:     delayMicroseconds(off);  
49:    }  
50:   }  
51:  }  
52:    
53:    
54:    
55:  void yellowtogreen()  
56:  {  
57:   digitalWrite(grnPin, HIGH);  
58:   digitalWrite(bluPin, LOW);  
59:    
60:   // fade down red  
61:   for(byte i=1; i<100; i++) {  
62:    byte on = 100-i;  
63:    byte off = i;  
64:    for( byte a=0; a<100; a++ ) {  
65:     digitalWrite(redPin, HIGH);  
66:     delayMicroseconds(on);  
67:     digitalWrite(redPin, LOW);  
68:     delayMicroseconds(off);  
69:    }  
70:   }  
71:  }  
72:    
73:    
74:  void greentocyan()  
75:  {  
76:   digitalWrite(grnPin, HIGH);  
77:   digitalWrite(redPin, LOW);  
78:    
79:   // fade up blue  
80:   for(byte i=1; i<100; i++) {  
81:    byte on = i;  
82:    byte off = 100-on;  
83:    for( byte a=0; a<100; a++ ) {  
84:     digitalWrite(bluPin, HIGH);  
85:     delayMicroseconds(on);  
86:     digitalWrite(bluPin, LOW);  
87:     delayMicroseconds(off);  
88:    }  
89:   }  
90:  }  
91:    
92:    
93:    
94:  void cyantoblue()  
95:  {  
96:   digitalWrite(bluPin, HIGH);  
97:   digitalWrite(redPin, LOW);  
98:    
99:   // fade down green  
100:   for(byte i=1; i<100; i++) {  
101:    byte on = 100-i;  
102:    byte off = i;  
103:    for( byte a=0; a<100; a++ ) {  
104:     digitalWrite(grnPin, HIGH);  
105:     delayMicroseconds(on);  
106:     digitalWrite(grnPin, LOW);  
107:     delayMicroseconds(off);  
108:    }  
109:   }  
110:  }  
111:    
112:    
113:  void bluetomagenta()  
114:  {  
115:   digitalWrite(bluPin, HIGH);  
116:   digitalWrite(grnPin, LOW);  
117:    
118:   // fade up red  
119:   for(byte i=1; i<100; i++) {  
120:    byte on = i;  
121:    byte off = 100-on;  
122:    for( byte a=0; a<100; a++ ) {  
123:     digitalWrite(redPin, HIGH);  
124:     delayMicroseconds(on);  
125:     digitalWrite(redPin, LOW);  
126:     delayMicroseconds(off);  
127:    }  
128:   }  
129:  }  
130:    
131:    
132:    
133:  void magentatored()  
134:  {  
135:   digitalWrite(redPin, HIGH);  
136:   digitalWrite(grnPin, LOW);  
137:    
138:   // fade down blue  
139:   for(byte i=1; i<100; i++) {  
140:    byte on = 100-i;  
141:    byte off = i;  
142:    for( byte a=0; a<100; a++ ) {  
143:     digitalWrite(bluPin, HIGH);  
144:     delayMicroseconds(on);  
145:     digitalWrite(bluPin, LOW);  
146:     delayMicroseconds(off);  
147:    }  
148:   }  
149:  }  
.  

It's really amazing that the bare-bones Arduino (BreadboArduino) can be used to flash a program to a tiny chip, which will just continue to drive the Night Time Mood Lamp for as long as it receives power.

And here is my ATTiny85 controlled Night Time Mood Lamp in the cyan part of its colour cycle:

The photoresistor is at the top right of the picture.

Thursday, April 25, 2013

14. Using an OLED Display with the Remote PIR Project

I came across a really neat display, available from Adafruit.  It's the 0.96 inch 128 x 64 pixel Organic LED (OLED) display.  This is a tiny, but effective display.  Adafruit provide very good instructions at http://learn.adafruit.com/downloads/pdf/monochrome-oled-breakouts.pdf (page 11) on how to set it up.  You have to solder an 8-pin header to make it breadboard connectable or even jump wire connectable.  Then you have to decide whether you want to use its I2C or SPI capability. 

I2C (or I squared C) is a 2-wire serial bus, meaning you can connect a large number of devices to it, and each device has a serial identification.  The connections are clock input (Clk) and bi-directional data port (Data) , reset (Rst) , and power (Vin) and ground (Gnd), 5 connections in all.

SPI is the Serial Peripheral Interface bus, a 4-wire system (not counting reset, power and ground) - so it requires more connections:

  • SCLK: serial clock (output from master);
  • MOSI: master output, slave input (output from master);
  • MISO: master input, slave output (output from slave);
  • SS: slave select (active low, output from master).

The Adafruit instructions explain that for I2C use, two jumper pairs need to be closed with solder.  The unit comes with the jumpers open, so it's ready for SPI.

I soldered mine closed, as I decided to use the I2C connections.  

You can have 8 rows of 21 characters which are very small, but very clear, or bigger characters, or bitmaps displayed.  It's possible to animate bitmaps too, and the Adafruit_GFX and Adafruit_SSD1306 libraries enable access to all the functions available.  There are also demonstration sketches giving examples of how to do all these things.

I connected the Rst pin to the Arduino RESET, Clk to Arduino analog pin A5, and Data to Arduino analog A4.  The sketch listing below is largely similar to the previous post, but it uses the Adafruit_GFX and Adafruit_SSD1306 libraries and I borrowed Adafruit's testfillrect(void) method.

This code starts the animation on the display, as well as lighting up the LED on pin 13, to announce the presence of an intruder.

The following video shows one of the demonstration animations, and you can see the OLED display in the top right while the Arduino is at the bottom left.  After a few seconds, the remote PIR is activated and the XBees communicate, turning on the LED and starting alternating images on the OLED display:


1:  //XBeeReceiveOLED  
2:  //Sketch for receiving XBee transmissions from RemotePIR on remote   
3:  //Boarduino connected to a PIR and XBee  
4:  //Intruder causes LED to light and OLED changes its display  
5:  //KC 11-Jan-13  
6:    
7:  #include <Adafruit_SSD1306.h>  
8:  #include <Adafruit_GFX.h>  
9:  #include <Wire.h>  
10:  #include "CLYCBitmap.h"  
11:  #include "CLYCBitmap2.h"  
12:    
13:  int LedPin = 13;  
14:    
15:  #define OLED_RESET 4  
16:  Adafruit_SSD1306 display(OLED_RESET);  
17:    
18:  void setup() {  
19:   Serial.begin(9600);  
20:   pinMode(LedPin, OUTPUT);  
21:  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)  
22:   display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // initialize with the I2C addr 0x3D (for the 128x64)  
23:  // init done  
24:   display.clearDisplay();  
25:  }  
26:    
27:  void loop() {  
28:   if (Serial.available())  
29:   {  
30:   int data = Serial.read();  
31:    if (data == 'H')  
32:    {  
33:     digitalWrite(LedPin, HIGH); //Turn on the LED  
34:     Serial.write(data);     //Send the received H character  
35:                    //to the Serial Monitor  
36:      // CLYC bitmap high display  
37:     CLYC2();  
38:      // CLYC bitmap low display  
39:     CLYC1();  
40:    }  
41:    else if (data == 'L')  
42:    {  
43:     digitalWrite(LedPin, LOW);  //Turn off the LED  
44:     Serial.write(data);     //Send the received L character  
45:                    //to the Serial Monitor  
46:    }  
47:    else  
48:    {  
49:     digitalWrite(LedPin, LOW);     
50:    }  
51:   }   
52:  }  
53:    
54:  // CLYC bitmap low display  
55:  void CLYC1(void) {  
56:     display.clearDisplay();  
57:     display.drawBitmap(1, 1, CLYCBitmap, 128, 64, WHITE);  
58:     display.display();   
59:  }  
60:    
61:  // CLYC bitmap high display  
62:  void CLYC2(void) {  
63:     display.clearDisplay();  
64:     display.drawBitmap(1, 1, CLYCBitmap2, 128, 64, WHITE);  
65:     display.display();   
66:  }  

The procedure for displaying these images is as follows:

Note that at lines 10 and 11 above, the files CLYCBitmap.h and CLYCBitmap2.h are included. For guidance on how to produce these 2 files, I have reproduced Adafruit's instructions below:(http://learn.adafruit.com/mini-thermal-receipt-printer/bitmap-printing) :

Windows

Use an image editing program to save your image as a 1-bit BMP — in Windows, the built-in Paint program will suffice.


Download, install and run LCD Assistant. This program is for Windows only but does a really fantastic job! Load the BMP file you previously generated (in Paint, etc.). The file must be in BMP format — the software won’t read PNG, GIF, etc. Then a couple of settings need to be adjusted…
lcd-assistant.png
First, in the “Byte orientation” section of the settings, select “Horizontal” (item A in the image above).


Second (item B above), you may need to change the Width setting. Because this software (and the thermal printer) handle images in horizontal groups of eight pixels, if the image width is not a multiple of 8, it will be truncated (cropped) to the nearest smaller 8-pixel boundary. For example, with the 75 pixel wide image above, the output will be cropped to only 72 pixels wide, losing some data from the right edge. To avoid this, increase this number to the next multiple of 8 (that would be 80 for the example above), and the output will be padded with blank pixels to cover the gap. Remember the number you use here, you’ll need it later.



The image height does not need to be adjusted this way, only width.



Set the table name to something short but descriptive (e.g. “adalogo” above), then select Save Output from the File menu. Give the file a similarly brief but descriptive name, ending in “.h” (e.g. “adalogo.h”).



To get this file into your Arduino sketch, select “Add File…” from the Sketch menu. This will add a new tab to your code. Your original code is still there under the leftmost tab.



A couple of small changes are now needed in both tabs. First, at the top of the file containing the new table data, change “const unsigned char” to “static PROGMEM prog_uchar” as shown below:
table.png
Next, in the tab containing the main body of your code, add an “include” statement to reference the new file:
Copy Code
  1. #include "adalogo.h"
 I went through this procedure and "added" 2 files to my sketch, CLYCBitmap and CLYCBitmap2.  Thanks are due to Adafruit for their help with this.




These three views show Tab 1 (the sketch), Tab 2 (the first bitmap) and Tab 3 (the second bitmap). This completes the procedure for displaying images on the OLED display.


13. Remote PIR Project

PIR (Passive Infra Red) detectors are commonly used in intruder alarm systems, for example, in your home, and in motion-activated lighting systems.  This is a very clever device, from the focusing system (Fresnel Lens) to the twin-detector system, to the electronics.  A good description of how it is constructed and how it works, is given at http://www.glolab.com/pirparts/infrared.html.   The detection range of the PIR is about 5 metres.

The wavelength of the radiation detected is 9.4 micro meters.  This is described as long-wave infra red, mid or thermal infra red, or IR-C.  The component looks like this:
Its operating voltage is between 5 V and 12 V or a jumper wire can be used for it to operate at 3.3 V.  The 3 wires correspond to ground (GND), voltage in (VIN) and signal out (alarm).

I have connected my PIR to my Boarduino, which, when it receives an alarm signal, sends a signal to the XBee, which transmits this signal by radio waves to a second XBee.  This second XBee is connected to my Arduino Uno R3, which lights up an LED to tell me that something warm has moved in front of my remotely-positioned PIR (an intruder!!!). 

I had hoped that I could place the remote PIR with Boarduino, outside my house, so that I would get advanced notice of someone approaching the front door.  However, because there are a couple of thick walls in the way, the transmitted signal isn't strong enough.  Never mind - It still works well, telling me when somebody comes into the room, even though I already know that.

I'm not sure whether replacing my 1 mW transmitter with a higher-powered transmitter will solve my problem.  In the meantime, I'll just have to rely on the front door bell.

Here is my remotely-positioned PIR system:


And here it is, connected to the Boarduino.  You can see that the Boarduino is powered by my previously-described power supply/voltmeter display:


The sketch running on the Boarduino is as follows (please forgive the untidy coding - there may well be some redundant stuff):

1:  // RemotePIR  
2:  // PIR motion detector with LED indicator  
3:  // Status info by XBee to PC  
4:  // 11 Jan 2013  
5:  //  
6:    
7:  #include <Wire.h>  
8:    
9:  int PIRpin = 4;          // digital pin 4 for PIR  
10:  int LEDpin = 13;     // digital pin 13 for LED  
11:  int PIRval;       // PIR HIGH or LOW value  
12:    
13:  void setup() {  
14:   pinMode(LEDpin, OUTPUT);  // set the LED pin as ouput  
15:   pinMode(PIRpin, INPUT);   // set the PIR pin as an input  
16:    
17:   Serial.begin(9600);  
18:  }  
19:    
20:  void loop() {  
21:   PIRval = digitalRead(PIRpin);  // read PIR  
22:   if (PIRval == HIGH) {  
23:    Serial.print("H");  
24:    digitalWrite(LEDpin, HIGH);  // LED ON  
25:   }  
26:   else {  
27:    Serial.print("L");  
28:    digitalWrite(LEDpin, LOW);   // LED OFF  
29:   }  
30:   delay(100);  
31:  }  
32:    

And now - the other end of this project, the receiving part:




On the left is the receiving XBee mounted on a mini breadboard (the red light shows that it is in communication with the first XBee and the green LED on the left flashes to confirm that power is applied).  On the right is my Arduino Uno R3 with an activated LED connected to pin 13, indicating that someone has come into the room.

The sketch running on the Arduino is as follows:


1:  //XBeeReceive  
2:  //Sketch for receiving XBee transmissions from RemotePIR on remote   
3:  //Boarduino connected to a PIR and XBee  
4:  //KC 11-Jan-13  
5:    
6:  int LedPin = 13;  
7:    
8:  void setup() {  
9:   //   
10:   Serial.begin(9600);  
11:   pinMode(LedPin, OUTPUT);  
12:   pinMode(speakerPin, OUTPUT);  
13:  }  
14:    
15:  void loop() {  
16:   //    
17:   if (Serial.available())  
18:   {  
19:   int data = Serial.read();  
20:    if (data == 'H')  
21:    {  
22:     digitalWrite(LedPin, HIGH);  
23:     Serial.write(data);  
24:    }  
25:    else if (data == 'L')  
26:    {  
27:     digitalWrite(LedPin, LOW);  
28:     Serial.write(data);  
29:    }  
30:    else  
31:    {  
32:     digitalWrite(LedPin, LOW);     
33:    }  
34:   }   
35:  }  
36:    



As an extra, I connected my DSO Nano, the Digital Storage Oscilloscope I told you about earlier, to the receiving XBee's input, and as you will see from the first sketch above, either a "H" for "high" or "L" for "low" character is transmitted, according to whether the PIR "sees" an intruder or not.  The second sketch reads the signal it receives - ie  "data", and if "data" is "H", it sends the LedPin "HIGH" and the Piezo buzzer plays, or else if "data" is "L", then it sets the LedPin "LOW" ie it turns it off.  The Serial.write(data); (line 41) command sends "L" or "H" to the Serial Monitor like this:









So the signals I see on the DSO Nano oscilloscope are as follows:


Remember that this serial data comes in from left to right on the oscilloscope, so the right-hand side came in first.  Going from right to left, the first dip is the first bit - 0. then comes 1,0,0,1,1,0,0 - making 01001100
Going from right to left, the first dip is the first bit - 0. then comes 1,0,0,1,0,0,0 - making 01001000

If you look up the ASCII Alphanumeric Code (http://hyperphysics.phy-astr.gsu.edu/hbase/electronic/ascii.html), you will find that the 7-bit ASCII - 1001100 represents the character "L", and the 7-bit ASCII - 1001000 represents the character "H"

The eagle-eyed will have spotted that there is an extra zero bit at the end (leftmost dip) of the 8-bit character.


Tuesday, April 23, 2013

12. The XBee

The XBee is another marvellous thing.  It is a wireless radio frequency transceiver which operates at the 2400-2483.5 MHz waveband.  This waveband doesn't require a licence.  You obviously need two of these so that they have something to communicate with.  There are different models, but the sort I bought from Adafruit was the 1mW model with wire antenna:

The Digi International XBee pin-out has a 2 mm separation, so you can't plug it directly into a breadboard, since the standard hole separation for breadboards is 0.1 inch.  So I got hold of the MaxStream XBee adapter, which comes in kit form, and when connected, looks after power and protection and provides LED indicators of power on, and transceiver activity handling serial data.  And of course, it has a 2 mm hole separation on the top, for plugging in the XBee, and 0.1 inch pin-outs suitable for the breadboard :


This shows the assembled adapter kit, before mounting the XBee.  This photo shows the 10-pin header on the left, protruding horizontally.  So that I could mount mine on a breadboard, I soldered my header so that it stuck out of the bottom of the board, ready for plugging into a breadboard.

Here is one of my XBees, complete with assembled adapter, mounted on a mini breadboard:


I'll cover the project details later, but suffice to say at this stage, that to get 2 XBees talking to one another, is a truly wondrous thing


11. The BreadboArduino

Hobbytronics supply the components necessary to build on a breadboard, an Arduino! They recommend using the Sparkfun FT232 breakout board, which enables power and USB communication to be delivered via a USB cable to your PC.

However, having bought the Adafruit FTDI cable, described in an earlier post,  I thought I would like to use that instead.

So I put the whole thing together, including a 6-pin header for the FTDI cable, made from an 8-pin length of double male header, using 6 of the pins for the FTDI cable, and pushing the remaining pins right through so that there is plenty of grip on the breadboard:



Here is the BreadboArduino in its final form (with some connections to another project), and with the FTDI cable plugged in at the top left:


In the bottom left area, I included a voltage regulator for powering the other project to which it is connected.  The ATMega chip supplied by Hobbytronics has a useful label stuck on top to indicate the pin connections, and comes pre-loaded with the bootloader program.

So now I have quite a collection of Arduinos - the Arduino Uno R3, the one on the Gertboard, the Boarduino, and the BreadboArduino.  There are of course many other forms of Arduino, but I suppose I'll have to call a halt on building up this part of the collection.

10. The Boarduino

The whole Arduino concept is open source, meaning that the design of its board, using the family of ATMega chips, can be copied by anyone, as can the software. (Although sometimes it is polite to mention where you got your ideas from).  So, you will see many different formats of the 'uino.  

The one I'm about to describe has been developed by Adafruit as a kit and is called the Boarduino.  It's cheaper than the standard Arduino, and has a smaller footprint (about a third of the size, less than an inch wide by about 3 inches long), so it could be useful where your project needs to be compact.  It can also do something an Arduino can't - plug in to a breadboard.

You can't have enough 'uinos, so I built the Boarduino kit, again a satisfying experience:


Notice that this photo shows an ATMega 168 chip - they now actually come with an ATMega 328 chip, which has twice as much memory, and comes pre-loaded with special bootloader software.  I intended to have this on a remote project, communicating remotely with my main Arduino Uno R3 - more on this later.

There is a 2.1 mm socket on the Boarduino to allow power to be connected, and there is (on the left of the board above) a 6-pin header for programming, which also takes in power from the USB supply.  You wouldn't use both power inlets for obvious reasons, so when you have your Boarduino programmed with a sketch from the IDE, you can disconnect the USB end, and run it on power through the 2.1 mm plug.  Its on-board 5 V regulator allows you to use anything from 7V to 17V through the 2.1 mm plug.  Don't forget to move the jumper on the board which selects one power inlet or the other.

Because the Boarduino doesn't have a chip on board enabling USB communication, I also got an FTDI cable.  This is more than just a USB to 6 wire female header connector - it has embedded within its insides, a special chip (it must be very small).



This cable connector allows the Boarduino to be connected to your PC USB port, essential for transmitting programs (sketches) to it, from the Arduino IDE software.

I found this cable to be very useful later for programming other 'uinos - as will be seen in a later post.