Modifying Touchy Feely Lamp Code for Current Project

Hello, I made my Arduino Projects Book Project 13 Touchy Feely Lamp Project in to an interactive painting. You can see from the photo that when you touch the hands in the painting, the LED lights in the eyes turn on. I want to modify the code so that when I touch the hands, the LEDs stay ON until touched again and then they go off. If someone knows how to modify the code I would greatly appreciate it. Here is my code:

#include <CapacitiveSensor.h>
CapacitiveSensor capSensor = CapacitiveSensor(4,2);
int threshold = 50;
const int ledPin = 12;

void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop(){
  long sensorValue = capSensor.capacitiveSensor(30);
  Serial.println(sensorValue);
  if(sensorValue > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else{
    digitalWrite(ledPin, LOW);
  }
  delay(10);
}

-Bwackv

The code as it stands is constantly checking that you're touching the hands:

if(sensorValue > threshold)

If not it turns off the LEDs again.

so you need to remove that line of code where it turns the LED output LOW

digitalWrite(ledPin, LOW);

and replace the previous line so it toggles the output (if HIGH now, make it LOW. If LOW now, make it HIGH) when you touch the hands.

I won't post all the code here because it is very simple and you should give it a go! (If you get stuck I'd be happy to nudge you in the right direction). Unless someone else jumps in with the entire solution, of course...

Thanks for your help, Ralph. I'm struggling to write the proper code for "if HIGH now, make it LOW. If LOW now, make it HIGH) when you touch the hands." Can you give me a nudge in the proper direction, I would like to figure it out on my own I just can't seem to figure it out!

Edit:

Do I have to use digitalRead to detect the state of the ledPin?

I understand it in principle but I can't translate that to the correct code. (I'm very new to this)

OK, let me give you a nudge :slight_smile:

This code reads the sensor value into a variable:

long sensorValue = capSensor.capacitiveSensor(30);

So now you only want to react (and turn the LEDs on / off when you RE-touch it.

So you need to know the previous state and toggle it.

Let's assume that this statement results in a TRUE result:

if(sensorValue > threshold)

So now the lights need to be either switched on or off. How do we know which it is to be?

We need to declare a new variable (I would suggest a boolean) outside the loop() and outside of the setup() methods (this makes it 'global', i.e. available to everything in the code):

bool LEDState = false; // start with assuming LEDs are off

Now, after that 'if' statement above you can check: I want to turn them off if they are on and vice-versa:

if (LEDState==true) { 
   digitalWrite(ledPin, LOW); // Turn off LEDs
} 
else {
  digitalWrite(ledPin, HIGH); // Turn on LEDs
}

Finally, you need to toggle the LEDState flag to the opposite of what it is now:

LEDState = !LEDState;

which means whatever the LEDState is now, reverse (or flip) that true/false value. You don't know (or care) what it is, just set to the other value. The exclamation mark means 'not' which can be read in English as 'the opposite value of'.

Finally, add a reasonable delay at the end of the loop() method to give you a chance to remove your hands otherwise it will flash on and off very quickly indeed (far too quickly for you to react)!

delay(1000); // milliseconds = 1 second

Given that I'm writing this on-the-fly without my IDE handy I'm really hoping there are no errors in the above but try it out and see how you get on. If you get problems post the entire code here so I (or others) can have a look,

Ralph,

Thanks for your continued help. Just so you know I'm an artist and very new to Arduino! I'm confused about the two if/else statements or how to integrate both because one is reading the sensor threshold and instructing the LED's to go high or low which seems to override everything else? Anyways, this is how I have it in its non-working condition now:

#include <CapacitiveSensor.h>
CapacitiveSensor capSensor = CapacitiveSensor(4,2);
int threshold = 50;
const int ledPin = 12;
bool LEDState = false; // start with assuming LEDs are off


void setup(){
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop(){
  long sensorValue = capSensor.capacitiveSensor(30);
  Serial.println(sensorValue);
  if(sensorValue > threshold) {
    digitalWrite(ledPin, HIGH);
  }
  else{
    digitalWrite(ledPin, LOW);
  }
  delay(10);
  if (LEDState==true){
    digitalWrite(ledPin, LOW); //turn off LEDs
  }
  else {
    digitalWrite(ledPin, HIGH); //turn on LEDs
    delay(1000); // milliseconds = 1 second
    LEDState = !LEDState;
  }
}

-B

That was a pretty good attempt - and don't apologise at not knowing any of this. I don't suppose I could wield a paintbrush or sculpt anything meaningful either. Each to their own!

#include <CapacitiveSensor.h>
CapacitiveSensor capSensor = CapacitiveSensor(4, 2);
int threshold = 50;
const int ledPin = 12;
bool LEDState = false; // start with assuming LEDs are off

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  long sensorValue = capSensor.capacitiveSensor(30);
  Serial.println(sensorValue);
  if (sensorValue > 50) {
    if (LEDState == true) {
      digitalWrite(ledPin, LOW); //turn off LEDs
    }
    else {
      digitalWrite(ledPin, HIGH); //turn on LEDs
    }
    LEDState = !LEDState;
  }

  // Give user a chance to let go
  delay(1000);
}

I emulated the 'capacitiveSensor' on my workbench and the above code worked fine so please give it a go. Once the LEDs go on (or off) let go of the sensor (you have 1000 milliseconds to do so = 1 second).

The $64000 dollar question is: now that you have a complete solution can you follow and understand what EACH and EVERY line of the above code is doing? There should be no 'magic black boxes' here.

Oh and remove that Serial.print line of code when you're done, it just uses up valuable time in the final code - it's meant for debugging so you can see the value of the sensor in the serial window (which you get to by clicking the magnifying glass in the top right corner of the Arduino IDE).

Yep works like a charm!

Now the part I'm having trouble understanding is:

if (sensorValue > 50) {
    if (LEDState == true) {
      digitalWrite(ledPin, LOW); //turn off LEDs
    }
    else {
      digitalWrite(ledPin, HIGH); //turn on LEDs
    }
    LEDState = !LEDState

the "if within an if" is throwing me off, I'm going to keep looking at it but I have to run for the evening and thought I would post this now.

Appreciate your help so much!

The 'if within an if' can be read almost as an 'AND' condition (it's not, but let's be pragmatic).

So we're saying that IF the sensor has been touched THEN (and only then) carry out the following block of code (that is, switching the LEDs on/off and flipping the flag, also carried out via an IF statement).

The reason we need an overall IF here is that regardless of which path we take in the inner IF statement we always want to flip the flag (LEDState) - this needs only to be done if the sensor has been touched.

If the sensor has not been touched (sensorValue <=50) then we do absolutely nothing.

This code, small as it is, could be optimised further but there is no need - it works, it's clear so let's not 'fixt it'!

I'm glad you got it working and I hope it might encourage you to have a go with other simple Arduino-related tasks.

It feels great to actually understand it. I really appreciate you taking the time to explain that to me. I will definitely be doing more arduino-related projects in the coming months!

All the best,

-B