I am new to Arduino. I am using Arduino Uno with H bridge to get forward and reverse rotation of the motor. I am also using encoder to get position of the motor. I would also like add 2 limit switches to get the end points of the particular path. For now I am able to get the forward and reverse rotation of the motor also adjusting the speed with PID. So my question is how can I add code for limit switches in the code that I already have.
Here is my code. I am using PID controller library which I found online.
#include <PIDController.h>
int distance = 30000;
int MotorSpeedLeft = 50;
int MotorSpeedRight = 70;
volatile int temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
PIDController pos_pid;
int motor_value = 255;
int difference = 100;
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP); // encoder white to arduino 2
pinMode(3, INPUT_PULLUP); // encoder green to arduino 3
pinMode(9, OUTPUT); // motor driver LPWM to arduino 9
pinMode(10, OUTPUT); // motor driver RPWM to arduino 10
attachInterrupt(0, ai0, RISING);
attachInterrupt(1, ai1, RISING);
pos_pid.begin();
pos_pid.tune(0.1,20, 0); //P,I,D
pos_pid.limit(-MotorSpeedLeft, MotorSpeedRight); //Motor speed
pos_pid.setpoint(distance);
TCCR1B = TCCR1B & B11111000 | B00000011; // for PWM frequency of 490.20 Hz (The DEFAULT)
}
void loop() {
Serial.print (counter);
Serial.println (motor_value);
temp = counter;
if (counter > distance-difference){
pos_pid.setpoint(-distance);
}
else if (counter < -(distance-difference))
{ pos_pid.setpoint(distance);
}
motor_value = pos_pid.compute(counter);
if(motor_value > 0){
MotorCounterClockwise(motor_value);
}else{
MotorClockwise(abs(motor_value));
}
Serial.print(counter);
// delay(1);
// digitalWrite(9, LOW);
// digitalWrite(10, LOW);
}
void ai0() {
if(digitalRead(3)==LOW) {
counter++;
}else{
counter--;
}
}
void ai1() {
if(digitalRead(2)==LOW) {
counter--;
}else{
counter++;
}
}
void MotorClockwise(int power){
if(power > 10){
Serial.print("CW");
analogWrite(9, power);
digitalWrite(10, LOW);
}else{
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}
}
void MotorCounterClockwise(int power){
if(power > 10){
Serial.print("CCW");
analogWrite(10, power);
digitalWrite(9, LOW);
}else{
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}
}
Thanks for presenting your program properly. I should also have mentioned that if you use the AutoFormat tool it will indent your code consistently and make it much easier to read - something like this
#include <PIDController.h>
int distance = 30000;
int MotorSpeedLeft = 50;
int MotorSpeedRight = 70;
volatile int temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
PIDController pos_pid;
int motor_value = 255;
int difference = 100;
void setup() {
Serial.begin (9600);
pinMode(2, INPUT_PULLUP); // encoder white to arduino 2
pinMode(3, INPUT_PULLUP); // encoder green to arduino 3
pinMode(9, OUTPUT); // motor driver LPWM to arduino 9
pinMode(10, OUTPUT); // motor driver RPWM to arduino 10
attachInterrupt(0, ai0, RISING);
attachInterrupt(1, ai1, RISING);
pos_pid.begin();
pos_pid.tune(0.1,20, 0); //P,I,D
pos_pid.limit(-MotorSpeedLeft, MotorSpeedRight); //Motor speed
pos_pid.setpoint(distance);
TCCR1B = TCCR1B & B11111000 | B00000011; // for PWM frequency of 490.20 Hz (The DEFAULT)
}
void loop() {
Serial.print (counter);
Serial.println (motor_value);
temp = counter;
if (counter > distance-difference){
pos_pid.setpoint(-distance);
}
else if (counter < -(distance-difference)) {
pos_pid.setpoint(distance);
}
motor_value = pos_pid.compute(counter);
if(motor_value > 0){
MotorCounterClockwise(motor_value);
}
else{
MotorClockwise(abs(motor_value));
}
Serial.print(counter);
// delay(1);
// digitalWrite(9, LOW);
// digitalWrite(10, LOW);
}
void ai0() {
if(digitalRead(3)==LOW) {
counter++;
}else{
counter--;
}
}
void ai1() {
if(digitalRead(2)==LOW) {
counter--;
}
else {
counter++;
}
}
void MotorClockwise(int power){
if(power > 10){
Serial.print("CW");
analogWrite(9, power);
digitalWrite(10, LOW);
}
else{
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}
}
void MotorCounterClockwise(int power){
if(power > 10){
Serial.print("CCW");
analogWrite(10, power);
digitalWrite(9, LOW);
}
else{
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}
}
Now to deal with your question about adding code for limit switches ...
I would add a function that reads the two switches and saves their values. Then you could add some code to loop() like this
checkLimitSwitches();
if (limitSwitchAstate == LOW) { // assumes LOW when pressed
// do something
}
if (limitSwitchBstate == LOW) {
// do something else
}
And it would probably be neater to put the code to act on the switches in its own function to simplify the extra code in loop() to