Giving your Arduino projects ‘sight’ and ‘touch’: using IR, Photocells and Touch Sensors to your project

12419231_974683622601393_320731550894605287_oOK, so I am taking some liberty here with the terms sight and touch, but it got your attention, yes?

In this post, I am going to briefly share how to use three sensors: a ‘light detector’ or photocell, a touch sensitive ‘button’ and an IR receiver.

These three sensors all came from a company called ‘OSEPP’, but similar sensors can be had from other vendors as well.  I am going to write about these three specific sensors, but you should be able to adapt the information to what ever you have.  I will present code in both Tiny Basic and Arduino.

LIGHT SENSOR

• 3 pin outs: GRD (-) VCC (+) S ( Signal)

• Suitable supply voltage: +3 to 5Vdc
• Analog voltage output: 0 to 5 Vdc
• Detects ambient light density
• Works with CdsPhotoresistor
• Interface with microcontrollers and logic circuits • Analog sensors
• Uses PH 2.0 socket
• Special sensor with Arduino expansion boards

The light sensor is a cool photocell that is mounted on little breakout board, making it easier to use in a project. There are three pins: VCC, GND and Signal. Signal would connect to any of the Analog pins. When in use, it not only will let you know if it detects light, but also returns the intensity. The higher the value, the more light it detects. Reading it easy and you do not need any libraries. See the HalfByte Tiny Basic example below.

100 CLS
110 L=0: # PIN A0
120 P=13:# PIN 13 LED
130 A=AREAD(L)
140 IF A>299 DWRITE P, 0
150 IF A<300 DWRITE P, 1
160 CURSOR 0,0
170 ?”Intensity: “, A,” ”
180 DELAY 250
190 GOTO 130

What this little piece of code will do is turn on the LED if the light level drops below 300 and turns it off if it goes above 299. It also writes the level to the screen.

if you add a line, say 155, you can test for no light:
155 IF A=0 CLS: ?”NO LIGHT DETECTED”:DELAY 2000

Or, you can test for too much light:
155 IF A>=600 CLS:?”THE LIGHT IS TOO BRIGHT.”:DELAY 2000

There are many things you can do, for example, control a servo that turns an armature to open a food door to distribute dog food to a dish when the sun comes up.

You can use it to log when the sun comes, goes down. Use it control lighting, etc.

Here’s the Arduino sample:

/* OSEPP example of measured ambient light intensity from photocell .
depending on brightness, an LED brightness is changed.
more light = brighter LED. */

int photocellPin = A0;    // photocell sensor input
int ledPin = 11;      // select the pin for the LED
int photocellValue = 0;  // variable to store the value coming from the photocell val

void setup() {
Serial.begin(9600);

}

void loop() {
// read the value from the sensor:
photocellValue = analogRead(photocellPin); 
photocellValue = constrain(photocellValue, 200, 800); //adjust depending on environment.  
   
  // change brightness of LED depending on light intensity of photocell
  int ledbrightness = map(photocellValue, 200, 800, 0, 255);
 
  Serial.print(“incoming value from photocell sensor =”);
  Serial.println( photocellValue);
  analogWrite(ledPin, ledbrightness); 
  delay(100);       
}

TOUCH SENSOR

• 3 pin outs: G (GRD) V (VCC) S ( Signal)Basic wiring scheme for all three sensors.
• 3-5 V operating range
• 5 mA minimum current requirement.
• Capacitive touch detection

The touch sensor detects when you are touching the plate on the breakout board.  As long as you are touching the sensor, it returns a value.  You can test the value and determine if there is someone touching the sensor.

Arduino Code:

/*

OSEPP Touch Sensor Module Example

Serial monitor prints values output from touch sensor
when body conductivity applied.
*/

int sensorPin = A0;    // select the input pin for the potentiometer
int sensorValue = 0;  // variable to store the value coming from the sensor

void setup() {
  Serial.begin(9600);
  // declare the ledPin as an OUTPUT:
}

void loop() {
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);
  Serial.println(“Touch Sensor Value = ” + sensorValue);

}

Tiny Basic Code:

100 CLS
110 L=0: # PIN A0
120 P=13:# PIN 13 LED
130 A=AREAD(L)
140 IF A>100 DWRITE P, 0
150 IF A<100 DWRITE P, 1
160 CURSOR 0,0
170 ?”Value: “, A,” ”
180 DELAY 250
190 GOTO 130

The Tiny Basic, very similar to the light sensor code, will turn the LED on and off each time you press the sensor.  On my setup, the values switch between 22 and 1023.  Your mileage may vary.

IR Sensor12792206_974716205931468_7006422127672690003_o

• 100% Arduino Compatible
• 3 pin outs: G –Ground V – 5V S – Signal
• Operates at a frequency of 38khz

The IR Sensor allows control of a circuit via an Infra Red remote or other IR source.  It works very much like the other two sensors here: has a ground, voltage and signal pins.  It returns values based on the IR signal received.  Admittedly, I have not yet done much with the sensor, so I have limited experience with it.  You can use the same Tiny Basic example from the Touch Sensor above.

Arduino Code:

/*
infrared sensor reciver. connect signal of infrared to analog pin 0. as the distance
from an object to sensor increases/decreases, you will increase/decrease
speed of led blinks from HIGH to LOW

*/

int IR_Pin = A0;    // select the input pin for the potentiometer
int IR_Value = 0;  // variable to store the value coming from the sensor

void setup() {
  // declare the ledPin as an OUTPUT:
  Serial.begin(9600);
}

void loop() {
  // read the value from the sensor:
  IR_Value = analogRead(IR_Pin);   
 
Serial.println(“delay value for LED = “+ IR_Value);  //what value are we reading once an IR led is detected?

// IR_VALUE  = constrain(IR_VALUE, 0, 100); // optional to add a strict range
}

In each of the examples above, the sensors are connected to the HalfByte Console (or your Arduino compatible) via pin A0.  You can use what ever analog pins you want, just change the reference in the code.  You can use them together as well.

Advertisements

PROGMEM issues with Arduino 1.6.x and how to fix them

WP_20140826_22_20_46_ProThere is a new version of the Arduino IDE out, version 1.6.1. If you do not have, you can go to the Arduino web site and grab yourself a copy.  It is much faster than the older versions.  Overall, it seems to be better in most aspects. Except for one…the new compiler breaks some of your code.

I installed it and then tried to compile Half-Byte Tiny Basic.  Expecting a clean compile, I was surprised by the errors it generated.  Upon investigation, I found that the references to PROGMEM was the cuprit. Further research revealed a fairly easy remedy, but one that was difficult to find, so I thought I’d make it easier.

Error:  variable ‘message’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))

So, this was the first error, which led to a second error that isn’t really an error (it goes away when you fix this) so I’m not going to talk about it, it is one that is safe to ignore.  Now, simply changing ‘Static’ to ‘Const’ does not actually fix the problem. No, like the error says, you need to specify the SECTION to put it in.  Look at the old way below, then check out the new way.

OLD WAY:
/***********************************************************/
// Keyword table and constants – the last character has 0x80 added to it
static unsigned char keywords[] PROGMEM = {
‘L’,’I’,’S’,’T’+0x80,
‘L’,’O’,’A’,’D’+0x80,
‘N’,’E’,’W’+0x80,
‘R’,’U’,’N’+0x80,
‘S’,’A’,’V’,’E’+0x80,
….
‘S’,’C’,’R’,’O’,’L’,’L’+0x80,
0
};
NEW WAY:
/***********************************************************/
// Keyword table and constants – the last character has 0x80 added to it
static unsigned char __attribute((section(“.progmem.data“))) keywords[] = {
‘L’, ‘I’, ‘S’, ‘T’ + 0x80,
‘L’, ‘O’, ‘A’, ‘D’ + 0x80,
‘N’, ‘E’, ‘W’ + 0x80,
‘R’, ‘U’, ‘N’ + 0x80,
‘S’, ‘A’, ‘V’, ‘E’ + 0x80,

‘S’,’C’,’R’,’O’,’L’,’L’+0x80,
0
};

Fixing this killed the second error that was showing up.  BUT…

ANOTHER error (third overall) reared its head:

Error: <variable> causes a section type conflict with <section>

Specifying the attribute did the trick, simply using PROGMEM causes issues. While the original error went away (along with that secondary error), the section type error appeared.  This one, though, was simple. I was stuffing two TYPES into the same section and that is a no-no in the new world.  Just adding the code below AND specifying a different section of PROGMEM did the trick. This way allows you to segment your data as well.

// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
‪#‎ifdef‬ PROGMEM
‪#‎undef‬ PROGMEM
‪#‎define‬ PROGMEM __attribute__((section(“.progmem.vars”)))
‪#‎endif‬

Once I made these changes, my code compiled and uploaded just fine.  I hope this saves you some time.

Holiday Greetings from Half-Byte!

To celebrate the season, I give you  a little code snippet for Half-Byte Tiny Basic:WP_20141221_13_57_19_Pro
100 CLS
110 LINE 40,2,20,22,1
120 LINE 40,2,60,22,1
130 LINE 20,22,60,22,1
140 BOX 38,22,4,2,1
150 SET 40,1
160 SET 38,10
170 SET 30,15
180 SET 45,17
190 SET 24,18
200 SET 48,19
210 SET 36,12
220 SET 32,16: RESET 37,14
230 DELAY 1000
240 # Seasons Greetings!
250 CURSOR 8,5
260 PRINT “Merry”
270 CURSOR 6,6
280 PRINT “Christmas!”
290 DELAY 1000
300 RESET 45,17
310 RESET 38,15
320 RESET 36,12
330 SET 37,14
340 SCROLL “Merry Christmas!        ”
350 DELAY 1000
500 GOTO  100

WP_20141221_13_49_32_Pro

NOTE: remove line 340 if you do not have Half-Byte Tiny Basic V2.2.

Holiday Greetings from Half-Byte!

To celebrate the season, I give you  a little code snippet for Half-Byte Tiny Basic:WP_20141221_13_57_19_Pro
100 CLS
110 LINE 40,2,20,22,1
120 LINE 40,2,60,22,1
130 LINE 20,22,60,22,1
140 BOX 38,22,4,2,1
150 SET 40,1
160 SET 38,10
170 SET 30,15
180 SET 45,17
190 SET 24,18
200 SET 48,19
210 SET 36,12
220 SET 32,16: RESET 37,14
230 DELAY 1000
240 # Seasons Greetings!
250 CURSOR 8,5
260 PRINT “Merry”
270 CURSOR 6,6
280 PRINT “Christmas!”
290 DELAY 1000
300 RESET 45,17
310 RESET 38,15
320 RESET 36,12
330 SET 37,14
340 SCROLL “Merry Christmas!        “
350 DELAY 1000
500 GOTO  100

WP_20141221_13_49_32_Pro