I'm working on this ball and beam project and I'm trying to match the dial potentiometer with the softpot in the beam in terms of inches. I would like it so that the ball stays on the right side from the center, but the strip is 20 inches long. That's what was supplied. My code works with the PID controller in it, just need help to map both potentiometers to the correct numbers. Here is my code:
#include <Servo.h> // Arduino Servo Library
#include <PID_v2.h>
// Servo, potentiometers setup
const int SetpointPotPin = A3; // User Input
const int FeedbackPotPin = A4; // Pin connected to softpot wiper
const int ServoPin = 9;
double Input, Output, Setpoint;
float Kp = 0.75; // Initial Proportional Gain
float Ki = 0; // Initial Integral Gain
float Kd = 0.25; // Initial Derivative gain
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Note: Use REVERSE instead of DIRECT when higher Output
// tilts the ball toward lower SoftPot values
Servo myServo;
void setup()
{
Serial.begin(115200);
myServo.attach(ServoPin);
myPID.SetMode(AUTOMATIC); // Start the control loop
myPID.SetOutputLimits(1000, 2000); // Output drives 'servo.writeMicroseconds)'
}
void loop()
{
// Where do we want the ball to settle
Setpoint = analogRead(SetpointPotPin);
// Where is the ball right now
Input = analogRead(FeedbackPotPin);
myPID.Compute();
myServo.writeMicroseconds(Output);
}
So what's it's supposed to do is whatever number the dial potentiometer is set to, that's the inch mark that the beam is supposed to self balance the ball using the softpot. My code has that working, I just need to scale the values so that the softpot knows where 0 inch to 12 inch is, samething with the dial potentiometer.
I'm working on this ball and beam project and I'm trying to match the dial potentiometer with the softpot in the beam in terms of inches. I would like it so that the ball stays on the right side from the center, but the strip is 20 inches long. That's what was supplied. My code works with the PID controller in it, just need help to map both potentiometers to the correct numbers. It works without the map functions in the loop, but once they're added the servo doesn't move the beam with the position but the mapping in the serial monitor is correct. Need help with fixing this. Here is my code:
#include <Servo.h> // Arduino Servo Library
#include <PID_v2.h>
// Servo, potentiometers setup
const int SetpointPotPin = A3; // User Input
const int FeedbackPotPin = A4; // Pin connected to softpot wiper
const int ServoPin = 9;
double DialPot, SoftPot;
double Input, Output, Setpoint;
float Kp = 0.75; // Initial Proportional Gain
float Ki = 0; // Initial Integral Gain
float Kd = 0.25; // Initial Derivative gain
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
// Note: Use REVERSE instead of DIRECT when higher Output
// tilts the ball toward lower SoftPot values
Servo myServo;
void setup()
{
Serial.begin(9600);
myServo.attach(ServoPin);
myPID.SetMode(AUTOMATIC); // Start the control loop
myPID.SetOutputLimits(1000, 2000); // Output drives 'servo.writeMicroseconds)'
}
void loop()
{
// Where do we want the ball to settle
DialPot = analogRead(SetpointPotPin);
DialPot = map(DialPot, 0, 1023, 8, 20);
Setpoint = DialPot;
// Where is the ball right now
SoftPot = analogRead(FeedbackPotPin);
SoftPot = map(SoftPot, 0, 1023, 0, 20);
Input = SoftPot;
myPID.Compute();
myServo.writeMicroseconds(Output);
Serial.print("Knob Val: ");
Serial.println(DialPot);
Serial.print("Strip Pot Val: ");
Serial.println(SoftPot);
}
You need to supply more information. What detects the position of the ball, and how? What would be the "correct numbers"? What have you done to verify the scaling in the map() function?
Put in print statements to see the PID input and output values and verify that they make sense. It should be easy to understand why the servo doesn't move.
Note: The map() function works in integers so there are only 21 positions between 0 and 20 while there are 1024 positions of the pot. I recommend you use positions in hundredths of an inch: SoftPot = map(SoftPot, 0, 1023, 0, 2000);
Is your mapping correct? If you put the ball at inch marker 0 do you get 0 for Input? If you put the ball at inch marker 20 to you get 2000?
You must use the same units for Setpoint as for Input. Whenyou change the Input to hundredths you must also change the Setpoint to the same scale.
Note: If you want to display in inches, just use Setpoint/100.0 and Input/100.0.