rualrite?
YaBB Newbies
Offline
Posts: 1
Serial xpos from processing to arduino problems
May 13th , 2009, 11:26am
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 } } }