Browse Source

git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7597 ddd99763-3ecb-0310-9145-efcb8ce7c51f

tags/zoom-1.0
jim 14 years ago
parent
commit
3becc85976
11 changed files with 337 additions and 255 deletions
  1. +9
    -0
      firmware/mode.h
  2. +182
    -0
      firmware/mode_debug.c
  3. +0
    -0
      firmware/mode_debug.h
  4. +121
    -0
      firmware/mode_normal.c
  5. +0
    -6
      firmware/mode_normal.h
  6. +9
    -0
      firmware/scaling.c
  7. +5
    -0
      firmware/scaling.h
  8. +3
    -247
      firmware/zoom.c
  9. +6
    -0
      firmware/zoom.h
  10. +2
    -2
      firmware/zoom.mcp
  11. BIN
      firmware/zoom.mcw

+ 9
- 0
firmware/mode.h View File

@@ -0,0 +1,9 @@
#ifndef MODE_H
#define MODE_H
#include "config.h"
void run_normal(void);
void run_debug(void);
#endif

+ 182
- 0
firmware/mode_debug.c View File

@@ -0,0 +1,182 @@
#include "config.h"
#include "adc.h"
#include "dac.h"
#include "uart.h"
#include "timer.h"
#include <stdio.h>
#include <math.h>
#include "scaling.h"
#include "util.h"
#include "led.h"
#include "mode.h"
#include "zoom.h"
#define DEBUG_BLINK_RATE 4
/* Debug LED */
void TISR_HANDLER(6)
{
static int toggle = 0;
timer_clear_txif(6);
toggle = !toggle;
if (toggle)
led_on();
else
led_off();
}
static uint16_t dac = 32768;
#define TIMER_RATE 8000
static int zero_adc = 0;
void TISR_HANDLER(7)
{
int16_t v;
float dac_current, i;
timer_clear_txif(7);
if (zero_adc) {
dac_current = dac_to_current(dac);
v = adc_get();
i = adc12_to_current(v);
/* adjust by 50% of the estimated value, in case our calibration is wrong */
dac_current -= (i * 0.5);
if (dac_current < dac_current_min)
dac_current = dac_current_min;
if (dac_current > dac_current_max)
dac_current = dac_current_max;
dac = current_to_dac(dac_current);
dac_write(dac);
}
}
void sweep(void)
{
int32_t d;
int16_t a;
/* sweep range */
for (d = (int32_t)dac - 1500; d < (int32_t)dac + 1500; d++) {
if (d < 0x0000) {
uart1_put_string("0 0\r\n");
continue;
}
if (d > 0xffff) {
uart1_put_string("65535 0\r\n");
continue;
}
dac_write(d);
msleep(1);
a = adc_get();
uart1_put_dec(d);
uart1_put(' ');
uart1_put_dec(a);
uart1_crlf();
}
}
void run_debug(void)
{
int16_t adc;
int32_t v;
char buf[4];
uart1_init(115200);
timer_setup_16bit(6, DEBUG_BLINK_RATE, 1);
timer_setup_16bit(7, TIMER_RATE, 1);
uart1_put_string("Zoom NILM Debug\r\n");
while (1) {
dac_write(dac);
uart1_put_hex16(dac);
uart1_put(' ');
uart1_put_dec(dac);
uart1_put(' ');
uart1_put(' ');
adc = adc_get();
uart1_put_hex16(adc);
uart1_put(' ');
uart1_put_dec(adc);
uart1_crlf();
switch (uart1_get()) {
// small step
case '[':
dac--;
break;
case ']':
dac++;
break;
// medium step
case '-':
dac -= 16;
break;
case '+':
case '=':
dac += 16;
break;
// big step
case ',':
case '<':
dac -= 1024;
break;
case '.':
case '>':
dac += 1024;
break;
// set DAC to midpoint
case '0':
dac = 32768;
break;
// run degauss (currently a noop)
case 'd':
uart1_put_string("degauss...");
degauss();
uart1_crlf();
dac = 32768;
break;
// set DAC to specified hex value
case 'v':
case 'V':
buf[0] = uart1_get();
buf[1] = uart1_get();
buf[2] = uart1_get();
buf[3] = uart1_get();
v = hex_to_u16(buf);
if (v < 0)
uart1_put_string("bad value\r\n");
else
dac = v;
break;
// maintain ADC input at zero
case 'z':
case 'Z':
uart1_put_string("zeroing input...\r\n");
zero_adc = 1;
uart1_get();
zero_adc = 0;
break;
// sweep DAC
case 's':
case 'S':
uart1_put_string("sweep around ");
uart1_put_dec(dac);
uart1_crlf();
sweep();
break;
}
}
}

+ 0
- 0
firmware/mode_debug.h View File


+ 121
- 0
firmware/mode_normal.c View File

@@ -0,0 +1,121 @@
#include "config.h"
#include "adc.h"
#include "adcext.h"
#include "dac.h"
#include "uart.h"
#include "timer.h"
#include <stdio.h>
#include <math.h>
#include "scaling.h"
#include "util.h"
#include "mode.h"
#include "zoom.h"
int send_data = 0;
uint16_t send_adc;
uint16_t send_dac;
int possible_overflow = 0;
float dac_current;
#define TIMER_RATE 8000 /* how often to read the ADC and update DAC */
#define PC_RATE 8000 /* how often to send data to the PC */
/* Run mode */
void TISR_HANDLER(5)
{
static int count = 0;
static uint16_t dac_cmd;
int16_t v;
float i;
/* toggle A9 every time an interrupt occurs */
LATAbits.LATA9 = 1;
timer_clear_txif(5);
/* Get most recent sample from 12-bit ADC. */
v = adc_get();
if (v < 0 || v >= 2047)
possible_overflow = 1;
/* Send data to PC at 1 Hz */
if (++count >= (TIMER_RATE / PC_RATE)) {
count = 0;
/* Send most recent sample and old DAC value */
send_adc = v;
send_dac = dac_cmd;
send_data = 1;
}
/* Convert ADC value to current */
i = adc12_to_current(v);
#if 0
/* Adjust DAC to null this current to 0 */
dac_current -= i;
#else
/* If this current exceeds +-1A, cancel it out at the DAC */
if (i < -1.0 || i > 1.0)
dac_current -= i;
#endif
if (dac_current < dac_current_min)
dac_current = dac_current_min;
if (dac_current > dac_current_max)
dac_current = dac_current_max;
/* Now send it out */
dac_cmd = current_to_dac(dac_current);
dac_write(dac_cmd);
LATAbits.LATA9 = 0;
}
void send_to_pc(uint16_t adc, uint16_t dac)
{
/* Sent data format:
1Aaa aaaa 0aaa aaDd 0ddd dddd 0ddd dddd
Aaaaaaaaaaaa = 12-bit ADC value (2s compliment signed)
Dddddddddddddddd = 16-bit DAC command (unsigned)
*/
uart1_put(0x80 | ((adc & 0x0FE0) >> 5));
uart1_put(((adc & 0x001F) << 2) | ((dac & 0xC000) >> 14));
uart1_put((dac & 0x3F80) >> 7);
uart1_put((dac & 0x007F));
}
void run_normal(void)
{
uart1_init(500000);
/* Assume startup current is 0 */
dac_current = 0.0;
dac_write(current_to_dac(dac_current));
msleep(100);
degauss();
timer_setup_16bit(5, TIMER_RATE, 1);
while(1) {
if (send_data) {
/* There's data to send. Disable the ISR briefly
while we grab it */
uint16_t a, d;
disable_int({
if (possible_overflow) {
/* Mark a possible overflow in the output
by setting ADC to an unlikely value */
possible_overflow = 0;
a = 0x0800;
} else {
a = send_adc;
}
d = send_dac;
send_data = 0;
});
send_to_pc(a, d);
}
}
}

+ 0
- 6
firmware/mode_normal.h View File

@@ -1,6 +0,0 @@
#ifndef MODE_NORMAL_H
#define MODE_NORMAL_H
#include "config.h"
#endif

+ 9
- 0
firmware/scaling.c View File

@@ -37,3 +37,12 @@ float adc12_to_current(int16_t picv)
amps = (picv - 1024.0) / 404.0;
return amps;
}
float dac_current_min;
float dac_current_max;
void scaling_init(void)
{
dac_current_min = dac_to_current(0x0000);
dac_current_max = dac_to_current(0xffff);
}

+ 5
- 0
firmware/scaling.h View File

@@ -5,4 +5,9 @@ float adc12_to_current(int16_t picv);
float dac_to_current(uint16_t dacv);
uint16_t current_to_dac(float amps);
void scaling_init(void);
extern float dac_current_min;
extern float dac_current_max;
#endif

+ 3
- 247
firmware/zoom.c View File

@@ -4,118 +4,10 @@
#include "dac.h"
#include "uart.h"
#include "timer.h"
#include <stdio.h>
#include <math.h>
#include "scaling.h"
#include "util.h"
#include "led.h"

int send_data = 0;
uint16_t send_adc;
uint16_t send_dac;
int possible_overflow = 0;

#define DAC_MIN 0x0000
#define DAC_MAX 0xFFFF
float dac_current;

float dac_current_min;
float dac_current_max;

#define TIMER_RATE 8000 /* how often to read the ADC and update DAC */
#define PC_RATE 8000 /* how often to send data to the PC */
#define DEBUG_BLINK_RATE 4

/* Debug LED */
void TISR_HANDLER(6)
{
static int toggle = 0;
timer_clear_txif(6);
toggle = !toggle;
if (toggle)
led_on();
else
led_off();
}

/* Debug mode */
int debug_zero_adc = 0;
void TISR_HANDLER(7)
{
timer_clear_txif(7);

if (debug_zero_adc)
{

}
}

/* Run mode */
void TISR_HANDLER(5)
{
static int count = 0;
static uint16_t dac_cmd;
uint16_t v;
float i;

/* toggle A9 every time an interrupt occurs */
LATAbits.LATA9 = 1;
timer_clear_txif(5);
/* Get most recent sample from 12-bit ADC. */
v = adc_get();

if (v < 0 || v >= 2047)
possible_overflow = 1;

/* Send data to PC at 1 Hz */
if (++count >= (TIMER_RATE / PC_RATE)) {
count = 0;
/* Send most recent sample and old DAC value */
send_adc = v;
send_dac = dac_cmd;
send_data = 1;
}

/* Convert ADC value to current */
i = adc12_to_current(v);

#if 0
/* Adjust DAC to null this current to 0 */
dac_current -= i;
#else
/* If this current exceeds +-1A, cancel it out at the DAC */
if (i < -1.0 || i > 1.0)
dac_current -= i;
#endif

if (dac_current < dac_current_min)
dac_current = dac_current_min;
if (dac_current > dac_current_max)
dac_current = dac_current_max;

/* Now send it out */
dac_cmd = current_to_dac(dac_current);
dac_write(dac_cmd);

LATAbits.LATA9 = 0;
}

void send_to_pc(uint16_t adc, uint16_t dac)
{
/* Sent data format:
1Aaa aaaa 0aaa aaDd 0ddd dddd 0ddd dddd
Aaaaaaaaaaaa = 12-bit ADC value (2s compliment signed)
Dddddddddddddddd = 16-bit DAC command (unsigned)
*/
uart1_put(0x80 | ((adc & 0x0FE0) >> 5));
uart1_put(((adc & 0x001F) << 2) | ((dac & 0xC000) >> 14));
uart1_put((dac & 0x3F80) >> 7);
uart1_put((dac & 0x007F));
}
#include "mode.h"
#include "zoom.h"

void degauss(void)
{
@@ -130,143 +22,6 @@ void degauss(void)
#endif
}

void run_debug(void)
{
uint16_t dac = 32768;
int16_t adc;
int32_t v;
char buf[4];
uart1_init(115200);

timer_setup_16bit(6, DEBUG_BLINK_RATE, 1);

uart1_put_string("Zoom NILM Debug\r\n");

while (1) {
dac_write(dac);
uart1_put_hex16(dac);
uart1_put(' ');
uart1_put_dec(dac);
uart1_put(' ');
uart1_put(' ');
adc = adc_get();
uart1_put_hex16(adc);
uart1_put(' ');
uart1_put_dec(adc);
uart1_crlf();
switch (uart1_get()) {

// small step
case '[':
dac--;
break;
case ']':
dac++;
break;

// medium step
case '-':
dac -= 16;
break;
case '+':
case '=':
dac += 16;
break;

// big step
case ',':
case '<':
dac -= 1024;
break;
case '.':
case '>':
dac += 1024;
break;

// set DAC to midpoint
case '0':
dac = 32768;
break;

// run degauss (currently a noop)
case 'd':
uart1_put_string("degauss...");
degauss();
uart1_crlf();
dac = 32768;
break;

// set DAC to specified hex value
case 'v':
case 'V':
buf[0] = uart1_get();
buf[1] = uart1_get();
buf[2] = uart1_get();
buf[3] = uart1_get();
v = hex_to_u16(buf);
if (v < 0)
uart1_put_string("bad value\r\n");
else
dac = v;
break;

// maintain ADC input at zero
case 'z':
case 'Z':
uart1_put_string("zeroing input...\r\n");
debug_zero_adc = 1;
uart1_get();
debug_zero_adc = 0;
break;

// sweep DAC
case 's':
case 'S':
uart1_put_string("sweep\r\n");
debug_sweep();
break;
}
}
}

void run_normal(void)
{
uart1_init(500000);

/* Assume startup current is 0 */
dac_current = 0.0;
dac_write(current_to_dac(dac_current));
msleep(100);
degauss();

/* Set min/max */
dac_current_min = dac_to_current(DAC_MIN);
dac_current_max = dac_to_current(DAC_MAX);

timer_setup_16bit(5, TIMER_RATE, 1);

while(1) {
if (send_data) {
/* There's data to send. Disable the ISR briefly
while we grab it */
uint16_t a, d;
disable_int({
if (possible_overflow) {
/* Mark a possible overflow in the output
by setting ADC to an unlikely value */
possible_overflow = 0;
a = 0x0800;
} else {
a = send_adc;
}
d = send_dac;
send_data = 0;
});
send_to_pc(a, d);
}
}
}

int main(void)
{
int jumper;
@@ -278,6 +33,7 @@ int main(void)
/* debug output */
TRISAbits.TRISA9 = 0;

scaling_init();
adcext_init();
dac_init();
dac_write(32768);


+ 6
- 0
firmware/zoom.h View File

@@ -0,0 +1,6 @@
#ifndef ZOOM_H
#define ZOOM_H
void degauss(void);
#endif

+ 2
- 2
firmware/zoom.mcp View File

@@ -63,8 +63,8 @@ file_017=adcext.h
file_018=adc.h
file_019=scaling.h
file_020=led.h
file_021=mode_debug.h
file_022=mode_normal.h
file_021=mode.h
file_022=zoom.h
file_023=p33fj256gp710.gld
[SUITE_INFO]
suite_guid={479DDE59-4D56-455E-855E-FFF59A3DB57E}


BIN
firmware/zoom.mcw View File


Loading…
Cancel
Save