Circuit Troubles

Hi there,

Well I'm currently working through the instructable Passion Sensing Scarves (which can be seen here: http://www.instructables.com/id/Arduino-Lilypad-Interactive-Passion-Sensing-Scarf/) using the Arduino Lilypad 328 Board and am having problems connecting the components successfully.

The basic idea is that the Phototransistor connects with the opposing Emitter on another device to change the colour of the RGB LED from blue to red. The following happens when the devices are switched on:

  1. Both RGB LEDs turn to blue.

  2. When the Emitter on Device 1 comes into contact with Device 2's Phototransistor, the RGB LED on Device 1 changes from blue to red.

  3. Once again, the visa versa of step 2 happens if the Emitter from Device 2 comes into contact with the Phototransistor of Device 1.

At the moment, I have the setup shown in the schematic below, but I cannot get the devices to change their RGB LED colour from blue to red which I assume is a problem with the Phototransistor, as everything else appears to work fine.

My setup differs from the instructable in that it is soldered together with wire rather than using conductive thread to make the connections.

If anyone can be of any assistance I would be very grateful.

Cheers,

KugarWeb.

What code do you have running?

Thank you for your reply! The code I have running is copied directly from the instructable above.
Here it is copied from my Arduino software.

/*++
  Sheep -  Use a combination of RGB and IR LEDs and a photosensor to imitate
           crowd-reactive (emergent) behavior
         
  This code goes with the Fuse Factory Workshop "Make an Emergent Behavior Sculpture
  With The Arduino"
  
  http://thefusefactory.org/2009/09/03/make-an-emergent-behavior-sculpture-with-the-arduino/
  
  The scultpture, or "sheep", is an artistic assemblage of a Lilypad Pro kit (Lilypad
  base attached to a Lilipad 5V power unit) with a tri-color LED mounted over the 328V
  MCU on the Lilypad board.  A Large Lilypad Protoboard sits between the PSU and the
  Lilypad itself to route power and to hold resistors and the IR components.  The illusion
  of a quadraped is completed by 1W and 2W LEDs soldered to the PSU "body" and bent as legs.
  
  The code depends on a persistent variable called "mood" - when it is zero or near zero,
  the sheep is "happy".  Below zero and the sheep is "lonely"; above zero and the sheep
  feels crowded or agitated.  Loneliness is represented by blue, happiness by green, and
  agitation by red.  In between expressing "mood" (using PWM to shade the RGB LED), the
  main part of the code checks for IR pulses from other sheep and may emit its own pulses
  to "call out" to other sheep.  By tweaking internal variables, the sheep can be more or
  less sensitive to the calls of other sheep.  The emergent behavior comes out when
  multiple sheep are assembled and placed on a table, calling out to each other.  The
  flurry of IR pulses can induce the sheep to be happy or perhaps agitated.  Few pulses
  and the sheep exhibits loneliness. 

  Sheep.pde - turn an Arduino into an emergent behavior sculpture
  
    Copyright (C) 2009, Ethan Dicks

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see .


--*/

/*++

  Variable initialization - before the code start, put all of the user-adjustable
                            parameters at the top so they are easy to tweak.
                            
--*/
// Definitions of "mood" values
#define MOODMAX 80
#define MOODMIN (-1 * MOODMAX)

#define LONELY (MOODMIN)
#define HAPPY (0)
#define CROWDED (MOODMAX)
#define MSTEPS 5

#define BLEAT_VOLUME 255

// Global definitions of pin assigments (to simplify individual function calls) 
int statusPin = 13; 	// onboard status LED is connected to digital pin 13
int redPin    = 11; 	// R petal on RGB LED module connected to digital pin 11
int greenPin  =  9; 	// G petal on RGB LED module connected to digital pin 9
int bluePin   = 10; 	// B petal on RGB LED module connected to digital pin 10
int sensorPin =  5;     // IR phototransistor connected to digital pin 5
int irPin     =  6;     // IR LED connected to digital pin 6

// Start off expecting to be happy	 
int mood = HAPPY;

// Keep track of the sense of the input pin
int eye = 0;

// And remember how "loud" we are "bleating" (flashing our IR LED)
int bleat = BLEAT_VOLUME;

/*++

  setup() - The Arduino environment will call the code in setup() one time
            only, right after the board is reset.
            
  Put code in this function to initialize I/O pins and such - things that
  only need to be done once during a run.
  
--*/
void setup() 	 
{ 	
 
  // for debugging
  Serial.begin(9600);
  Serial.println("Sheep v0.02");

  // Mostly, our I/O pins are outputs to LEDs  
  pinMode(statusPin, OUTPUT); 	// sets the statusPin to be an output

  pinMode(redPin, OUTPUT); 	// sets the redPin to be an output
  pinMode(greenPin, OUTPUT); 	// sets the greenPin to be an output
  pinMode(bluePin, OUTPUT); 	// sets the bluePin to be an output
         
  pinMode(irPin, OUTPUT); 	// sets the irPin to be an output

  // One exception is the IR phototransistor
  pinMode(sensorPin, INPUT); 	// sets the sensorPin to be an input

  Serial.print("Setting IR 'bleat' to ");
  Serial.println(bleat);
  
  analogWrite(irPin, bleat);
  
} 	 

/*++

  loop() - the Arduino environment will call the code in this loop forever.
  
  Put interesting things in here that are meant to run endlessly after setup()
  is called once.
  
  The only way out of this loop is to reset the board.
  
--*/
void loop() 	// run over and over again
{ 
  // Set our RGB LED to reflect our "mood", which will hopefully change from time to time
  set_mood(mood);
  
  // Slow down how fast we react to other 'sheep'
  delay(20); 	// delay for .1 second

  // sensorPin has a 10K pullup resistor, so *no* light reports a 1.  We need to
  // invert the logical sense of the pin if we want to think of the light logically
  // as 1-is-on/0-is-off
 // eye = 1 - digitalRead(sensorPin);    // set eye to 1 if we "see" any IR light

  // Report our present status everytime through the loop  
  Serial.print("Mood is ");
  Serial.print(mood);
  Serial.print(".  Sensor is ");
  Serial.println(eye);
  Serial.print("Digital Read = " );
  Serial.print(digitalRead(sensorPin));
  
  
  // If we see pulses from another 'sheep', increment the mood, but not past MOODMAX
  if (eye) {
    // since humans cannot "see" infrared light, use the status LED as a visible indicator
    digitalWrite(statusPin, HIGH);  // echo IR input detection on the status LED
    mood += MSTEPS * 2;
    if (mood >MOODMAX) {
      mood = MOODMAX;
    }
  }
  // If we don't see any IR pulses, decrement the mood, but not below MOODMIN
  else {
    // since humans cannot "see" infrared light, use the status LED as a visible indicator
    digitalWrite(statusPin, LOW);  // echo IR input detection on the status LED
    mood -= 1;
    if (mood < MOODMIN) {
      mood = MOODMIN;
    }
  }
} 

/*++
  set_mood - convert "mood" to a color scheme
  
  Mood varies from some negative number to that same value as a positive number
  (so far, -80/+80 and -100/+100 produce reasonable results).

  Proportionally, the continuum of mood to color mapping resembles the following:
  
                    Mood
  -100                0                +100

  Lonely     ->     Happy      ->     Crowded

R   0        0        0        30       100
G   0        30      100       70        0
B  100       70       0         0        0

--*/
void set_mood (int mood)
{
  // Start out with each color being off - adjust upwards based on "mood"
  unsigned char redness   = 0;
  unsigned char greenness = 0;
  unsigned char blueness  = 0;

#ifdef DEBUG
  Serial.print("Mood is ");
  Serial.println(mood);
#endif

  // blueness is all about mood being less then happy 
  if (mood < HAPPY) {
      blueness  = abs(mood);
      greenness = MOODMAX + mood;
  }
  // redness is all about mood being more than happy
  else if (mood > HAPPY) {
      redness   = mood;
      greenness = MOODMAX - mood;
  }
  // greenness is about mood being around happy
  else {
      greenness = MOODMAX;
  }
  
  // Set the LED to reflect our present mood
  color(redness, greenness, blueness);
  
}

/*++

  color(r, g, b) - set the tri-color LED to the requested color value
  
  Uses analogWrite(pin, value) to set PWM value for each individual LED color

  The Tri-color LED is a common-anode device, so to make light, we ground the
  desired pin.  To invert the PWM waveform, we subtract our desired intensity
  from 255, so that, for example, if we want red off, logically, we pass around
  a value of zero, but set the PWM value to 255 so that the pin is driven high
  100% of the time.  To get red to the maximum brightness, we pass around a
  logical value of 255, but set the PWM value to 0, pulling that pin low 100%
  of the time.

--*/ 
void color (unsigned char red, unsigned char green, unsigned char blue)     // the color generating function
{ 
#ifdef DEBUG
  Serial.print("color(");
  Serial.print(red,HEX);
  Serial.print(blue,HEX);
  Serial.print(green,HEX);
  Serial.println(")");
#endif

  // invert the sense of the PWM value when calling analogWrite() for each color
  analogWrite(redPin, 255-red); 	 
  analogWrite(bluePin, 255-blue);
  analogWrite(greenPin, 255-green);
  
}

You need to enable the debug code already written into this program. To do this add the line:-
#define DEBUG
then run the arduino with the serial monitor enabled. This should show you what is happening inside the code.

.. also, you could put a mutimeter across the resistor used with the phototransistor to make sure that the voltage at the input changes with the light level.

And check all your wiring and the orientation of the phototransistor.

Thanks for your replies.

Grumpy_Mike:
You need to enable the debug code already written into this program. To do this add the line:-
#define DEBUG
then run the arduino with the serial monitor enabled. This should show you what is happening inside the code.

I tried putting "#define DEBUG" in the code and running both devices with the Serial Monitor open but all it displays is the mood decreasing from to 0 to -80, which falls in line with the LED changing to it's blue colour upon startup.

Si:
.. also, you could put a mutimeter across the resistor used with the phototransistor to make sure that the voltage at the input changes with the light level.

And check all your wiring and the orientation of the phototransistor.

Please could you explain in more detail where I would need to place the multimeter probes?

Below is a picture of my previous and current circuit setup. As you can see, the difference is the placement of the resistor, which is now next to GND which I changed in line with the schematic posted above.

Previous:

Current:

There is a line which says:-
Serial.print(". Sensor is ");
Serial.println(eye);

It should print this out every time through the loop. What is it printing and does it change when you cover the light sensor.

Please could you explain in more detail where I would need to place the multimeter probes?

What a feed line.
Never mind put the meter on volts and connect the black wire to ground and the red wire to pin 5. Again you should see the voltage reading change as the light is covered up. If you see this but not a change in the printout, it is your software at fault, if there is no change it is your hardware (wiring or components) that is at fault.

Grumpy_Mike:
There is a line which says:-
Serial.print(". Sensor is ");
Serial.println(eye);

It should print this out every time through the loop. What is it printing and does it change when you cover the light sensor.

Please could you explain in more detail where I would need to place the multimeter probes?

What a feed line.
Never mind put the meter on volts and connect the black wire to ground and the red wire to pin 5. Again you should see the voltage reading change as the light is covered up. If you see this but not a change in the printout, it is your software at fault, if there is no change it is your hardware (wiring or components) that is at fault.

The output from the Serial Monitor is as follows:

Sheep v0.02
Setting IR 'bleat' to 255
Mood is 0. Sensor is 0
Digital Read = 0Mood is -1. Sensor is 0

The reading does not change when it is covered.

I went to see an electronics shop local to me and they said that the setup of the hardware was correct. He checked that the Phototransistor was responding to an output from a IR Emitter (remote control) using an Oscilloscope and the reading was indeed pulsing. However, he said that Pin 5 was taking all of the current (around 5V), which was being sent across the Phototransistor itself. However, there is no change in the readout on the printout. His conclusion was that there was something wrong with the software.

Thank you for your help so far, much appreciated!

Okay, I've just been to see my tutor for this project and he has looked over the code, saying that it is fine. However, the particular Phototransistor I have is apparently insensitive to the Emitter and so is not able to pick up the signal. He also put a metal spoon (odd I know!) across the Phototransistor which caused it to create a Digital Read of 1.

He has suggested that to limit the current through the Phototransistor, I should place a resistor of some value across the Phototransistor's connections which should hopefully solve the problem - albeit a "bodge" to get it working.

So, I now have to try several combinations of resistor so that I can create a working circuit (hopefully). Failing that, I need to pick up a more sensitive resistor as the signal from the Emitter is low. I have tried to combat this problem by adjusting the "bleat volume" in the code from 255 to 500 to make the Emitter transmit at a higher amount.

If you have any other suggestions I would be very grateful!

I've now tested the circuit by placing a 10K and a 56K resistor across the Phototransistor. The 10K created a Digital Read of 1, while the 56K made no difference. Also, neither changed the LEDs' colour from blue to red.

Both of these tests were carried out using a "bleat volume" of 500.

I guess my next step is to try resistors between the value of 10K and 56K?

If anyone has any other suggestions please let me know! :slight_smile:

I am sorry but you are being told a lot of rubbish from both the man in your shop and your tutor.

There is no such thing as a sensitive resistor. Resistors have no sensitivity.

On the code you posted the light sensor is never read hence it always shows the initial value of zero. There is a line to read it but it is commented out. It is also quite a rubbish line.

eye = 1 - digitalRead(sensorPin); // set eye to 1 if we "see" any IR light

You don't go subtracting numbers from digital logic levels, it will produce something but is just a plane stupid bit of code, reflecting the fact that the person who wrote it doesn't know what he is doing.

All this talk about putting resistors across things is again rubbish. What you need is to put a bigger value of resistor in the emitter IN PLACE of the one you have.
In fact the circuit is a bit stupid because the emitter and resistor are the wrong way round for maximum sensitivity. The emitter should go to ground, the collector should go to the aduino input and also be connected through a 100K resistor to +5V.

eye = 1 - digitalRead(sensorPin); // set eye to 1 if we "see" any IR light

You don't go subtracting numbers from digital logic levels, it will produce something but is just a plane stupid bit of code, reflecting the fact that the person who wrote it doesn't know what he is doing.

Sorry Mike, but nothing wrong with that line of code - it's just a simple inversion.
1 - 0 = 1
1 - 1 = 0

Yes I said it will produce something but the idea of subtracting a number for a logic level shows very sloppy thinking and some one who doesn't know what he is doing. Or someone who does know what he is doing and want's to look stupid.

Grumpy_Mike:
All this talk about putting resistors across things is again rubbish. What you need is to put a bigger value of resistor in the emitter IN PLACE of the one you have.
In fact the circuit is a bit stupid because the emitter and resistor are the wrong way round for maximum sensitivity. The emitter should go to ground, the collector should go to the aduino input and also be connected through a 100K resistor to +5V.

So putting a resistor across the phototransistor will not do anything? (by the way, can phototransistors also be known as resistors? as I said before the phototransistor has been said as being insensitive, not a resistor :))

I see. So it is likely that the circuit will work if I use the setup of re-ordering the circuit as you say and replacing the resistor next to the emitter with another? What value would you suggest?

Also, is there anything particularly wrong with the code? Is this another element which is stopping the circuit from working properly?

can phototransistors also be known as resistors

No a photo transistor and resistor are two different thing. Also a photo transistor and a photo resistor are two very different things.

is there anything particularly wrong with the code?

Yes the photo transistor is never read, that line is commented out.

I have been thinking about this and your best bet is to swap the resistor and photo transistor round like I said. Use a 100K resistor and connect it to an analogue input, say A0.
Then read it with a line
eye = analogRead(0); // set eye to the light value we "see"
Serial.println(eye); // look at the value
Then try it and look at the range of numbers you get when you cover the light. Pick a number in the middle of this range and assign it to a variable call threshold at the start of your code. For example if 200 is the middle number you would put:-
int threshold = 200; Then remove the Serial.println(eye); line.
Just before the void setup();
Then change the line:-
if (eye) {
to
if ( eye < threshold ) {

@Grumpy Mike,
still having difficulties understanding your antipathy towards what, to me, looks to be a perfectly mathematically-correct inversion.

Would you be happier if it were written:
eye = (HIGH + LOW) - digitalRead(sensorPin);     ?

(not trying to make a mountain out of a molehill)

looks to be a perfectly mathematically-correct inversion.

Yes it does produce a result. My problem with it is that is just making something a lot more complicated than it needs to be and at the same time shows that the writer of it doesn't know what they are doing. If it were me I would have simply put:-
eye = digitalRead(sensorPin);
And then when I used it put:-
If(!eye) {
Well actually if it were me I would have wired up the sensor correctly and so there would have been no need to invert it anyway. :slight_smile:

Grumpy_Mike:

can phototransistors also be known as resistors

No a photo transistor and resistor are two different thing. Also a photo transistor and a photo resistor are two very different things.

Okay, thank you for that explanation :).

Grumpy_Mike:

is there anything particularly wrong with the code?

Yes the photo transistor is never read, that line is commented out.

I have been thinking about this and your best bet is to swap the resistor and photo transistor round like I said. Use a 100K resistor and connect it to an analogue input, say A0.
Then read it with a line
eye = analogRead(0); // set eye to the light value we "see"
Serial.println(eye); // look at the value
Then try it and look at the range of numbers you get when you cover the light. Pick a number in the middle of this range and assign it to a variable call threshold at the start of your code. For example if 200 is the middle number you would put:-
int threshold = 200; Then remove the Serial.println(eye); line.
Just before the void setup();
Then change the line:-
if (eye) {
to
if ( eye < threshold ) {

So, from my understanding of your posts, I will need to produce one of the following circuits? Please excuse the crude drawings! :slight_smile:

(Version 4)

(Version 5)

Please note that on the Version 4 drawing, the positive from the RGB LED is to go to the positive on the LiPo board (left-most board).

It is almost impossible to follow something like that but it does look wrong.
Where is the 56R resistor, it wasn't on the original schematic from the first post. I can't make that bit out. It seems to say on the photographs emitter positive and emitter negative. An emitter is the name of one of the pins on a transistor so it does not make much sense.

The photo transistor circuit is also wrong. The junction of the 100K resistor and the photo transistor should go to the arduino with the other end of the 100K going to +5 and the other end of the photo resistor going to ground.

Grumpy_Mike:
It is almost impossible to follow something like that but it does look wrong.
Where is the 56R resistor, it wasn't on the original schematic from the first post. I can't make that bit out. It seems to say on the photographs emitter positive and emitter negative. An emitter is the name of one of the pins on a transistor so it does not make much sense.

The Emitter circuit drawn above is exactly the same as before (although admittedly I have made a mistake on the Version 5 drawing - the resistor connected to the Emitter should be a 56R (ohm) not a 56K).

Should I keep the Emitter circuit as it is at the moment? GND >> Emitter >> 56R >> Pin 6?

Grumpy_Mike:
The photo transistor circuit is also wrong. The junction of the 100K resistor and the photo transistor should go to the arduino with the other end of the 100K going to +5 and the other end of the photo resistor going to ground.

Right okay, thank you for clearing that up :). When you say "should go to the arduino", do you mean the "a0" pad you mentioned in your previous post?