Changing a button to a touch sensor

Hi. I'm trying to use 6 flexi light strips with a touch sensor. It's one you'd stand on to set an alarm off, I've got a small one to try first. The strips are set to come on randomly. I've made the code work with a button (thanks to a bit of forum help), I'd now like to swap the button for the touch sensor. Can anyone help? I've been struggling! This is the code I have with the button (it's for four lights at the moment, I can change that):

#include <Bounce2.h> // https://github.com/thomasfredericks/Bounce2/archive/refs/heads/master.zip

#define BUTTON_PIN 2 // Button connected to pin 2
#define NUM_LEDS 4   // Number of LEDs used on project

const int LED_PINS[NUM_LEDS] = {3, 4, 5, 6}; // Pins where the LEDs are connected

Bounce2::Button button = Bounce2::Button();

void blink(int positionOnArray )
{
  digitalWrite(LED_PINS[positionOnArray], HIGH);
  delay(1000); // Keep the LED on by 1 second
  digitalWrite(LED_PINS[positionOnArray], LOW);
}

void setup()
{
  for(int i = 0; i < NUM_LEDS; i++)
  {
    pinMode(LED_PINS[i], OUTPUT);
  }

  button.attach(BUTTON_PIN,  INPUT);
  button.interval(5);    // Bounce interval in ms
  button.setPressedState(LOW);
}

void loop()
{
  button.update();

  if (button.pressed())
  {
    randomSeed(micros());
    int randomNumber = random(0, NUM_LEDS);
    blink(randomNumber);
    // blink(0); // Will blink pin 3
    // blink(1); // Will blink pin 4
    // blink(2); // Will blink pin 5
    // blink(3); // Will blink pin 6
  }
}
1 Like

Yes, you did it wrong. Please read the forum guide in the sticky post to find out how to post code the correct way and other useful tips, then edit your post please.

Hi Paul, thanks for your comment. You refer to 'sticky'. I've searched for sticky and googled sticky to try and find them to fix my post but I only come across posts talking about people not following the sticky properly. I'll take out all the bits I added in and see if that helps you. Please do point me in the right direction for the sticky and I will have a go at following it. Or if yo know of a how to post for newbies guide I'll take a look at that. I'm happy to learn

Here is the “sticky post”;

It is a post that is pinned at the top of every section so that it can’t be missed!? and gives lots of useful information.

1 Like

Thank you. I'm reading it through now

1 Like

Thanks for fixing the code tags. Much better.

Why does it need to change with the touch sensor? Can you post a link to the sensor please?

Hi Paul, the difference is I want people to stand on it and the light come on. At the moment it comes on when people get off (let go of the button). I think the problem is within the bounce2, I was wondering if I actually need bounce2. I want a light to be when people stand on the touch sensor and to turn off when they get off. This is the link to the sensor mat. Thanks for your help

Look up detecting state change. Depending on how your “button” is wired that will be the moment it changes from high to low (typical) or low to high. You don’t want to detect if the button is pressed, you want to detect the change in state

If buttonstate is low and lastbuttonstate is high then buttonPressed

The first problem is that you have not complied with the "sticky".

Hardware

We need to know exactly what hardware you have. We need to know what Arduino board (or other brand, such as ESP32) you are using and exactly what other hardware you are connecting it to. The more details we have, the easier it is to help.

If you are using something that is a non-Arduino product then it helps to have a link to its technical data sheet or a link to where you bought it.

Clearly, your secret touch switch is giving an opposite signal to your covert "button". If we ever knew what they both were, we could suggest the remedy. :roll_eyes:

If the "touch switch" happens to be a TTP223, you do not need to de-bounce it and you can choose the polarity of its output.

Hi Julia,

No idea why that should be, there must be some important details you have not shared with us. Your sensor has Normally Open (NO) contacts, same as most buttons, so your sketch should work the same.

Try changing

button.setPressedState(LOW);

to

button.setPressedState(HIGH);

I don't know how, but apparently I missed the link to the sensor mat. :roll_eyes:

We still don't have any idea how it is all wired though.

The sensor mat would however require debouncing. That stupid datasheet ("seem welding"? Really? :astonished:) fails to explain the most obvious concern: why the mat has four wires!

1 Like

I’ve tested the four wires and only two seem to be needed, one as grown and one as power. I don’t know what the other two do. I did lots of standing on and off with a multimeter and they didn’t seem to do anything. The one thing the data sheet does say is it’s normally open, I think a button is usually closed.

I did this late last night and I remember it didn’t work but I can’t remember why!

Excellent work. You used your initiative and experimented and tested to find out if the device works at all and which wires to use. I'm not being patronising: disappointingly few beginners do that without being prompted.

No, most are normally open. That means when the button is not being pressed, the contacts are open, and current cannot flow though the switch. Some buttons are normally closed: current can pass through them until the button is pressed and the contacts open. Other types of switches, that have 3 terminals, can be both/either. There is a NO terminal, a NC terminal and a common terminal.

1 Like

Somewhat unusual, except for the switches on your refrigerator and car doors. :grin:

2 Likes

Sorry for the late reply. I have a little girl so don't get much time to my self over the weekend. By magic it's working today with the following code:

#include <Bounce2.h> // https://github.com/thomasfredericks/Bounce2/archive/refs/heads/master.zip

#define BUTTON_PIN 2 // Button connected to pin 2
#define NUM_LEDS 4   // Number of LEDs used on project

const int LED_PINS[NUM_LEDS] = {3, 4, 5, 6}; // Pins where the LEDs are connected

Bounce2::Button button = Bounce2::Button();

void blink(int positionOnArray )
{
  digitalWrite(LED_PINS[positionOnArray], HIGH);
  delay(10000); // Keep the LED on by 1 second
  digitalWrite(LED_PINS[positionOnArray], LOW);
}

void setup()
{
  for(int i = 0; i < NUM_LEDS; i++)
  {
    pinMode(LED_PINS[i], OUTPUT);
  }

  button.attach(BUTTON_PIN,  INPUT);
  button.interval(5);    // Bounce interval in ms
  button.setPressedState(HIGH);
}

void loop()
{ 
  button.update();

  if (button.pressed())
  {
    randomSeed(micros());
    int randomNumber = random(0, NUM_LEDS);
    blink(randomNumber);
    // blink(0); // Will blink pin 3
    // blink(1); // Will blink pin 4
    // blink(2); // Will blink pin 5
    // blink(3); // Will blink pin 6
  }
}

Thank you for all your help getting there. I think it's changing the button.setPressedState(HIGH) from low to high and checking all the wires this morning.

I'd now like to make it more fun by having something like this at the beginning and end:

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
  int one = 3;
  int two = 4;
  int three = 5;
  int four = 6;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(one, OUTPUT); 
  pinMode(two, OUTPUT);  
  pinMode(three, OUTPUT);
  pinMode(four, OUTPUT);
}

void loop() {
  digitalWrite(one, HIGH);   
  digitalWrite(two, LOW);
  digitalWrite(three, LOW);
  digitalWrite(four, LOW);
  delay(1000); 
  digitalWrite(one, HIGH);   
  digitalWrite(two, LOW);
  digitalWrite(three, LOW);
  digitalWrite(four, LOW);
  delay(1000); 
  digitalWrite(one, LOW);   
  digitalWrite(two, HIGH);
  digitalWrite(three, LOW);
  digitalWrite(four, LOW);
  delay(1000); 
  digitalWrite(one, LOW);   
  digitalWrite(two, LOW);
  digitalWrite(three, HIGH);
  digitalWrite(four, LOW);
  delay(1000); 
  digitalWrite(one, LOW);   
  digitalWrite(two, LOW);
  digitalWrite(three, LOW);
  digitalWrite(four, HIGH);
  }  

To add a bit of suspense. When you stand on it each light shows before the final light being selected. Another really cool thing would be to make the lights flash every five minutes when it's not being used.

Is that all too complicated? Thanks for all of your help

It is easy. Look up state machines. Decide how many states you want. Eg waiting, stand on for 1 sec, flashing etc
Write a function for arch state to perform the required action. If state ==1 do something, if 2 do something different else do something completely different etc.

If you want to avoid a lot of ifs look up switch case

Don’t use delay or blocking code. Use blink without delay to gain knowledge of non-blocking code.

Thanks. That makes sense. I'll have a look into it now.

I'm having ago after reading through a few examples and it's not easy! I wish my brain worked more like yours. This is what I've tried but I'm getting invalid use of template-name 'State" without an argument for State Random = State(LED_PINSRandom); where I initialise the states. I'm sure I've done many more things wrong too!

I think I've ended up with too many libraries too, when I've added it by going Sketch; Include Libraries; Finite-State-Machine. Seven libraries come up. The code looks like this

#include <Singleton.h>
#include <StateMachine.h>
#include <Transition.h>
#include <Action.h>
#include <Decision.h>
#include <ArrayList.h>
#include <State.h>
#include <Bounce2.h>

#define BUTTON_PIN 2 // Button connected to pin 2
#define NUM_LEDS 4   // Number of LEDs used on project

const int LED_PINS[NUM_LEDS] = {3, 4, 5, 6}; // Pins where the LEDs are connected

const byte NUMBER_OF_STATES = 3; //how many states are we cycling through?

//initialize states
State Off = State(LED_PINSWaiting); 
State Flashing = State(LED_PINSFlashing);
State Random = State(LED_PINSRandom); 

FSM ledStateMachine = FSM(On);     //initialize state machine, start in state: On

Buounce2::Button button = Button::Bounce(); //initialize the button (wire between pin 12 and ground)
byte buttonPresses = 0;            

void blink(int positionOnArray )
{
  digitalWrite(LED_PINS[positionOnArray], HIGH);
  delay(10000); // Keep the LED on by 1 second
  digitalWrite(LED_PINS[positionOnArray], LOW);
}

void setup()
{
  for(int i = 0; i < NUM_LEDS; i++)
  {
    pinMode(LED_PINS[i], OUTPUT);
  }

  button.attach(BUTTON_PIN,  INPUT);
  button.interval(5);    // Bounce interval in ms
  button.setPressedState(HIGH);
}
void loop()
    {
      case 1: ledStateMachine.transitionTo(Waiting); break;
      case 2: ledStateMachine.transitionTo(Flashing); break;
      case 3: ledStateMachine.transitionTo(Random); break;
    }
  {
  ledStateMachine.update();
}

void LED_PINSWaiting()
{
  interval(300000);
  digitalWrite(LED_PINS[1], HIGH);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], HIGH);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW); 
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], HIGH);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], HIGH);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], HIGH);
  interval(300000); 
  }

void button.press (){LED_PINSFlash();   
  digitalWrite(LED_PINS[1], HIGH);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], HIGH);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW); 
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], HIGH);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], HIGH);
  digitalWrite(LED_PINS[4], LOW);
  digitalWrite(LED_PINS[1], LOW);   
  digitalWrite(LED_PINS[2], LOW);
  digitalWrite(LED_PINS[3], LOW);
  digitalWrite(LED_PINS[4], HIGH); 
  }

 void Random {LED_PINSRandom()
    randomSeed(micros());
    int randomNumber = random(0, NUM_LEDS);
    blink(randomNumber);
    // blink(0); // Will blink pin 3
    // blink(1); // Will blink pin 4
    // blink(2); // Will blink pin 5
    // blink(3); // Will blink pin 6
  }

I think I've lost the instruction to do the blink for 10 seconds along the way too.

I didn't even realise there were libraries for state machines! I would never have thought to go look for them. To me, it's just a way of structuring your code. You don't use a library every time you want to write a function or a loop, you just write it. But it's by no means the first time I've come across an Arduino library where I've wondered whether the library actually saves more code than it took to write it! I should at least read the library, ideally try it out, before judging it.