Mercurial > templog
changeset 363:99e7c2958a06
merge
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 24 Jun 2012 23:48:25 +0800 |
parents | cfcd200c69da (diff) 8fea6144951b (current diff) |
children | 8645fdcacad1 |
files | |
diffstat | 2 files changed, 272 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/main.c Sun Jun 24 23:48:11 2012 +0800 +++ b/main.c Sun Jun 24 23:48:25 2012 +0800 @@ -7,6 +7,7 @@ #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/eeprom.h> +#include <avr/wdt.h> #include <util/crc16.h> // for DWORD of get_fattime() @@ -46,6 +47,8 @@ #define PIN_SHDN PD7 // limited to uint16_t +// XXX - increasing this to 300 causes strange failures, +// not sure why #define NUM_MEASUREMENTS 280 // limited to uint8_t #define MAX_SENSORS 3 @@ -58,6 +61,7 @@ int uart_putchar(char c, FILE *stream); static void long_delay(int ms); static void blink(); +static void adc_internal(uint16_t *millivolt_vcc, uint16_t *int_temp); static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); @@ -115,8 +119,15 @@ static void setup_chip() { + cli(); + + // stop watchdog timer (might have been used to cause a reset) + wdt_reset(); + MCUSR &= ~_BV(WDRF); + WDTCSR |= _BV(WDCE) | _BV(WDE); + WDTCSR = 0; + // Set clock to 2mhz - cli(); CLKPR = _BV(CLKPCE); // divide by 4 CLKPR = _BV(CLKPS1); @@ -245,15 +256,24 @@ uint8_t n_sensors; eeprom_read(n_sensors, n_sensors); + uint16_t millivolt_vcc, int_temp; + + adc_internal(&millivolt_vcc, &int_temp); + fprintf_P(crc_stdout, PSTR("START\n")); fprintf_P(crc_stdout, PSTR("now=%lu\n" "time_step=%hu\n" "first_time=%lu\n" - "last_time=%lu\n"), + "last_time=%lu\n" + "voltage=%hu\n" + "avrtemp=%hu\n"), clock_epoch, (uint16_t)MEASURE_WAKE, first_measurement_clock, - last_measurement_clock); + last_measurement_clock, + millivolt_vcc, + int_temp + ); fprintf_P(crc_stdout, PSTR("sensors=%u\n"), n_sensors); for (uint8_t s = 0; s < n_sensors; s++) { @@ -294,6 +314,23 @@ } static void +cmd_awake() +{ + comms_timeout = WAKE_SECS; + printf_P(PSTR("awake %hu\n"), WAKE_SECS); +} + +static void +cmd_reset() +{ + printf_P(PSTR("reset\n")); + _delay_ms(100); + cli(); // disable interrupts + wdt_enable(WDTO_15MS); // enable watchdog + while(1); // wait for watchdog to reset processor +} + +static void cmd_measure() { printf_P(PSTR("measuring\n")); @@ -466,10 +503,18 @@ { cmd_add_all(); } + else if (strcmp_P(readbuf, PSTR("awake"))== 0) + { + cmd_awake(); + } else if (strcmp_P(readbuf, PSTR("init")) == 0) { cmd_init(); } + else if (strcmp_P(readbuf, PSTR("reset")) == 0) + { + cmd_reset(); + } else { printf_P(PSTR("Bad command\n")); @@ -479,6 +524,7 @@ ISR(INT0_vect) { need_comms = 1; + comms_timeout = WAKE_SECS; blink(); _delay_ms(100); blink(); @@ -561,6 +607,42 @@ sleep_mode(); } +static void +adc_internal(uint16_t *millivolt_vcc, uint16_t *int_temp) +{ + PRR &= ~_BV(PRADC); + + // left adjust + ADMUX = _BV(ADLAR); + + // ADPS2 = /16 prescaler, 62khz at 1mhz clock + ADCSRA = _BV(ADEN) | _BV(ADPS2); + + // set to measure 1.1 reference + ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); + ADCSRA |= _BV(ADSC); + loop_until_bit_is_clear(ADCSRA, ADSC); + uint8_t low_11 = ADCL; + uint8_t high_11 = ADCH; + uint16_t f_11 = low_11 + (high_11 << 8); + + float res_volts = 1.1 * 1024 / f_11; + *millivolt_vcc = 1000 * res_volts; + + // measure AVR internal temperature against 1.1 ref. + ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(REFS1) | _BV(REFS0); + ADCSRA |= _BV(ADSC); + loop_until_bit_is_clear(ADCSRA, ADSC); + uint16_t res_internal = ADCL; + res_internal |= ADCH << 8; + float internal_volts = res_internal * (1.1 / 1024.0); + // decidegrees + *int_temp = (internal_volts - 2.73) * 1000; + + PRR |= _BV(PRADC); + ADCSRA = 0; +} + #if 0 // untested static void @@ -623,17 +705,13 @@ do_measurement() { uint8_t n_sensors; - printf("do_measurement\n"); eeprom_read(n_sensors, n_sensors); - printf("do_measurement sensors %d\n", n_sensors); - uint8_t ret = simple_ds18b20_start_meas(NULL); - printf_P(PSTR("Read all sensors, ret %d, waiting...\n"), ret); + simple_ds18b20_start_meas(NULL); _delay_ms(DS18B20_TCONV_12BIT); if (n_measurements == NUM_MEASUREMENTS) { - printf_P(PSTR("Measurements overflow\n")); n_measurements = 0; } @@ -728,7 +806,6 @@ printf_P(PSTR("Bad interrupt\n")); } - int main(void) { setup_chip();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/dump.py Sun Jun 24 23:48:25 2012 +0800 @@ -0,0 +1,186 @@ +#!/usr/bin/env python2.7 + +BTADDR = "00:12:03:27:70:88" +SLEEP_TIME = 5 +# time that the bluetooth takes to get going? +EXTRA_WAKEUP = 0 + +FETCH_TRIES = 3 + +# avoid turning off the bluetooth etc. +TESTING = False + +import sys +# for wrt +sys.path.append('/root/python') +import httplib +import time +import traceback +import binascii +import hmac +import zlib +import urllib +import urllib2 + +import config + +from utils import monotonic_time, retry, readline, crc16 + +lightblue = None +try: + import lightblue +except ImportError: + import bluetooth + +def get_socket(addr): + if lightblue: + s = lightblue.socket() + s.connect((addr, 1)) + s.settimeout(3) + else: + s = bluetooth.BluetoothSocket( bluetooth.RFCOMM ) + s.connect((addr, 1)) + + s.setblocking(False) + + return s + + +@retry() +def fetch(sock): + print "fetch" + sock.send("fetch\n") + + crc = 0 + + lines = [] + l = readline(sock) + if l != 'START\n': + print>>sys.stderr, "Bad expected START line '%s'\n" % l.rstrip('\n') + return None + crc = crc16(l, crc) + + while True: + l = readline(sock) + + crc = crc16(l, crc) + + if l == 'END\n': + break + + lines.append(l.rstrip('\n')) + + print lines + + l = readline(sock) + recv_crc = None + try: + k, v = l.rstrip('\n').split('=') + print k,v + if k == 'CRC': + recv_crc = int(v) + if recv_crc < 0 or recv_crc > 0xffff: + recv_crc = None + except ValueError: + pass + + if recv_crc is None: + print>>sys.stderr, "Bad expected CRC line '%s'\n" % l.rstrip('\n') + return None + + if recv_crc != crc: + print>>sys.stderr, "Bad CRC: calculated 0x%x vs received 0x%x\n" % (crc, recv_crc) + return None + + return lines + +@retry() +def turn_off(sock): + if TESTING: + return 99 + print>>sys.stderr, "sending btoff" + sock.send("btoff\n"); + # read newline + l = readline(sock) + if not l: + print>>sys.stderr, "Bad response to btoff\n" + return None + + if not l.startswith('off:'): + print>>sys.stderr, "Bad response to btoff '%s'\n" % l + return None + off, next_wake = l.rstrip().split(':') + print>>sys.stderr, "Next wake %s" % next_wake + + return int(next_wake) + +@retry() +def clear_meas(sock): + sock.send("clear\n"); + l = readline(sock) + if l and l.rstrip() == 'cleared': + return True + + print>>sys.stderr, "Bad response to clear %s\n" % str(l) + return False + +def send_results(lines): + enc_lines = binascii.b2a_base64(zlib.compress('\n'.join(lines))) + mac = hmac.new(config.HMAC_KEY, enc_lines).hexdigest() + + url_data = urllib.urlencode( {'lines': enc_lines, 'hmac': mac} ) + con = urllib2.urlopen(config.UPDATE_URL, url_data) + result = con.read(100) + if result == 'OK': + return True + else: + print>>sys.stderr, "Bad result '%s'" % result + return False + +def do_comms(sock): + args = sys.argv[1:] + print "do_comms" + for a in args: + sock.send('%s\n', a) + + while True: + l = readline(sock) + print l + +testcount = 0 + +def sleep_for(secs): + until = monotonic_time() + secs + while True: + length = until - monotonic_time() + if length <= 0: + return + time.sleep(length) + +def main(): + next_wake_time = 0 + + while True: + sock = None + try: + sock = get_socket(BTADDR) + except Exception, e: + print>>sys.stderr, "Error connecting:" + traceback.print_exc(file=sys.stderr) + sleep_time = SLEEP_TIME + if sock: + next_wake = None + try: + next_wake_interval = do_comms(sock) + next_wake_time = time.time() + next_wake_interval + except Exception, e: + print>>sys.stderr, "Error in do_comms:" + traceback.print_exc(file=sys.stderr) + if next_wake_time > time.time(): + sleep_time = min(next_wake_time - time.time() - EXTRA_WAKEUP, sleep_time) + + print "Sleeping for %d" % sleep_time + sleep_for(sleep_time) + +if __name__ == '__main__': + main()