diff --git a/greenhouse.ino b/greenhouse.ino index affd9d0..278c626 100644 --- a/greenhouse.ino +++ b/greenhouse.ino @@ -54,22 +54,24 @@ }; struct State { - unsigned int voltage, moisture, intervals; - unsigned int dry, wet; - byte state, delay_hours, max_time_mins, pumpSpeed; + unsigned int voltage, moisture; + byte pumpSpeed; bool pumpRunning; byte errors; }; -struct Payload { - Header header; - State state; +#define PROC_PUMP_OFF 0 +#define PROC_PUMP_ON 1 +#define PROC_SLEEP 2 + +struct Cmd { + byte proc, arg; }; +Header my_header, their_header; + State state; -Header my_header = { - HOME_ID, STATION_ID, 0, 0 -}; +Cmd cmd; bool setupLoRa() { LoRa.setPins(10, 9, 2); @@ -82,15 +84,10 @@ #ifdef DEBUG Serial.begin(9600); #endif - state.state = WAIT_FOR_DELAY_OR_DRY; - state.intervals = 0; - state.pumpRunning = false; - state.pumpSpeed = PUMP_SPEED; - state.dry = DRY; - state.wet = WET; - state.delay_hours = DELAY; - state.max_time_mins = MAX_TIME; - state.errors = 0; + my_header = { HOME_ID, STATION_ID, 0, 0 }; + their_header = { 0, 0, 0, 0 }; + state = { 0, 0, PUMP_SPEED, false, 0 }; + cmd = { 0, 0 }; // DPRINTLN("Setting one time state to EEPROM"); // EEPROM.put(0, state); @@ -113,16 +110,20 @@ } void pumpOn(int speed) { + DPRINT("Switching pump on at "); + DPRINTLN(speed); pinMode(motor_in_1, OUTPUT); pinMode(motor_in_2, OUTPUT); pinMode(motor_sleep_pin, OUTPUT); digitalWrite(motor_sleep_pin, HIGH); digitalWrite(motor_in_1, LOW); analogWrite(motor_in_2, speed); + state.pumpSpeed = speed; state.pumpRunning = true; } void pumpOff() { + DPRINTLN("Switching pump off"); pinMode(motor_in_1, OUTPUT); pinMode(motor_in_2, OUTPUT); pinMode(motor_sleep_pin, OUTPUT); @@ -144,72 +145,36 @@ moisture = moisture + moisture_reads[i]; } state.voltage = voltage / SAMPLES; + state.moisture = moisture / SAMPLES; if (state.voltage <= 135) { + LoRa.sleep(); LoRa.end(); radio_initialized = false; + pumpOff(); + } else { + sendState(); + delay(2000); + LoRa.sleep(); } - state.moisture = moisture / SAMPLES; DPRINT("voltage = "); DPRINTLN(state.voltage); DPRINT("moisture = "); DPRINTLN(state.moisture); - DPRINT("state = "); - DPRINTLN(state.state); - DPRINT("intervals = "); - DPRINTLN(state.intervals); DPRINT("radio = "); DPRINTLN(radio_initialized); DFLUSH; - switch(state.state) { - case WAIT_FOR_DELAY_OR_DRY: - if ((state.moisture >= state.dry) || (state.intervals > (state.delay_hours * 60 * 60 / INTERVAL))) { - state.state = WATER_TILL_WET_MAX_TIME; - pumpOn(state.pumpSpeed); - state.intervals = 0; - } - break; - case WATER_TILL_WET_MAX_TIME: - if (state.intervals > (state.max_time_mins * 60 / INTERVAL)) { - // not yet wet enough, so leave for another MAX_TIME before watering - state.state = WAIT_FOR_MAX_TIME; - pumpOff(); - state.intervals = 0; - } else if (state.moisture <= state.wet) { - state.state = WAIT_FOR_DELAY_OR_DRY; - pumpOff(); - state.intervals = 0; - } - break; - case WAIT_FOR_MAX_TIME: - if (state.intervals > (state.max_time_mins * 60 / INTERVAL)) { - state.state = WATER_TILL_WET_MAX_TIME; - pumpOn(PUMP_SPEED); - state.intervals = 0; - } - break; - default: - state.state = WAIT_FOR_DELAY_OR_DRY; - pumpOff(); - state.intervals = 0; - state.errors++; - } - sendState(); if (state.pumpRunning) { - delay(INTERVAL * 1000); + delay(8000); // LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_ON, TIMER1_ON, TIMER0_ON, // SPI_OFF, USART0_OFF, TWI_OFF); } else { -// LowPower.powerDown(SLEEP_2S, ADC_OFF, BOD_OFF); - delay(2000); - LoRa.sleep(); LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); -// delay(8000); } - state.intervals++; } void sendState() { if (radio_initialized) { + my_header.seq++; LoRa.beginPacket(); LoRa.write((byte *)&(my_header), sizeof(Header)); LoRa.write((byte *)&(state), sizeof(State)); @@ -223,9 +188,8 @@ void onReceive(int packetSize) { DPRINT("Received packet, size="); DPRINTLN(packetSize); - if (packetSize == (sizeof(Header) + sizeof(State))) { + if (packetSize == (sizeof(Header) + sizeof(Cmd))) { DPRINT("Reading: "); - Header their_header; for (int i=0; i