Project outline:
Using the capsense library, create a touch sensitive lamp that increases in brightness each time the sensor is touched. In this case, the sensor will be the metal frame of a bedside table. The lamp itself is a large LED strip, and will be mounted on the bed frame to provide a nice gentle back light.
It starts in mode 0 (which is off). Each time a touch is sensed, the mode value is increased by +1. Once the mode variable hits a value of 4, it rolls over to a value of 0 (OFF).
The Problem
- The code compiles okay. The lamp starts OFF, but after the first touch the mode is stuck on 3 (full power). This can be seen using the serial monitor.
- Also, not critical, but I'd like to learn how to do the following. use millis() instead of delay() as I really don't like having breaks in my code.
This is my first project, I'm just learning how to code so please excuse any sloppy code. I've tried to write lots of notes to make it easier to understand. Cheers.
EDIT
Changed byte mode = 0; to int mode = 0;
Changed mode comparisons
int LEDPin = 11; //PWM Output pin for LED
int capSensePin = 2; //Pin to attach to capacitive sensor
int mode = 0; //Determines LED brightness. 0 is off. Varies between 0 and 255.
int touchThreshold = 50; //Minimum capacitive touch value in order to trigger next mode
void setup(){
Serial.begin(9600);
pinMode(LEDPin, OUTPUT); //Set LEDPin to output mode
}
void loop(){
if (readCapacitivePin(capSensePin) > touchThreshold) //If the value of capSensePin exceeds touchThreshold then do...
{
delay(250); //Button Debounce. How would I remove this break using millis()??
mode++; //increase value of mode by 1
//This next section outlines the different LED brightness levels
if (mode == 0) analogWrite(LEDPin, 0);
if (mode == 1) analogWrite(LEDPin, 100);
if (mode == 2) analogWrite(LEDPin, 150);
if (mode == 3) analogWrite(LEDPin, 255);
if (mode > 3) mode = 0; //If the value for mode is equal to 4 then set value of mode to 0.
Serial.print("The current mode is..."); //Serial monitor to bebug mode increases
Serial.println(mode); //print value of mode to seial monitor
}
// THIS POINT ONWARD I DIDNT WRITE.
// Every 500 ms, print the value of the capacitive sensor
if ( (millis() % 500) == 0){
Serial.print("Capacitive Sensor on Pin 2 reads: ");
Serial.println(readCapacitivePin(capSensePin));
}
}
// readCapacitivePin
// Input: Arduino pin number
// Output: A number, from 0 to 17 expressing
// how much capacitance is on the pin
// When you touch the pin, or whatever you have
// attached to it, the number will get higher
// In order for this to work now,
// The pin should have a 1+Megaohm resistor pulling
// it up to +5v.
uint8_t readCapacitivePin(int pinToMeasure){
// This is how you declare a variable which
// will hold the PORT, PIN, and DDR registers
// on an AVR
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
if ((pinToMeasure >= 0) && (pinToMeasure <= 7)){
port = &PORTD;
ddr = &DDRD;
bitmask = 1 << pinToMeasure;
pin = &PIND;
}
if ((pinToMeasure > 7) && (pinToMeasure <= 13)){
port = &PORTB;
ddr = &DDRB;
bitmask = 1 << (pinToMeasure - 8);
pin = &PINB;
}
if ((pinToMeasure > 13) && (pinToMeasure <= 19)){
port = &PORTC;
ddr = &DDRC;
bitmask = 1 << (pinToMeasure - 13);
pin = &PINC;
}
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
// Make the pin an input WITHOUT the internal pull-up on
*ddr &= ~(bitmask);
// Now see how long the pin to get pulled up
int cycles = 16000;
for(int i = 0; i < cycles; i++){
if (*pin & bitmask){
cycles = i;
break;
}
}
// Discharge the pin again by setting it low and output
// It's important to leave the pins low if you want to
// be able to touch more than 1 sensor at a time - if
// the sensor is left pulled high, when you touch
// two sensors, your body will transfer the charge between
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
return cycles;
}