I've done a basic circuit that is consisting of a: servo, button, LED and 16x2 LCD.
Servo is doing a preprogrammed dancing rotine and while arm is doing its swings, I thought to try to pick up input from a push button. So, instead of delay(), I am making use of millis() function.
Thing is that, it works, but not so well. In order to get a code to pick up the push button's press, I need to press the button several times. Can somebody spot in the code what makes it so irresponsive to button's input?
/*
* 3.7.10 - original code is modified so that:
*
* - millis() is used instead of delay(). That way, precious clock cycles are not wasted, doing nothing.
* - a single button, with pull up resistor, and one variable are used to provide software & hardware
* toggle switch,
*
* -
*/
// Sweep
// by BARRAGAN <http://barraganstudio.com>
#include <Servo.h>
#include <LiquidCrystal.h>
// initialise SERVO:
const int pinServoLED = 10; // pin for controling circuit mode LED. When green LED is ON, than
// servo should be running, when OFF servo should be motionless.
const int pinServo = 9; // pin for controling servo #1.
const int inputPin = 8; // pushbutton's Arduino input pin: button pressed, pin goes LOW.
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created.
int posServo = 0; // variable to store the servo position.
int modeCircuit = 0; // circuit toggles from OFF to ON to OFF to ON state. And so on.
// initialize LCD:
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
// SERVO:
pinMode(pinServoLED, OUTPUT); // declare LED controling pin.
digitalWrite(pinServoLED, LOW);
pinMode(inputPin, INPUT); // declare pushbutton on inputPin as input.
myservo.attach(pinServo); // attaches the servo on pinServo to the servo object
myservo.write(90); // set servo to mid-point.
// LCD: set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// LCD: Print an initial message to the LCD.
lcd.print("MODE= "); lcd.print(modeCircuit);
}
void loop() {
unsigned long tNow;
/*
for(posServo = 0; posServo < 180; posServo += 20) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(posServo); // tell servo to go to position in variable 'posServo'
delay(500); // waits 15ms for the servo to reach the position
}
for(posServo = 180; posServo>=1; posServo-=20) // goes from 180 degrees to 0 degrees
{
myservo.write(posServo); // tell servo to go to position in variable 'posServo'
delay(500); // waits 15ms for the servo to reach the position
}
*/
// 3.7.10 - This is sort of dancing alghoritam, just to understand it properly.
myservo.write(0); timeGap(millis(), 375UL);
myservo.write(90); timeGap(millis(), 750UL);
myservo.write(80); timeGap(millis(), 350UL);
myservo.write(90); timeGap(millis(), 350UL);
myservo.write(100); timeGap(millis(), 350UL);
myservo.write(180); timeGap(millis(), 375UL);
myservo.write(90); timeGap(millis(), 750UL);
myservo.write(100); timeGap(millis(), 350UL);
myservo.write(90); timeGap(millis(), 350UL);
myservo.write(80); timeGap(millis(), 350UL);
myservo.write(0);
}
/*
* checkCircuitMode() function takes care of the software switch variable modeCircuit that
* regulates a behaviour of the circuit.
*/
void checkCircuitMode() {
int intButtonState = digitalRead(inputPin); // Check the inputPint, to see weather button was pressed.
if ( intButtonState == LOW ) { // When button is pressed, inputPin will go to LOW.
if (modeCircuit == 0) {
modeCircuit = 1; digitalWrite(pinServoLED, HIGH);
} else {
modeCircuit = 0; digitalWrite(pinServoLED, LOW);
}
// LCD: tell the circuit mode to everybody.
lcd.clear(); lcd.print("MODE= "); lcd.print(modeCircuit);
}
return;
}
/*
* timeGap(unsigned long tOld, unsigned long tGap);
*
* tOld - time gap's start time [miliseconds],
* tGap - length of the time gap [miliseconds],
*
* Using delay() function is not very productive. Because of it, a whole microprocessor
* gets halted, doing nothing, receiving no inputs, unitl the specified delay passes. It
* lays to waste usefull microprocessor time, during which something can be done.
*
*/
void timeGap(unsigned long tOld, unsigned long tGap) {
unsigned long tCurrent;
// During the time gap, Arduino can do few usefull things:
do {
// Here, from this line to the end of the loop, you just put things you want to be
// done doring the gap time. Much better than delay(), since something is done.
checkCircuitMode(); // Check weather circuit mode change button was pressed.
tCurrent = millis();
} while ((tCurrent - tOld) < tGap);
tOld = tCurrent;
return;
}
Here is the pretty picture, as well: