#include "app.h" #include #include // http://bleaklow.com/2010/09/05/progmem_and_gcc_bug_34734.html #undef PROGMEM #define PROGMEM __attribute__((section(".progmem.data"))) #define SENSOR_COUNT 1 // See http://redbearlab.com/blendmicro/ struct sm_sensor { uint8_t pin; uint8_t value; uint16_t warning_value; uint8_t name_length; uint8_t name[SENSOR_NAME_LEN]; } sensors[SENSOR_COUNT] = { {9, 0, 10, 9, 'sensor #1'}, }; void on_loop() { static unsigned long last = 0, now; static uint8_t x = 10; now = millis(); if (now - last > 3000) { last = now; struct sm_res res; res.code = SM_CMD_GET_VALUE; res.get_value.value = x; x++; if(x == 0) { x = 10; } // if(x % 2 == 0) { // notify_soil_moisture(res); // } else { // notify_battery_level(x); // } notify_soil_moisture(res, sizeof(sm_get_value_res)); } } #ifdef SM_DEBUG static void write_name(uint8_t const* name, uint8_t len) { for(int i = 0; i < len; i++) { Serial.print((char)name[i]); } } void write_req(struct sm_req const& req) { int i; Serial.print(">> "); switch(req.code) { case SM_CMD_GET_SENSOR_COUNT: Serial.print("SM_CMD_GET_SENSOR_COUNT"); break; case SM_CMD_GET_VALUE: Serial.print("SM_CMD_GET_VALUE"); Serial.print(": sensor="); Serial.print(req.get_value.sensor, DEC); break; case SM_CMD_SET_WARNING_VALUE: Serial.print("SM_CMD_SET_WARNING_VALUE"); Serial.print(": sensor="); Serial.print(req.set_warning_value.sensor, DEC); Serial.print(", warning_value="); Serial.print(req.set_warning_value.warning_value, DEC); break; case SM_CMD_GET_WARNING_VALUE: Serial.print("SM_CMD_GET_WARNING_VALUE"); Serial.print(": sensor="); Serial.print(req.get_warning_value.sensor, DEC); break; case SM_CMD_SET_SENSOR_NAME: Serial.print("SM_CMD_SET_SENSOR_NAME"); Serial.print(": sensor="); Serial.print(req.set_sensor_name.sensor, DEC); Serial.print(", name="); write_name(req.set_sensor_name.name, req.set_sensor_name.length); break; case SM_CMD_GET_SENSOR_NAME: Serial.print("SM_CMD_GET_SENSOR_NAME"); break; default: Serial.print("Unknown command!"); } Serial.println(); } void write_res(struct sm_res const& res) { int i; Serial.print("<< "); switch(res.code) { case SM_CMD_GET_SENSOR_COUNT: Serial.print("SM_CMD_GET_SENSOR_COUNT"); Serial.print(": count="); Serial.print(res.get_sensor_count.count, DEC); break; case SM_CMD_GET_VALUE: Serial.print("SM_CMD_GET_VALUE"); Serial.print(": value="); Serial.print(res.get_value.value, DEC); break; case SM_CMD_SET_WARNING_VALUE: Serial.print("SM_CMD_SET_WARNING_VALUE"); break; case SM_CMD_GET_WARNING_VALUE: Serial.print("SM_CMD_GET_WARNING_VALUE"); Serial.print(": warning_value="); Serial.print(res.get_warning_value.warning_value, DEC); break; case SM_CMD_SET_SENSOR_NAME: Serial.print("SM_CMD_SET_SENSOR_NAME"); break; case SM_CMD_GET_SENSOR_NAME: Serial.print("SM_CMD_GET_SENSOR_NAME"); Serial.print(": name="); write_name(res.get_sensor_name.name, res.get_sensor_name.length); break; default: Serial.print("Unknown command!"); } Serial.println(); } #endif void on_soil_moisture_ctrl(uint8_t *data, uint8_t len) { struct sm_req *req = (struct sm_req *) data; struct sm_res res; uint8_t sensor; #if SM_DEBUG == 1 write_req(*req); #endif res.code = req->code; uint8_t body_len; switch(req->code) { case SM_CMD_GET_SENSOR_COUNT: body_len = sizeof(sm_get_sensor_count_res); res.get_sensor_count.count = SENSOR_COUNT; break; case SM_CMD_GET_VALUE: body_len = sizeof(sm_get_value_res); sensor = req->get_value.sensor; if (sensor < SENSOR_COUNT) { // TODO: update the sensor's value res.get_value.value = sensors[sensor].value; } else { res.code = SM_CMD_FAIL; } break; case SM_CMD_SET_WARNING_VALUE: body_len = sizeof(sm_set_warning_value_res); sensor = req->set_warning_value.sensor; if (sensor < SENSOR_COUNT) { sensors[sensor].warning_value = req->set_warning_value.warning_value; } else { res.code = SM_CMD_FAIL; } break; case SM_CMD_GET_WARNING_VALUE: body_len = sizeof(sm_get_warning_value_res); sensor = req->get_warning_value.sensor; if (sensor < SENSOR_COUNT) { res.get_warning_value.warning_value = sensors[sensor].warning_value; } else { res.code = SM_CMD_FAIL; } break; case SM_CMD_SET_SENSOR_NAME: body_len = sizeof(sm_set_sensor_name_res); sensor = req->set_sensor_name.sensor; if (sensor < SENSOR_COUNT) { sensors[sensor].name_length = min(req->set_sensor_name.length, SENSOR_NAME_LEN); memcpy(sensors[sensor].name, req->set_sensor_name.name, sensors[sensor].name_length); } else { res.code = SM_CMD_FAIL; } break; case SM_CMD_GET_SENSOR_NAME: body_len = sizeof(sm_get_sensor_name_res); sensor = req->get_sensor_name.sensor; Serial.print("sensor="); Serial.print(sensor, DEC); if (sensor < SENSOR_COUNT) { res.get_sensor_name.length = sensors[sensor].name_length; memcpy(res.get_sensor_name.name, sensors[sensor].name, SENSOR_NAME_LEN); } else { res.code = SM_CMD_FAIL; } break; default: res.code = SM_CMD_FAIL; break; } Serial.println(); if (res.code == SM_CMD_FAIL) { body_len = 0; } notify_soil_moisture(res, body_len); }