time to save again, added a system clock so we can check temperature every 250ms and run a PID loop

This commit is contained in:
Michael Moon 2010-01-17 19:50:34 +11:00
parent 4bf2d005c2
commit db94bf21e8
7 changed files with 98 additions and 30 deletions

View File

@ -14,7 +14,7 @@
PROGRAM = mendel
SOURCES = $(PROGRAM).c ringbuffer.c serial.c dda.c gcode.c timer.c
SOURCES = $(PROGRAM).c ringbuffer.c serial.c dda.c gcode.c timer.c clock.c temp.c
##############################################################################
# #

53
mendel/clock.c Normal file
View File

@ -0,0 +1,53 @@
/*
clock.c
a system clock with 1ms ticks
*/
#include "clock.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include "arduino.h"
// global clock
volatile uint32_t clock = 0;
// 1/4 second tick
uint8_t clock_counter_250ms = 0;
volatile uint8_t clock_flag_250ms = 0;
void clock_setup() {
// use system clock
ASSR = 0;
// no compare match, CTC mode
TCCR2A = MASK(WGM21);
// 128 prescaler (16MHz / 128 = 125KHz)
TCCR2B = MASK(CS22) | MASK(CS20);
// 125KHz / 125 = 1KHz for a 1ms tick rate
OCR2A = 125;
// interrupt on overflow, when counter reaches OCR2A
TIMSK2 |= MASK(TOIE2);
}
ISR(TIMER2_OVF_vect) {
// global clock
clock++;
// 1/4 second tick
if (++clock_counter_250ms == 250) {
clock_flag_250ms = 255;
clock_counter_250ms = 0;
}
}
uint32_t clock_read() {
uint32_t c;
cli(); // set atomic
c = clock; // copy clock value
sei(); // release atomic
return c;
}

13
mendel/clock.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef _CLOCK_H
#define _CLOCK_H
#include <stdint.h>
void clock_setup(void);
uint32_t clock_read(void);
extern volatile uint8_t clock_flag_250ms;
#define CLOCK_FLAG_250MS_TEMPCHECK 1
#endif /* _CLOCK_H */

View File

@ -24,13 +24,4 @@
#define STEPS_PER_MM_Z (3200)
#define STEPS_PER_MM_E (EXTRUDER_STEPS_PER_REV * EXTRUDER_SHAFT_RADIUS * PI * EXTRUDER_INLET_DIAMETER / EXTRUDER_NOZZLE_DIAMETER)
/*
heater PID variables
used as int16_t * FACTOR so don't put brackets around them
*/
#define P_FACTOR 133 / 1024
#define I_FACTOR 17 / 1024
#define D_FACTOR 180 / 1024
#endif /* _MACHINE_H */

View File

@ -5,13 +5,14 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include "serial.h"
#include "machine.h"
#include "serial.h"
#include "dda.h"
#include "gcode.h"
#include "timer.h"
#include "machine.h"
#include "clock.h"
#include "temp.h"
uint8_t option_bitfield;
@ -46,17 +47,30 @@ int main (void)
WRITE(HEATER_PIN, 0); SET_OUTPUT(HEATER_PIN);
WRITE(SCK, 0); SET_OUTPUT(SCK);
WRITE(MISO, 1); SET_INPUT(MISO);
WRITE(SS, 0); SET_OUTPUT(SS);
// set up timers
setupTimerInterrupt();
// enable interrupts
sei();
serial_writeblock((uint8_t *) "Start\n", 6);
// main loop
for (;;)
{
for (;serial_rxchars() == 0;);
uint8_t c = serial_popchar();
if (serial_rxchars()) {
uint8_t c = serial_popchar();
scan_char(c);
}
scan_char(c);
if (clock_flag_250ms & CLOCK_FLAG_250MS_TEMPCHECK) {
clock_flag_250ms &= ~CLOCK_FLAG_250MS_TEMPCHECK;
temp_tick();
}
}
}

View File

@ -8,22 +8,20 @@
#include "machine.h"
#include "pinout.h"
#include "clock.h"
uint16_t current_temp;
uint16_t target_temp;
uint16_t current_temp = 0;
uint16_t target_temp = 0;
int16_t heater_p;
int16_t heater_i;
int16_t heater_d;
int16_t heater_p = 0;
int16_t heater_i = 0;
int16_t heater_d = 0;
void temp_setup() {
SET_OUTPUT(SCK);
SET_INPUT(MISO);
SET_OUTPUT(SS);
int16_t p_factor = 680;
int16_t i_factor = 18;
int16_t d_factor = 200;
WRITE(SS, 0);
WRITE(SCK, 0);
}
#define PID_SCALE 1024
uint16_t temp_read() {
uint16_t temp;
@ -71,7 +69,7 @@ void temp_tick() {
// note: D follows temp rather than error so there's no large derivative when the target temperature changes
heater_d = (current_temp - last_temp);
int16_t pid_output = (heater_p * P_FACTOR) + (heater_i * I_FACTOR) + (heater_d * D_FACTOR);
int16_t pid_output = ((heater_p * p_factor) + (heater_i * i_factor) + (heater_d * d_factor)) / PID_SCALE;
#ifdef HEATER_PIN_PWMABLE
HEATER_PIN_PWMABLE = pid_output

View File

@ -3,7 +3,6 @@
#include <stdint.h>
void temp_setup(void);
uint16_t temp_read(void);
void temp_set(uint16_t t);
void temp_tick(void);