im trying to write code for a robot to accellerate and decelerate. currently testing it with leds on an atmel xmega a1 board. everything seems to be in order except for the deceleration. one side doesnt go through the deceleration process for some reason even though the code is exactly the same just switched out the pins.
insert
Code:
/**
* \file
*
* \brief Empty user application template
*
*/
/*
* Include header files for all drivers that have been imported from
* Atmel Software Framework (ASF).
*/
#include <asf.h>
struct _Device{
int direction;
//0 is forward
//1 is backward
volatile int pulseAmount;
//points to position
int pulseTotal;
int pulseWidth;
//The amount of time the pin is set on
int rateChange;
//The amount of pulses it takes to reach max speed
int period;
//The amount of time between pulses
double acceleration;
double changeAcceleration;
double maxTimer;
double minTimer;
};
void findChangeAcceleration(struct _Device *useDevice);
//finds the change in acceleration required for device to accurately reach maxSpeed from minSpeed
int main (void)
{
board_init();
// Insert application code here, after the board has been initialized.
struct _Device leftWheel; struct _Device rightWheel;
leftWheel.pulseTotal = 500; rightWheel.pulseTotal = 500;
leftWheel.direction = 0; rightWheel.direction = 0;
leftWheel.pulseWidth = 0x05; rightWheel.pulseWidth = 0x05;
leftWheel.rateChange = 100; rightWheel.rateChange = 100;
leftWheel.acceleration = 0; rightWheel.acceleration = 0;
leftWheel.minTimer = 0x50; rightWheel.minTimer = 0x50;
leftWheel.maxTimer = 0x70; rightWheel.maxTimer = 0x70;
leftWheel.pulseAmount = 0; rightWheel.pulseAmount = 0;
leftWheel.period = leftWheel.maxTimer + leftWheel.pulseWidth; rightWheel.period = rightWheel.maxTimer + rightWheel.pulseWidth;
findChangeAcceleration(&leftWheel); findChangeAcceleration(&rightWheel);
//Sets Pins to Output
PORTE.DIRSET = 0xff;
//Prepares Timer 0
TCE0.CTRLB = TC_WGMODE_DS_B_gc;
TCE0.CTRLB |= TC0_CCAEN_bm;
//Prepares Timer 1
TCE1.CTRLB = TC_WGMODE_DS_B_gc;
TCE1.CTRLB |= TC1_CCAEN_bm;
//Sets Timer 0 channels A, B
TCE0.CCABUF = leftWheel.maxTimer;
//Sets Timer 1 Channel A, B
TCE1.CCABUF = rightWheel.maxTimer;
//Set the timer 0
TCE0.PER = leftWheel.period;
TCE0.CTRLA = ( (TCE0.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV1024_gc);
//Set the timer 1
TCE1.PER = rightWheel.period;
TCE1.CTRLA = ( (TCE1.CTRLA & ~TC0_CLKSEL_gm ) | TC_CLKSEL_DIV1024_gc);
//Begins the loop
while(1)
{
//Begin the acceleration process
while(leftWheel.pulseAmount < leftWheel.rateChange)
{
if(TCE0.INTFLAGS & TC0_OVFIF_bm)
{
TCE0.INTFLAGS = TC0_OVFIF_bm;
leftWheel.pulseAmount++;
if(leftWheel.pulseAmount < (leftWheel.rateChange / 2))
leftWheel.acceleration += leftWheel.changeAcceleration;
else
leftWheel.acceleration -= leftWheel.changeAcceleration;
leftWheel.period -= leftWheel.acceleration;
TCE0.PER = leftWheel.period;
TCE0.CCABUF = leftWheel.period - leftWheel.pulseWidth;
TCE0.CCBBUF = leftWheel.period - leftWheel.pulseWidth;
}
if(TCE1.INTFLAGS & TC1_OVFIF_bm)
{
TCE1.INTFLAGS = TC1_OVFIF_bm;
rightWheel.pulseAmount++;
if(rightWheel.pulseAmount < (rightWheel.rateChange / 2))
rightWheel.acceleration += rightWheel.changeAcceleration;
else
rightWheel.acceleration -= rightWheel.changeAcceleration;
rightWheel.period -= rightWheel.acceleration;
TCE1.PER = rightWheel.period;
TCE1.CCABUF = rightWheel.period - rightWheel.pulseWidth;
TCE1.CCBBUF = rightWheel.period - rightWheel.pulseWidth;
}
}
//Device at Constant Speed
while((leftWheel.pulseAmount >= leftWheel.rateChange) && (leftWheel.pulseAmount < (leftWheel.pulseTotal - leftWheel.rateChange)))
{
if(TCE0.INTFLAGS & TC0_OVFIF_bm)
{
TCE0.INTFLAGS = TC0_OVFIF_bm;
leftWheel.pulseAmount++;
}
if(TCE0.INTFLAGS & TC0_OVFIF_bm)
{
TCE1.INTFLAGS = TC1_OVFIF_bm;
rightWheel.pulseAmount++;
}
}
//Begins the deceleration process
while((leftWheel.pulseAmount >= (leftWheel.pulseTotal - leftWheel.rateChange)))
{
if(TCE0.INTFLAGS & TC0_OVFIF_bm)
{
TCE0.INTFLAGS = TC0_OVFIF_bm;
leftWheel.pulseAmount++;
if(leftWheel.pulseAmount < (leftWheel.pulseTotal - (leftWheel.rateChange / 2)))
leftWheel.acceleration += leftWheel.changeAcceleration;
else
leftWheel.acceleration -= leftWheel.changeAcceleration;
leftWheel.period += leftWheel.acceleration;
TCE0.PER = leftWheel.period;
TCE0.CCABUF = leftWheel.period - leftWheel.pulseWidth;
TCE0.CCBBUF = leftWheel.period - leftWheel.pulseWidth;
}
if(TCE1.INTFLAGS & TC1_OVFIF_bm)
{
TCE1.INTFLAGS = TC1_OVFIF_bm;
rightWheel.pulseAmount++;
if(rightWheel.pulseAmount < (rightWheel.pulseTotal - (rightWheel.rateChange / 2)))
rightWheel.acceleration += rightWheel.changeAcceleration;
else
rightWheel.acceleration -= rightWheel.changeAcceleration;
rightWheel.period += rightWheel.acceleration;
TCE1.PER = rightWheel.period;
TCE1.CCABUF = rightWheel.period - rightWheel.pulseWidth;
TCE1.CCBBUF = rightWheel.period - rightWheel.pulseWidth;
}
}
TCE0.CTRLA = 0x00;
TCE1.CTRLA = 0x00;
}
}
void findChangeAcceleration(struct _Device *useDevice)
{
double aveAcceleration;
aveAcceleration = (useDevice->maxTimer - useDevice->minTimer) / useDevice->rateChange;
useDevice->changeAcceleration = 2 * aveAcceleration / useDevice->rateChange;
}