267 lines
5.4 KiB
C++
267 lines
5.4 KiB
C++
#define MtAchA 2
|
|
#define MtAchB 3
|
|
#define MtBchA 11
|
|
#define MtBchB 12
|
|
#define MtAI1 4
|
|
#define MtAI2 7
|
|
#define MtBI1 8
|
|
#define MtBI2 9
|
|
#define MtAE 5
|
|
#define MtBE 6
|
|
|
|
volatile int lastEncA = 0;
|
|
volatile long encValA = 0;
|
|
volatile int lastEncB = 0;
|
|
volatile long encValB = 0;
|
|
|
|
long lastencValA = 0;
|
|
long lastencValB = 0;
|
|
|
|
int lastMSBA = 0;
|
|
int lastLSBA = 0;
|
|
int lastMSBB = 0;
|
|
int lastLSBB = 0;
|
|
|
|
void setup() {
|
|
Serial.begin(57600);
|
|
|
|
pinMode(MtAchA, INPUT);
|
|
pinMode(MtAchB, INPUT); //interrupt pins
|
|
pinMode(MtBchA, INPUT);
|
|
pinMode(MtBchB, INPUT);
|
|
|
|
pinMode(MtAE, OUTPUT); //pwn pins
|
|
pinMode(MtBE, OUTPUT);
|
|
|
|
pinMode(MtAI1, OUTPUT); //direction pins
|
|
pinMode(MtAI2, OUTPUT);
|
|
pinMode(MtBI1, OUTPUT);
|
|
pinMode(MtBI2, OUTPUT);
|
|
|
|
PORTB = (PORTB & 0b11111100) | 0b00000011;
|
|
PORTD = (PORTD & 0b01101111) | 0b10010000;
|
|
digitalWrite(MtAchA, HIGH);
|
|
digitalWrite(MtAchB, HIGH);
|
|
digitalWrite(MtBchA, HIGH);
|
|
digitalWrite(MtBchB, HIGH);
|
|
|
|
attachInterrupt(0, updateEncA, CHANGE);
|
|
attachInterrupt(1, updateEncA, CHANGE);
|
|
|
|
*digitalPinToPCMSK(MtBchA) |= bit(digitalPinToPCMSKbit(MtBchA)); // enable pin
|
|
PCIFR |= bit(digitalPinToPCICRbit(MtBchA)); // clear any outstanding interrupt
|
|
PCICR |= bit(digitalPinToPCICRbit(MtBchA)); // enable interrupt for the group
|
|
*digitalPinToPCMSK(MtBchB) |= bit(digitalPinToPCMSKbit(MtBchB)); // enable pin
|
|
PCIFR |= bit(digitalPinToPCICRbit(MtBchB)); // clear any outstanding interrupt
|
|
PCICR |= bit(digitalPinToPCICRbit(MtBchB)); // enable interrupt for the group
|
|
|
|
analogWrite(MtAE, 1);
|
|
analogWrite(MtBE, 1);
|
|
OCR0A = OCR0B = 0;
|
|
}
|
|
|
|
|
|
int pos = 0;
|
|
int ang = 0;
|
|
int vel = 0;
|
|
float pP = 0, iP = 0, dP = 0, alphaP = 0.7;
|
|
float pA = 0, iA = 0, dA = 0, alphaA = 0.7;
|
|
int errA = 0, perrA = 0, cerrA = 0;
|
|
int errP = 0, perrP = 0, cerrP = 0;
|
|
int pwmA = 0, pwmB = 0, pwm = 0, outA = 0;
|
|
|
|
|
|
void loop() {
|
|
|
|
if (Serial.available() > 2)
|
|
{
|
|
char ch = Serial.read();
|
|
if (ch == 's')
|
|
{
|
|
switch (Serial.read())
|
|
{
|
|
case 'p':
|
|
pos = Serial.parseInt();
|
|
break;
|
|
case 'a':
|
|
ang = Serial.parseInt();
|
|
break;
|
|
case 'v':
|
|
vel = Serial.parseInt();
|
|
if (abs(vel) > 225)
|
|
vel = 255;
|
|
else
|
|
vel = abs(vel);
|
|
break;
|
|
|
|
|
|
// tuning
|
|
|
|
case 'P':
|
|
switch (Serial.read())
|
|
{
|
|
case 'p':
|
|
pP = Serial.parseFloat();
|
|
break;
|
|
case 'i':
|
|
iP = Serial.parseFloat();
|
|
break;
|
|
case 'd':
|
|
dP = Serial.parseFloat();
|
|
break;
|
|
}
|
|
case 'A':
|
|
switch (Serial.read())
|
|
{
|
|
case 'p':
|
|
pA = Serial.parseFloat();
|
|
break;
|
|
case 'i':
|
|
iA = Serial.parseFloat();
|
|
break;
|
|
case 'd':
|
|
dA = Serial.parseFloat();
|
|
break;
|
|
}
|
|
/*
|
|
case '0':
|
|
ang = 0;
|
|
cerrA = 0;
|
|
pos = 0;
|
|
cerrP = 0;
|
|
encValA = encValB = 0;
|
|
break;
|
|
*/
|
|
}
|
|
Serial.read();
|
|
}
|
|
}
|
|
|
|
errP = 2 * pos - (encValA + encValB);
|
|
cerrP += errP * iP;
|
|
|
|
if(vel > 0)
|
|
cerrP = constrain(cerrP, -vel*0.5, vel*0.5);
|
|
else if(vel == 0)
|
|
cerrP = 0;
|
|
|
|
pwm = errP * pP + (-perrP * alphaP + errP * (1 - alphaP)) * dP + cerrP;
|
|
|
|
perrP = errP;
|
|
|
|
if (vel > 0)
|
|
pwm = constrain(pwm, -vel, vel);
|
|
else if (vel == 0)
|
|
pwm = 0;
|
|
|
|
errA = ang - (encValB - encValA);
|
|
cerrA += errA * iA;
|
|
|
|
if(vel > 0)
|
|
cerrA = constrain(cerrA, -vel, vel);
|
|
else if(vel == 0)
|
|
cerrA = 0;
|
|
|
|
outA = errA * pA + (-perrA * alphaA + errA * (1 - alphaA)) * dA + cerrA;
|
|
|
|
perrA = errA;
|
|
if (vel > 0)
|
|
{
|
|
outA = constrain(outA, -vel * 0.95, vel * 0.95);
|
|
pwmA = pwm - outA;
|
|
pwmB = pwm + outA;
|
|
pwmA = constrain(pwmA, -255, 255);
|
|
pwmB = constrain(pwmB, -255, 255);
|
|
}
|
|
else if(vel == 0)
|
|
{
|
|
pwmA = pwmB = 0;
|
|
outA = 0;
|
|
errP = 0;
|
|
}
|
|
|
|
|
|
Serial.print(errP);
|
|
Serial.print('\t');
|
|
Serial.print(pwm);
|
|
Serial.print('\t');
|
|
Serial.print(errA);
|
|
Serial.print('\t');
|
|
Serial.print(outA);
|
|
Serial.print('\t');
|
|
Serial.print(pwmA);
|
|
Serial.print('\t');
|
|
Serial.println(pwmB);
|
|
|
|
/*
|
|
if (errP == 0)
|
|
{
|
|
cerrP = 0;
|
|
encValA = encValB = pos;
|
|
}
|
|
|
|
if (errA == 0)
|
|
{
|
|
ang = 0;
|
|
cerrA = 0;
|
|
|
|
}
|
|
*/
|
|
if ((errP == 0) && (errA == 0))
|
|
{
|
|
ang = 0;
|
|
cerrA = 0;
|
|
pos = 0;
|
|
cerrP = 0;
|
|
encValA = encValB = 0;
|
|
}
|
|
|
|
if (pwmB > 0)
|
|
PORTB = (PORTB & 0b11111100) | 0b00000010;
|
|
else if (pwmB < 0)
|
|
{
|
|
pwmB *= -1;
|
|
PORTB = (PORTB & 0b11111100) | 0b00000001;
|
|
}
|
|
else
|
|
PORTB = PORTB | 0b00000011;
|
|
|
|
if (pwmA > 0)
|
|
PORTD = (PORTD & 0b01101111) | 0b00010000;
|
|
else if (pwmA < 0)
|
|
{
|
|
pwmA *= -1;
|
|
PORTD = (PORTD & 0b01101111) | 0b10000000;
|
|
}
|
|
else
|
|
PORTD = PORTD | 0b10010000;
|
|
|
|
OCR0A = pwmB;
|
|
OCR0B = pwmA;
|
|
}
|
|
|
|
void updateEncA() {
|
|
int MSB = (PIND >> 2) & 0b00000001; //MSB = most significant bit
|
|
int LSB = (PIND >> 3) & 0b00000001; //LSB = least significant bit
|
|
|
|
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
|
|
int sum = (lastEncA << 2) | encoded; //adding it to the previous encoded value
|
|
|
|
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encValA++;
|
|
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encValA--;
|
|
|
|
lastEncA = encoded; //store this value for next time
|
|
}
|
|
|
|
ISR(PCINT0_vect) {
|
|
int MSB = (PINB >> 3) & 0b00000001; //MSB = most significant bit
|
|
int LSB = (PINB >> 4) & 0b00000001; //LSB = least significant bit
|
|
|
|
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number
|
|
int sum = (lastEncB << 2) | encoded; //adding it to the previous encoded value
|
|
|
|
if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encValB--;
|
|
if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encValB++;
|
|
|
|
lastEncB = encoded; //store this value for next time
|
|
} |