I want to control a servo motor in a way that
- if you push the button, you can control it by potentiometer a
- if you push double time, you can control servo with infrared
- if you hold button step motor start to to rotate from one position to another
I have a problem that when I press button it goes to an infinite loop and I can not stop it . I try different button library but I still have a same problem. Here is my code :
// includes the Servo library
#include <Servo.h>
#include <IRremote.h>
#include <OneButton.h>
int state = 0;
int RECV_PIN = 12;
const char type ='W';// W for white, B for black. Must keep single quotes like 'B' or 'W'
const boolean PCB = 0;// if receiver is PCB set to 1, if not set to 0. See video for details
boolean displayCode = true;// to display remote code. if not, set to false
const int SERVO_PIN = 8; // analog pin used to connect the potentiometer
int angle =90; // initial angle for servo
int angleStep =10;
const int ANGLE_CENTRE =90;// the centre/reset angle of your servo
//**** Servo settings settings ends
// remote settings
const String RIGHT="CH+";// move servo to the right with this key on remote
const String LEFT ="CH-";// move servo to the left with this key on remote
const String CENTRE ="CH";// move servo to centre with this key on remote
// remote settings end
IRrecv irrecv(RECV_PIN);
// Defines Tirg and Echo pins of the Ultrasonic Sensor
const int trigPin = 10;
const int echoPin = 11;
const int potPin = 0;
const int pushButton = 8;
OneButton button(A1, true);
int value;
// Variables for the duration and the distance
long duration;
int distance_cm;
Servo myServo; // Creates a servo object for controlling the servo motor
// this is array holding codes for White Remote when used with non-PCB version of receiver
unsigned int whiteRemote[] ={
0xFFA25D, // CH-
0xFF629D, // CH
0xFFE21D, // CH+
0xFF22DD, // |<<
0xFF02FD, // >>|
0xFFC23D, // >||
0xFFE01F, // -
0xFFA857, // +
0xFF906F, // EQ
0xFF6897, // 0
0xFF9867, // 100+
0xFFB04F, // 200+
0xFF30CF, // 1
0xFF18E7, // 2
0xFF7A85, // 3
0xFF10EF, // 4
0xFF38C7, // 5
0xFF5AA5, // 6
0xFF42BD, // 7
0xFF4AB5, // 8
0xFF52AD // 9
};
// key lables of white remote
String whiteRemoteKey[] ={
"CH-",
"CH",
"CH+",
"|<<",
">>|",
">||",
"-",
"+",
"EQ",
"0",
"100+",
"200+",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
};
// this is array holding codes for Black Remote when used with non-PCB version of receiver
unsigned int blackRemote[] ={
0xFF629D, // ^
0x38D3975C, // <
0x9334F738, // OK
0x320412D8, // >
0xFFA857, // v
0xFF6897, // 1
0xFF9867, // 2
0xF0C41643, // 3
0xFF30CF, // 4
0xFF18E7, // 5
0xFF7A85, // 6
0xFF10EF, // 7
0xFF38C7, // 8
0xFF5AA5, // 9
0xFF42BD, // *
0xFF4AB5, // 0
0xFF52AD // #
};
// Black remote key names
String blackRemoteKey[] ={
"^",
"<",
"OK",
">",
"v",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"*",
"0",
"#"
};
decode_results results;
void setup() {
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an input
Serial. begin(9600);
irrecv.enableIRIn(); // Start the receiver
myServo.attach(SERVO_PIN); // Defines on which pin is the servo motor attached
button.attachDoubleClick(doubleClick); // link the function to be called on a doubleClick event.
button.attachClick(singleClick); // link the function to be called on a singleClick event.
button.attachLongPressStop(longClick); // link the function to be called on a longpress event.
}
void loop() {
button.tick(); // check the status of the button
delay(10); // a short wait between checking the button
}
// Function for calculating the distance measured by the Ultrasonic sensor
int calculateDistance(){
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HiGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH); // Reads the echoPin, returns the sound wave travel time in microseconds
//Comment by me!
//distance= duration*0.034/2;
//
distance_cm = (duration/2) / 29.1;
return distance_cm;
}
void doubleClick() { // what happens when button is double-clicked
while(1) {
if (irrecv.decode(&results)) {
if(displayCode)Serial.println(results.value, HEX);
validateCode(results.value);// used the "robojaxValidateCode" bellow
irrecv.resume(); // Receive the next value
}
delay(50);// 50 melisecond delay
break;
}
}
void singleClick(){ // what happens when the button is clicked
while(1) {
value = analogRead(potPin);
value = map(value, 0, 1023, 15, 165);
myServo.write(value);
delay(30);
distance_cm = calculateDistance();
Serial.print(value); // Sends the current degree into the Serial Port
Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing iDE for indexing
Serial.print(distance_cm); // Sends the distance value into the Serial Port
Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing iDE for indexin
}
}
void longClick(){ // what happens when buton is long-pressed
for(int i=15;i<=165;i++){
myServo.write(i);
delay(30);
distance_cm = calculateDistance();// Calls a function for calculating the distance measured by the Ultrasonic sensor for each degree
Serial.print(i); // Sends the current degree into the Serial Port
Serial.print(","); // Sends addition character right next to the previous value needed later in the Processing iDE for indexing
Serial.print(distance_cm); // Sends the distance value into the Serial Port
Serial.print("."); // Sends addition character right next to the previous value needed later in the Processing iDE for indexin
}
// Repeats the previous lines from 165 to 15 degrees
for(int i=165;i>15;i--){
myServo.write(i);
delay(30);
distance_cm = calculateDistance();
Serial.print(i);
Serial.print(",");
Serial.print(distance_cm);
Serial.print(".");
}
}
/*
* function: validateCode
* validates the remote code and prints correct key name
* cd is code poassed from the loop
* Written by A. S. for Robojax
*/
void validateCode(int cd)
{
// Robojax IR Remote decoder
int found=0;
if(type =='W' && !PCB)
{
// Robojax IR White Remote decoder
// if tyepe is set to 'W' (white remote) and PCB=0 then check Black remote code
for(int i=0; i< sizeof(whiteRemote)/sizeof(int); i++)
{
if(whiteRemote[i] ==cd)
{
Serial.print("Key pressed:");
Serial.println(whiteRemoteKey[i]);
servoAction(whiteRemoteKey[i]);// take action
found=1;
}// if matched
}// for
}else{
// if tyepe is set to 'B' (black remote) and PCB =0 then check Black remote code
for(int i=0; i< sizeof(blackRemote)/sizeof(int); i++)
{
// Robojax IR black Remote decoder
if(blackRemote[i] ==cd)
{
Serial.print("Key pressed:");
Serial.println(blackRemoteKey[i]);
servoAction(blackRemoteKey[i]);// take action
found=1;
}// if matched
}// for
}// else
if(!found){
if(cd !=0xFFFFFFFF)
{
Serial.println("Key unkown");
}
}// found
}// validateCode end
/*
*
* servoAction()
* receives string "value" as input and based on the settings,
* sends translates it to servo value and controls servo
* either
* rotates servo to right
* rotates servo to left
* moves the servo to middle
*
*/
void servoAction(String value){
// Servo button demo with IR remote by Robojax.com
while(value == RIGHT){
if (angle > 0 && angle <= 180) {
angle = angle - angleStep;
if(angle < 0){
angle = 0;
}else{
myServo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}// if
value =".";
delay(100);
}// while for RIGHT
while(value == LEFT){
// Servo button demo with IR remote by Robojax.com
if (angle >= 0 && angle <= 180) {
angle = angle + angleStep;
if(angle >180){
angle =180;
}else{
myServo.write(angle); // move the servo to desired angle
Serial.print("Moved to: ");
Serial.print(angle); // print the angle
Serial.println(" degree");
}
}
value =".";
delay(100);
}// while for LEFT
if(value == CENTRE)
{
angle = ANGLE_CENTRE;
myServo.write(angle); // move the servo to centre at 90 degree angle
}
// Robojax IR Servo control
}//relayAction end
sorry about my English. I hope someone help me.