#include <util/twi.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
+#include <avr/pgmspace.h>
#include "uart.h"
/*
#define WHEEL_DIST 0.39912 // Measured: 0.252
#define PWM_BREAK INT16_MIN
#define STALL_LIMIT 140000
+#define I2C_TIMEOUT_DISABLE 255
#define TWI_ACK TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE)
#define TWI_NAK TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE)
static volatile uint8_t front_handicap=0;
static volatile uint8_t aft_handicap=0;
static volatile uint8_t error_state=0;
+static volatile uint8_t last_man_update_count=0;
+static volatile uint8_t last_i2c_status = 0;
ISR(TWI_vect)
{
static ufloat_t tmp_speed;
static ufloat_t tmp_angle;
+ last_i2c_status = TW_STATUS;
switch(TW_STATUS)
{
case TW_SR_SLA_ACK: // start write
tmp_angle.i = tmp_angle.i << 8 | TWDR;
cmd_vel.angle = tmp_angle.f;
cmd_vel.bUpdate = 1;
+ last_man_update_count = 0;
TWI_ACK;
break;
case 0x90: // Motor 1 switch
default:
TWI_NAK;
}
- ireg++;
+ if (ireg < 0xff) ireg++;
break;
case TW_ST_SLA_ACK: // start read
case TW_ST_DATA_ACK: // read
case TW_SR_STOP:
TWI_ACK;
break;
+ case TW_NO_INFO:
+ break;
default:
TWI_RESET;
}
speed1_wish_old = speed1_wish;
}
- if (speed1_wish == 0) {
+ uint8_t dir_change = (speed1_wish > 0 && speed1 < 0) || (speed1_wish < 0 && speed1 > 0); // Prevent dangerous immediate engine reverse
+ if (speed1_wish == 0 || dir_change) {
motor1 = 0;
eold1 = 0;
error_state &= ~(1<<4);
speed2_wish_old = speed2_wish;
}
- if (speed2_wish == 0) {
+ uint8_t dir_change = (speed2_wish > 0 && speed2 < 0) || (speed2_wish < 0 && speed2 > 0); // Prevent dangerous immediate engine reverse
+ if (speed2_wish == 0 || dir_change) {
motor2 = 0;
eold2 = 0;
error_state &= ~(1<<5);
speed3_wish_old = speed3_wish;
}
- if (speed3_wish == 0) {
+ uint8_t dir_change = (speed3_wish > 0 && speed3 < 0) || (speed3_wish < 0 && speed3 > 0); // Prevent dangerous immediate engine reverse
+ if (speed3_wish == 0 || dir_change) {
motor3 = 0;
eold3 = 0;
error_state &= ~(1<<6);
speed4_wish_old = speed4_wish;
}
- if (speed4_wish == 0) {
+ uint8_t dir_change = (speed4_wish > 0 && speed4 < 0) || (speed4_wish < 0 && speed4 > 0); // Prevent dangerous immediate engine reverse
+ if (speed4_wish == 0 || dir_change) {
motor4 = 0;
eold4 = 0;
error_state &= ~(1<<7);
TCCR0 = (1 << WGM01) | (1 << WGM00) | (1 << CS00);
OCR0 = 0;
- printf("\r\nStart\r\n");
+ printf_P(PSTR("\r\nStart\r\n"));
set_sleep_mode(SLEEP_MODE_IDLE);
// Enable Timer 1 Overflow Interrupt
update_pid();
update_motor();
count_test++;
+ if (last_man_update_count != I2C_TIMEOUT_DISABLE) last_man_update_count++;
+
+ if (last_man_update_count >= 100) {
+ // ~1s without a new i2c command
+ cmd_vel.speed = 0;
+ cmd_vel.angle = 0;
+ cmd_vel.bUpdate = 1;
+ if (last_man_update_count == 100) {
+ printf_P(PSTR("I2C State: 0x%x\r\n"), last_i2c_status);
+ }
+ last_man_update_count = I2C_TIMEOUT_DISABLE;
+ }
}
sleep_mode();