I'm doing a ball and beam project in which I must use a dial potentiometer to change the setpoint of a PID system and have it move the ball to the designated position on the beam. I am measuring the balls position with a soft membrane potentiometer. I have tested both potentiometers and they both read accurately the servo I'm using also works fine. I know to change the values of kp, ki, kd. The code uploads fine.
My current problem is that the PID seems to ignore the setpoint from the dial. I know the dial is reading because of serial print. I just don't know how to get the loop to use the dial as a changing setpoint.
#include <Servo.h> // add servo library
#include<PID_v1.h>
const int potpin = 1; // analog pin used to connect the potentiometer strip
const int dial = 2; // analog pin used to connect the potentiometer dial
const int servoPin = 4; //Servo Pin 4
float val;
float bal;
float cal;
float val2;
float bal2;
float cal2;
float Kp = 10; //Initial Proportional Gain
float Ki = 0; //Initial Integral Gain
float Kd = 0; //Intitial Derivative Gain
double Setpoint, Input, Output, ServoOutput;
// the setup routine runs once when you press reset:
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT); //Initialize PID object, which is in the class PID.
Servo myServo; //Initialize Servo.
void setup() {
Serial.begin(9600); //Begin Serial
myServo.attach(servoPin); //Attach Servo
Input = readPosition(); //Calls function readPosition() and sets the balls position as the input to the PID algorithm
Setpoint = setPosition();
myPID.SetMode(AUTOMATIC); //Set PID object myPID to AUTOMATIC
myPID.SetOutputLimits(-30,30); //Set Output limits to -30 and 30 degrees.
}
void loop()
{
pinMode(dial, INPUT);
pinMode(potpin, INPUT);
Input = -readPosition();
Setpoint = setPosition();
myPID.Compute(); //computes Output in range
ServoOutput=110+Output; // 110 degrees is my horizontal (level to how I mounted the servo)
myServo.write(ServoOutput); //Writes value of Output to servo
delay(10);
}
float readPosition() {
delay(10);
pinMode(potpin, INPUT);
// read the input on analog pin 1:
float sensorValue = cal;
// print out the value you read:
Serial.println(sensorValue); // prints the read value ( this has been checked, I am getting a correct reading)
val = analogRead(A1); // reads the value of the potentiometer (value between 0 and 1096)
bal = map(val, 0, 1023, 0, 1968); // scale it to use it with the servo (value between 0 and 12)
cal = (12.3-(bal/100));
}
float setPosition() {
delay(10);
pinMode(dial, INPUT);
// read the input on analog pin 2:
float sensorValue = cal2;
//Serial.println(sensorValue); // prints the read value ( this has been checked, I am getting a correct reading)
val2 = analogRead(A2); // reads the value of the potentiometer (value between 0 and 1023) and maps it to (0 to 1200)
bal2 = map(val2, 0, 1023, 0, 1200); // scale it to use it with the servo (value between 0 and 12) and filp so zero is on the side I want
cal2 = (12-(bal2/100));
FINAL.ino (3.29 KB)