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.

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

// 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;

There is a difference between using single = and double == A single one will assign a value to mode and a double will check the value against mode. Your code is correct for mode 4 but the others are wrong.

There is a difference between using single = and double == A single one will assign a value to mode and a double will check the value against mode. Your code is correct for mode 4 but the others are wrong.

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. Is the new code I put in. Something I noticed is that when it rolls over to 0, the led stays on. The serial monitor output suggests it IS in mode 0 but there is still an output. Any ideas why?

I love the idea of the gliding up in brightness. I'll have to have a look at that fade tutorial and see if I can figure it out from there.

You are only checking the value of mode and setting the lamp output when the lamp is touched. When the value of mode rolls over and is set back to 0 no action is taken immediately unless you have the analog.write in place.

Look at the BlinkWithoutDelay example in the IDE to see how to avoid the use of delay(). The basic idea is to note a start time, do stuff, check whether the 'delay' period has elapsed and if not, do stuff until it is. The timing is done using the millis() function which does not block the execution of other code.

Please do not send me PMs asking for help. Post in the forum then everyone will benefit from seeing the questions and answers.

You are only checking the value of mode and setting the lamp output when the lamp is touched. When the value of mode rolls over and is set back to 0 no action is taken immediately unless you have the analog.write in place.

Look at the BlinkWithoutDelay example in the IDE to see how to avoid the use of delay(). The basic idea is to note a start time, do stuff, check whether the 'delay' period has elapsed and if not, do stuff until it is. The timing is done using the millis() function which does not block the execution of other code.

Thanks for the explanation regarding why I had to include another line of analogWrite.

As for fading the light between modes, I am somewhat at a loss. The "fade" and "fading" tutorials don't seem to be what i'm looking for.

I'd like to for the lights to ramp up in brightness after each button press.

As for fading the light between modes, I am somewhat at a loss. The "fade" and "fading" tutorials don't seem to be what i'm looking for.

I'd like to for the lights to ramp up in brightness after each button press.

Thanks for the help thus far.

To ramp up/down the brightness you need to have a couple extra variables. 1 will hold the target brightness you want to achieve the other will hold the current brightness. The code then increments/decrements current brightness a bit at a time trying to match it with target brightness.

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

// 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;}

I might seem like an idiot but remember it takes one to know one.Forum user generally fall into three categories (the good, the bad & the a**hole) what category do you fit in?