I at the moment trying solve my issue of why an non related function mess up the output my ISR routine were supposed to give me.
The code i am executing is this.
main.ino
#include "speed_profile.h"
void setup() {
// put your setup code here, to run once:
cli();
output_pin_setup();
timer1_setup();
sei();
}
void loop()
{
int motor_steps = -23400;//-9600; //23400 - 100%
// Accelration to use.
int motor_acceleration = 500;//500;
// Deceleration to use.
int motor_deceleration = 500;//500;
// Speed to use.
int motor_speed = 1000; // 1000
init_tipper_position();
compute_speed_profile(motor_steps, motor_acceleration, motor_deceleration, motor_speed);
}
Problem is that when i choose to execute init_tipper_position()
before compute_speed_profile()
it somehow mess up my ISR, and don’t properly end it as it was supposed to.
My ISR is coded as such:
ISR(TIMER1_COMPA_vect)
{
// Holds next delay period.
unsigned int new_first_step_delay;
// Remember the last step delay used when accelrating.
static int last_accel_delay;
// Counting steps when moving.
static unsigned int step_count = 0;
// Keep track of remainder from new_step-delay calculation to incrase accurancy
static unsigned int rest = 0;
OCR1A = profile.first_step_delay;
switch (profile.run_state)
{
case STOP:
step_count = 0;
global_state = false;
rest = 0;
TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Stop the timer, No clock source
break;
case ACCEL:
digitalWrite(step_pin, !digitalRead(step_pin));
step_count++;
if (profile.dir == CCW)
{
profile.current_step_position++;
}
else
{
profile.current_step_position--;
}
profile.accel_count++;
new_first_step_delay = profile.first_step_delay - (((2 * (long)profile.first_step_delay) + rest) / (4 * profile.accel_count + 1));
rest = ((2 * (long)profile.first_step_delay) + rest) % (4 * profile.accel_count + 1);
// Chech if we should start decelration.
if (step_count >= profile.decel_start)
{
profile.accel_count = profile.decel_length;
profile.run_state = DECEL;
}
// Chech if we hitted max speed.
else if (new_first_step_delay <= profile.min_time_delay)
{
last_accel_delay = new_first_step_delay;
new_first_step_delay = profile.min_time_delay;
rest = 0;
profile.run_state = RUN;
}
break;
case RUN:
digitalWrite(step_pin, !digitalRead(step_pin));
step_count++;
if (profile.dir == CCW)
{
profile.current_step_position++;
}
else
{
profile.current_step_position--;
}
new_first_step_delay = profile.min_time_delay;
// Chech if we should start decelration.
if (step_count >= profile.decel_start)
{
profile.accel_count = profile.decel_length;
// Start decelration with same delay as accel ended with.
new_first_step_delay = last_accel_delay;
profile.run_state = DECEL;
}
break;
case DECEL:
digitalWrite(step_pin, !digitalRead(step_pin));
step_count++;
if (profile.dir == CCW)
{
profile.current_step_position++;
}
else
{
profile.current_step_position--;
}
profile.accel_count++;
new_first_step_delay = profile.first_step_delay - (((2 * (long)profile.first_step_delay) + rest) / (4 * profile.accel_count + 1));
rest = ((2 * (long)profile.first_step_delay) + rest) % (4 * profile.accel_count + 1);
// Check if we at last step
if (profile.accel_count >= 0)
{
digitalWrite(en_pin, !digitalRead(en_pin));
profile.run_state = STOP;
}
break;
}
profile.first_step_delay = new_first_step_delay;
}
The ISR is started by the function compute_speed_profile(motor_steps, motor_acceleration, motor_deceleration, motor_speed);
and is always initialised with the same value. Usually would the ISR go through all the states and end at STOP, but here stops it at DECEL, and never gets a change to change the bool global_state = false, such that the ISR will be turned of. The timer stalls at DECEL, and never continues.
The init_tipper_position() looks like this
void init_tipper_position()
{
digitalWrite(en_pin, HIGH);
delay(1);
digitalWrite(dir_pin, LOW);
delay(1);
int sensor_value = digitalRead(slot_sensor_pin);
while(sensor_value == LOW)
{
sensor_value = digitalRead(slot_sensor_pin);
digitalWrite(step_pin, HIGH);
delay(1);
digitalWrite(step_pin, LOW);
delay(1);
}
digitalWrite(en_pin, LOW);
}
Both functions are basically non-related which make me more confused what is going wrong.
I tried by some debugging to narrow the search space, and the error seem to occur due to the executing of the while(digitalRead(slot_sensor_pin) == LOW). Executing this before causes the ISR to perform incorrectly, removing it and it performs correctly.
it should be noted that slot_sensor_pin is initialized as and INPUT_PULLUP.
Most of the variable in the ISR are constant, except those that are being increment or calculated inside.
The values that are used for comparison are constants.
profile
is basically a struct that keeps track of the values.
any clue why this is a problem?