i just done coding below for my project...but now i need put PID at this system......
i have parameters Kp=10.15,Ki=20.19,Kd=-0.4461 this parameters i get from matlab.... some 1 plz help me
//Digital pin 7 for reading in the pulse width from the MaxSonar device.
const int pwPin = 7;
long pulse, inches, cm; //variables needed to store values
//stepper motor
#include <Stepper.h>
#define motorSteps 200 // change this depending on the number of steps
// per revolution of your motor
#define motorPin1 8
#define motorPin2 10
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
Stepper myStepper(motorSteps, motorPin1,motorPin2); // initialize of the Stepper library:
void setup(){
// set the motor speed at 300 RPMS:
myStepper.setSpeed(300);
// Initialize the Serial port:
Serial.begin(9600);
}
void loop() {
Input = analogRead(pwPin);
myPID.Compute();
analogWrite(8,Output);
pinMode(pwPin, INPUT);
//Used to read in the pulse that is being sent by the MaxSonar device.
//Pulse Width representation with a scale factor of 147 uS per Inch.
pulse = pulseIn(pwPin, HIGH);
//147uS per inch
inches = pulse/147;
//change inches to centimetres
cm = inches * 2.54;
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(50);
if ((inches > 35) || (cm > 88))
{
Serial.println("Backward");
myStepper.step(-1000);
delay(50);
}
if ((inches < 35) || (cm < 88))
{
Serial.println("Forward");
myStepper.step(30);
delay(50);
}
if ((inches=35) || (cm=88))
{
delay (50);
myStepper.step(0);
}
if ((inches=0) || (cm=0))
{
delay (50);
myStepper.step(0);
}}
What is "myPID.Compute()" sory for this code tag before this i try do PID autotune at this system but fail.....
my project is ROV but i use sensor at out side off pool....so i put ROV inside pool n sensor i hold out side same level my ROV when i press power button motor start moving follow sensor readying until. i will move sensor follow ROV until reach target position.....my project is to make sure my simple ROV can maintain underwater at some level....So i need apply PID to this sistem to make system batter.....before this i make manually run using arduino+stepper to get data to get transfer function so for this data i get tf for this system...now is my last step to make this system have PID
I would caution about using Matlab or anything else to simulate your system if it's not performing the PID calculations/decisions in precisely the same way as your target code, and uses precisely the same signal units with precisely the same value ranges. A PID solution in a simulation domain gives you feasibility results only, not gain values you can apply to a different target domain.
If you have access to a test pool, you may instead like to tune it intuitively. Start with a P-system only, try it with a low gain and check that the control responds in the correct phase first, (the control acts in the direction to oppose the error), then increase gain carefully until you get the beginnings of instability. Then try introducing a D-term to stabilise, and see if that helps you increase the P-gain further. The higher P-gain your system will take without instability, the less you need to worry about the I-term which is the most destabilising of all. Finally, use the lowest amount of I-gain possible to correct for long-term depth error, and consider using any integral anti-wind-up mechanism your PID algorithm has.
Correct, I want to control, indepth I set the 35inci = 88cm.
for code "myPID.Compute ()". before I try to use the library as an example PID Basic Example * Reading analog input 0 to control analog PWM output 3, but I do not know because I use to control PWM output pin 8 and 10. Become code "myPID.Compute ()". I forgot to delete before post .... so the code is only attempted before.
for a while I was using lv maxsensor ez01 pin PW. I use this sensor for swindling a cause close to malaysia hard to find a waterproof sensor. so I will hold the sensor on the outside of pool as the height of the ROV, when I was on the sensor will affect the initial height of 110cm so the motor will move forward and ROV began to sink in the same time hold the sensor that i will follow the ROV body in outdoor pool ... I can follow reason for pool ROV has a mirror so I can see the ROV from outside the pool.
the parameters in the original post I meant before using the sensor. I'm just using the stepper manually using a switch + Arduino to move the motor. I manually using the clock, where when switching installed before I let the motor move where will attract piston motor for 1.40min and stop the motor, and a delay where stable ROV In Britain obtained on into 88cm, after 5sec delay revived motor and the motor will push the piston and ROV rises to the surface ... when do I have to record vedio manual movement ROV for go down and up .. I recorded the results of each moment, using my count can calculate the length of the piston is pulled in 1 second as input, and each reached into each 1 second as output. I have a record of data available and the next using matlab system identification, from system identification i get transfer function, after that i using simulink and use PID autotune from here i get Kp,Ki,Kd...... now just want know how to make by using coding that i post to add PID auto tuning or by using value i have Kp,Ki,Kd..
I'm sorry but I can't make sense of your explanation. I think you are trying to put too much information into each sentence.
I'm guessing that English is not your native language and I'm sure you are much better at English than I am with your language (I probably know none of it).
Can you explain in detail what makes your submarine rise or sink? And how that is controlled by the Arduino?
Can you also say how accurately you want it to keep to the required depth +/- 10cm, perhaps?
my submarine rise or sink by movement piston,movement piston push n pull control by stepper motor,stepper motor move forward or reverse control using sensor.....yes keep to the required depth +/- 10cm.
How many steps can the stepper motor move the piston from one end to the other end, and how fast can it step?
Can you please explain how you measure depth, and what scale your depth sensor numbers are? (As an example: depth is 12-bit int, range 0 to 4095, depth=244 at surface and depth=4095 at 56 metres, so 1.5cm per increment).
I suspect a small geared DC motor would be sufficient to move the piston. Or perhaps it could rotate a screw to screw the piston in or out.
A stepper motor is only likely to be useful if you know how many steps are needed to make the submarine rise or sink a known amount. For example - 300 steps for 1 cm of depth.
1000step=1cm to get my setpoint 88cm 34000 step....can give me example coding PID motor wit feedback sensor....i cannot sleep now 2 week more need submit report..
How many steps can the stepper motor move the piston from one end to the other end, and how fast can it step?
stepper motor move the piston from one end to the other end 34000step and -34000step use 300rpm go reach depth target 1min 45sec..
manually measure by use ruler...this reading from sensor range 0 to 1042, depth=86.6 at surface and depth=0 to 70
I agree with Robin2 about using a servo motor, but if you only have 2 weeks for your report then perhaps we should stick with the stepper for now.
I want to make sure I understand correctly:
You have a piston controlling a buoyancy chamber. With the piston fully in you have maximum sink and with the piston fully out you have maximum rise. Am I correct so far?
At maximum sink, you expect the ROV to descend 88cm in 105 seconds (8.4mm/second), and you want the ROV to settle within ±10cm of the set point.
You can control the buoyancy by driving the piston with a stepper motor connected to a screw, and the maximum piston movement is given by 34,000 steps of the motor.
You can drive the motor at 300rpm, but we do not know the step resolution. If it's a 200 step/rev motor, then 300rpm = 5 revolutions per second = 1000 steps/second, so it takes 34 seconds to move from maximum sink to maximum rise, or 17 seconds to move from maximum sink to neutral buoyancy. Am I still correct?
You have a depth sensor reading values 0 to 1042 (or is it 1023?), which has a reading that goes from 0 to 70 as you descend from the surface to 86.6cm depth. I'm not sure I understood this part correctly, so please correct me if I did not.
If all of this is correct, then setting the proportional band to ±10cm, (choosing a proportional gain value which converts ±10cm depth error to ±1700 steps for the piston), and fine-tuning the buoyancy so the piston mid point is step zero and gives neutral buoyancy, then by my calculations the system is unconditionally stable. It will exponentially approach your set point without any derivative gain or integral gain at all. But correcting for what I have misunderstood may change that
all correct Billysugger.....if u look now my code sensor use pw so i will change to analog....what i need from my coding add PID
depth sensor reading values 0 to 1042 and has a reading that goes from 0 to 70 as me descend from the surface to 86.6cm depth.
this my new coding plz help me add PID
//analog pin 3 for reading in the pulse width from the MaxSonar device.
const int anPin = 3;
//variables needed to store values
long anVolt, inches, cm;
int sum=0;//Create sum variable so it can be averaged
int avgrange=60;//Quantity of values to average (sample size)
//stepper motor
#include <Stepper.h>
#define motorSteps 200 // change this depending on the number of steps
// per revolution of your motor
#define motorPin1 8
#define motorPin2 10
// initialize of the Stepper library:
Stepper myStepper(motorSteps, motorPin1,motorPin2);
void setup(){
// set the motor speed at 300 RPMS:
myStepper.setSpeed(300);
// Initialize the Serial port:
Serial.begin(9600);
}
void loop() {
//A simple fix is to average out a sample of n readings to get a more consistant reading.\\
//Even with averaging I still find it to be less accurate than the pw method.\\
//This loop gets 60 reads and averages them
for(int i = 0; i < avgrange ; i++)
{
//Used to read in the analog voltage output that is being sent by the MaxSonar device.
//Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
//Arduino analog pin goes from 0 to 1024, so the value has to be divided by 2 to get the actual inches
anVolt = analogRead(anPin)/2;
sum += anVolt;
delay(10);
}
inches = sum/avgrange;
cm = inches * 2.54;
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
//reset sample total
sum = 0;
delay(50);
if ((inches > 35) || (cm > 88))
{
Serial.println("Backward");
myStepper.step(-200);
delay(50);
}
if ((inches < 35) || (cm < 88))
{
Serial.println("Forward");
myStepper.step(200);
delay(50);
}
if ((inches=35) || (cm=88))
{
delay (50);
myStepper.step(0);
}
if ((inches=0) || (cm=0))
{
delay (50);
myStepper.step(0);
}}
Okay, I see you've used code published by Bruce Allen which has some flaws in it. I understand the temptation to use code published by others, but unless you know exactly how it works, it will be very difficult or impossible to debug your system.
Please do not add PID to your code until you have achieved excellent depth measurement. If you do, you will make the system too complex to debug in the time you have - this is embedded engineering, not IT! Also, there is a saying "garbage in, garbage out", which means that any computer system will give results no better than its inputs. Because the key input to a control system, like PID, is the feedback value, it's the depth measurement you must get working fully first.
You are working with depth units of cm but your code calculates range in inches. You are using integer math, unlike Mohannad Rawashdeh in http://www.instructables.com/id/Max-Sonar-EZ0/ who uses floating point math. So you will only have 35 different depth values. You are converting an integer number of inches to an integer number of cm, probably using integer division, so your line cm = inches * 2.54; will give exactly the same results as cm = inches * 2. And in integer math, every time you divide you lose resolution, and there is a lot of division in this code. So you must do some serious work on re-writing this section.
My suggestion is to keep integer math, but work in millimetres. Or convert to floating point math and cut out the inches. If you really must use an average filter with integers, then keep the sum without dividing it but just remember that it is a scaled-up value and all your other calculations using this value must account for that.
Personally I prefer PW to Analogue input - there's the opportunity to get much better resolution. But use whatever works for you.
I am curious about your use of the MaxSonar: this is an ultrasonic device for use in air, indeed the pulse timing of 147us/inch is based on the speed of sound in air. Sound in water travels around five times faster, so even if the MaxSonar works through water, your ROV will need to be at a depth of 4.4m to give you the same value you'd get at range 88cm in air.