/* Soil Sensor Firmware * Sensiplicity Systems * * Copyright 2015 * * Department of Botany and Plant Pathology * Center for Genome Research and Biocomputing * Oregon State University * Corvallis, OR 97331 * * This program is not free software; you can not redistribute it and/or * modify it at all. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* * This firmware has several duties: * -Measure... * -Temperature within the soil * -Ambient temperature and humidity * -Soil moisture, in several zones * -Light level * -Current Vcc * -Time since last reset * -Report (over the Sense/Net RS-485 Bus)... * -All measurements * -Unique ID, when enumerating * -Blink an LED when commanded. * -Update firmware over the Sense/Net bus */ #include #define F_CPU 2000000UL /* 16Mhz crystal / 8. */ #include #include #include #include "bus.h" #include "light.h" #include "humidity.h" #include "time.h" #include "moisture.h" #include #include #ifndef BREV #error "No board revision specified. Please provide -DBREV=2 or -DBREV=4 on the command line." #endif #if BREV != 2 && BREV != 4 && BREV!=5 #error "Incorect board revision specified. Please provide -DBREV=2, -DBREV=4, or -DBREV=5 on the command line." #endif /* Setup pins and peripherals. * Returns 0 on success, -1 on error. */ int init(void){ /* Set system clock to 16MHz/8 = 2MHz */ CLKPR = _BV(CLKPCE); CLKPR = _BV(CLKPS1) | _BV(CLKPS0); init_led(); init_bus(); init_i2c(); init_adc(); //TODO: Check for response from peripherals /* Shutdown unused SPI peripheral to save power. */ PRR |= _BV(PRSPI); /* Set unused pins as outputs to save power. * This is disabled for now because node 0x2625FF756E6B6E6F77 * has a short on one of these pins. */ // DDRD |= _BV(PD5) | _BV(PD6) | _BV(PD7); // DDRE |= _BV(PE1); // DDRC |= | _BV(PC3); sei(); return 0; } /* Get a value, then atomically set the target variable. */ #define get_atomic_set(target, value) do {typeof(target) __valstore = value; ATOMIC_BLOCK(ATOMIC_RESTORESTATE){target = __valstore;} } while(0) #if BREV == 2 #error "Implement for old revision" #endif int main(void){ init(); while(1){ uint16_t u16; int16_t i16; get_atomic_set(MeasurementData.light, measure_light()); measure_humidity(); get_atomic_set(MeasurementData.temp_soil_z0, get_soil_temp(0)); get_atomic_set(MeasurementData.temp_soil_z1, get_soil_temp(1)); get_atomic_set(MeasurementData.temp_soil_z2, get_soil_temp(2)); get_atomic_set(MeasurementData.temp_soil_z3, get_soil_temp(3)); _delay_ms(150); if(read_humidity(&u16, &i16)){ set_led(LED_RED); } ATOMIC_BLOCK(ATOMIC_RESTORESTATE){ MeasurementData.temp_ambient = i16; MeasurementData.humidity = u16; } get_atomic_set(MeasurementData.volt_idle, get_vcc()); get_atomic_set(MeasurementData.zones, num_zones()); get_atomic_set(MeasurementData.moisture_z0, get_moisture(0)); get_atomic_set(MeasurementData.moisture_z1, get_moisture(1)); get_atomic_set(MeasurementData.moisture_z2, get_moisture(2)); get_atomic_set(MeasurementData.moisture_z3, get_moisture(3)); get_atomic_set(MeasurementData.mtime, get_uptime()); if(LEDBlink){ set_led(LED_GREEN); LEDBlink = 0; _delay_ms(500); set_led(LED_OFF); _delay_ms(500); } else { _delay_ms(1000); } } return(0); }