comparison main.c @ 21:83a0663c082f

Add temperature
author Matt Johnston <matt@ucc.asn.au>
date Sun, 16 Jun 2013 19:17:07 +0800
parents bc48a1d17edf
children a55d7c2440fd
comparison
equal deleted inserted replaced
20:bc48a1d17edf 21:83a0663c082f
572 static void 572 static void
573 cmd_vcc() 573 cmd_vcc()
574 { 574 {
575 uint16_t vcc = adc_vcc(); 575 uint16_t vcc = adc_vcc();
576 uint16_t v5 = adc_5v(vcc); 576 uint16_t v5 = adc_5v(vcc);
577 printf_P(PSTR("vcc: %u mV\n5v: %u mV\n"), vcc, v5); 577 uint16_t temp = adc_temp();
578 // roughly?
579 uint16_t temp_deg = temp - 290;
580 printf_P(PSTR("vcc: %u mV\n"
581 "5v: %u mV\n"
582 "temp: %u mV (%dÂșC)\n"),
583 vcc, v5, temp, temp_deg);
578 } 584 }
579 585
580 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00; 586 void(*bootloader)() __attribute__ ((noreturn)) = (void*)0x7e00;
581 587
582 #if 0 588 #if 0
809 { 815 {
810 set_sleep_mode(SLEEP_MODE_IDLE); 816 set_sleep_mode(SLEEP_MODE_IDLE);
811 sleep_mode(); 817 sleep_mode();
812 } 818 }
813 819
814 static uint16_t 820 static void
815 adc_vcc() 821 adc_generic(uint8_t admux, uint8_t *ret_num, uint16_t *ret_sum)
816 { 822 {
817 PRR &= ~_BV(PRADC); 823 PRR &= ~_BV(PRADC);
818 824
819 // /16 prescaler 825 // /16 prescaler
820 ADCSRA = _BV(ADEN) | _BV(ADPS2); 826 ADCSRA = _BV(ADEN) | _BV(ADPS2);
821 827
822 // set to measure 1.1 reference 828 // set to measure 1.1 reference
823 ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); 829 ADMUX = admux;
824 // average a number of samples 830 // average a number of samples
825 uint16_t sum = 0; 831 uint16_t sum = 0;
826 uint8_t num = 0; 832 uint8_t num = 0;
827 for (uint8_t n = 0; n < 20; n++) 833 for (uint8_t n = 0; n < 20; n++)
828 { 834 {
840 } 846 }
841 } 847 }
842 ADCSRA = 0; 848 ADCSRA = 0;
843 PRR |= _BV(PRADC); 849 PRR |= _BV(PRADC);
844 850
851 *ret_num = num;
852 *ret_sum = sum;
853 }
854
855 static uint16_t
856 adc_vcc()
857 {
858 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
859 uint16_t sum;
860 uint8_t num;
861
862 adc_generic(mux, &num, &sum);
863
845 //float res_volts = 1.1 * 1024 * num / sum; 864 //float res_volts = 1.1 * 1024 * num / sum;
846 //return 1000 * res_volts; 865 //return 1000 * res_volts;
847 return ((uint32_t)1100*1024*num) / sum; 866 return ((uint32_t)1100*1024*num) / sum;
848 } 867 }
849 868
850 #define SCALER_5V 2 869 #define SCALER_5V 2
851 870
852 static uint16_t 871 static uint16_t
853 adc_5v(uint16_t vcc) 872 adc_5v(uint16_t vcc)
854 { 873 {
855 PRR &= ~_BV(PRADC); 874 // set to measure ADC4 against AVCC
875 const uint8_t mux = _BV(REFS0) | _BV(MUX2);
876 uint16_t sum;
877 uint8_t num;
856 878
857 // /16 prescaler 879 adc_generic(mux, &num, &sum);
858 ADCSRA = _BV(ADEN) | _BV(ADPS2); 880
859 881 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));
860 // set to measure ADC4 against AVCC 882 }
861 ADMUX = _BV(REFS0) | _BV(MUX2); 883
862 // average a number of samples 884 static uint16_t
863 uint16_t sum = 0; 885 adc_temp()
864 uint8_t num = 0; 886 {
865 for (uint8_t n = 0; n < 20; n++) 887 // set to measure temperature against 1.1v reference.
866 { 888 const uint8_t mux = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
867 ADCSRA |= _BV(ADSC); 889 uint16_t sum;
868 loop_until_bit_is_clear(ADCSRA, ADSC); 890 uint8_t num;
869 891
870 uint8_t low_11 = ADCL; 892 adc_generic(mux, &num, &sum);
871 uint8_t high_11 = ADCH; 893
872 uint16_t val = low_11 + (high_11 << 8); 894 // return the voltage
873 895 return ((uint32_t)1100*1024*sum) / num;
874 if (n >= 4)
875 {
876 sum += val;
877 num++;
878 }
879 }
880 ADCSRA = 0;
881 PRR |= _BV(PRADC);
882
883 return ((uint32_t)vcc*sum*SCALER_5V/(num*1024));;
884 } 896 }
885 897
886 static void 898 static void
887 reboot_pi() 899 reboot_pi()
888 { 900 {