Mercurial > templog
comparison main.c @ 60:2ebe33714989
average voltages
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Tue, 26 Jun 2012 00:00:42 +0800 |
parents | d5b269352ba0 |
children | 68c1e2b26bc5 |
comparison
equal
deleted
inserted
replaced
59:d5b269352ba0 | 60:2ebe33714989 |
---|---|
268 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) | 268 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) |
269 { | 269 { |
270 epoch_copy = clock_epoch; | 270 epoch_copy = clock_epoch; |
271 } | 271 } |
272 | 272 |
273 fprintf_P(crc_stdout, PSTR("START\n")); | 273 fprintf_P(crc_stdout, PSTR("START\n" |
274 fprintf_P(crc_stdout, PSTR("now=%lu\n" | 274 "now=%lu\n" |
275 "time_step=%hu\n" | 275 "time_step=%hu\n" |
276 "first_time=%lu\n" | 276 "first_time=%lu\n" |
277 "last_time=%lu\n" | 277 "last_time=%lu\n" |
278 "comms_time=%lu\n" | 278 "comms_time=%lu\n" |
279 "voltage=%hu\n" | 279 "voltage=%hu\n" |
280 "avrtemp=%hu\n"), | 280 ), |
281 epoch_copy, | 281 epoch_copy, |
282 (uint16_t)MEASURE_WAKE, | 282 (uint16_t)MEASURE_WAKE, |
283 first_measurement_clock, | 283 first_measurement_clock, |
284 last_measurement_clock, | 284 last_measurement_clock, |
285 last_comms_clock, | 285 last_comms_clock, |
626 PRR &= ~_BV(PRADC); | 626 PRR &= ~_BV(PRADC); |
627 | 627 |
628 // left adjust | 628 // left adjust |
629 ADMUX = _BV(ADLAR); | 629 ADMUX = _BV(ADLAR); |
630 | 630 |
631 // ADPS2 = /16 prescaler, 62khz at 1mhz clock | 631 // /128 prescaler |
632 ADCSRA = _BV(ADEN) | _BV(ADPS2); | 632 ADCSRA = _BV(ADEN) | _BV(ADPS2); |
633 | 633 |
634 // set to measure 1.1 reference | 634 // set to measure 1.1 reference |
635 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | 635 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); |
636 _delay_ms(30); | 636 // average a number of samples |
637 // try a few times so it can stabilise | 637 uint16_t sum = 0; |
638 for (uint16_t n = 0; n < 20; n++) | 638 uint8_t num = 0; |
639 for (uint8_t n = 0; n < 20; n++) | |
639 { | 640 { |
640 ADCSRA |= _BV(ADSC); | 641 ADCSRA |= _BV(ADSC); |
641 loop_until_bit_is_clear(ADCSRA, ADSC); | 642 loop_until_bit_is_clear(ADCSRA, ADSC); |
642 } | 643 |
643 uint8_t low_11 = ADCL; | 644 uint8_t low_11 = ADCL; |
644 uint8_t high_11 = ADCH; | 645 uint8_t high_11 = ADCH; |
645 uint16_t f_11 = low_11 + (high_11 << 8); | 646 uint16_t val = low_11 + (high_11 << 8); |
646 | 647 |
647 float res_volts = 1.1 * 1024 / f_11; | 648 if (n >= 4) |
648 | 649 { |
650 sum += val; | |
651 num++; | |
652 } | |
653 } | |
654 ADCSRA = 0; | |
649 PRR |= _BV(PRADC); | 655 PRR |= _BV(PRADC); |
650 ADCSRA = 0; | 656 |
657 float res_volts = 1.1 * 1024 * num / sum; | |
651 | 658 |
652 return 1000 * res_volts; | 659 return 1000 * res_volts; |
653 } | 660 } |
654 | |
655 #if 0 | |
656 // untested | |
657 static void | |
658 do_adc_335() | |
659 { | |
660 //PRR &= ~_BV(PRADC); | |
661 | |
662 ADMUX = _BV(ADLAR); | |
663 | |
664 // ADPS2 = /16 prescaler, 62khz at 1mhz clock | |
665 ADCSRA = _BV(ADEN) | _BV(ADPS2); | |
666 | |
667 // measure value | |
668 ADCSRA |= _BV(ADSC); | |
669 loop_until_bit_is_clear(ADCSRA, ADSC); | |
670 uint8_t low = ADCL; | |
671 uint8_t high = ADCH; | |
672 uint16_t f_measure = low + (high << 8); | |
673 | |
674 // set to measure 1.1 reference | |
675 ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
676 ADCSRA |= _BV(ADSC); | |
677 loop_until_bit_is_clear(ADCSRA, ADSC); | |
678 uint8_t low_11 = ADCL; | |
679 uint8_t high_11 = ADCH; | |
680 uint16_t f_11 = low_11 + (high_11 << 8); | |
681 | |
682 float res_volts = 1.1 * f_measure / f_11; | |
683 | |
684 // 10mV/degree | |
685 // scale to 1/5 degree units above 0C | |
686 int temp = (res_volts - 2.73) * 500; | |
687 // XXX fixme | |
688 //measurements[n_measurements] = temp; | |
689 // XXX something if it hits the limit | |
690 | |
691 // measure AVR internal temperature against 1.1 ref. | |
692 ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(REFS1) | _BV(REFS0); | |
693 ADCSRA |= _BV(ADSC); | |
694 loop_until_bit_is_clear(ADCSRA, ADSC); | |
695 uint16_t res_internal = ADCL; | |
696 res_internal |= ADCH << 8; | |
697 | |
698 float internal_volts = res_internal * (1.1 / 1024.0); | |
699 | |
700 // 1mV/degree | |
701 int internal_temp = (internal_volts - 2.73) * 5000; | |
702 // XXX fixme | |
703 //internal_measurements[n_measurements] = internal_temp; | |
704 | |
705 printf_P("measure %d: external %d, internal %d, 1.1 %d\n", | |
706 n_measurements, temp, internal_temp, f_11); | |
707 | |
708 n_measurements++; | |
709 //PRR |= _BV(PRADC); | |
710 } | |
711 #endif | |
712 | 661 |
713 static void | 662 static void |
714 do_measurement() | 663 do_measurement() |
715 { | 664 { |
716 uint8_t n_sensors; | 665 uint8_t n_sensors; |