Go Down

Topic: Serial xpos from Processing to Arduino for DC moto (Read 1 time) previous topic - next topic

rualrite

I am trying to send the serial data of the xpos of a ficudial ID being video-captured in Processing to Arduino to control a dc motor with an encoder.  I am using A Big Magnet's code for dc motor control with potentiometer, except I switched out the potentiometer for my serial data of the xpos from processing.  I have gotten the PID control to make the speed of the motor change according to how large the # value of the serial data is, but I need it to change direction and have the position of the dc motor correspond to the xpos in processing.  Does this make sense??  The video recognition is ReacTIVision -> Processing, processing serial-> arduino.  here is the arduino code I am using, the processing is just port.write(x); and println(x); in the class for updating the position of the ID, any help is greatly appreciated I'm totally lost:


#include <AFMotor.h>
AF_DCMotor motor(1, MOTOR12_8KHZ);

#define encoder0PinA 2
#define encoder0PinB 3

volatile int encoder0Pos = 0;
//correction = Kp * error + Kd * (error - prevError) + kI * (sum of errors)
//PID controller constants
float KP = 1; //position multiplier (gain)
float KI = .5; // Intergral multiplier (gain)
float KD = 1; // derivative multiplier (gain)

//track the previous error for the derivitive term, and the sum of the errors for the integral term
int lastError = 0;
int sumError = 0;
//Integral term min/max (random value and not yet tested/verified)
int iMax = 255;
int iMin = 0;


void setup() {
 
 Serial.begin(9600);
 pinMode(encoder0PinA, INPUT);
 pinMode(encoder0PinB, INPUT);
 // attach interrupt service routine (ISR) to the encoder pins
 attachInterrupt(0, doEncoderA, CHANGE);
 //to use the full 4x encoding uncomment out the other ISR attachment
 //attachInterrupt(1, doEncoderB, CHANGE);  
 pinMode(13, OUTPUT);
}

void loop() {
 if (Serial.available()>0) {

   int val = Serial.read();//(0-300)
   Serial.flush();
   int target = map(val,0,255,0,3600);
   int error = encoder0Pos - target; // find the error term of current position - target
   // generalized PID formula
   //correction = Kp * error + Kd * (error - prevError) + kI * (sum of errors)
   int ms = KP * error + KD * (error - lastError) + KI * (sumError);// calculate a motor speed for the current conditions
   // set the last and sumerrors for next loop iteration
   lastError = error;
   sumError += error;
   //scale the sum for the integral term
   if(sumError > iMax){
     sumError = iMax;
   }
   else if(sumError < iMin){
     sumError = iMin;
   }

   int direction;
   if(ms > 0){
     direction = BACKWARD;
     digitalWrite(13,LOW);
   }

   if(ms < 0){
     direction = FORWARD;
     digitalWrite(13,HIGH);
     ms = -1 * ms;

   }

 
  int motorSpeed = map(ms,0,255,0,255);//i just put 255 for both since I'm not sure what values these would be

   motor.setSpeed(100);
   motor.run(direction);

 }
 
 }

//ISR functions
void doEncoderA(){

 // look for a low-to-high on channel A
 if (digitalRead(encoder0PinA) == HIGH) {

   // check channel B to see which way encoder is turning
   if (digitalRead(encoder0PinB) == LOW) {  
     encoder0Pos = encoder0Pos + 1;         // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;         // CCW
   }
 }
 // look for a high-to-low on channel A
 else                                        
 {
   // check channel B to see which way encoder is turning  
   if (digitalRead(encoder0PinB) == HIGH) {  
     encoder0Pos = encoder0Pos + 1;          // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;          // CCW
   }
 }

}

void doEncoderB(){

 // look for a low-to-high on channel B
 if (digitalRead(encoder0PinB) == HIGH) {  

   // check channel A to see which way encoder is turning
   if (digitalRead(encoder0PinA) == HIGH) {  
     encoder0Pos = encoder0Pos + 1;         // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;         // CCW
   }
 }

 // Look for a high-to-low on channel B

 else {
   // check channel B to see which way encoder is turning  
   if (digitalRead(encoder0PinA) == LOW) {  
     encoder0Pos = encoder0Pos + 1;          // CW
   }
   else {
     encoder0Pos = encoder0Pos - 1;          // CCW
   }
 }

}


Go Up