summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-05-23 16:40:34 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-05-23 16:40:34 +0200
commit92c81eb247f121ab24a5b7e5783d8d92c0467c43 (patch)
tree01c57600393cb62532f218706682e56995f9295b
parentimproved contrib Makefile (diff)
parentreimplemented rpm based speed setting (diff)
Merge branch 'master' of gitspread:avr
-rw-r--r--tube-rotator/stepper.c97
-rw-r--r--tube-rotator/stepper.h29
-rw-r--r--tube-rotator/tube-rotator.c30
3 files changed, 134 insertions, 22 deletions
diff --git a/tube-rotator/stepper.c b/tube-rotator/stepper.c
index ff68072..8b718ae 100644
--- a/tube-rotator/stepper.c
+++ b/tube-rotator/stepper.c
@@ -22,18 +22,13 @@
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
+#include <util/atomic.h>
+#include <math.h>
#include "stepper.h"
uint8_t step_table [] =
{
- /* full steps */
- /* 6, // 0110 */
- /* 5, // 0101 */
- /* 9, // 1001 */
- /* 10, // 1010 */
-
- /* half steps */
2, // 0010
6, // 0110
4, // 0100
@@ -52,20 +47,30 @@ uint8_t step_table [] =
#define LENGTH_STEP_TABLE (sizeof(step_table)/sizeof(uint8_t))
#define STEPPER_OUTPUT_BITMASK (~(0xF << STEPPER_FIRST_BIT ))
+volatile uint16_t target_speed;
+uint16_t current_speed;
+stepper_state_t current_state;
+
void stepper_init(void)
{
+ target_speed = STEPPER_SPEED_DEFAULT;
STEPPER_PORT &= ~(0xF << STEPPER_FIRST_BIT | 1<<STEPPER_ENABLE_A_BIT | 1<<STEPPER_ENABLE_B_BIT);
STEPPER_DDR |= (0xF << STEPPER_FIRST_BIT) | (1<<STEPPER_ENABLE_A_BIT) | (1<<STEPPER_ENABLE_B_BIT);
+ stepper_stop();
}
void stepper_start(void)
{
+ if(current_state == stepper_running) return;
+
+ current_speed = STEPPER_SPEED_MIN;
STEPPER_PORT |= (1<<STEPPER_ENABLE_A_BIT) | (1<<STEPPER_ENABLE_B_BIT);
- TCCR1A = 0; // prescaler 1:256, WGM = 4 (CTC)
- TCCR1B = 1<<WGM12 | 1<<CS12; //
- OCR1A = 20;
TCNT1 = 0;
+ OCR1A = current_speed;
+ TCCR1A = 0; // prescaler 1:64, WGM = 4 (CTC)
+ TCCR1B = 1<<WGM12 | 1<<CS11 | 1<<CS10; //
TIMSK1 = 1<<OCIE1A;
+ current_state = stepper_running;
}
void stepper_stop(void)
@@ -73,6 +78,7 @@ void stepper_stop(void)
STEPPER_PORT &= ~(0xF << STEPPER_FIRST_BIT | 1<<STEPPER_ENABLE_A_BIT | 1<<STEPPER_ENABLE_B_BIT);
TCCR1B = 0; // no clock source
TIMSK1 = 0; // disable timer interrupt
+ current_state = stepper_stopped;
}
static inline void stepper_handle(void)
@@ -84,9 +90,80 @@ static inline void stepper_handle(void)
STEPPER_PORT = (STEPPER_PORT & STEPPER_OUTPUT_BITMASK ) | stepper_output;
step_idx++;
step_idx %= LENGTH_STEP_TABLE;
+
+ if(step_idx != 0 && step_idx % 8) {
+ if(current_speed > target_speed)
+ OCR1A = (uint16_t)((STEPPER_SPEED_CONVERT_VALUE/(--current_speed)) - 1);
+ else if(current_speed < target_speed)
+ OCR1A = (uint16_t)((STEPPER_SPEED_CONVERT_VALUE/(++current_speed)) - 1);
+ }
}
ISR(TIMER1_COMPA_vect)
{
stepper_handle();
}
+
+stepper_state_t stepper_get_state(void)
+{
+ return current_state;
+}
+
+const char* stepper_state_to_string(stepper_state_t state)
+{
+ switch(state) {
+ case stepper_running: return "running";
+ case stepper_stopped: return "stopped";
+ }
+ return "?";
+}
+
+void stepper_set_speed(uint16_t new_speed)
+{
+ if(new_speed >= STEPPER_SPEED_MIN && new_speed <= STEPPER_SPEED_MAX) {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = new_speed;
+ }
+ }
+}
+
+void stepper_inc_speed(void)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = (target_speed >= STEPPER_SPEED_MAX) ? STEPPER_SPEED_MAX : target_speed + 1;
+ }
+}
+
+void stepper_dec_speed(void)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ target_speed = (target_speed <= STEPPER_SPEED_MIN) ? STEPPER_SPEED_MIN : target_speed - 1;
+ }
+}
+
+uint16_t stepper_get_speed(void)
+{
+ return target_speed;
+}
+
+void stepper_set_speed_rpm(uint8_t new_rpm)
+{
+ stepper_set_speed( (uint16_t)lround( ( (double)(64.0 * 800.0 * (double)STEPPER_SPEED_CONVERT_VALUE) / (double)(60.0 * (double)F_CPU) ) * (double)new_rpm) );
+}
+
+uint8_t stepper_get_speed_rpm(void)
+{
+ return (uint8_t)lround( ( (double)(60.0 * (double)F_CPU) / (double)(64.0 * 800.0 * (double)STEPPER_SPEED_CONVERT_VALUE) ) * (double)(target_speed) );
+}
+
+void stepper_inc_speed_rpm(void)
+{
+ uint8_t rpm = stepper_get_speed_rpm();
+ stepper_set_speed_rpm((rpm >= 255) ? 255 : rpm+1);
+}
+
+void stepper_dec_speed_rpm(void)
+{
+ uint8_t rpm = stepper_get_speed_rpm();
+ stepper_set_speed_rpm((rpm <= 1) ? 1 : rpm-1);
+}
diff --git a/tube-rotator/stepper.h b/tube-rotator/stepper.h
index 7fb70ec..5b5a315 100644
--- a/tube-rotator/stepper.h
+++ b/tube-rotator/stepper.h
@@ -23,8 +23,37 @@
#ifndef R3TUBE_stepper_h_INCLUDED
#define R3TUBE_stepper_h_INCLUDED
+#define STEPPER_SPEED_MIN 150
+#define STEPPER_SPEED_MAX 700
+#define STEPPER_SPEED_CONVERT_VALUE (uint32_t)(105000)
+
+#define STEPPER_SPEED_30RPM 168
+#define STEPPER_SPEED_40RPM 224
+#define STEPPER_SPEED_50RPM 281
+#define STEPPER_SPEED_60RPM 336
+#define STEPPER_SPEED_70RPM 393
+#define STEPPER_SPEED_80RPM 451
+#define STEPPER_SPEED_90RPM 507
+#define STEPPER_SPEED_100RPM 561
+
+#define STEPPER_SPEED_DEFAULT STEPPER_SPEED_60RPM
+
+typedef enum { stepper_stopped = 0, stepper_running = 1 } stepper_state_t;
+
void stepper_init(void);
void stepper_start(void);
void stepper_stop(void);
+stepper_state_t stepper_get_state(void);
+const char* stepper_state_to_string(stepper_state_t state);
+
+void stepper_set_speed(uint16_t new_speed);
+void stepper_inc_speed(void);
+void stepper_dec_speed(void);
+uint16_t stepper_get_speed(void);
+
+void stepper_set_speed_rpm(uint8_t new_rpm);
+uint8_t stepper_get_speed_rpm(void);
+void stepper_inc_speed_rpm(void);
+void stepper_dec_speed_rpm(void);
#endif
diff --git a/tube-rotator/tube-rotator.c b/tube-rotator/tube-rotator.c
index 7a0e2ec..065dd2f 100644
--- a/tube-rotator/tube-rotator.c
+++ b/tube-rotator/tube-rotator.c
@@ -37,19 +37,25 @@
void handle_cmd(uint8_t cmd)
{
switch(cmd) {
- case '!':
- reset2bootloader();
- break;
- case 'r':
- led_on();
- stepper_start();
- break;
- case 's':
- stepper_stop();
- led_off();
- break;
- default: printf("Error(cmd): unknown command %02X '%c'\r\n", cmd, cmd); return;
+ case '!': reset2bootloader(); break;
+ case 'r': led_on(); stepper_start(); break;
+ case 's': stepper_stop(); led_off(); break;
+ case '*': stepper_inc_speed(); break;
+ case '+': stepper_inc_speed_rpm(); break;
+ case '-': stepper_dec_speed_rpm(); break;
+ case '_': stepper_dec_speed(); break;
+ case '3': stepper_set_speed_rpm(30); break;
+ case '4': stepper_set_speed_rpm(40); break;
+ case '5': stepper_set_speed_rpm(50); break;
+ case '6': stepper_set_speed_rpm(60); break;
+ case '7': stepper_set_speed_rpm(70); break;
+ case '8': stepper_set_speed_rpm(80); break;
+ case '9': stepper_set_speed_rpm(90); break;
+ case '0': stepper_set_speed_rpm(100); break;
+ case '1': stepper_set_speed_rpm(110); break;
+ case '2': stepper_set_speed_rpm(120); break;
}
+ printf("state: %s, %3d rpm\r", stepper_state_to_string(stepper_get_state()), stepper_get_speed_rpm());
}
int main(void)