Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: LawrenceLeung/reflow_controller
base: 920cd538cd
...
head fork: LawrenceLeung/reflow_controller
compare: 5f655cd903
  • 2 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
View
119 avr/max6675.c
@@ -1,4 +1,4 @@
-/**
+/**
* Copyright (c) 2011, Daniel Strother < http://danstrother.com/ >
* All rights reserved.
*
@@ -27,10 +27,16 @@
#include "max6675.h"
#include "ovencon.h"
+#include <avr/pgmspace.h>
+#include <avr/io.h>
+
#ifdef TEMP_AVERAGING
int16_t temps[DEVICES][AVERAGE];
#endif
+// defined below
+int16_t thermocouple_lookup(int16_t x);
+
static void _max6675_select(uint8_t device, uint8_t cs)
{
switch(device)
@@ -101,7 +107,6 @@ int16_t max6675_read(uint8_t device)
{
int16_t result;
int16_t avg;
- uint8_t i;
cli();
@@ -135,7 +140,7 @@ int16_t max6675_read(uint8_t device)
thermocouple_fault(result);
return result;
}
-
+
// result is in upper 13 bits (12 real bits; MSbit is dummy sign (always 0))
result >>= 3;
@@ -148,11 +153,11 @@ int16_t max6675_read(uint8_t device)
// average
avg = result;
-
+
#ifdef TEMP_AVERAGING
temps[device][0] = result;
- for(i=1;i<AVERAGE;i++)
+ for(uint8_t i=1;i<AVERAGE;i++)
{
avg += temps[device][i];
temps[device][i] = temps[device][i-1];
@@ -161,6 +166,110 @@ int16_t max6675_read(uint8_t device)
avg >>= AVERAGE_BITS;
#endif
+// use remap table?
+// return thermocouple_lookup(avg);
+
return avg;
}
+
+/* The following is necessary to correct unexplained Thermocouple reading skew
+
+ */
+
+#define KEY_TYPE int16_t
+#define VALUE_TYPE int16_t
+
+typedef struct {
+ KEY_TYPE k;
+ VALUE_TYPE v;
+} lut2_bs_kvp;
+
+
+/*generated by LUTGenerator
+ Input is Raw Thermocouple in CX4. Output is corrected Temp in C/2
+ * (Overall calibration for thermocouple that's ~6% hot)
+ */
+
+static const lut2_bs_kvp thermocouple_lut_data[] = {
+ {0, 0}, {400, 200}, {420, 210}, {530, 217}, {600, 302}, {660, 333}, {1000, 503}
+};
+
+
+
+
+#define LUT_READ_K(idx) (KEY_TYPE) thermocouple_lut_data[idx].k
+#define LUT_READ_V(idx) (VALUE_TYPE) (thermocouple_lut_data[idx].v<<1)
+
+#define LOOKUP_ABS(x,y) ((x>=y) ? x-y : y-x )
+#define LUT_LENGTH 7
+
+#define MAX(a,b) ((a>b) ? a: b )
+
+
+VALUE_TYPE thermocouple_lookup(KEY_TYPE x){
+ uint8_t low=0,
+ high=LUT_LENGTH-1,
+ search_marker=(LUT_LENGTH-1)>>1;
+
+ KEY_TYPE k;
+ if (x<0) return x; // preserve error code
+ if (x>1000) return x;
+
+ while (high-low>1){
+
+ k=LUT_READ_K(search_marker);
+ // exact match
+ if (k==x){
+ return (VALUE_TYPE)LUT_READ_V(search_marker)<<2;
+ }
+
+ if (k>x){
+ high=search_marker;
+ search_marker=high-MAX((high-low)>>1,1);
+ } else {
+ low=search_marker;
+ search_marker=low+MAX((high-low)>>1,1);
+ }
+ }
+
+
+ // check search marker one last time
+ k=LUT_READ_K(search_marker);
+ // exact match
+ if (k==x){
+ return (VALUE_TYPE)LUT_READ_V(search_marker)<<2;
+ }
+
+
+ // interpolate between high and low with fixed point math
+ // = l.v + (X-l.k) * (h.v-l.v)/(h.k-l.k)
+
+ KEY_TYPE lk=LUT_READ_K(low),
+ hk=LUT_READ_K(high);
+ VALUE_TYPE lv=LUT_READ_V(low),
+ hv=LUT_READ_V(high);
+
+ KEY_TYPE tb=LOOKUP_ABS(hk,lk); // temporarily store bottom in tb
+
+ if (tb!=0){
+
+ // need the extra res to avoid overflows
+ int32_t temp_tb=LOOKUP_ABS(x,lk);
+
+ temp_tb*=LOOKUP_ABS(hv,lv);
+ temp_tb/=tb;
+
+ tb=temp_tb;
+
+ // original math:
+ //tb=(LOOKUP_ABS(x,lk)* LOOKUP_ABS(hv,lv))/tb;
+ } else {
+ tb=0;
+ }
+
+
+// never negative!
+ return ((VALUE_TYPE)lv)+tb;
+
+}
View
11 avr/oven_lcd.cpp
@@ -13,7 +13,7 @@
-extern int16_t temp_t, temp_b;
+extern volatile int16_t temp_t, temp_b;
// Note pins are in arduino format
@@ -61,16 +61,11 @@ void lcd_update(){
nokia.clear();
nokia.setCursor(0, 0);
nokia.print("Temp: ");
+
nokia.print(temp_t>>2); // temp is in .25C
- nokia.print('.');
- uint8_t decimal=(temp_t & 0x03)*25;
- nokia.print(decimal);
- if (!decimal){
- nokia.print('0');
- nokia.print('0'); // 2 zeros
- }
nokia.print("C");
+
nokia.display();
View
2  avr/oven_pid.c
@@ -31,7 +31,7 @@ volatile uint8_t k_p;
volatile uint8_t k_i;
volatile uint8_t k_d;
-const uint8_t k_div = 8;
+const uint8_t k_div = 9;
#define k_delay 40
// state
View
27 avr/oven_profile.c
@@ -30,19 +30,21 @@ typedef struct
{
uint16_t delta_time; // time steps to run at temp_rate (0.25s each)
int16_t temp_rate; // rate of temperature change (1/1024 degrees per time step)
+ uint8_t fan_pwm;
} s_profile_step;
-#define STEPS 7
+#define STEPS 8
// profile table entries computed in reflow_profiles.ods spreadsheet
-const s_profile_step profile[STEPS] = {
- { 960, 64 },
- { 720, 135 },
- { 120, 213 },
- { 180, 85 },
- { 120, 0 },
- { 180, -228 },
- { 360, -441 }
+const s_profile_step profile[STEPS] = {
+ { 360, 242,0},
+ { 360, 114,0},
+ { 120, 256,0},
+ { 120, 282,0},
+ { 60, 85, 0},
+ { 40, -128, 128},
+ { 60, -563, 255},
+ { 240, -661, 255}
};
uint8_t profile_step; // current step
@@ -56,7 +58,11 @@ void profile_reset(void)
profile_temp = (25*1024); // room temp start point
}
-uint8_t profile_update(int16_t *target)
+
+extern uint8_t fan_pwm;
+
+
+uint8_t profile_update(volatile int16_t *target)
{
if(profile_step >= STEPS)
return 1;
@@ -67,6 +73,7 @@ uint8_t profile_update(int16_t *target)
profile_time = profile[profile_step].delta_time;
*target = profile_temp >> 8;
+ fan_pwm=profile[profile_step].fan_pwm;
return 0;
}
View
2  avr/oven_profile.h
@@ -35,7 +35,7 @@ extern "C"{
#include <stdint.h>
void profile_reset(void);
-uint8_t profile_update(int16_t *target);
+uint8_t profile_update(volatile int16_t *target);
View
18 avr/oven_ssr.c
@@ -136,3 +136,21 @@ void ssr_update(void)
}
+#define FAN_PIN 7
+
+extern uint8_t fan_pwm;
+
+// temporarily here
+void fan_setup(void) {
+ DDRC |= _BV(FAN_PIN);
+ PORTC &= ~(_BV(FAN_PIN));
+ fan_pwm=0;
+}
+
+void fan_update(uint8_t pwm){
+
+ if(pwm)
+ PORTC |= _BV(FAN_PIN);
+ else
+ PORTC &= ~(_BV(FAN_PIN));
+}
View
4 avr/oven_ssr.h
@@ -40,6 +40,10 @@ void ssr_update(void);
void ssr_set(uint8_t top, uint8_t bot);
void ssr_fault(void);
+// temporarily here
+void fan_setup(void);
+
+void fan_update(uint8_t pwm);
View
15 avr/ovencon.cpp
@@ -89,12 +89,13 @@ volatile uint8_t comm_cmd;
const char *state_names[5] = { "fault","idle","run","done","pause" };
-uint8_t state = ST_FAULT;
+volatile uint8_t state = ST_FAULT;
-int16_t target;
-uint16_t time;
+volatile int16_t target;
+volatile uint16_t time;
+volatile uint8_t fan_pwm;
-int16_t temp_t,temp_b; // last read temps
+volatile int16_t temp_t,temp_b; // last read temps
volatile uint8_t should_update_lcd;
@@ -156,7 +157,7 @@ void oven_output(uint8_t top, uint8_t bot)
}
}
-void oven_input(int16_t *top, int16_t *bot)
+void oven_input(volatile int16_t *top,volatile int16_t *bot)
{
if( !mode_fake_in )
{
@@ -184,6 +185,8 @@ void oven_input(int16_t *top, int16_t *bot)
}
}
+
+
void oven_setup(void)
{
@@ -219,6 +222,7 @@ void oven_setup(void)
should_update_lcd=0;
ssr_setup();
+ fan_setup();
lcd_init();
pid_reset();
profile_reset();
@@ -339,6 +343,7 @@ void oven_update_4hz(void)
}
oven_output(cmd_t,cmd_b);
+ fan_update(fan_pwm);
// produce status update message
// (provided previous update has already been sent)
View
18 avr/ovencon.h
@@ -57,7 +57,7 @@ extern uint8_t is_usb_ready(void);
// Thermocouple settings
-//#define USE_THERMOCOUPLE
+#define USE_THERMOCOUPLE
// Do we have 2 thermocouple chips? If not, top=bottom
//#define BOTTOM_THERM
@@ -79,16 +79,24 @@ extern uint8_t is_usb_ready(void);
// default pid settings. The term is actually 2^n for simplicity of calculation. These nubers should probably be <15
-#define DEFAULT_K_P 13
-#define DEFAULT_K_I 3
-#define DEFAULT_K_D 13
+#define DEFAULT_K_P 14
+#define DEFAULT_K_I 5
+#define DEFAULT_K_D 12
// use the thermistor instead of the thermocouple?
-#define USE_THERMISTOR
+//#define USE_THERMISTOR
// use ADC 7
#define THERMISTOR_CHANNEL 7
+
+
+#define READ(U, N) ((U) >> (N) & 1u)
+#define SET(U, N) ((void)((U) |= 1u << (N)))
+#define CLR(U, N) ((void)((U) &= ~(1u << (N))))
+#define FLIP(U, N) ((void)((U) ^= 1u << (N)))
+
+
#endif

No commit comments for this range

Something went wrong with that request. Please try again.