# Using PID to call (boolean) functions - Hit the gas or simply coast

I need to keep a rolling object at the top/center of a convex surface/circle (Setpoint = (radius of 0). I only have two functions: “Move-Towards-Center” and “Do-Nothing” (“Do-Nothing” lets gravity pull the object away from center, lets momentum keep the object moving, or (target) temporarily stabilize the object at the center).

I would like to use PID to call “Move-Towards-Center” when the Radius exceeds (say) 10%-off, but I would like PID to calculate and call “Do-Nothing” before the object returns and over-shoots the center. This is what PID does best.

Using an MPU-6050 gyro - My code amazingly calculates “radius” (distance from center) and determines location on one of eight areas around the center (which is required by the “Move-Towards-Center” function).

HELP!!! Can PID call functions as Output? If yes, how? If they do - how are boolean decisions made?

And BTW - Are functions simply "int function-name(int x, inty){some action;}

Thank you - Mark

``````#include "Wire.h" // This library allows you to communicate with I2C devices
#include <Servo.h>
#include <PID_v1.h>  //This library is the PID decision maker
const int MPU_ADDR = 0x68; // I2C address of the MPU-6050. If AD0 pin is set to HIGH, the I2C address will be 0x69.
int16_t gyro_x, gyro_y, gyro_z;      // variables for gyro raw data
int nozzle; //variable for direction
char tmp_str; // temporary variable used in convert function
char* convert_int16_to_str(int16_t i) { // converts int16 to string. Moreover, resulting strings will have the same length in the debug monitor.
sprintf(tmp_str, "%6d", i);
return tmp_str;
}

// PID variables
double Setpoint, Input, Output;
double Kp=4;
double Ki=0.2;
double Kd=1;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
int WindowSize = 5000;
unsigned long windowStartTime;

void setup() {
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(MPU_ADDR); // Begins a transmission to the I2C slave (GY-521 board)
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);

//initialize PID variables

Setpoint = 0;
myPID.SetMode(AUTOMATIC);
windowStartTime = millis();
myPID.SetOutputLimits(0, WindowSize);
}

void loop() {
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H) [MPU-6000 and MPU-6050 Register Map and Descriptions Revision 4.2, p.40]
Wire.endTransmission(false); // the parameter indicates that the Arduino will send a restart. As a result, the connection is kept active.
Wire.requestFrom(MPU_ADDR, 7*2, true); // request a total of 7*2=14 registers

// Use X and Y data to determine location 1-8 around center of circle

if ((gyro_y>2.4145*gyro_x) && (gyro_y>=-2.4145*gyro_x)) {
location = 1;
}
else if ((gyro_y<-2.4145*gyro_x) && (gyro_y>=-.41416*gyro_x)) {
location = 2;
}
else if ((gyro_y<-.41416*gyro_x) && (gyro_y>=.41416*gyro_x)) {
location = 3;
}
else if ((gyro_y<.41416*gyro_x) && (gyro_y>=2.4145*gyro_x)) {
location = 4;
}
else if ((gyro_y<2.4145*gyro_x) && (gyro_y<=-2.4145*gyro_x)) {
location = 5;
}
else if ((gyro_y>-2.4145*gyro_x) && (gyro_y<=-.41415*gyro_x)) {
location = 6;
}
else if ((gyro_y>-.41415*gyro_x) && (gyro_y<=.41415*gyro_x)) {
location = 7;
}
else if ((gyro_y>.41416*gyro_x) && (gyro_y<=2.4145*gyro_x)) {
location = 8;
}

radius = sqrt(sq(gyro_x)+sq(gyro_y));    //My Arduino attempt at Pythagoras' Theorem

// print out data
Serial.print(" | gX = "); Serial.print(convert_int16_to_str(gyro_x));
Serial.print(" | gY = "); Serial.print(convert_int16_to_str(gyro_y));
Serial.print(" | Location = "); Serial.print(location);
Serial.println();

// PID loop data - output must be "Move-Towards-Center" and "Do-Nothing"

myPID.Compute();                        // Will this compute "Move-Towards-Center" vs "Do-Nothing"?
myPID.SetMode(AUTOMATIC);
myPID.SetOutputLimits(0, WindowSize);

if (Output = WindowSize){
Move-Towards-Center;
}
if (Output = 0){
Do-Nothing;
}

// delay
delay(100);
}
``````

I would like to use PID to call "Move-Towards-Center" when the Radius exceeds (say) 10%-off,

How much is 10 % off of 0?

Keeping something balance on top of something with a radius of 0 is going to be very difficult.

So, I suspect that your first paragraph needs some work before your post makes any sense.