Browse Source

calibration works

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7696 ddd99763-3ecb-0310-9145-efcb8ce7c51f
tags/zoom-1.0
jim 13 years ago
parent
commit
a9379588cf
8 changed files with 69 additions and 25 deletions
  1. +39
    -9
      firmware/calibrate.c
  2. +3
    -3
      firmware/calibrate.h
  3. +1
    -1
      firmware/led.h
  4. +4
    -11
      firmware/mode_debug.c
  5. +16
    -0
      firmware/uart.c
  6. +3
    -0
      firmware/uart.h
  7. +1
    -1
      firmware/util.h
  8. +2
    -0
      firmware/zoom.c

+ 39
- 9
firmware/calibrate.c View File

@@ -5,13 +5,14 @@
#include "dac.h"
#include "led.h"
#include "timer.h"
#include "uart.h"
float g_scale; /* delta(DAC) / delta(ADC) */
/* Initialize. Assume some relatively-safe scaling if no calibration is run */
void calibrate_init(void)
{
g_scale = 0.1; /* 1 count at DAC means 10 counts at ADC */
g_scale = 0.5; /* 1 count at DAC means 4 counts at ADC */
}
/* Given the current DAC and ADC values d1 and a1,
@@ -22,7 +23,7 @@ uint16_t adc_to_dac(uint16_t d1, int16_t a1, int16_t a2, float scale)
int32_t d2;
delta = (int32_t)((a2 - a1) * scale + 0.5);
d2 = d1 - delta;
d2 = d1 + delta;
return clamp(DAC_MIN, d2, DAC_MAX);
}
@@ -32,7 +33,7 @@ float calculate_scale(uint16_t d1, float a1, uint16_t d2, float a2)
if (d1 == d2)
return 1.0;
else
return (a2 - a1) / (float)(d2 - d1);
return (a2 - a1) / ((float)d2 - d1);
}
/* Seek with the DAC to reach a specific ADC value. Uses g_scale as
@@ -55,7 +56,7 @@ uint16_t seek(uint16_t starting_dac, int16_t desired_adc)
{
/* give up if we're not making progress */
if (steps++ > SEEK_MAX_STEPS) {
led_pattern(0b00000001);
led_pattern(0b00101000);
break;
}
@@ -70,9 +71,21 @@ uint16_t seek(uint16_t starting_dac, int16_t desired_adc)
msleep(1);
adc = adc_get();
#if 0
uart1_put_hex16(dac);
uart1_put(' ');
uart1_put_hex16(adc);
uart1_put(' ');
uart1_put_hex16(desired_adc);
uart1_put(' ');
uart1_put_hex32(*(uint32_t *)&scale);
uart1_crlf();
#endif
/* if we're close, accept it */
if (abs(adc - desired_adc) <= SEEK_FUZZ_ADC)
if (abs(adc - desired_adc) <= SEEK_FUZZ_ADC) {
break;
}
/* otherwise, if we were within ADC clamp limits, and
the DAC changed a non-trivial amount, readjust
@@ -95,7 +108,7 @@ uint16_t seek(uint16_t starting_dac, int16_t desired_adc)
}
/* Perform calibration */
float do_calibrate(void)
uint16_t do_calibrate(void)
{
uint16_t daczero, x1, x2;
float y1, y2;
@@ -103,18 +116,35 @@ float do_calibrate(void)
/* Zero ADC */
daczero = seek((DAC_MIN + DAC_MAX) / 2, CALIBRATE_ADC_ZERO);
/* Go halfway down and take an accurate sample */
/* Go down take an accurate sample */
x1 = seek(daczero, CALIBRATE_ADC_LOW);
y1 = oversample(x1);
/* Go halfway up and take an accurate sample */
/* Go up and take an accurate sample */
x2 = seek(daczero, CALIBRATE_ADC_HIGH);
y2 = oversample(x2);
/* Calculate scale */
g_scale = calculate_scale(x1, y1, x2, y2);
return g_scale;
#if 1
uart1_put_string("calibrate x1=");
uart1_put_dec(x1);
uart1_put_string(" y1=");
uart1_put_float(y1);
uart1_put_string(" x2=");
uart1_put_dec(x2);
uart1_put_string(" y2=");
uart1_put_float(y2);
uart1_put_string(" scale=");
uart1_put_float(g_scale);
uart1_crlf();
#endif
/* Return to zero position */
dac_write(daczero);
return daczero;
}
/* Oversample to get a nice ADC value */


+ 3
- 3
firmware/calibrate.h View File

@@ -7,10 +7,10 @@
#define DAC_MIN 0
#define DAC_MAX 65535
#define OVERSAMPLE_COUNT 128
#define OVERSAMPLE_COUNT 256
#define SEEK_MAX_STEPS 1000
#define SEEK_FUZZ_ADC 20
#define SEEK_FUZZ_ADC 10
#define SEEK_FUZZ_DAC 5
#define CALIBRATE_ADC_ZERO 1024
@@ -32,7 +32,7 @@ float calculate_scale(uint16_t d1, float a1, uint16_t d2, float a2);
uint16_t seek(uint16_t starting_dac, int16_t desired_adc);
/* Perform calibration */
float do_calibrate(void);
uint16_t do_calibrate(void);
/* Oversample to get a nice ADC value */
float oversample(uint16_t dac);


+ 1
- 1
firmware/led.h View File

@@ -3,7 +3,7 @@
#include "config.h"
#define LED_BLINK_RATE 4
#define LED_BLINK_RATE 8
extern int16_t __led_pattern;
/* Initialize LED */


+ 4
- 11
firmware/mode_debug.c View File

@@ -121,28 +121,21 @@ void run_debug(void)
// test seeking
case '1':
uart1_put_string("seek 512\r\n");
while (!uart1_can_get())
dac = seek(dac, 512);
uart1_get();
dac = seek(dac, 512);
break;
case '2':
uart1_put_string("seek 1536\r\n");
while (!uart1_can_get())
dac = seek(dac, 1536);
uart1_get();
dac = seek(dac, 1536);
break;
// run calibration
case 'c':
case 'C':
uart1_put_string("old g_scale ");
uart1_put_hex32(*(uint32_t *)&g_scale);
uart1_crlf();
uart1_put_string("calibrating...\r\n");
do_calibrate();
dac = do_calibrate();
uart1_put_string("new g_scale ");
uart1_put_hex32(*(uint32_t *)&g_scale);
uart1_put_float(g_scale);
uart1_crlf();
break;


+ 16
- 0
firmware/uart.c View File

@@ -121,6 +121,22 @@ void uart_put_dec(int uart, int32_t x)
}
}

void uart_put_float(int uart, float x)
{
int i;
int32_t v;

v = (int32_t) x;
uart_put_dec(uart, v);
uart_put(uart, '.');
for (i = 0; i < 6; i++) {
x -= v;
x *= 10;
v = (int32_t) x;
uart_put(uart, v + '0');
}
}

void uart_crlf(int uart)
{
uart_put(uart, '\r');


+ 3
- 0
firmware/uart.h View File

@@ -15,6 +15,7 @@ void uart_put_hex16(int uart, uint16_t x);
void uart_put_hex32(int uart, uint32_t x);
void uart_put_bin(int uart, uint8_t x);
void uart_put_dec(int uart, int32_t x);
void uart_put_float(int uart, float x);

/* Blocking receives */
uint8_t uart_get(int uart);
@@ -35,6 +36,7 @@ int uart_can_put(int uart);
#define uart1_put_hex32(x) uart_put_hex32(1,x)
#define uart1_put_bin(x) uart_put_bin(1,x)
#define uart1_put_dec(x) uart_put_dec(1,x)
#define uart1_put_float(x) uart_put_float(1,x)

#define uart2_init(x) uart_init(2, x)
#define uart2_can_get() uart_can_get(2)
@@ -47,5 +49,6 @@ int uart_can_put(int uart);
#define uart2_put_hex32(x) uart_put_hex32(2,x)
#define uart2_put_bin(x) uart_put_bin(2,x)
#define uart2_put_dec(x) uart_put_dec(2,x)
#define uart2_put_float(x) uart_put_float(2,x)

#endif

+ 1
- 1
firmware/util.h View File

@@ -36,6 +36,6 @@ int32_t hex_to_u16(char x[4]);

#define abs(a) \
({ typeof (a) _a = (a); \
_a < 0 ? _a : -_a; })
_a < 0 ? -_a : _a; })

#endif

+ 2
- 0
firmware/zoom.c View File

@@ -8,6 +8,7 @@
#include "led.h"
#include "mode.h"
#include "zoom.h"
#include "calibrate.h"

int main(void)
{
@@ -16,6 +17,7 @@ int main(void)
config_init();
led_init();
led_on();
calibrate_init();

/* debug output */
TRISAbits.TRISA9 = 0;


Loading…
Cancel
Save