Пример #1
0
void calculate_power(volatile struct state_struct *pstate)
{
	int32_t rest, power = 0;
	uint8_t pulse_count;

	cli();
	rest = pstate->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
	// power[watt] = 3.6/10^6 * rest[nWh/s]
	// power[watt] = 3.6/10^6 * 65536 * (rest[nWh/s] / 65536)
	// power[watt] = 3.6/10^6 * 65536 * 262144 / 262144 * (rest[nWh/s] / 65536)
	// power[watt] = 61847.53 / 262144 * (rest[nWh/s] / 65536)
	// We have to correct for only using 666 samples iso 2000/3, so:
	// power[watt] = 61847.53 * 1/666 * 2000/3 / 262144 * (rest[nWh/s] / 65536)
	// power[watt] = 61909.44 / 262144 * (rest[nWh/s] / 65536)
	// We round the constant down to 61909 to prevent 'underflow' in the
	// consecutive else statement.
	// The error introduced in the fixed-point rounding equals 7.1*10^-6.
	MacU16X16to32(power, (uint16_t)(labs(rest)/65536), 61909);
	power /= 262144;

	if (rest >= 0) {
		power += pulse_count*3600;
	}
	else {
		power = pulse_count*3600 - power;
	}

	pstate->power = power;
}
Пример #2
0
void send(uint8_t msg_type, const struct sensor *measurement, const struct state *aux)
{
  uint8_t i;
  uint32_t value = 0;
  uint32_t ms = 0;
  int32_t rest;
  uint8_t pulse_count;

  char message[60];

  switch (msg_type) {
  case PULSE:
    // blink the green LED
    PORTB |= (1<<PB7);//DONE
    _delay_ms(20);
    PORTB &= ~(1<<PB7);//DONE

    cli();
    value = measurement->value;
    ms = aux->time;
    sei();
 
    strcpy(message, "pls ");
    break;

  case POWER:
    cli();
    rest = aux->nano_end - aux->nano_start;
    pulse_count = aux->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(value, (uint16_t)(labs(rest)/65536), 61847);
    value /= 262144;

    if (rest >= 0)
      value += pulse_count*3600;
    else
      value = pulse_count*3600 - value;

    strcpy(message, "pwr ");
    break;
  }

  strcpy(&message[4], measurement->id);
  strcpy(&message[36], ":0000000000\n");

  i = 46;
  do {                                // generate digits in reverse order
    message[i--] = '0' + value % 10;  // get next digit
  } while ((value /= 10) > 0);        // delete it

  if ((msg_type == PULSE) && ms) {
    strcpy(&message[47], ":0000000000\n");
    i = 57;
    do {                                // generate digits in reverse order
      message[i--] = '0' + ms % 10;     // get next digit
    } while ((ms /= 10) > 0);           // delete it
  }

  printString(message);
//  printString("\r");
}