Commit bbffdb39 authored by James Pallister's avatar James Pallister

Added averaged debug output

parent 752b7f33
......@@ -101,8 +101,8 @@ void error_condition();
// Power data ///////////////////////////////////////////////////////
#define NUM_BUFFERS 128
#define PWR_SAMPLES 32
#define INSTANT_AVG_BITS 5
#define INSTANT_AVG_NUM (1<<INSTANT_AVG_BITS)
typedef struct {
uint64_t energy_accum;
......@@ -118,21 +118,19 @@ typedef struct {
typedef struct {
unsigned voltage;
unsigned current;
unsigned average_voltage;
unsigned average_current;
unsigned current_time;
} instant_data;
typedef struct {
unsigned short data[PWR_SAMPLES];
unsigned short idx;
} power_data;
int tperiod=500;
typedef struct {
accumulated_data accum_data;
instant_data id;
power_data data_bufs[NUM_BUFFERS];
int idx;
int running; // Are we collecting measurements
int number_of_runs;
......@@ -144,6 +142,9 @@ typedef struct {
unsigned short lastI, lastV;
unsigned short avgI[INSTANT_AVG_NUM], avgV[INSTANT_AVG_NUM];
unsigned short avg_ptr;
unsigned char chans[2];
} measurement_point;
......@@ -376,10 +377,21 @@ static int usbdev_control_request(usbd_device *usbd_dev, struct usb_setup_data *
case 11: // Get instantaneous
{
int m_point = req->wValue - 1;
int tot_current = 0, tot_voltage = 0, i;
measurement_point *mp = &m_points[m_point];
mp->id.current = mp->lastI;
mp->id.voltage = mp->lastV;
for(i = 0; i < INSTANT_AVG_NUM; ++i)
{
tot_current += mp->avgI[i];
tot_voltage += mp->avgV[i];
}
mp->id.average_current = tot_current >> INSTANT_AVG_BITS;
mp->id.average_voltage = tot_voltage >> INSTANT_AVG_BITS;
mp->id.current_time = mp->accum_data.elapsed_time;
*len = sizeof(instant_data);
......@@ -565,49 +577,59 @@ void exti_timer_setup()
nvic_set_priority(NVIC_EXTI15_10_IRQ, 0x40);
}
static void systick_setup(void)
{
systick_set_reload(16800);
systick_set_clocksource(STK_CSR_CLKSOURCE_AHB);
systick_counter_enable();
nvic_set_priority(NVIC_SYSTICK_IRQ, 0x80);
systick_interrupt_enable();
}
void error_condition()
{
gpio_set(GPIOD, GPIO15);
while(1);
}
void process_buffer(power_data *pd, accumulated_data *a_data)
{
int i;
unsigned pp_tot = 0, pv_tot = 0, pi_tot=0;
// void process_buffer(power_data *pd, accumulated_data *a_data)
// {
// int i;
// unsigned pp_tot = 0, pv_tot = 0, pi_tot=0;
// Subtract 1 incase we have an unpaired sample at the end
unsigned short n_samples = pd->idx - 1;
// // Subtract 1 incase we have an unpaired sample at the end
// unsigned short n_samples = pd->idx - 1;
for(i = 0; i < n_samples; i+=2)
{
unsigned short c = pd->data[i+1];
unsigned short v = pd->data[i];
unsigned p = c*v;
a_data->energy_accum += p;
pp_tot += p;
pi_tot += c;
pv_tot += v;
a_data->n_samples += 1;
a_data->elapsed_time += tperiod;
a_data->avg_voltage += v;
a_data->avg_current += c;
}
// for(i = 0; i < n_samples; i+=2)
// {
// unsigned short c = pd->data[i+1];
// unsigned short v = pd->data[i];
// unsigned p = c*v;
pp_tot /= n_samples/2;
pv_tot /= n_samples/2;
pi_tot /= n_samples/2;
// a_data->energy_accum += p;
// pp_tot += p;
// pi_tot += c;
// pv_tot += v;
if(pp_tot > a_data->peak_power)
a_data->peak_power = pp_tot;
if(pv_tot > a_data->peak_voltage)
a_data->peak_voltage = pv_tot;
if(pi_tot > a_data->peak_current)
a_data->peak_current = pi_tot;
// a_data->n_samples += 1;
// a_data->elapsed_time += tperiod;
// a_data->avg_voltage += v;
// a_data->avg_current += c;
// }
}
// pp_tot /= n_samples/2;
// pv_tot /= n_samples/2;
// pi_tot /= n_samples/2;
// if(pp_tot > a_data->peak_power)
// a_data->peak_power = pp_tot;
// if(pv_tot > a_data->peak_voltage)
// a_data->peak_voltage = pv_tot;
// if(pi_tot > a_data->peak_current)
// a_data->peak_current = pi_tot;
// }
int cnt=0;
......@@ -745,23 +767,28 @@ void adc_isr()
// Get measurement point & buffer
mp = &m_points[m_point];
power_data *pd = &mp->data_bufs[mp->tail_ptr];
// Read ADC
val = ADC_DR(adcs[i]);
pd->data[pd->idx] = val;
// Save last value
if(pd->idx&1)
if(mp->idx&1)
{
mp->lastI = val;
mp->avgI[mp->avg_ptr] = val;
mp->avg_ptr = (mp->avg_ptr + 1) & (INSTANT_AVG_NUM - 1);
}
else
{
mp->lastV = val;
mp->avgV[mp->avg_ptr] = val;
}
if((pd->idx & 1) == 1)
if((mp->idx & 1) == 1)
{
accumulated_data *a_data = &mp->accum_data;
unsigned short c = pd->data[1];
unsigned short v = pd->data[0];
unsigned short c = mp->lastI;
unsigned short v = mp->lastV;
unsigned p = c*v;
a_data->energy_accum += p;
......@@ -779,7 +806,7 @@ void adc_isr()
a_data->peak_current = c;
}
pd->idx = 1-pd->idx;
mp->idx = 1-mp->idx;
// HACK. Here we initialise the next channel to read from
// because very occasionally the ADC seems to skip the next channel
......@@ -787,7 +814,7 @@ void adc_isr()
unsigned char chan[1];
// Select odd or even channel
chan[0] = mp->chans[(pd->idx&1)];
chan[0] = mp->chans[(mp->idx&1)];
adc_set_regular_sequence(adcs[i], 1, chan);
adc_enable_eoc_interrupt(adcs[i]);
......
......@@ -4,14 +4,31 @@
import pyenergy
from time import sleep
import sys
m_points = []
for arg in sys.argv[1:]:
try:
m = int(arg)
if m < 1 or m > 4:
print "Expected measurement point in range 1-4"
continue
m_points.append(m)
except TypeError:
print "Expected integer measurement point number, got:",arg
em = pyenergy.EnergyMonitor("EE00")
em.connect()
em.enableMeasurementPoint(1)
em.start()
for m in m_points:
em.enableMeasurementPoint(m)
em.start(m)
while True:
m = em.getInstantaneous()
em.debugInstantaneous(m)
for m in m_points:
meas = em.getInstantaneous(m)
print "Measurement point:", m
em.debugInstantaneous(meas)
print ""
sleep(0.1)
......@@ -29,11 +29,11 @@ while True:
print m
print m[1] * float(vref)**2 / gain / resistor / 4096**2 * 2
ydata.append(m[1] * float(vref)**2 / gain / resistor / 4096**2 * 2*1000)
print m[3] * float(vref)**2 / gain / resistor / 4096**2 * 2
ydata.append(m[3] * float(vref)**2 / gain / resistor / 4096**2 * 2*1000)
# ydata2.append(m2[1] * float(vref)**2 / gain / resistor / 4096**2 * 2)
# ydata3.append(m3[1] * float(vref)**2 / gain / resistor / 4096**2 * 2*1000)
xdata.append(m[2] / 168000000. * 2)
xdata.append(m[4] / 168000000. * 2)
# em.debugInstantaneous(m)
fig.clf()
......
......@@ -16,8 +16,8 @@ class EnergyMonitor(object):
MeasurementData = namedtuple('MeasurementData', 'energy_accum elapsed_time peak_power peak_voltage peak_current n_samples avg_current avg_voltage')
MeasurementData_packing = "=QQLLLLQQ"
InstantaneousData = namedtuple('InstantaneousData', 'voltage current current_time')
InstantaneousData_packing = "=LLL"
InstantaneousData = namedtuple('InstantaneousData', 'voltage current average_voltage average_current current_time')
InstantaneousData_packing = "=LLLLL"
ADC1 = 0
ADC2 = 1
......@@ -161,34 +161,35 @@ class EnergyMonitor(object):
return m
def getMeasurement(self, m_point=1):
b = self.dev.ctrl_transfer(0xc1, 6, int(m_point), 0, 48)
b = self.dev.ctrl_transfer(0xc1, 6, int(m_point), 0, calcsize(EnergyMonitor.MeasurementData_packing))
u = EnergyMonitor.MeasurementData._make(unpack(EnergyMonitor.MeasurementData_packing, b))
return self.convertData(u, samplePeriod=self.samplePeriod, **self.measurement_params[m_point])
# get an instantaneous measurement of voltage and current (debugging)
def getInstantaneous(self, m_point=1):
b = self.dev.ctrl_transfer(0xc1, 11, int(m_point), 0, 12)
b = self.dev.ctrl_transfer(0xc1, 11, int(m_point), 0, calcsize(EnergyMonitor.InstantaneousData_packing))
args = list(unpack(EnergyMonitor.InstantaneousData_packing, b))
args.append(m_point)
return args
# Convert and display instantaneous measurement
def debugInstantaneous(self, v):
resistor = self.measurement_params[v[3]]['resistor']
gain = self.measurement_params[v[3]]['gain']
vref = self.measurement_params[v[3]]['vref']
print "Timestamp:", v[2] * 2. / 168000000 * 2
print "Current: Raw={:4d} Voltage@{}={:1.3f}V Res Vdrop={:1.5f}V Current={:1.5f}A".format(v[1],
EnergyMonitor.port_mappings[v[3]][1],
v[1]/4096.*vref,
float(vref) / gain / 4096. * v[1],
float(vref) / gain / resistor / 4096. * v[1])
print "Voltage: Raw={:4d} Voltage@{}={:1.3f}V Voltage={:1.5f}V".format(v[0],
EnergyMonitor.port_mappings[v[3]][0],
v[0]/4096.*vref,
float(vref) / 4096. * v[0] * 2)
mp = v[5]
resistor = self.measurement_params[mp]['resistor']
gain = self.measurement_params[mp]['gain']
vref = self.measurement_params[mp]['vref']
print "Timestamp:", v[4] * 2. / 168000000 * 2
print "Current: Raw={:4d} Voltage@{}={:1.3f}V Res Vdrop={:1.5f}V Current={:1.5f}A".format(mp,
EnergyMonitor.port_mappings[mp][1],
v[3]/4096.*vref,
float(vref) / gain / 4096. * v[3],
float(vref) / gain / resistor / 4096. * v[3])
print "Voltage: Raw={:4d} Voltage@{}={:1.3f}V Voltage={:1.5f}V".format(v[2],
EnergyMonitor.port_mappings[mp][0],
v[2]/4096.*vref,
float(vref) / 4096. * v[2] * 2)
print ""
def disconnect(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment