Compare commits

...

3 Commits

Author SHA1 Message Date
radex 0c3dd769bc
ugly interrupt-based stepper control 2024-02-14 21:59:02 +01:00
radex 50a70f5725
Timer: uptime report demo 2024-02-14 21:21:02 +01:00
radex a4e0a69165
Timer: set up a 62.5kHz timer 2024-02-14 21:17:41 +01:00
5 changed files with 64 additions and 22 deletions

View File

@ -30,6 +30,6 @@
// --- Z axis motor
#define STEPPER_ENABLE 10
#define STEPPER_DIR 8
#define STEPPER_STEP 9
#define STEPPER_ENABLE A0
#define STEPPER_STEP A1
#define STEPPER_DIR A2

View File

@ -52,6 +52,10 @@ void loop() {
sadBuzz();
} else if (key == KEY_C) {
beep();
} else if (digit == 4) {
demo_moveBy(-8000);
} else if (digit == 5) {
demo_moveBy(8000);
} else {
tick();
}
@ -65,6 +69,6 @@ void loop() {
if (auto event = handleEncoder()) {
tick();
Serial.println(event == ENCODER_CLOCKWISE ? "Clockwise" : "Counter-clockwise");
demoStepper(event == ENCODER_CLOCKWISE ? LOW : HIGH);
demo_moveBy(event == ENCODER_CLOCKWISE ? 800 : -800);
}
}

View File

@ -1,6 +1,14 @@
#include <Arduino.h>
#include "constants.h"
/*
A4988 Stepper Motor Driver.
NOTE: minimum pulse width 1us high, 1us low
*/
void setupStepper() {
pinMode(STEPPER_ENABLE, OUTPUT);
pinMode(STEPPER_DIR, OUTPUT);

View File

@ -1,21 +1,34 @@
#include <Arduino.h>
#include "constants.h"
#define DEMO_TRIGGER_MS 1500
#define DEMO_REPORT_SECONDS 2
#define DEMO_TRIGGER_MS DEMO_REPORT_SECONDS * 1000
#if F_CPU != 16000000
#error "Unsupported F_CPU"
#endif
void setupTimer() {
// Set up Timer 0 to trigger interrupt every 1ms
// Timer 0 is already used and configured by Arduino for millis()
// however it uses TOIE0 (overflow interrupt), so we'll use OCIE0A:
// When this bit is written to one, and the I-flag in the Status Register is set
// (interrupts globally enabled), the Timer/Counter0 Output Compare A Match interrupt is enabled
// The corresponding Interrupt Vector is executed when the OCF0A Flag, located in TIFR0, is set.
OCR0A = 0xAF; // any number is OK, it will trigger at some point during the counter
TIMSK0 |= _BV(OCIE0A);
noInterrupts();
// reset timer settings
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 256 prescaler (16MHz / 256 = 62.5kHz)
TCCR1B |= (1 << CS12);
// CTC mode (Clear Timer on Compare Match)
TCCR1B |= (1 << WGM12);
// interrupt at 62.5kHz / (OCR1A + 1)
OCR1A = 19;
// enable timer
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
// incremented every DEMO_TRIGGER_MS by interrupt,
// read and decremented by main loop
volatile uint8_t timerEvents = 0;
uint8_t demoCounter = 0;
void demoTimer() {
bool shouldTrigger = false;
@ -28,19 +41,34 @@ void demoTimer() {
interrupts();
if (shouldTrigger) {
Serial.println("Timer tick!");
demoCounter += DEMO_REPORT_SECONDS;
Serial.print("Uptime: ");
Serial.print(demoCounter);
Serial.println("s");
}
}
volatile int16_t stepsLeft = 0;
void demo_moveBy(int16_t steps) {
bool dir;
noInterrupts();
stepsLeft += steps;
dir = steps > 0 ? LOW : HIGH;
digitalWrite(STEPPER_DIR, dir);
interrupts();
}
volatile uint16_t timerTicks = 0;
volatile uint16_t timerMillis = 0;
// triggers every 1ms
ISR(TIMER0_COMPA_vect) {
timerMillis++;
if (timerMillis >= DEMO_TRIGGER_MS) {
timerMillis -= DEMO_TRIGGER_MS;
timerEvents++;
}
ISR(TIMER1_COMPA_vect) {
if (stepsLeft != 0) {
stepsLeft += stepsLeft > 0 ? -1 : 1;
// TODO: Add motor encoder reading, calculate required carriage offset, control stepper
// pulse STEP
PORTC |= 1<<1;
PORTC &= ~(1<<1);
}
}

View File

@ -1,2 +1,4 @@
void setupTimer();
void demoTimer();
void demo_moveBy(int16_t steps);