diff --git a/mote/v2/avr/ctrl.c b/mote/v2/avr/ctrl.c index 083e8f0..b01af32 100644 --- a/mote/v2/avr/ctrl.c +++ b/mote/v2/avr/ctrl.c @@ -42,6 +42,8 @@ extern uint8_t phy_to_log[MAX_SENSORS]; extern volatile struct sensor_struct EEMEM EEPROM_sensor[MAX_SENSORS]; extern volatile struct sensor_struct sensor[MAX_SENSORS]; +extern volatile struct state_struct state[MAX_SENSORS]; + void ctrlInit(void) { // initialize the CTRL receive buffer @@ -223,7 +225,7 @@ void ctrlDecode(void) void ctrlCmdGet(uint8_t cmd) { uint8_t i; - uint32_t tmp32; + uint32_t tmp32, tmp32_bis; switch (cmd) { case 'p': @@ -254,6 +256,24 @@ void ctrlCmdGet(uint8_t cmd) case 'b': ctrlWriteShortToTxBuffer(event.brown_out); break; + + case 'd': + for (i = 0 ; i < MAX_SENSORS; i++) { + if (state[i].flags & (STATE_PULSE | STATE_POWER)) { + ctrlWriteCharToTxBuffer(i); + + cli(); + tmp32 = sensor[i].counter; + tmp32_bis = (i < 3) ? state[i].power : state[i].timestamp; + sei(); + + ctrlWriteLongToTxBuffer(tmp32); + ctrlWriteLongToTxBuffer(tmp32_bis); + + state[i].flags &= ~(STATE_PULSE | STATE_POWER); + } + } + break; } } diff --git a/mote/v2/avr/main.c b/mote/v2/avr/main.c index e031577..37199ca 100644 --- a/mote/v2/avr/main.c +++ b/mote/v2/avr/main.c @@ -19,6 +19,8 @@ // // $Id$ +#include + #include #include #include @@ -47,6 +49,11 @@ volatile struct sensor_struct sensor[MAX_SENSORS]; volatile struct state_struct state[MAX_SENSORS]; +volatile uint8_t muxn = 0; +volatile uint16_t timer = 0; + +volatile struct time_struct time = {0, 0}; + ISR(SPI_STC_vect) { uint8_t spi_rx, rx, tx; @@ -140,7 +147,39 @@ ISR(SPI_STC_vect) ISR(TIMER1_COMPA_vect) { - /* void */ + uint8_t muxn_l = phy_to_log[muxn]; + + MacU16X16to32(state[muxn_l].nano, sensor[muxn_l].meterconst, ADC); + + if (state[muxn_l].nano > WATT) { + sensor[muxn_l].counter++; + + state[muxn_l].flags |= STATE_PULSE; + state[muxn_l].nano -= WATT; + state[muxn_l].pulse_count++; + } + + if ((timer == SECOND) && (muxn == muxn_l)) { + state[muxn].nano_start = state[muxn].nano_end; + state[muxn].nano_end = state[muxn].nano; + state[muxn].pulse_count_final = state[muxn].pulse_count; + state[muxn].pulse_count = 0; + state[muxn].flags |= STATE_POWER_CALC; + } + + /* Cycle through the available ADC input channels (0/1/2). */ + muxn++; + if (!(muxn %= 3)) timer++; + if (timer > SECOND) timer = 0; + + /* In order to map this to 1000Hz (=ms) we have to skip every second interrupt. */ + if (!time.skip) time.ms++ ; + time.skip ^= 1; + + ADMUX &= 0xF8; + ADMUX |= muxn; + /* Start a new ADC conversion. */ + ADCSRA |= (1<nano_end - pstate->nano_start; + pulse_count = pstate->pulse_count_final; + sei(); + + // Since the AVR has no dedicated floating-point hardware, we need + // to resort to fixed-point calculations for converting nWh/s to W. + // 1W = 10^6/3.6 nWh/s + // value[watt] = 3.6/10^6 * rest[nWh/s] + // value[watt] = 3.6/10^6 * 65536 * (rest[nWh/s] / 65536) + // value[watt] = 3.6/10^6 * 65536 * 262144 / 262144 * (rest[nWh/s] / 65536) + // value[watt] = 61847.53 / 262144 * (rest[nWh/s] / 65536) + // We round the constant down to 61847 to prevent 'underflow' in the + // consecutive else statement. + // The error introduced in the fixed-point rounding equals 8.6*10^-6. + MacU16X16to32(power, (uint16_t)(labs(rest)/65536), 61847); + power /= 262144; + + if (rest >= 0) { + power += pulse_count*3600; + } + else { + power = pulse_count*3600 - power; + } + + pstate->power = power; +} + int main(void) { + uint8_t i; + // RS-485: Configure PD5=DE as output pin with low as default DDRD |= (1< 32 unsigned MAC in 37 cycles with operands and results in memory * based on http://www2.ife.ee.ethz.ch/~roggend/publications/wear/DSPMic_v1.1.pdf par 3.4 and table 31. diff --git a/mote/v2/avr/makefile b/mote/v2/avr/makefile index 8b8e216..6b1a08d 100644 --- a/mote/v2/avr/makefile +++ b/mote/v2/avr/makefile @@ -123,7 +123,7 @@ CDEFS += -DUART_DEFAULT_BAUD_RATE=115200 # override default CTRL buffer sizes CDEFS += -DCTRL_RX_BUFFER_SIZE=32 -CDEFS += -DCTRL_TX_BUFFER_SIZE=32 +CDEFS += -DCTRL_TX_BUFFER_SIZE=128 # Place -I options here CINCS =