Skip to content

Commit

Permalink
Implements acceleration profiles: linear, trapezoid and s-curve
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrazio committed Jun 11, 2018
1 parent 441f35b commit e2d4be2
Show file tree
Hide file tree
Showing 19 changed files with 340 additions and 194 deletions.
2 changes: 0 additions & 2 deletions ardufocus/a4988.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ void a4988::init()
{
stepper::init();

OCR1A = 0x32; // (5kHz)

IO::set_as_output(m_pinout.ms1);
IO::set_as_output(m_pinout.ms2);
IO::set_as_output(m_pinout.ms3);
Expand Down
11 changes: 2 additions & 9 deletions ardufocus/a4988.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,13 @@
#include "util.h"
#include "io.h"

#undef MOTOR_DRIVER
#define MOTOR_DRIVER a4988

class a4988: public stepper
{
public:
struct pinout_t
{
uint8_t ms1;
uint8_t ms2;
uint8_t ms3;
uint8_t sleep;
uint8_t step;
uint8_t direction;
pin_t ms1, ms2, ms3;
pin_t sleep, step, direction;
};

protected:
Expand Down
11 changes: 7 additions & 4 deletions ardufocus/ardufocus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,22 @@ int main(void)
// --------------------------------------------------------------------------
// Timer1 ISR init routine --------------------------------------------------
// --------------------------------------------------------------------------
TCCR1B = 0; TIMSK1 = 0;
TCCR1A = 0; TCCR1B = 0; TIMSK1 = 0; OCR1A = 0; OCR1B = 0; TCNT1 = 0;

// Normal port operation, no output
TCCR1A &= ~(bit(COM1A1) | bit(COM1A0));

// set waveform generation mode to CTC, top OCR1A (D9, D10)
TCCR1B |= bit(WGM12);

// set clock select to clk/64
TCCR1B |= bit(CS11) | bit(CS10);
// set clock select to clk/8
TCCR1B |= bit(CS11);

// output Compare A Match Interrupt Enable
TIMSK1 |= bit(OCIE1A);

// sets the Output Compare Register values
//OCR1A = 0x32; // (5kHz)
OCR1A = MAX_ISR_FREQ;


// --------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions ardufocus/ardufocus.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "log.h"
#include "analog.h"
#include "protocol.h"
#include "motor1drv.h"

// --------------------------------------------------------------------------
// Globals ------------------------------------------------------------------
Expand Down
31 changes: 29 additions & 2 deletions ardufocus/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@
#define __ASSERT_H__

#if defined(USE_A4988_DRIVER)
#include "a4988.h"
#define MAX_ISR_FREQ 0x3E8 // 2KHz
#define MIN_ISR_FREQ 0xFA0 // 500Hz

#elif defined(USE_ULN2003_DRIVER)
#include "uln2003.h"
#define MAX_ISR_FREQ 0x7D0 // 1KHz
#define MIN_ISR_FREQ 0x4E20 // 100Hz

#else
#error No stepper driver selected.
#error Please review the config.h file.
Expand All @@ -38,4 +42,27 @@
#warning Remote reset is enabled, make sure your bootloader is updated !
#endif

#if defined(USE_LINEAR_ACCEL) || defined(USE_TRAPEZOID_ACCEL) || defined(USE_SMOOTHSTEP_ACCEL)
#define HAS_ACCELERATION

#ifndef ACCEL_DURATION
#define ACCEL_DURATION 250
#elif (ACCEL_DURATION < 100)
#warning The acceleration duration is less than 100 steps.
#warning Maybe you should consider disabling acceleration at al ?
#endif

#ifndef ACCEL_MIN_STEPS
#define ACCEL_MIN_STEPS 10
#elif (ACCEL_MIN_STEPS < 1)
#error ACCEL_MIN_STEPS cannot be lower than 1 step.
#error Please review the config.h file.
#endif

#if (ACCEL_MIN_STEPS >= ACCEL_DURATION)
#error ACCEL_MIN_STEPS must be lower than ACCEL_DURATION.
#error Please review the config.h file.
#endif
#endif

#endif
51 changes: 38 additions & 13 deletions ardufocus/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
// damage your board. For more information read the README.md file or the source
// code commit history.
//
// [8375767]: https://github.com/jbrazio/ardufocus/commit/8375767da8008305e1cb2a93d049970c49c1482d
// [8375767]: https://github.com/jbrazio/Ardufocus/commit/8375767da8008305e1cb2a93d049970c49c1482d

// ----------------------------------------------------------------------------
// Remote reset ---------------------------------------------------------------
Expand Down Expand Up @@ -63,24 +63,51 @@
// Example for ULN2003 driver board
//
// IN1, IN2, IN3, IN4
//#define MOTOR1_PINOU 5, 4, 3, 2
//#define MOTOR1_PINOUT 5, 4, 3, 2
//
// Example for A4988 driver board
//
// MS1, MS2, MS3, SLEEP, STEP, DIR
// MS1, MS2, MS3, SLEEP, STEP, DIR
#define MOTOR1_PINOUT 7, 8, 9, 10, 11, 12

// Activate the following directive if you'd like to invert the motor rotation
// changing the focus direction.
//#define INVERT_MOTOR_DIR

// When active ardufocus will apply a linear acceleration profile to the motor's
// speed. The objective is to help the system cope with heavier loads such as
// FF + FW + CCD combos.
// When active Ardufocus will apply the selected acceleration profile to the
// motor's speed. The objective is to help the system cope with heavier loads
// such as FF + FW + CCD combos.
//
//
// Linear Acceleration Trapezoid Acceleration Smooth Step Acceleration
// (S-Curve)
//
// | /\ | ___________ | __---__
// V | / \ V | / \ V | - -
// | / \ | / \ | - -
// |/ \ |/ \ |__- -__
// +---------------- +------------------- +-------------------
// T T T
//
//#define USE_LINEAR_ACCEL

// When active ardufocus will cut the stepper motor current when idle, in theory
// this could lead to less accuracy betwen movements but will keep the motor
//#define USE_TRAPEZOID_ACCEL
#define USE_SMOOTHSTEP_ACCEL

// The acceleration profile, independent of the method used, has at least two
// main periods: the ramp-up period when the motor is gaining speed and the
// ramp-down period when the motor is losing speed. This setting controls the
// duration of each one of those periods, the default value is 250 steps for
// each period if left undefined.
//#define ACCEL_DURATION 250

// When acceleration control is active this setting controls the minimum
// required number of steps on a movement for the algorithm to kick in. Any
// movement with less steps than this will be done at minimum speed without
// any acceleration control. The default value is 10 steps of left undefined.
//#define ACCEL_MIN_STEPS 10

// When active Ardufocus will cut the stepper motor current when idle, in theory
// this could lead to less accuracy between movements but will keep the motor
// cool. When disabling this flag make sure your motor does not overheat.
#define MOTOR_SLEEP_WHEN_IDLE

Expand All @@ -96,7 +123,7 @@
// According to the Moonlite protocol the temperature probe should only be read
// when the command ":C#" is received but some applications, such as SGP, seems
// not to respect this and only call the get temperature command ":GT#" which
// means the temperature will never get updated and the last value is always
// means the temperature will never get updated and the last read value is always
// returned, either it is valid or not. Enabling the following option will force
// the temperature gathering process on every temperature read command.
// #define START_TEMP_CONVERSION_ON_EVERY_GET
Expand All @@ -114,8 +141,6 @@
// ----------------------------------------------------------------------------
// DO NOT EDIT ANYTHING BELLOW THIS HEADER ------------------------------------
// ----------------------------------------------------------------------------
#ifndef __DO_NOT_ASSERT__
#include "assert.h"
#endif
#include "assert.h"

#endif
1 change: 1 addition & 0 deletions ardufocus/isr.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "config.h"

#include "analog.h"
#include "motor1drv.h"

extern MOTOR_DRIVER g_motor1;

Expand Down
2 changes: 1 addition & 1 deletion ardufocus/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class Log
// float:
static void number(const float& n)
{
Log::fraq(n, 2);
Log::fraq(n, 3);
}

public:
Expand Down
54 changes: 24 additions & 30 deletions ardufocus/macro.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,37 @@
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>

#ifndef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START const uint8_t __SREG___ = SREG; cli();
#define CRITICAL_SECTION_END SREG = __SREG___;
#endif
#undef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START const uint8_t __SREG___ = SREG; cli();

#ifndef bit
#define bit(b) (1UL << (b))
#endif
#undef CRITICAL_SECTION_END
#define CRITICAL_SECTION_END SREG = __SREG___;

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#undef bit
#define bit(b) (1UL << (b))

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#undef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))

#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#endif
#undef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

#ifndef max
#define max(a,b) ((a)>(b)?(a):(b))
#endif
#undef min
#define min(a,b) ((a)<(b)?(a):(b))

/*
#ifndef abs
#define abs(x) ((x)>0?(x):-(x))
#endif
*/
#undef max
#define max(a,b) ((a)>(b)?(a):(b))

#ifndef constrain
#define constrain(n, low, high) ((n)<(low)?(low):((n)>(high)?(high):(n)))
#endif
//#undef abs
//#define abs(n) ((n)>0?(n):-(n))

#ifndef asizeof
#define asizeof(a) (sizeof(a) / sizeof(*a))
#endif
#undef constrain
#define constrain(n, l, h) ((n)<(l)?(l):((n)>(h)?(h):(n)))

#undef map
#define map(n, a, b, x, y) ((n-a)*(y-x)/(b-a)+x)

#undef asizeof
#define asizeof(a) (sizeof(a) / sizeof(*a))

#endif
35 changes: 6 additions & 29 deletions ardufocus/struct.h → ardufocus/motor1drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,15 @@
*
*/

#ifndef __STRUCT_H__
#define __STRUCT_H__

#include <stdint.h>
#include <stdlib.h>

#include "version.h"
#include "config.h"

struct stepper_position_t
{
bool moving;

uint16_t current,
target,
last;

uint16_t delta,
accelin,
accelout;
};
#if defined(USE_A4988_DRIVER)
#include "a4988.h"
#define MOTOR_DRIVER a4988

struct stepper_pin_t
{
uint8_t enable;
uint8_t ms1;
uint8_t ms2;
uint8_t ms3;
uint8_t reset;
uint8_t sleep;
uint8_t step;
uint8_t direction;
};
#elif defined(USE_ULN2003_DRIVER)
#include "uln2003.h"
#define MOTOR_DRIVER uln2003

#endif
1 change: 1 addition & 0 deletions ardufocus/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "log.h"
#include "util.h"
#include "analog.h"
#include "motor1drv.h"

extern float g_ambient;
extern MOTOR_DRIVER g_motor1;
Expand Down
1 change: 0 additions & 1 deletion ardufocus/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

#ifndef __SERIAL_H__
#define __SERIAL_H__
#define __DO_NOT_ASSERT__

#include <stdint.h>
#include <stdlib.h>
Expand Down
Loading

0 comments on commit e2d4be2

Please sign in to comment.