im making a obstacle avoiding maze solver robot for that im using arduino 9 axis motion shield and Arduino_NineAxesMotion.h library . i have mapped right half of orientaion as 0 to 180 and left as 0 to -180 for ease in pid . for finding open path im using 3 ir sensors , i change the direction of robot by adding or subtracting 90 in setpoint but after 2 turns the setpoint become 180 and im unable to handle it , please clear my doubt,where can i use the reset shield function so that the robot can make tuns
Have you forgotten something?
im working on a obsstacle avoide maze solver robot for that im using 3 ir sensors 1 front ,1 left and one in right for direction . to keep the bot in straight line im using arduino 9 axis motion shield with pid control for that i have mapped right half from 0 to 180 and left half as 0 to -179 to use pid by ease . now my actual problem is when im taking turn i have to add or subtract the setpoint but after second addition or subtraction the setpoint goes beyond my limits then im unable to control it . for taking turn setpoint has to update .anyone have solution , idea ,suggetion regarding it will be very helpful to me .my second thought is to reset the shield ,im using "Arduino_NineAxesMotion.h" is there any method in this lib which can reset the value to zero ,i have alredy used the reset function in the library .please help me with this i will be very thankful to you
#include "Arduino_NineAxesMotion.h" //Contains the bridge code between the API and the Arduino Environment
#include <Wire.h>
//IR pinouts
#define leftIR A2
#define frontIR A1
#define rightIR A0
//Motor pinouts
#define AIN1 8
#define AIN2 5
#define PWMA 3
#define BIN1 6
#define BIN2 7
#define PWMB 9
int val = 30;
int turn_val = 10;
int out = 0;
int cnt=0;
long randNumber;
void right_turn(int turn_val);
void left_turn(int turn_val);
void uturn(int val);
void forward(int val);
double computePID(double orientation);
void resetInput(int input);
void randompath();
bool Lflag = 0;
bool Rflag = 0;
bool Uflag = 0;
bool flag = 0;
bool Sflag = 0;
//bool Mflag = 0;
// PID constants
double kp = 2;
double ki = 0.0;
double kd = 2.0;
double error;
double lastError;
double inp;
int input = 0;
double P;
double I;
double D;
// Setpoint
int setpoint = 0;
NineAxesMotion mySensor; //Object that for the sensor
unsigned long lastStreamTime = 0; //To store the last streamed time stamp
const int streamPeriod = 20; //To stream at 50Hz without using additional timers (time period(ms) =1000/frequency(Hz))
void setup() {
//IR Sensor pinouts
pinMode(leftIR, INPUT);
pinMode(frontIR, INPUT);
pinMode(rightIR, INPUT);
// motor setup pins
pinMode(AIN1, OUTPUT);
pinMode(AIN2, OUTPUT);
pinMode(BIN1, OUTPUT);
pinMode(BIN2, OUTPUT);
pinMode(PWMA, OUTPUT);
pinMode(PWMB , OUTPUT);
//Peripheral Initialization
Serial.begin(9600); //Initialize the Serial Port to view information on the Serial Monitor
Wire.begin(); //Initialize I2C communication to the let the library communicate with the sensor.
//Sensor Initialization
mySensor.initSensor(); //The I2C Address can be changed here inside this function in the library
mySensor.setOperationMode(OPERATION_MODE_NDOF); //Can be configured to other operation modes as desired
mySensor.setUpdateMode(MANUAL); //The default is AUTO. Changing to MANUAL requires calling the relevant update functions prior to calling the read functions
//Setting to MANUAL requires fewer reads to the sensor
randomSeed(analogRead(0)); // Initialize the random number generator
}
void loop() {
int left = digitalRead(leftIR);
int front = digitalRead(frontIR);
int right = digitalRead(rightIR);
// Serial.print(left);
// Serial.print("\t");
// Serial.print(front);
// Serial.print("\t");
// Serial.println(right);
if ((millis() - lastStreamTime) >= streamPeriod)
{
lastStreamTime = millis();
mySensor.updateEuler(); //Update the Euler data into the structure of the object
mySensor.updateCalibStatus(); //Update the Calibration Status
// Serial.println(mySensor.readEulerHeading());
input = mySensor.readEulerHeading(); //Heading data
if (input > 180) {
input = input - 360;
}
computePID(input);
Serial.println(input);
Serial.print("\t\t\t");
Serial.println(out);
}
// if (left == HIGH && front == HIGH && right == HIGH) {
// randompath();
// }
if (front == HIGH) {
forward(val);
}
else if (Rflag == 1) {
flag = 1;
right_turn(turn_val );
// resetInput(input);
cnt++;
Rflag = 0;
}
else if (Lflag == 1) {
flag = 1;
left_turn(turn_val);
// resetInput(input);
cnt++;
Lflag = 0;
}
else if (Uflag == 1) {
uturn(turn_val);
flag = 1;
// resetInput(input);
}
// right only
else if (right == HIGH) {
Rflag = 1;
}
// left only
else if (left == HIGH) {
Lflag = 1;
}
else if (left == LOW && front == LOW && right == LOW) {
Uflag = 1;
}
// else if()
}
void forward(int val) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, constrain(val - out, 0, 255));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain(val + out , 0, 255));
}
void right_turn(int turn_val) {
if (Sflag == 0) {
setpoint = setpoint + 90;
flag=0;
Sflag = 1;
}
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, constrain(turn_val + out , 0, 50));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain(turn_val + out , 0, 50));
// delay(200);
// Serial.println("Right");
}
void left_turn(int turn_val) {
if (Sflag == 0) {
setpoint = setpoint - 90;
flag=0;
Sflag = 1;
}
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, constrain(turn_val - out , 0, 70));
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, constrain(turn_val - out , 0, 70));
// delay(200);
// Serial.println("left");
}
void uturn (int turn_val) {
if (Sflag == 0) {
setpoint = setpoint + 90;
Sflag = 1;
}
digitalWrite(AIN1, LOW );
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, constrain( turn_val + out, 0, 70));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain( turn_val + out, 0, 70));
}
double computePID(double inp) {
error = setpoint - inp;
P = kp * error;
D = kd * (lastError - error);
I = ki * (error + I);
lastError = error;
out = P + I + D;
// Serial.println(out);
return out;
}
void resetInput(int input) {
// if (setpoint == 90 || setpoint == -90) {
mySensor.initSensor(0x28); //The I2C Address can be changed here inside this function in the library
mySensor.setOperationMode(OPERATION_MODE_NDOF); //Can be configured to other operation modes as desired
// setpoint = 0;
// flag=0;
// }
}
void randompath() {
if (randNumber == 0) {
// Generate a single random number from 0 to 3
randNumber = random(4);
// Serial.println(randNumber);
}
switch (randNumber)
{
case 1:
flag = 0;
// Serial.println("forward");
break;
case 2:
Lflag = 1;
// Serial.println("Left turn");
break;
case 3:
Rflag = 1;
// Serial.println("right turn");
break;
default :
break;
}
}
this is my code by using random fill please help me
Show this.
It might not matter just yet, but given you are writing a PID here, there is a betetr form of PID algorithm one can write which fixes a few crash causing cases which your current implementation can suffer from:
http://brettbeauregard.com/blog/2011/04/improving-the-beginners-pid-introduction/
after two same turns the setpoint becomes 180 and pid stops working
hello im working on a maze solving robot for that im using arduino 9 axis motion shield and pid control for moving straight i have mapped values right half as 0 to 180 and left half as 0 to -180 ,for taking turns i just ad or subtract 90 in the setpoint and when the setpoint becomes 90 or -90 i just reset the shield , problem is when the shield resets it does not reset on 90 and not nove streight what can i do now this is my code
void loop() {
int left = digitalRead(leftIR);
int front = digitalRead(frontIR);
int right = digitalRead(rightIR);
if ((millis() - lastStreamTime) >= streamPeriod)
{
lastStreamTime = millis();
mySensor.updateEuler(); //Update the Euler data into the structure of the object
mySensor.updateCalibStatus(); //Update the Calibration Status
// Serial.println(mySensor.readEulerHeading());
input = mySensor.readEulerHeading(); //Heading data
if (input > 180) {
input = input - 360;
}
computePID(input);
}
if (front == HIGH) {
forward(val);
Sflag = 0;
resetInput();
}
else if (Rflag == 1) {
flag = 1;
right_turn(turn_val );
Rflag = 0;
}
else if (Lflag == 1) {
flag = 1;
left_turn(turn_val);
Lflag = 0;
}
else if (Uflag == 1) {
uturn(turn_val);
flag = 1;
}
// right only
else if (right == HIGH) {
Rflag = 1;
}
// left only
else if (left == HIGH) {
Lflag = 1;
}
else if (left == LOW && front == LOW && right == LOW) {
Uflag = 1;
}
// else if()
}
void forward(int val) {
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, constrain(val - out, 0, 255));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain(val + out , 0, 255));
Serial.println("forward");
}
void right_turn(int turn_val) {
if (Sflag == 0) {
setpoint = setpoint + 90;
Sflag = 1;
}
digitalWrite(AIN1, LOW);
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, constrain(turn_val + out , 0, 30));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain(turn_val + out , 0, 30));
Serial.println("Right");
}
void left_turn(int turn_val) {
if (Sflag == 0) {
setpoint = setpoint - 90;
Sflag = 1;
}
digitalWrite(AIN1, HIGH);
digitalWrite(AIN2, LOW);
analogWrite(PWMA, constrain(turn_val - out , 0, 30));
digitalWrite(BIN1, LOW);
digitalWrite(BIN2, HIGH);
analogWrite(PWMB, constrain(turn_val - out , 0, 30));
Serial.println("left");
}
void uturn (int turn_val) {
if (Sflag == 0) {
setpoint = setpoint + 90;
Sflag = 1;
}
digitalWrite(AIN1, LOW );
digitalWrite(AIN2, HIGH);
analogWrite(PWMA, constrain( turn_val + out, 0, 70));
digitalWrite(BIN1, HIGH);
digitalWrite(BIN2, LOW);
analogWrite(PWMB, constrain( turn_val + out, 0, 70));
}
double computePID(double inp) {
error = setpoint - inp;
P = kp * error;
D = kd * (lastError - error);
I = ki * (error + I);
lastError = error;
out = P + I + D;
// Serial.println(out);
return out;
}
void resetInput() {
if ((setpoint==90 || setpoint==-90) && (input==90 ||input==-90)) {
mySensor.initSensor(0x28); //The I2C Address can be changed here inside this function in the library
mySensor.setOperationMode(OPERATION_MODE_NDOF); //Can be configured to other operation modes as desired
setpoint = 0;
}
//thse are my pid values
double kp = 0.75;
double ki = 0;
double kd = 1.5;
I have merged your topics due to them having too much overlap on the same subject matter @new_guy_in_coding.
In the future, please only create one topic for each distinct subject matter and be careful not to cause them to converge into parallel discussions.
The reason is that generating multiple threads on the same subject matter can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.
Thanks in advance for your cooperation.
if ( Lflag == 1) {
left_turn(turn_val);
// delay(500);
if (input % 90 == 0 ) {
setpoint = input;
// Serial.println(setpoint);
Lflag = 0;
flag = 1;
}
}
else if ( Rflag == 1) {
right_turn(turn_val);
// delay(500);
if (input % 90 == 0 ) {
setpoint = input;
// Serial.println(setpoint);
Rflag = 0;
flag = 1;
}
}
input is 9 axis value but due to speed and inertia the bot cross the mark of 90 and take turn at 180 what can i do so it take turn at exact 90
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.