git-svn-id: https://bucket.mit.edu/svn/nilm/zoom@7597 ddd99763-3ecb-0310-9145-efcb8ce7c51f
This commit is contained in:
parent
45afdd15ba
commit
3becc85976
9
firmware/mode.h
Normal file
9
firmware/mode.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef MODE_H
|
||||
#define MODE_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
void run_normal(void);
|
||||
void run_debug(void);
|
||||
|
||||
#endif
|
|
@ -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 +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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#ifndef MODE_NORMAL_H
|
||||
#define MODE_NORMAL_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#endif
|
|
@ -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,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
|
||||
|
|
250
firmware/zoom.c
250
firmware/zoom.c
|
@ -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
firmware/zoom.h
Normal file
6
firmware/zoom.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef ZOOM_H
|
||||
#define ZOOM_H
|
||||
|
||||
void degauss(void);
|
||||
|
||||
#endif
|
|
@ -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}
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user