Arduino Basics: UNO
Showing posts with label UNO. Show all posts
Showing posts with label UNO. Show all posts

2 April 2013

Bluetooth Android Processing 4

PART FOUR

The Video





This is part 4 of my tutorial on designing an Android Phone Bluetooth App using the Android/Processing language. The App sends information to an Arduino via Bluetooth after pressing a button on the phone. The RGB LED attached to the Arduino Uno (or compatible board) will change colour depending on the button being pressed on the phone. The Arduino gains Bluetooth capabilities through the Seeedstudio Bluetooth shield (which can be found here).

Parts 1-3 of the tutorial were designed to take you step-by-step through designing the app. If you are wondering what you missed, here is a summary:

This is what you'll find in partone:
  • Downloading and setting up the Android SDK
  • Downloading the Processing IDE
  • Setting up and preparing the Android device
  • Running through a couple of Processing/Android sketches on an Andoid phone.

This is what you will find in part two:

  • Introducing Toasts (display messages)
  • Looking out for BluetoothDevices using BroadcastReceivers
  • Getting useful information from a discovered Bluetooth device
  • Connecting to a Bluetooth Device
  • An Arduino Bluetooth Sketch that can be used in this tutorial

This is what you will find in part three:

  • InputStreams and OutputStreams
  • Error Logs using logcat
  • Testing the InputStreams and OutputStreams
  • Using the APWidgets library to create buttons
  • Adding Buttons to the BlueTooth Project



In Part 4, we simplify and strip down the App so that it will only sends a specific String to the Arduino via Bluetooth. The String sent to the Arduino depends on the Button being pressed. The code has been cleaned up and has many comments to help you understand what is going on. You should be able to run this sketch without having to go back through parts one, two or three of the tutorial. This fourth part of the tutorial was designed for those people who want the final end product, and are happy to work it out for themselves. I hope this serves you well.
I will therefore assume that you have already setup your phone and have downloaded all the neccesary drivers, libraries, SDKs and IDEs. If not, then here are a few quick links:
If you are a bit lost and want want a bit more information then please go through parts one, two and three of this tutorial.
Make sure that you have selected the Bluetooth permissions as per the following:

  • Android > Sketch permissions  (as per the picture below)


Make sure that BLUETOOTH and BLUETOOTH_ADMIN are selected (as per the picture below). Then press the OK button.



Then copy and paste the following sketch into the processing/android IDE:

Android/Processing Sketch 9: Bluetooth App2

 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
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/* BluetoothApp2: Written by ScottC on 1st April 2013 using 
 Processing version 2.0b8
 Tested on a Samsung Galaxy SII, with Android version 2.3.4
 Android ADK - API 10 SDK platform
 Apwidgets version: r44 : http://code.google.com/p/apwidgets/
 */


/*------------------------------------------------------------------------------
 IMPORT statements required for this sketch
-----------------------------------------------------------------------------*/
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.util.UUID; 
import android.util.Log; 

import apwidgets.APWidgetContainer;
import apwidgets.APButton; 
import apwidgets.APWidget;
import apwidgets.OnClickWidgetListener;


/*------------------------------------------------------------------------------
 GLOBAL Variables to be used between a number of classes.
-----------------------------------------------------------------------------*/
public int[] bg={0,80,0};
public BluetoothDevice btShield = null;
public BluetoothSocket btSocket = null;
public OutputStream btOutputStream = null;
public APWidgetContainer widgetContainer=null;
public Connect2BtDevice ConBTdevice=new Connect2BtDevice();



/*------------------------------------------------------------------------------
 The following variables are used to setup the Buttons used in the GUI
 of the phone. It includes the variables that determine the
 - text on the buttons
 - the number of buttons
 - the letters that will be sent to Arduino when the buttons are pressed
 - the colour that the background will change to when the buttons are pressed
 - the dimensions of the buttons (width and height)
 - The gap between each button
-----------------------------------------------------------------------------*/
String[] buttonText = { "RED", "GREEN", "BLUE", "OFF"}; //Button Labels
String[] sendLetter={"r","g","b","x"}; //Letters to send when button pressed
int n= buttonText.length; //Number of buttons
int[][] buttonColour = { {255,10,10}, 
 {10,255,10}, 
 {10,10,255}, 
 {0,0,0} 
 }; //The Background colour on phone when button pressed


APButton[] guiBtns = new APButton[n]; //Array of buttons
int gap=10; //gap between buttons
int buttonWidth=0; //initialising the variable to hold the WIDTH of each button
int buttonHeight=0; //initialising the variable to hold the HEIGHT of each button




/*------------------------------------------------------------------------------
 The setup() method is used to connect to the Bluetooth Device, and setup
 the GUI on the phone.
-----------------------------------------------------------------------------*/
void setup(){
 new Thread(ConBTdevice).start(); //Connect to SeeedBTSlave device
 orientation(LANDSCAPE); //Make GUI appear in landscape mode
 
 //Setup the WidgetContainer and work out the size of each button
 widgetContainer = new APWidgetContainer(this);
 buttonWidth=((width/n)-(n*(gap/2))); //button width depends on screen width
 buttonHeight=(height/2); //button height depends on screen height
 
 //Add ALL buttons to the widgetContainer.
 for(int i=0; i<n;i++){
 guiBtns[i]= new APButton(((buttonWidth*i)+(gap*(i+1))), gap, buttonWidth, buttonHeight, buttonText[i]);
 widgetContainer.addWidget(guiBtns[i]);
 }
}



/*------------------------------------------------------------------------------
 The draw() method is only used to change the colour of the phone's background
-----------------------------------------------------------------------------*/
void draw(){
 background(bg[0],bg[1],bg[2]);
}




/*------------------------------------------------------------------------------
 onClickWidget is called when a button is clicked/touched, which will
 change the colour of the background, and send a specific letter to the Arduino.
 The Arduino will use this letter to change the colour of the RGB LED 
 -----------------------------------------------------------------------------*/
void onClickWidget(APWidget widget){ 
 String letrToSend="";
 
 /*Identify the button that was pressed, Change the phone background 
 colout accordingly and choose the letter to send */
 for(int i=0; i<n;i++){
 if(widget==guiBtns[i]){
 ConBTdevice.changeBackground(buttonColour[i][0],
 buttonColour[i][1],
 buttonColour[i][2]);
 letrToSend=sendLetter[i];
 }
 }
 
 /* Send the chosen letter to the Arduino/Bluetooth Shield */
 if(ConBTdevice!=null){
 ConBTdevice.write(letrToSend);
 }
}



/*==============================================================================
 CLASS: Connect2BtDevice implements Runnable
 - used to connect to remote bluetooth device and send values to the Arduino
==================================================================================*/
public class Connect2BtDevice implements Runnable{

/*------------------------------------------------------------------------------
 Connect2BtDevice CLASS Variables 
-----------------------------------------------------------------------------*/ 
 BluetoothAdapter btAdapter=null;
 BroadcastReceiver broadcastBtDevices=null;
 private UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
 
 
 
/*------------------------------------------------------------------------------
 DEFAULT CONSTRUCTOR: Connect2BtDevice() 
 - Create a BroadcastReceiver (registered in run() method).
 - Get the default Bluetooth Adapter
 - Enable the adapter (if it is not already enabled).
 - Discover available Bluetooth devices to connect to 
-----------------------------------------------------------------------------*/
 public Connect2BtDevice(){
 broadcastBtDevices = new btBroadcastReceiver();
 getBtAdapter();
 enableBtAdapter();
 discoverBtDevices();
 }



/*------------------------------------------------------------------------------
 run() method
 - used to register the broadcast receiver only
-----------------------------------------------------------------------------*/
 @Override
 public void run() {
 registerReceiver(broadcastBtDevices, new IntentFilter(BluetoothDevice.ACTION_FOUND));
 }
 
 
 
/*------------------------------------------------------------------------------
 getBtAdapter() method
 - get the default Bluetooth adapter
-----------------------------------------------------------------------------*/
 void getBtAdapter(){
 btAdapter = BluetoothAdapter.getDefaultAdapter();
 }
 
 
 
/*------------------------------------------------------------------------------
 enableBtAdapter() method
 - Enable the default Bluetooth Adapter if it isn't already enabled
-----------------------------------------------------------------------------*/ 
 void enableBtAdapter(){
 if (!btAdapter.isEnabled()) {
 btAdapter.enable();
 }
 }
 
 
 
/*------------------------------------------------------------------------------
 discoverBtDevices() method
 - Discover other Bluetooth devices within range (ie SeeedBTSlave device)
-----------------------------------------------------------------------------*/ 
 void discoverBtDevices(){
 while(!btAdapter.isEnabled()){
 //Wait until the Bluetooth Adapter is enabled before continuing
 }
 if (!btAdapter.isDiscovering()){
 btAdapter.startDiscovery();
 }
 }
 
 
 
/*------------------------------------------------------------------------------
 connect2Bt() method: called by the btBroadcastReceiver
 - Create a BluetoothSocket with the discovered Bluetooth device
 - Change background to yellow at this step
 - Connect to the discovered Bluetooth device through the BluetoothSocket
 - Wait until socket connects then
 - Attach an outputStream to the BluetoothSocket to communicate with Bluetooth
 device. (ie. Bluetooth Shield on the the Arduino)
 - Write a "g" string through the outputStream to change the colour of the LED
 to green and change the phone background colour to green also.
 A green screen and green LED suggests a successful connection, plus the
 Bluetooth shield's onboard LED starts flashing green slowly (1 per second),
 which also confirms the successful connection.
-----------------------------------------------------------------------------*/ 
 void connect2Bt(){
 try{
 btSocket = btShield.createRfcommSocketToServiceRecord(uuid);
 changeBackground(255,255,0); //YELLOW Background
 try{
 btSocket.connect();
 while(btSocket==null){
 //Do nothing
 }
 try {
 btOutputStream = btSocket.getOutputStream();
 changeBackground(0,255,0); //Green Background
 write("g"); //Green LED (Successful connection)
 }catch (IOException e) { 
 Log.e("ConnectToBluetooth", "Error when getting output Stream");
 }
 }catch(IOException e){
 Log.e("ConnectToBluetooth", "Error with Socket Connection");
 changeBackground(255,0,0); //Red background
 }
 }catch(IOException e){
 Log.e("ConnectToBluetooth", "Error with Socket Creation");
 changeBackground(255,0,0); //Red background
 try{
 btSocket.close(); //try to close the socket
 }catch(IOException closeException){
 Log.e("ConnectToBluetooth", "Error Closing socket");
 }return;
 }
 }
 
 
/*------------------------------------------------------------------------------
 write(String str) method
 - Allows you to write a String to the remote Bluetooth Device
-----------------------------------------------------------------------------*/ 
 public void write(String str) {
 try {
 btOutputStream.write(stringToBytes(str));
 } catch (IOException e) { 
 Log.e("Writing to Stream", "Error when writing to btOutputStream");
 }
 }
 
 
 
/*------------------------------------------------------------------------------
 byte[] stringToBytes(String str) method
 - Used by the write() method 
 - This method is used to convert a String to a byte[] array
 - This code snippet is from Byron: 
 http://www.javacodegeeks.com/2010/11/java-best-practices-char-to-byte-and.html
-----------------------------------------------------------------------------*/ 
 public byte[] stringToBytes(String str) {
 char[] buffer = str.toCharArray();
 byte[] b = new byte[buffer.length << 1];
 for(int i = 0; i < buffer.length; i++) {
 int bpos = i << 1;
 b[bpos] = (byte) ((buffer[i]&0xFF00)>>8);
 b[bpos + 1] = (byte) (buffer[i]&0x00FF);
 }
 return b;
 }
 
 
 
/*------------------------------------------------------------------------------
 cancel() method
 - Can be called to close the Bluetooth Socket
-----------------------------------------------------------------------------*/ 
 public void cancel() {
 try {
 btSocket.close();
 } catch (IOException e){
 }
 }
 
 
 
/*------------------------------------------------------------------------------
 changeBackground(int bg0, int bg1, int bg2) method
 - A method to change the background colour of the phone screen
-----------------------------------------------------------------------------*/ 
 void changeBackground(int bg0, int bg1, int bg2){
 bg[0] = bg0;
 bg[1] = bg1;
 bg[2] = bg2; 
 } 
}


/*==============================================================================
 CLASS: btBroadcastReceiver extends BroadcastReceiver
 - Broadcasts a notification when the "SeeedBTSlave" is discovered/found.
 - Use this notification as a trigger to connect to the remote Bluetooth device
==================================================================================*/
public class btBroadcastReceiver extends BroadcastReceiver {
 @Override
 public void onReceive(Context context, Intent intent) {
 String action=intent.getAction();
 /* Notification that BluetoothDevice is FOUND */
 if(BluetoothDevice.ACTION_FOUND.equals(action)){
 /* Get the discovered device Name */
 String discoveredDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
 
 /* If the discovered Bluetooth device Name =SeeedBTSlave then CONNECT */
 if(discoveredDeviceName.equals("SeeedBTSlave")){ 
 /* Get a handle on the discovered device */
 btShield = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
 /* Connect to the discovered device. */
 ConBTdevice.connect2Bt();
 }
 }
 }
}


Here is a picture of the components used in this sketch:
Bluetooth Shield with Grove RGB LED



Please take notice of the Jumper pin placement on the Bluetooth Shield. This ensures communication between the Arduino and Bluetooth Shield, and is reflected in the Arduino code further down this page. The Arduino transmits information to the Bluetooth Shield on Digital pin 7, and therefore the Bluetooth Shield receives information from the Arduino on Digital pin 7. On the other hand, the Bluetooth shield transmits and the Arduino receives information on Digital pin 6 (see picture below).  This serial communication between the Arduino and the Bluetooth Shield occurs through the SoftwareSerial library. This is different from the Serial library used in some of my other tutorials (often to display information in the Serial Monitor). The Arduino UNO's Serial pins are 0 (RX) and 1 (TX). It is worth looking at the Arduino Serial page if you happen to have an Arduino Leonardo, because there are some differences that you should take into consideration when running this sketch.



Jumpers on Shield


Make sure that your Arduino has the following code installed and running BEFORE you launch the Android/Processing Sketch on your Android Device. If you don't do it in this order, your Android phone will not discover the Bluetooth Device attached to the Arduino, and you will waste a lot of time. Make sure that the Bluetooth shield is flashing it's red/green LEDs. Once you see this alternating red/green LED display, launch the Android/Processing sketch on the Android device. When you see the chainable RGB LED turn from white to green, you know you have a successful connection. You may then press the GUI buttons on the Android phone to change the colour of the LED to either Red, Green, Blue or Off.

Arduino Sketch 3: Bluetooth RGB Colour Changer (with OFF option)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* This project combines the code from a few different sources.
This project was put together by ScottC on the 15/01/2013
http://arduinobasics.blogspot.com/

Bluetooth slave code by Steve Chang - downloaded from :
http://www.seeedstudio.com/wiki/index.php?title=Bluetooth_Shield

Grove Chainable RGB code can be found here :
http://www.seeedstudio.com/wiki/Grove_-_Chainable_RGB_LED#Introduction

Updated on 25 March 2013: Receive 'x' to turn off RGB LED.

*/
 
#include <SoftwareSerial.h> //Software Serial Port

#define uint8 unsigned char 
#define uint16 unsigned int
#define uint32 unsigned long int

#define RxD 6 // This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7 // This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)
 
#define DEBUG_ENABLED 1

int Clkpin = 9; //RGB LED Clock Pin (Digital 9)
int Datapin = 8; //RGB LED Data Pin (Digital 8)
 
SoftwareSerial blueToothSerial(RxD,TxD);
/*----------------------SETUP----------------------------*/ void setup() { 
 Serial.begin(9600); // Allow Serial communication via USB cable to computer (if required)
 pinMode(RxD, INPUT); // Setup the Arduino to receive INPUT from the bluetooth shield on Digital Pin 6
 pinMode(TxD, OUTPUT); // Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
 pinMode(13,OUTPUT); // Use onboard LED if required.
 setupBlueToothConnection(); //Used to initialise the Bluetooth shield
 
 pinMode(Datapin, OUTPUT); // Setup the RGB LED Data Pin
 pinMode(Clkpin, OUTPUT); // Setup the RGB LED Clock pin
 
} 
/*----------------------LOOP----------------------------*/ void loop() { 
 digitalWrite(13,LOW); //Turn off the onboard Arduino LED
 char recvChar;
 while(1){
 if(blueToothSerial.available()){//check if there's any data sent from the remote bluetooth shield
 recvChar = blueToothSerial.read();
 Serial.print(recvChar); // Print the character received to the Serial Monitor (if required)
 
 //If the character received = 'r' , then change the RGB led to display a RED colour
 if(recvChar=='r'){
 Send32Zero(); // begin
 DataDealWithAndSend(255, 0, 0); // first node data
 Send32Zero(); // send to update data 
 }
 
 //If the character received = 'g' , then change the RGB led to display a GREEN colour
 if(recvChar=='g'){
 Send32Zero(); // begin
 DataDealWithAndSend(0, 255, 0); // first node data
 Send32Zero(); // send to update data 
 }
 
 //If the character received = 'b' , then change the RGB led to display a BLUE colour
 if(recvChar=='b'){
 Send32Zero(); // begin
 DataDealWithAndSend(0, 0, 255); // first node data
 Send32Zero(); // send to update data 
 }
 
 //If the character received = 'x' , then turn RGB led OFF
 if(recvChar=='x'){
 Send32Zero(); // begin
 DataDealWithAndSend(0, 0, 0); // first node data
 Send32Zero(); // send to update data 
 }
 }
 
 //You can use the following code to deal with any information coming from the Computer (serial monitor)
 if(Serial.available()){
 recvChar = Serial.read();
 
 //This will send value obtained (recvChar) to the phone. The value will be displayed on the phone.
 blueToothSerial.print(recvChar);
 }
 }
} 

//The following code is necessary to setup the bluetooth shield ------copy and paste----------------
void setupBlueToothConnection()
{
 blueToothSerial.begin(38400); //Set BluetoothBee BaudRate to default baud rate 38400
 blueToothSerial.print("\r\n+STWMOD=0\r\n"); //set the bluetooth work in slave mode
 blueToothSerial.print("\r\n+STNA=SeeedBTSlave\r\n"); //set the bluetooth name as "SeeedBTSlave"
 blueToothSerial.print("\r\n+STOAUT=1\r\n"); // Permit Paired device to connect me
 blueToothSerial.print("\r\n+STAUTO=0\r\n"); // Auto-connection should be forbidden here
 delay(2000); // This delay is required.
 blueToothSerial.print("\r\n+INQ=1\r\n"); //make the slave bluetooth inquirable 
 Serial.println("The slave bluetooth is inquirable!");
 delay(2000); // This delay is required.
 blueToothSerial.flush();
}

//The following code snippets are used update the colour of the RGB LED-----copy and paste------------
void ClkProduce(void){
 digitalWrite(Clkpin, LOW);
 delayMicroseconds(20); 
 digitalWrite(Clkpin, HIGH);
 delayMicroseconds(20); 
}
 void Send32Zero(void){
 unsigned char i;
 for (i=0; i<32; i++){
 digitalWrite(Datapin, LOW);
 ClkProduce();
 }
}
 
uint8 TakeAntiCode(uint8 dat){
 uint8 tmp = 0;
 if ((dat & 0x80) == 0){
 tmp |= 0x02; 
 }
 
 if ((dat & 0x40) == 0){
 tmp |= 0x01; 
 }
 
 return tmp;
}
 // gray data
void DatSend(uint32 dx){
 uint8 i;
 for (i=0; i<32; i++){
 if ((dx & 0x80000000) != 0){
 digitalWrite(Datapin, HIGH);
 } else {
 digitalWrite(Datapin, LOW);
 }
 
 dx <<= 1;
 ClkProduce();
 }
}
 // data processing
void DataDealWithAndSend(uint8 r, uint8 g, uint8 b){
 uint32 dx = 0;
 
 dx |= (uint32)0x03 << 30; // highest two bits 1,flag bits
 dx |= (uint32)TakeAntiCode(b) << 28;
 dx |= (uint32)TakeAntiCode(g) << 26; 
 dx |= (uint32)TakeAntiCode(r) << 24;
 
 dx |= (uint32)b << 16;
 dx |= (uint32)g << 8;
 dx |= r;
 
 DatSend(dx);
}


Please note that this Arduino code/project will work with SeeedStudio's Bluetooth Shield.  You may need to modify the Arduino Code (lines 95-107) to coincide with your own bluetooth shield. I got the code snippet within the my setupBlueToothConnection() method from some example code from Steve Chang which was found on SeeedStudio's Bluetooth Shield Wiki page. Here is some other useful information in relation to setting up this Bluetooth Shield that could be of help in your project (here).

Much of the code used within the Android/Processing sketch was made possible through constant reference to these sites:
And I would also like to thank Pauline303 who made the suggestion within the Processing Forums to use APWidgets Library for my Buttons in the App.
The Arduino and Processing Forums are always a great place to get help in a short amount of time.




19 August 2011

Poor Man's Colour Detector (Part 2) - The project

In this project we will be detecting the colour of 3 different Mega Blok colours (Red, Yellow and Green). We will be using an Arduino UNO connected to  2 LEDs (one Yellow and one Red LED) as light detectors, and an RGB LED to illuminate the subject. We will use a Photocell to account for varying ambient light levels. 

The signals from the LED light sensors will be sent to a Processing.org program via a Serial command. The computer program will make use of my Neural Network to classify the pattern of results and hopefully provide the correct colour "answer". The program should change the colour of the computer screen background to coincide with the colour of the Mega Blok.

The Video


4 August 2011

Poor Man's Colour Detector (Part 1) - The concept

Well, I have finally done it. Not sure if I should post the tutorial, because it is not very basic. But then again, a novice like me managed to do it, so why not !! We will need to pull together a number of previous blogs, but rather than jumping back and forth, I think I will just walk you through from beginning to end, and hope that I don't lose you along the way. 

The concept

In my earlier blog posts, I managed to get LEDs to detect light. And through a bit of trial an error, plus a bit of internet research, I found out that an LED will detect light of the same wavelength that it emits. Therefore a red LED will detect RED light, and a yellow LED will detect yellow light etc etc.

I decided to test this theory by placing different coloured MEGA-BLOKs over the LEDs to see if there was any difference ? And from my simplistic experiments, I could see that the RED LED responded much better to a RED Mega-blok than any other colour, and a YELLOW LED responded much better to a Yellow mega-blok than any other colour.

I decided to test out another theory.
Could I detect other mega-blok colours using a red and yellow LED?

While I was aware that I would be better off using primary colour LEDs (RYB - red yellow and blue) or even RGB (red green and blue) in this experiment, I was limited by the LEDs that came in the Sparkfun's Inventor Kit. So I had to use red and yellow.

I developed a little program in "Processing" that would change the colour of the computer screen based on the colour of the mega-blok sitting over the LEDs. I would use specific cut-off values to separate the different readings and translate them into 4 different classes. This was a bit hit and miss. Depending on the ambient light level, the cut-off values would shift. Plus there was a bit of imprecision in the readings.

I then decided to introduce an RGB LED to shine light on the subject. This helped a bit, however, changes in ambient light were proving to be my enemy. I then introduced a photo-cell, however, by this stage, I had so many values and readings and conditions to meet, that I almost gave up.

That was until I read something about neural networks. Then the real fun began. One month later, and a determined novice that was keen to see this project through to the end, my Arduino UNO can now detect coloured mega-bloks!! How did I do it?  I made the computer figure it out !!

Using a feed-forward neural network with a supervised learning back-propagation model (don't switch off just yet), I got the computer to learn the colours under different light conditions and voila ! I ended up with an Arduino UNO and a couple of LEDs (and photocell) that could tell me what colour Mega-blok was sitting over it. The end result is not 100% perfect, but it works quite well.

In the next part, I will walk you through my neural network step by step. Not sure how this tutorial will pan out, but I'll do my best. (Click here for the Neural Network Tutorial)

Or go here for the table of contents

25 June 2011

Arduino UNO: PhotoCell - sensing light

In this tutorial, we will send the analog readings obtained from a Photo Resistor, also known as a Light Dependent Resistor (LDR), to the computer. We will display the each reading on the monitor using a simple Processing sketch.


Here is what you will need to complete the Arduino side of the project:

Parts Required:

  • PhotoCell (or PhotoResistor)
  • 10K resistor
  • Breadboard
  • Arduino UNO
  • 3-4 wires(to connect it all together)
  • USB cable to upload sketch and for Serial communication with Processing.


Fritzing sketch:



Arduino Sketch


 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
/* ==========================================================
Project : Send Photo resistor values to computer
Author: ScottC
Created: 25th June 2011
Description: This sketch will make the arduino read Photo resistor
             values on analog pin A0. The analog readings will
             be dependent on the amount of light reaching the
             sensor. The Analog readings will be sent to the
             computer via the USB cable using Serial communication.
==============================================================
*/

int photoRPin = 0; 
int minLight;          //Used to calibrate the readings
int maxLight;          //Used to calibrate the readings
int lightLevel;
int adjustedLightLevel;

void setup() {
 Serial.begin(9600);
 
 //Setup the starting light level limits
 lightLevel=analogRead(photoRPin);
 minLight=lightLevel-20;
 maxLight=lightLevel;
}

void loop(){
 //auto-adjust the minimum and maximum limits in real time
 lightLevel=analogRead(photoRPin);
 if(minLight>lightLevel){
 minLight=lightLevel;
 }
 if(maxLight<lightLevel){
 maxLight=lightLevel;
 }
 
 //Adjust the light level to produce a result between 0 and 100.
 adjustedLightLevel = map(lightLevel, minLight, maxLight, 0, 100); 
 
 //Send the adjusted Light level result to Serial port (processing)
 Serial.println(adjustedLightLevel);
 
 //slow down the transmission for effective Serial communication.
 delay(50);
}

Arduino Sketch Explanation:

Serial.begin(9600) : starts the serial communication between the Arduino and Processing
lightLevel=analogRead(photoRPin) : take a reading from the analog pin 0.
minLight and maxLight: automatically adjust the minimum and maximum range of the sensor
adjustedLightLevel: used to map the reading from the PhotoCell to a value between 0-100.

The adjustment of the light level is not necessary, and could be handled in Processing instead.
The delay(50) at the end of the sketch, is only used to slow down the transmission of the Serial messages to Processing. Depending on what you want to do with the sensor data, you may wish to increase or decrease the amount of delay.



 Processing Sketch

Here is a very basic Processing Sketch that will allow you to receive data from the Serial port attached to the Arduino and display the reading on your computer screen. In my case, the Arduino is connected to COM13. You may need to change this if you decide to follow in my footsteps.

The processing sketch will look for the line feed character ' \n' coming from COM13, which will trigger a serialEvent(). You can get processing to look for another character if you want to: just change the character within the bufferUntil() command. The draw() method is made redundant because the screen updating is handled by the serialEvent() in response to serial data communication with the Arduino UNO.

 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
/* ============================================================
Processing Version: 2.2.1
Project: Display Sensor data on computer screen
Author:  ScottC
Created: 25th June 2011
Description: This Processing sketch will allow you to display
             sensor data received from the Arduino via the
             serial COM port (or USB cable).
=============================================================== */
import processing.serial.*;
Serial myPort;
String sensorReading="";
PFont font;


void setup() {
  size(400,200);
  myPort = new Serial(this, "COM13", 9600);
  myPort.bufferUntil('\n');
  font = createFont(PFont.list()[2],32);
  textFont(font);
}

void draw() {
  //The serialEvent controls the display
}  

void serialEvent (Serial myPort){
 sensorReading = myPort.readStringUntil('\n');
  if(sensorReading != null){
    sensorReading=trim(sensorReading);
  }

  writeText("Sensor Reading: " + sensorReading);
}


void writeText(String textToWrite){
  background(255);
  fill(0);
  text(textToWrite, width/20, height/2);   
}

This is how the data will be displayed on the computer screen:

If this tutorial helped you, please support me here:



Displaying Serial data from an Arduino UNO on your computer screen - using Processing

Here is a very basic Processing Sketch that will allow you to receive data from the Serial port attached to the Arduino and display the reading on your computer screen. In my case, the Arduino is connected to COM13. You may need to change this if you decide to follow in my footsteps.


You will need to setup an Arduino sketch to send serial data to the computer using a Serial.println(value) command. The processing sketch will look for the line feed character ' \n' coming from COM13, which will trigger a serialEvent(). You can get processing to look for another character if you want to: just change the character within the bufferUntil() command.
The draw() method is made redundant because the screen updating is handled by the serialEvent() in response to serial data communication with the Arduino UNO



Here is the Processing sketch code:

 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
import processing.serial.*;
Serial myPort;
String sensorReading="";
PFont font;


void setup() {
  size(400,200);
  myPort = new Serial(this, "COM13", 9600);
  myPort.bufferUntil('\n');
  font = createFont(PFont.list()[2],32);
  textFont(font);
}

void draw() {
  //The serialEvent controls the display
}  

void serialEvent (Serial myPort){
 sensorReading = myPort.readStringUntil('\n');
  if(sensorReading != null){
    sensorReading=trim(sensorReading);
  }

  writeText("Sensor Reading: " + sensorReading);
}


void writeText(String textToWrite){
  background(255);
  fill(0);
  text(textToWrite, width/20, height/2);   
}
This was formatted using this site.

If you want an Arduino project that goes well with this code, see this post.





12 June 2011

Colour Sensing - Update One

I successfully modified the previous sketch to detect the colour of the Mega Blok that was over the sensors. However, it was taking up to 10-20 seconds to reveal the answer.

The problem I am experiencing is mainly due to the effect of ambient light levels. Just when I get all my limits set up, something changes, and I lose the ability to identify one of the Bloks.

I get the feeling that I may have over-complicated the design or the method to detect the Blok colour, and am now trying to simplify and speed up the process.

Once again, I think I may be able to get faster results using a PhotoCell, but I don't want to differentiate by light level alone. I would like to read colour using one or more LEDs as a Sensor.

I think I need to utilise the RGB LED functionality a little bit more. So instead of white light, I might scan with different colours.

Stay tuned.

If you have any ideas, please make suggestions in the comments.

Colour Sensing - Intro

Now that I have different patterns for the different coloured Mega Bloks, I will try to get processing to "Identify" or tell me which Blok is which. I am essentially trying to make a DIY colour sensor.
I know that if I get the RGB LED to produce different coloured light (rather than just white), I will be able to get more information/patterns from my Red and Yellow LED sensors, however, I think I have enough information from the white light to tell the difference between the Red, the yellow and the green Mega Bloks.

We'll see how we go. Stay tuned.

For more information about what project I referring to - jump to this Blog Posting:
Arduino UNO: LED Sensor Part Two

Arduino UNO: LED Sensor, Part Two




Building on the last project, I am now using a Red and a Yellow LED as a Sensor to detect light coming from an RGB LED.

Putting different coloured Mega Bloks over the LEDs has different effects on the Sensors as the RGB LED gets brighter and brighter.

I used the Processing Language to control the brightness of the RGB LED through a Serial command, and then use the resulting Sensor readings from the Yellow and the Red LEDs to create a chart or plot.

Here are the results of my experiment.

Red Mega Blok




Yellow Mega Blok



Green Mega Blok













When the displayed bars are RED, it indicates that the Red LED is absorbing MORE light than the Yellow LED (and vice versa). Hence this is a "Difference Chart".
The Green Mega Blok absorbs more Red Light than the other blocks, therefore producing a big difference between Red LED sensor readings and Yellow Sensor readings.

Here is the list of components required to perform this experiment
All parts hardware parts except for the wires and the Mega Bloks
can be found in the Sparkfun Inventors Kit.

Here is the Sketch: (created in Fritzing):

































Here is the Arduino Code:

arduino code RedYellow Sensor with RGB LED

01
02
03
04
05
06
07
08
09
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//Define the pins for the Red LED Sensor
#define Red_LED_Sensor_POS 4
#define Red_LED_Sensor_NEG 5

//Define the pins for the Yellow LED Sensor
#define Yellow_LED_Sensor_POS 7
#define Yellow_LED_Sensor_NEG 8

//Define the pin for the RGB LED torch
#define RGB_LED_RedPin 9
#define RGB_LED_GreenPin 10
#define RGB_LED_BluePin 11
int intensity=0;


//Define the maximum cycles/time allowed for each LED to capture light
long max_darkness=80000;


void setup(){
  //Setup the RED LED Sensor
  pinMode(Red_LED_Sensor_POS,OUTPUT);
  digitalWrite(Red_LED_Sensor_POS,LOW);
  
  //Setup the YELLOW LED Sensor
  pinMode(Yellow_LED_Sensor_POS,OUTPUT);
  digitalWrite(Yellow_LED_Sensor_POS,LOW);
  
  //No need to setup the RGB LED Pins
    
  //Turn on Serial Protocol
  Serial.begin(9600);
}

void loop()
{      
  
  byte byteRead;
   // check if data has been sent from the computer:
  if (Serial.available()) {
    // read the most recent byte (which will be from 0 to 255):
    byteRead = Serial.read();
    // set the brightness of the LED:
    analogWrite(RGB_LED_RedPin, byteRead);
    analogWrite(RGB_LED_GreenPin, byteRead);
    analogWrite(RGB_LED_BluePin, byteRead);
  
  //Read the amount of Yellow light
  read_LED('Y', Yellow_LED_Sensor_NEG);
  
  //Read the amount of Red light
  read_LED('R', Red_LED_Sensor_NEG);
  }
}

void read_LED(char LED_Colour, int LED_Pin){

  // Charge the LED by applying voltage in the opposite direction
  pinMode(LED_Pin,OUTPUT);
  digitalWrite(LED_Pin,HIGH);
  
  //Read the amount of Light coming into the LED sensor
  long darkness=0;
  int lightLevel=0;
  pinMode(LED_Pin,INPUT);
  digitalWrite(LED_Pin,LOW);
  
  while((digitalRead(LED_Pin)!=0) && darkness < max_darkness){
     darkness++;
  }
  
  lightLevel=((max_darkness-darkness)+1)/80;
  
  //Print the LED colour
  Serial.println(LED_Colour);
  //Print the light level
  Serial.println(lightLevel);
}




Here is the Processing Code:

processing code Read Serial Chart and Write Serial

01
02
03
04
05
06
07
08
09
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* Processing code for this example */
 
 // Graphing sketch
 
 //This sketch was written by ScottC, but was adapted from a sketch
 //written by Tom Igoe in 2005
 
 // This example code is in the public domain.
 
 import processing.serial.*;
 
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 float YellowVal=0;    // The variable to hold the Yellow Sensor Reading
 float RedVal=0;       // The variable to hold the Red Sensor Reading
 float Diff=0;         // The variable to hold the difference between the readings
 int Switcher=0;       // Used to control the flow of the program
 
 void setup () {
 // set the window size:
 size(1020, 750);        
 
 // List all the available serial ports
 println(Serial.list());
 // I use COM13 for my Serial Port - you will need to change this to suit your system
 myPort = new Serial(this, "COM13", 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\\n');
 // set inital background:
 background(0);
 //Send a value to the Arduino to start the feedback mechanism
 myPort.write(0);
}
 void draw () {
 // everything happens in the serialEvent()
 }
 
 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\\n');
 
 if (inString != null) {
   // trim off any whitespace:
   inString = trim(inString);
   
   //The arduino sends 2 sensor readings. The following code 
   //helps to identify which reading is which.
   if(inString.equals("Y")){
     Switcher=0;
   } else if (inString.equals("R")){
     Switcher=1;
   } else {
     
     //Convert the String to a float
     float inByte = float(inString); 
     //Map the reading, so that the chart fits within the window.
     inByte = map(inByte, 0, 1000, 0, height);
     
     if(Switcher==0){
       //Save the reading from the yellow sensor to YellowVal
       YellowVal=inByte;
     } else {
       //Save the reading from the red sensor to RedVal
       RedVal=inByte;
       //Calculate the difference between the readings
       Diff=RedVal-YellowVal;
       
       //If the yellow sensor is greater, plot with a yellow line
       //If the red sensor reading is greater, plot a red line.
       if(Diff<=0){
         stroke(255,255,0);
         Diff=abs(Diff);
       } else {
         stroke(255,0,0);
       }
       // draw the line:
       line(xPos, height, xPos, height - Diff);
 
       // at the edge of the screen, go back to the beginning:
       if (xPos > width) {
         xPos = 0;
         background(0);
         //Send a value to the Arduino to change the intensity
         //of the RGB LED and take another reading
         myPort.write(xPos); 
       } else {
         // increment the horizontal position: Increment by more
         // to get less readings and to make it quicker
         xPos+=4;
         if (xPos>0){
           //Send a value to the Arduino to change the intensity
           //of the RGB LED and take another reading
           myPort.write(xPos/4);
         } else {
           myPort.write(xPos);
         }
       }
     }
   }
 }
}

8 June 2011

Arduino UNO: LED Sensor, Part One

As seen in the previous blog postings, the LED (Light Emitting Diode) was used to DISPLAY the result of various sensors. It was also used to create a variety of Light patterns or sequences.

The LED is commonly used as an OUTPUT device, however, I have since found out: there is another option.

You can use the LED as an INPUT device !!



I have only tried this with a Yellow LED and a Red LED, however, this should work with any colour. Some sites recommend using a clear/transparent/colourless LED for best effect, but it depends on what you are trying to achieve.

The LED responds better to light of the same wavelength that it emits. So a yellow LED responds better to yellow light, and a red LED responds better to Red light.

The following experiment attempts to prove this theory.
A Red and Yellow LED alternate and fade in to maximum brightness using PWM (Analog Output). Meanwhile, a separate LED is used as an INPUT device to receive the light. The value obtained is plotted using a processing sketch.

The chart above used a Yellow LED to measure the light emitted from a Red and then a Yellow LED.
As the Yellow LED gets brighter, the INPUT LED takes less time to discharge, and thus produces a lower result. On the other hand, the Red LED has little effect on the INPUT LED, despite it's brightness.
Ambient light will produce different graph patterns.

Parts Required:
  • Arduino UNO
  • 2 x Yellow LEDs
  • 1 x Red LED
  • 3 x 330 ohm Resistors (choose resistors suitable for your LEDs)
  • 5 wires to connect the circuit
  • Breadboard
  • Processing software
Here is the Sketch:

     Created with Fritzing : http://fritzing.org/


Here is the Arduino Code: which was adapted from this site.
 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
49
50
51
52
53
54
55
56
57
58
#define LED_Sensor_NEG 8
#define LED_Sensor_POS 7
#define Yellow_LED 10
#define Red_LED 9

int switcher=0;
int lightLevelY=0;
int lightLevelR=0;

void setup(){
  pinMode(LED_Sensor_POS,OUTPUT);
  digitalWrite(LED_Sensor_POS,LOW);
  pinMode(Yellow_LED,OUTPUT);
  pinMode(Red_LED,OUTPUT);
    
  //Turn on Serial Protocol
  Serial.begin(9600);
}

void loop()
{      

  //Alternate the flashing of the Yellow and Red LED 
  if(switcher==0){
    lightLevelR+=4;
    if(lightLevelR>255){
      lightLevelR=0;
      switcher=1;
    }
  } else {
    lightLevelY+=3;
    if(lightLevelY>255){
      lightLevelY=0;
      switcher=0;
    }
  }
  analogWrite(Red_LED,lightLevelR);
  analogWrite(Yellow_LED,lightLevelY);


  // Charge the LED by applying voltage in the opposite direction
  pinMode(LED_Sensor_NEG,OUTPUT);
  digitalWrite(LED_Sensor_NEG,HIGH);
  
  // Set pin 8 to read the input and Turn off the internal pull up resistor. 
  // The greater the amount of light in the room, the smaller the number represented by variable "darkness".
  long darkness=0;
  int outputVal=0;
  pinMode(LED_Sensor_NEG,INPUT);
  digitalWrite(LED_Sensor_NEG,LOW);  
  while((digitalRead(LED_Sensor_NEG)!=0) && darkness<80000){
     darkness++;
  }

  outputVal=darkness/80;
  //Print the darkness level in the room.
  Serial.println(outputVal);
}

Here is the Processing Code:     Code Source
 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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/* Processing code for this example */
 
 // Graphing sketch
 
 
 // This program takes ASCII-encoded strings
 // from the serial port at 9600 baud and graphs them. It expects values in the
 // range 0 to 1023, followed by a newline, or newline and carriage return 
 // Created 20 Apr 2005
 // Updated 18 Jan 2008
 // by Tom Igoe
 // This example code is in the public domain.
 
 import processing.serial.*;
 
 Serial myPort;        // The serial port
 int xPos = 1;         // horizontal position of the graph
 
 void setup () {
 // set the window size:
 size(400, 300);        
 
 // List all the available serial ports
 println(Serial.list());
 // I know that the second port in the serial list on my PC 
 // is always my  Arduino, so I open Serial.list()[1].
 // Open whatever port is the one you're using.
 myPort = new Serial(this, Serial.list()[1], 9600);
 // don't generate a serialEvent() unless you get a newline character:
 myPort.bufferUntil('\n');
 // set inital background: 
background(0);
 }
 void draw () {
 // everything happens in the serialEvent()
 }
 
 void serialEvent (Serial myPort) {
 // get the ASCII string:
 String inString = myPort.readStringUntil('\n');
 
 if (inString != null) {
 // trim off any whitespace:
 inString = trim(inString);
 // convert to a float and map to the screen height:
 float inByte = float(inString); 
 inByte = map(inByte, 0, 1023, 0, height);
 
 // draw the line: 
stroke(127,34,255);
 line(xPos, height, xPos, height - inByte);
 
 // at the edge of the screen, go back to the beginning:
 if (xPos >= width) {
 xPos = 0;
 background(0); 
 } 
 else {
 // increment the horizontal position:
 xPos++;
 }
 }
 }

24 May 2011

Arduino UNO: Potentiometer used as a 10-way LED switch


Using similar principles as before, I have used a potentiometer (variable resistor) as an Analog input. I have mapped the value received from the potentiometer (0 to 1023) and converted the value to a number between 4 and 13, which represent the OUTPUT pins that light up the LEDs.

If you would like to see the sketch/code, let me know in the comments.

23 May 2011

Arduino UNO: Flex Sensor and LEDs

Using the same LED matrix as before, and swapping the Photo Resistor for a Flex (or Bend) sensor, and a slight modification to the code, I can now have a light show that can be controlled by "Bending".

I used my finger to bend the sensor, but I could have attached it to a plant, a tree or anything else that bends. The bending changes the resistance, and therefore the INPUT value at analog pin 0.

The parts required:
  • Arduino UNO
  • 10 x Red LEDs
  • 9 x 330 Ohm resistors for the LEDs
  • 1 x 10K Ohm resistors for the flex sensor.
  • 1 x Flex sensor
  • Wires and Breadboard to connect it all together
Most of the components needed for this project can be sourced from the Sparkfun Inventor's Kit

The video:


The Sketch:







































The Arduino Code: 


 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
49
50
51
52
53
/*
Flex Sensor and LEDs created by ScottC on 23rd May 2011
updated on 16/05/2012.

-----------------------------------------------------*/

//Flex Sensor Pin (flexPin)
//the analog pin the Flex Sensor is connected to
int flexPin = 0;  
                  
void setup() {
  for (int i=4; i<14; i++){
    pinMode(i, OUTPUT); //sets the led pins 4 to 13 to output
  }
}

void loop(){
 //Ensure to turn off ALL LEDs before continuing 
 for (int i=4; i<14; i++){
    digitalWrite(i, LOW); 
  }
 
 /* Read the flex Level 
  Adjust the value 130 to 275 to span 4 to 13
  The values 130 and 275 may need to be widened to suit 
  the minimum and maximum flex levels being read by the 
  Analog pin */
 int flexReading = map(analogRead(flexPin), 130, 275, 4, 13); 
         
// Make sure the value does not go beyond 4 or 13
 int LEDnum = constrain(flexReading, 4, 13); 
 
/*Call the blink function: this will turn the LED on for 10 milliseconds, and keep it
  off for only 1 millisecond. You can change the blink rate by changing these values,
  however, I want a quick response time when the flex sensor bends, hence the small 
  values. LEDnum determines which LED gets turned on.*/
 blink(LEDnum, 10,1);
}

// The blink function - used to turn the LEDs on and off
void blink(int LEDPin, int onTime, int offTime){
  // Turn the LED on                                         
 digitalWrite(LEDPin, HIGH);  
 
  // Delay so that you can see the LED go On.
 delay(onTime);
 
  // Turn the LED Off                                         
  digitalWrite(LEDPin, LOW);  
 
 // Increase this Delay if you want to see an actual blinking effect.
  delay(offTime);
}


The flex sensor pins/legs are a bit fragile, so be careful when poking it into the breadboard.


For more projects - have a look at the ArduinoBasics Project Page