I am very new to Arduino and programming.
While I have owned some for years I have found it hard to get my head around the programming side of things.
But I now have a project where an Arduino would be very useful so I am again trying to force myself to get my head around programming.
What I would like to do is press and hold a button switch which causes a servo to move say 20° to the right then return to its original position. This will need to happen only once but while the button is continually pressed.
The servo is going to actuate a trigger on a pneumatic nail remover (the trigger needs to be released before the pin will retract).
So I have tried to modify the servo sweep example and add a button which does work in the fact that when I press the button the servo starts to sweep and when I release the button it stops.
The problem is that I cannot seem to work out how to get this to happen only once (while the button is continually pressed).
I hopefully have posted my code below.
I tried adding a counter so that when the count reached 1 it would stop but I do now understand that this would not work.
If somebody could help point me in the right place to look so that I can learn how to wright the correct code that would be great.
#include <Servo.h>
Servo servo1;
const int buttonPin = 5;
int pos = 50;
int delayPeriod = 250;
int buttonState = (digitalRead(buttonPin));
int count = 0;
void setup() {
servo1.attach(9); // put your setup code here, to run once:
pinMode (buttonPin,INPUT_PULLUP);
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == LOW){
servo1.write(pos);
delay (delayPeriod);
servo1.write(150);
delay (delayPeriod);
servo1.write(pos);
delay (delayPeriod);
count ++;
if (count == 1){
servo1.write(pos);
count = 0;
}
}
}
What I would like to do is press and hold a button switch which causes a servo to move say 20° to the right then return to its original position. This will need to happen only once but while the button is continually pressed.
Expand on this.
BTW
Use CTRL T to format your code.
Attach your ‘complete’ sketch between code tags, use the </> icon in the posting menu. [code]Paste your sketch here[/code]
So what this is going to be used for is a punch for fixing plastic tube ends into some aluminium tube.
The idea is that the tube will be pushed into the machine and up against the button switch.
The problem is that the way the machine works you do not press and release a button with your hand.
Because it is done when you slide the tube in we don't want it left there getting punched more than once.
I know that I could add a longer delay to give enough time to remove the tube but I was just wondering if there was a way to have the code only perform this once with the button pressed?
What would be the minimum time for a valid switch press?
EDIT No free servo here to test, to be tested:
//Version 1
//Switch must be held or released for a minimum amount of time ex: 1/2 second
#include <Servo.h>
Servo servo1;
const byte buttonPin = 5; //closed = pushed
//machine state stuff
const byte STOPPED = 0;
const byte START = 1;
const byte STATE1 = 2;
byte mState = STOPPED;
//
byte buttonState;
byte lastState;
bool machineBusyFlag = false;
//servo timing stuff
unsigned long timingMillis;
//time at moveTo = 250ms
const unsigned long delayPeriod = 250ul;
const byte pos = 50;
const byte moveTo = 150;
//switch timing stuff
unsigned long validateMillis;
//switch must be pressed for 1/2 second to be valid
const unsigned long validatePeriod = 500ul;
//heartBeat timing
unsigned long heartBeatMillis;
//***************************************************************************
void setup()
{
servo1.attach(9);
//move to position pos
servo1.write(pos);
//heartBeat LED
pinMode(13, OUTPUT);
pinMode (buttonPin, INPUT_PULLUP);
lastState = (digitalRead(buttonPin));
}
//***************************************************************************
void loop()
{
//********************************
//to monitor for blocking code, toggle the heart beat LED every 500ms
if (millis() - heartBeatMillis >= 500)
{
//restart timer
heartBeatMillis = millis();
//toggle heartBeat LED
digitalWrite(13, !digitalRead(13));
}
//********************************
readSwitch();
stateMachine();
//other non-blocking code
} //END of loop()
//***************************************************************************
void readSwitch()
{
//********************************
if (machineBusyFlag == true)
{
//we are busy now don't read the switch
return;
}
buttonState = digitalRead(buttonPin);
//********************************
//is the switch in the same position?
if (lastState == buttonState)
{
//restart the validation timer
validateMillis = millis();
}
//********************************
//has the validation time passed?
if (millis() - validateMillis < validatePeriod)
{
//switch has not stayed stable long enough
return;
}
//********************************
if (lastState != buttonState)
{
lastState = buttonState;
//********************************
//has the switch just been closed
if (buttonState == LOW)
{
servo1.write(pos); //move to position pos
//machine state to the starting state
mState = START;
timingMillis = millis();
machineBusyFlag = true;
}
} //END of if (lastState != buttonState)
} //END of readSwitch()
//***************************************************************************
void stateMachine()
{
switch (mState)
{
case STOPPED:
//do nothing
break;
case START:
if (millis() - timingMillis >= delayPeriod)
{
servo1.write(moveTo);
timingMillis = millis();
mState = STATE1;
}
break;
case STATE1:
if (millis() - timingMillis >= delayPeriod)
{
servo1.write(pos);
mState = STOPPED;
//flag that we are not busy now
machineBusyFlag = false;
}
break;
} //END of switch/case
} //END of stateMachine()
I have a question regarding your code.
Did you use "byte" instead of "int" to save on program size and if so is there a reason not to use byte all of the time?
boolean (8 bit) - simple logical true/false, Arduino does not use single bits for bool
byte (8 bit) - unsigned number from 0-255
char (8 bit) - signed number from -128 to 127. The compiler will attempt to interpret this data type as a character in some circumstances, which may yield unexpected results
unsigned char (8 bit) - same as 'byte'; if this is what you're after, you should use 'byte' instead, for reasons of clarity
word (16 bit) - unsigned number from 0-65535
unsigned int (16 bit)- the same as 'word'. Use 'word' instead for clarity and brevity
int (16 bit) - signed number from -32768 to 32767. This is most commonly what you see used for general purpose variables in Arduino example code provided with the IDE
unsigned long (32 bit) - unsigned number from 0-4,294,967,295. The most common usage of this is to store the result of the millis() function, which returns the number of milliseconds the current code has been running
long (32 bit) - signed number from -2,147,483,648 to 2,147,483,647
float (32 bit) - signed number from -3.4028235E38 to 3.4028235E38. Floating point on the Arduino is not native; the compiler has to jump through hoops to make it work. If you can avoid it, you should. We'll touch on this later.
You select the ‘type’ best suited for your variables.
ex:
your variable does not change and it defines a pin on the Arduino. const byte limitSwitchPin = 34;
since an analog variable can be 0 to 1023, a byte will not do, you can select ‘int’. int temperature;
if your variable needs to be within -64 to +64 a ‘char’ will do nicely. char joystick;
if your variable is used for ASCII then you need type ‘char’, char myText[] = {“AtomicWedgie”};
if your variable enables some code then boolean can be used. boolean enableFlag = false;
etc.