Push Button Counter

i would like to do this sequence...

when i push the button (first time) Pin do something (push button counter + 1)
when i push the button (second time) pin do something

reset push button counter

how can i do this..?
i try this sketch but don't work... errors are
UDP_write_pushbutton1.cpp: In function 'void loop()':
UDP_write_pushbutton1:57: error: jump to case label
UDP_write_pushbutton1:51: error: crosses initialization of 'char DataOut [4]'

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int statoButton = 0; // stato del pulsante (inizialmente non premuto)
int lastStatoButton = 0; // ultimo stato del pulsante (per ora non premuto)
int countButton = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() {

if(digitalRead(BUTTON))
{
delay(15);

if(lastStatoButton==0) lastStatoButton=1;
else lastStatoButton=0;

if(countButton=0) countButton=countButton+1;
else countButton=0;
}

switch (countButton)
{
case 1:
Udp.beginPacket(remote_ip,remote_port);
char DataOut[] = "P6H";
Udp.write(DataOut);
Udp.endPacket();
delay(250);
break;

case 2:
Udp.beginPacket(remote_ip,remote_port);
char Data[] = "P6L";
Udp.write(Data);
Udp.endPacket();
delay(250);
}
}

  if(countButton=0) countButton=countButton+1;

Don't you know the difference between = and ==? You should learn the difference.

  char Data[] = "P6L";
  Udp.write(Data);

as opposed to the simpler

  Udp.write("P6L");

?

You can avoid the error messages by enclosing the whole case statement in curly braces.

i'm sorry...you are right! I have to write == or <= or >= ok... i modify... if(countButton=0) in if(countButton<=1)

and Udp.write("P6L"); and i delete char variable

Now work but when i push the button send many udp messages i want to send only one message for push, is possible that?

Thanks :slight_smile:

You are sending many message because countbutton is 1. Every time through the loop you will be doing this.

Have you declared lastStatoButton for a reason? you do not appear to be using it and it may be the way to resolve your problem if you detect the change of state rather than the state itself.

I changed the sketch ... and I only used the buttoncounter but as you said when you enter the loop sends many messages. i can't stop the loop...
maybe i have to use...if...else...

Nick,

So when I press the button the first time it does something, the next time it does..... the same thing or something different?

What happens on the third press? Does it do what was press number 1?

Post your new code please.

(Don't forget to put the [ code ] and [ /code ] commands around it - without the spaces.)

I would like...
when i push the button (first time) arduino send the udp message P9H
when i push the same button (second time) arduino send the udp message P9L
restart
when i push the same button (third time) arduino send the udp message P9H
when i push the same button (fourth time) arduino send the udp message P9L

this is my code... now when i push the button (first time) arduino send INFINITY udp messages P9H
when i push the same button (second time) arduino send INFINITY udp messages P9L
restart
when i push the same button (third time) arduino send INFINITY udp messageS P9H
when i push the same button (fourth time) arduino send INFINITY udp messageS P9L

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int countButton = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() {
  
  if(digitalRead(BUTTON))  
  {
    delay(30);  
    if(countButton<=1) countButton=countButton+1;  
    else countButton=0;  
  }    
  switch (countButton)  
  {
  case 1:
  Udp.beginPacket(remote_ip,remote_port);
  Udp.write("P9H");
  Udp.endPacket();
  delay(250);
  break;
  
  case 2:
  Udp.beginPacket(remote_ip,remote_port);
  Udp.write("P9L");
  Udp.endPacket();
  delay(250);
  break;
}
}

Try this:

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int countButton = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() 
{
int button_flag;
    if(digitalRead(BUTTON))  
    {
          //
          button_flag = 1;
          delay(30);
          countButton = countButton + 1;
          countButton = countButton % 2;
      }
      if button_flag = 1
      {
        switch (countButton)  
        {
          case 1:
          Udp.beginPacket(remote_ip,remote_port);
          Udp.write("P9H");
          Udp.endPacket();
          delay(250);
          break;
  
          case 2:
          Udp.beginPacket(remote_ip,remote_port);
          Udp.write("P9L");
          Udp.endPacket();
          delay(250);
          break;
        }
    }
    button_flag = 0;
}

I think you were falling over with the delays. They maybe weren't long enough.
Also I simplified the counting of the button presses.
countButton = countButton + 1;
countButton = countButton % 2;
This will cycle countButton from 0 and 1 and back.
The % 2 is "Modulo 2" which means if gets the value and finds the remainder of dividing it by two.
So basically the answers are: 0, 1, 0, 1, 0, 1 and so on.

Button_flag is outside the loop so it will only be set to 0 once BUTTON is low.
That may help.

This is not good:

  if(digitalRead(BUTTON))  
  {
    delay(30);  
    if(countButton<=1) countButton=countButton+1;  
    else countButton=0;  
  }

Your requirements talk about pushing the switch n times, not incrementing as you hold the switch down.

You had a variable for the previous state of the switch. Put that back.

void loop()
{
   byte currState = digitalRead(SWITCH); // Buttons are for shirts; switches are for Arduinos
   if(currState != prevState)
   {
      if(currState == HIGH)
         countSwitch++;
   }
   prevState = currState;
}

Drats! Paul did a better job for not looping than I did.

i try the sketch posted by lost_and_confused but don't work..when i push the button send infinity P9H and the second push continue to send P9H

and i try this sketck with the part posted by PaulS..but when i push the button send infinity P9H, second push send infinity P9L and third push stop to send message and dont' restart.. is right the sketch?

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define SWITCH 7

int countSwitch = 0;
int prevState = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(SWITCH, INPUT);

}

void loop()
{
   byte currState = digitalRead(SWITCH); // Buttons are for shirts; switches are for Arduinos
   if(currState != prevState)
   {
      if(currState == HIGH)
         countSwitch++;
  
   prevState = currState;
}
  
  switch (countSwitch)  
  {
  case 1:
  Udp.beginPacket(remote_ip,remote_port);
  Udp.write("P9H");
  Udp.endPacket();
  delay(250);
  break;
  
  case 2:
  Udp.beginPacket(remote_ip,remote_port);
  Udp.write("P9L");
  Udp.endPacket();
  delay(250);
  break;
}
}
#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int statoButton     = 0;      // stato del pulsante (inizialmente non premuto) 
int lastStatoButton = 0;      // ultimo stato del pulsante (per ora non premuto) 
int countButton     = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;


EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() {
 
  if(digitalRead(BUTTON)) 
  {   
    delay(15);   

    if(lastStatoButton==0) lastStatoButton=1; 
    else lastStatoButton=0; 
 
    if(countButton=0) countButton=countButton+1; 
    else countButton=0; 
  } 
   
  switch (countButton) 
  {
  case 1:
  {
  Udp.beginPacket(remote_ip,remote_port);
  char DataOut[] = "P6H";
  Udp.write(DataOut);
  Udp.endPacket();
  delay(250);
  break;
  }
  case 2:
  {
  Udp.beginPacket(remote_ip,remote_port);
  char Data[] = "P6L";
  Udp.write(Data);
  Udp.endPacket();
  delay(250);
  }
}
}

I should really go down and really all the comments and code lol...

but all i did was add { } around case to make it compile.

ok cjdelphi...now Arduino don't send nothing :slight_smile:

If i use this sketch...arduino does what i want but with 2 button! but i would like to do this only with a button...

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7
#define BUTTON2 2
int  val = 0;
int  val2 = 0;

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x66, 0x7F };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;


EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);
pinMode(BUTTON2, INPUT);

}

void loop() { 
  
  val = digitalRead(BUTTON);
  val2 = digitalRead(BUTTON2);
  
  if (val == HIGH) { 
  char DataOut[] = "P6H";
  Udp.beginPacket(remote_ip,remote_port);
  Udp.write(DataOut);
  Udp.endPacket();
  delay(250);  
}
  else if (val2 == HIGH) { 
  Udp.beginPacket(remote_ip,remote_port);
  char Data[] = "P6L";
  Udp.write(Data);
  Udp.endPacket();
  delay(250);
}
}

@cjdelphi
First, you need to start using Tools + Auto Format to format your code. Properly indented code is easy to read. That stuff you posted with the random indents is not.

Second, you need to adopt a consistent style. Either { goes on a new line (as I prefer) or it does not. Mixing styles makes for hard to read code.

Third, you really need to start helping yourself. For instance, use Serial.print() to print some information about countButton/countSwitch each time it is changed. Does it change when you expect, and only when you expect?

In my code, I only showed how to increment the value at the transitions, from released to pressed. You needed to add the code to limit the value to the range you desire. In my code, countSwitch counts 0, 1, 2, 3, 4, 5... You only have cases for 1 and 2.

What you should have cases for is odd or even or you should ensure that countSwitch never exceeds 2.

Hi again.

I bashed that code and see I made a misakte.

What have I done?

READ THIS!

Originally I messed up with a counter - called button_flag.
It is acutally a bad name - it is more a loop_counter.
So I have changed its name now.

When you press the button it is set to ZERO.

Then the sketch looks at loop_counter and only if it is ZERO, does it do the next part.
Then: loop_counter is set to ONE.
This stops the loop happening agian until the button is presssed and loop_counter is reset to ZERO.

I wasn't thinking too straight when I did the code, and like you I am new to the Arduino.

I hope this works for you now.

By the way, the indents:
If they are not the best, I am sorry, but for some reason notepad seems to have messed them up.

And I agree with what Paul said:
You need to find and stick to ONE way of writing your codes/sketches. Mixing as you type is confusing for people reading it.

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int countButton = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() 
{
int loop_counter;
    if(digitalRead(BUTTON))  
    {
          //
          loop_counter = 0;
          delay(30);
          countButton = countButton + 1;
          countButton = countButton % 2;
     }
     if (loop_counter == 0)
     {
        loop_counter = 1;
        switch (countButton)  
        {
          case 1:
          Udp.beginPacket(remote_ip,remote_port);
          Udp.write("P9H");
          Udp.endPacket();
          delay(250);
          break;
  
          case 2:
          Udp.beginPacket(remote_ip,remote_port);
          Udp.write("P9L");
          Udp.endPacket();
          delay(250);
          break;
        }
     }
}
[/code[

not my code....

PaulS:
@cjdelphi
First, you need to start using Tools + Auto Format to format your code. Properly indented code is easy to read. That stuff you posted with the random indents is not.

Second, you need to adopt a consistent style. Either { goes on a new line (as I prefer) or it does not. Mixing styles makes for hard to read code.

Third, you really need to start helping yourself. For instance, use Serial.print() to print some information about countButton/countSwitch each time it is changed. Does it change when you expect, and only when you expect?

In my code, I only showed how to increment the value at the transitions, from released to pressed. You needed to add the code to limit the value to the range you desire. In my code, countSwitch counts 0, 1, 2, 3, 4, 5... You only have cases for 1 and 2.

What you should have cases for is odd or even or you should ensure that countSwitch never exceeds 2.

Another thought on how to "approcah" this requirement with the sketch and how it works.

With what you have said you want it to do:
It waits for the button to be pressed.
The "message number" is toggled between 0 and 1.
Depending on the value of "message number" a different message is sent on the TCP line.

But how to do all that.

Wait for the button to be pressed - ofcourse there is the problem of swtich bounce.
So, to remove bounce, you could then wait for the switch to be released.

Then act on what was set with the switch was pressed.
That means a bit more coding - but doesn't it always?
For now, I won't go into that. I have done test stuff with two wires for the switch and not had switch bounce.
(Funny that.)

But let us know how things are going with the latest sketch.

Note to others:
I am not trying to say in any way mine is better than yours. There are MANY ways to do what he wants, and we are all putting our own perceived way of doing it.

Thank you lost_and_confused for your interest... i try your last sketch but unfortunately doesn't work.. when i push the button send infinity PH9 and the second push conntinue to send P9H

No problems.

Just a couple of thoughts:

PUSH - what does that mean to you?

A quick press, or a press and hold for about 3 seconds then release?

The sketch may "fail" if the button is down for a "while" because it will keep reseting the "loop_counter".
But once the button is up/released, it should only happen once more.

And, for the sake of making things a lot clearer, the two messages:
Make them VERY different to help people when "we" are quickly reading the reply.

For instance: For the first message make it send "Button press 1" and when it is pressed the second time make it send "Button press 2" so it is clear there is not any other problems lurking.

The P9H and PH9 are confusing for me when I am reading and now thinking a bit more:
Seem to be the right way around. So really it is extra information which isn't really needed.
The problem now as it seems is that somehow the messages are being sent continually.

Here is another effort to try and work out where the problem is:

#include <SPI.h>
#include <EthernetUdp.h>
#include <Ethernet.h>

#define BUTTON 7

int countButton = 0;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168,1, 177 };

unsigned int localPort = 7777;

byte remote_ip[] = { 192, 168,1, 100 };

unsigned int remote_port = 7777;

EthernetUDP Udp;

void setup() {

Ethernet.begin(mac,ip);

Udp.begin(localPort);

pinMode(BUTTON, INPUT);

}

void loop() 
{
int loop_counter;
    if(digitalRead(BUTTON)== 1)  
    {
          //  Clear loop counter when the button is pressed.
          loop_counter = 0;
          delay(30);
          countButton = countButton + 1;
          countButton = countButton % 2;
     }
     if (digitalRead(Button) == 0)
     //  Now, this part of the code won't happen until the button is released.
     {
         if (loop_counter == 0)
         //  This part will only happen if loop_counter is zero.
         {
            loop_counter = 1;
            //  Set loop_counter to one so this code can only happen once
            //  In some ways this is not needed now because we are waiting for
            //  the button to be released before getting here.
            //  But it is better to be safe than sorry, and where you seem to be
            //  it is probably a good idea to do.
            switch (countButton)  
            {
                case 1:
                Udp.beginPacket(remote_ip,remote_port);
                Udp.write("P9H");
                Udp.endPacket();
                delay(250);
                break;
    
                case 2:
                Udp.beginPacket(remote_ip,remote_port);
                Udp.write("P9L");
                Udp.endPacket();
                delay(250);
                break;
            }
         }
     }
}