* 0x95 Aft Handicap
* free
* 0xA0 Reset reason
- * 0xA1 TLE Error status
+ * 0xA1 Error status
* 0xA2 count test
* free
* 0xff Bootloader
#define TWI_RESET TWCR &= ~((1 << TWSTO) | (1 << TWEN)); TWI_ACK
#define TWI_NAK TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
-#define KP 0.009
-#define KI 0.051429
-#define KD 0.000378
+#define KP 0.025
+#define KI 2.3
+#define KD 0.0
#define PID_T 0.01
// wheel diameter=12cm, encoder=48cpr, gear ratio=1:34, real wheel diameter: 0.12454m
#define STEP_PER_M_AVG 4171.4
static volatile enum mode motor2_mode=MOTOR_MANUAL;
static volatile enum mode motor3_mode=MOTOR_MANUAL;
static volatile enum mode motor4_mode=MOTOR_MANUAL;
-static volatile uint8_t motor1_switch=0;
-static volatile uint8_t motor2_switch=0;
+static volatile uint8_t motor1_switch=1;
+static volatile uint8_t motor2_switch=1;
static volatile uint8_t motor3_switch=0;
static volatile uint8_t motor4_switch=0;
static volatile int16_t speed1_wish=0; // step/s
TWDR = OCR1A;
TWI_ACK;
break;
+ case 0x03: // Dummy to allow continous read
+ TWDR = 0;
+ TWI_ACK;
+ break;
case 0x04: // Motor 2 PWM
TWDR = OCR1B;
TWI_ACK;
break;
+ case 0x05: // Dummy to allow continous read
+ TWDR = 0;
+ TWI_ACK;
+ break;
case 0x06: // Motor 3 PWM
TWDR = OCR2;
TWI_ACK;
break;
+ case 0x07: // Dummy to allow continous read
+ TWDR = 0;
+ TWI_ACK;
+ break;
case 0x08: // Motor 4 PWM
TWDR = OCR0;
TWI_ACK;
break;
+ case 0x09: // Dummy to allow continous read
+ TWDR = 0;
+ TWI_ACK;
+ break;
case 0x10: // Hall 1 MSB
tmp16 = pos1;
TWDR = tmp16>>8;
MCUCSR = 0x0;
TWI_ACK;
break;
- case 0xA1: // TLE Error status
+ case 0xA1: // Error status
TWDR = error_state;
TWI_ACK;
break;
error_state = ~((PIND & 0x40)>>3 | (PINB & 0x07)) & 0xf;
- // if error and running: stop
- if (bit_is_set(error_state, 0) && m1_old != 0) motor1 = 0;
- if (bit_is_set(error_state, 1) && m2_old != 0) motor2 = 0;
- if (bit_is_set(error_state, 2) && m3_old != 0) motor3 = 0;
- if (bit_is_set(error_state, 3) && m4_old != 0) motor4 = 0;
-
- // if we start motor in error state: start with full power
- if (bit_is_set(error_state, 0) && m1_old == 0 && motor1 != 0) motor1 = 255;
- if (bit_is_set(error_state, 1) && m2_old == 0 && motor2 != 0) motor2 = 255;
- if (bit_is_set(error_state, 2) && m3_old == 0 && motor3 != 0) motor3 = 255;
- if (bit_is_set(error_state, 3) && m4_old == 0 && motor4 != 0) motor4 = 255;
-
if (m1_old != motor1) { // update only when changed
if (motor1 == 0) {
// stop
- PORTC |= (1 << 3) | (1 << 2);
+ PORTC &= ~(1 << 3) & ~(1 << 2);
} else if ((!motor1_switch && motor1 > 0) || (motor1_switch && motor1 < 0)) {
// forward
- PORTC &= ~(1 << 3) & ~(1 << 2);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 3);
+ tmp |= (1 << 2);
+ PORTC = tmp;
} else { // motor1 < 0
// backward
- PORTC &= ~(1 << 2);
- PORTC |= (1 << 3);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 2);
+ tmp |= (1 << 3);
+ PORTC = tmp;
}
m1_old = motor1;
if (m2_old != motor2) { // update only when changed
if (motor2 == 0) {
// stop
- PORTC |= (1 << 5) | (1 << 4);
+ PORTC &= ~(1 << 5) & ~(1 << 4);
} else if ((!motor2_switch && motor2 > 0) || (motor2_switch && motor2 < 0)) {
// forward
- PORTC &= ~(1 << 5) & ~(1 << 4);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 5);
+ tmp |= (1 << 4);
+ PORTC = tmp;
} else { // motor2 < 0
// backward
- PORTC &= ~(1 << 4);
- PORTC |= (1 << 5);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 4);
+ tmp |= (1 << 5);
+ PORTC = tmp;
}
m2_old = motor2;
if (m3_old != motor3) { // update only when changed
if (motor3 == 0) {
// stop
- PORTC |= (1 << 7) | (1 << 6);
+ PORTC &= ~(1 << 7) & ~(1 << 6);
} else if ((!motor3_switch && motor3 > 0) || (motor3_switch && motor3 < 0)) {
// forward
- PORTC &= ~(1 << 7) & ~(1 << 6);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 7);
+ tmp |= (1 << 6);
+ PORTC = tmp;
} else { // motor3 < 0
// backward
- PORTC &= ~(1 << 6);
- PORTC |= (1 << 7);
+ uint8_t tmp=PORTC;
+ tmp &= ~(1 << 6);
+ tmp |= (1 << 7);
+ PORTC = tmp;
}
m3_old = motor3;
if (m4_old != motor4) { // update only when changed
if (motor4 == 0) {
// stop
- PORTD |= (1 << 3) | (1 << 2);
+ PORTD &= ~(1 << 3) & ~(1 << 2);
} else if ((!motor4_switch && motor4 > 0) || (motor4_switch && motor4 < 0)) {
// forward
- PORTD &= ~(1 << 3) & ~(1 << 2);
+ uint8_t tmp=PORTD;
+ tmp &= ~(1 << 3);
+ tmp |= (1 << 2);
+ PORTD = tmp;
} else { // motor4 < 0
// backward
- PORTD &= ~(1 << 2);
- PORTD |= (1 << 3);
+ uint8_t tmp=PORTD;
+ tmp &= ~(1 << 2);
+ tmp |= (1 << 3);
+ PORTD = tmp;
}
m4_old = motor4;
} else {
int16_t e = speed1_wish - speed1;
esum1+=e;
- motor1 += KP*e + KI*PID_T*esum1 + KD/PID_T*(e - eold1);
+ motor1 = KP*e + KI*PID_T*esum1 + KD/PID_T*(e - eold1);
eold1 = e;
if (motor1 > 255) motor1 = 255;
} else {
int16_t e = speed2_wish - speed2;
esum2+=e;
- motor2 += KP*e + KI*PID_T*esum2 + KD/PID_T*(e - eold2);
+ motor2 = KP*e + KI*PID_T*esum2 + KD/PID_T*(e - eold2);
eold2 = e;
if (motor2 > 255) motor2 = 255;
} else {
int16_t e = speed3_wish - speed3;
esum3+=e;
- motor3 += KP*e + KI*PID_T*esum3 + KD/PID_T*(e - eold3);
+ motor3 = KP*e + KI*PID_T*esum3 + KD/PID_T*(e - eold3);
eold3 = e;
if (motor3 > 255) motor3 = 255;
} else {
int16_t e = speed4_wish - speed4;
esum4+=e;
- motor4 += KP*e + KI*PID_T*esum4 + KD/PID_T*(e - eold4);
+ motor4 = KP*e + KI*PID_T*esum4 + KD/PID_T*(e - eold4);
eold4 = e;
if (motor4 > 255) motor4 = 255;
DDRB = (1 << 3);
DDRC = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
DDRD = (1 << 7) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
- // Pullup TLEs EF
+ // Pullup Diag/Enable
PORTB = (1 << 0) | (1 << 1) | (1 << 2);
PORTD = (1 << 6);
TWI_RESET;
// Motor 1 & 2
- // Timer 1: Fast PWM inverting mode, Top=256 => 15.625kHz
+ // Timer 1: Fast PWM non-inverting mode, Top=255 => 15.625kHz
// Prescaler=1
- TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << COM1A0) | (1 << COM1B0) | (1 << WGM10);
+ TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
TCCR1B = (1 << WGM12) | (1 << CS10);
OCR1A = 0;
OCR1B = 0;
// Motor 3
- // Timer 2: Fast PWM inverting mode, Top=256
+ // Timer 2: Fast PWM non-inverting mode, Top=255
// Prescaler=1
- TCCR2 = (1 << WGM21) | (1 << WGM20) | (1 << COM21) | (1 << COM20) | (1 << CS20);
+ TCCR2 = (1 << WGM21) | (1 << WGM20) | (1 << COM21) | (1 << CS20);
OCR2 = 0;
// Motor 4
- // Timer 0: Fast PWM inverting mode, Top=256
+ // Timer 0: Fast PWM non-inverting mode, Top=255
// Prescaler=1
- TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << COM01) | (1 << COM00) | (1 << CS00);
+ TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << COM01) | (1 << CS00);
OCR0 = 0;
printf("\r\nStart\r\n");