diff --git a/src/main.c b/src/main.c index a76f443..a7bee55 100644 --- a/src/main.c +++ b/src/main.c @@ -16,12 +16,20 @@ static float pwm = 30.0; static float flashLightSpeed = 50.0; /* 0.0 .. 100.0 */ +static uint16_t motorRampUpTime_msec = 2000; +static uint16_t motorRampDownTime_msec = 1000; +static uint16_t motorUpdateTime_msec = 100; +static float flashLightRampUp_deltaSpeed = 0; +static float flashLightRampDown_deltaSpeed = 0; +static uint8_t motorDirection = _CW; static const char * clientId = ""; static char commandTopic[256] = {'\0'}; #if 0 #endif static char pubStatusTopic[256] = {'\0'}; static bool mqttConnected = false; +enum MotorStatus { MotorStatus_Off = 0, MotorStatus_RampUp, MotorStatus_RampDown, MotorStatus_On, MotorStatus_DemoMode }; +static uint8_t motorStatus = MotorStatus_DemoMode; // Motor numbers //Motor shiled I2C Address: 0x30 @@ -32,6 +40,11 @@ static bool mqttConnected = false; static uint8_t motorAddress = M1_addr; static uint32_t motorFrequency = M1_freq; +static void recalcTimings() { + flashLightRampUp_deltaSpeed = (flashLightSpeed * motorUpdateTime_msec) / motorRampUpTime_msec; + flashLightRampDown_deltaSpeed = (flashLightSpeed * motorUpdateTime_msec) / motorRampDownTime_msec; +} + static void pubStatus(const char *statusString, float percentage) { struct mbuf fb; struct json_out out = JSON_OUT_MBUF(&fb); @@ -49,23 +62,56 @@ static void pubStatus(const char *statusString, float percentage) { static void motor_timer_cb(void *arg) { static bool stopped = false; - if (pwm > flashLightSpeed + 5.0) { - pwm = 0.0; // start again - stopped = false; - } else { - pwm += 0.1; - if (stopped) return; + switch (motorStatus) { + case MotorStatus_Off: + break; + case MotorStatus_On: + break; + case MotorStatus_RampUp: + pwm += flashLightRampUp_deltaSpeed; + if (pwm >= flashLightSpeed) { + pwm = flashLightSpeed; + motorStatus = MotorStatus_On; + } + wemos_motor_setmotor(M1, motorDirection, pwm); + break; + case MotorStatus_RampDown: + pwm -= flashLightRampDown_deltaSpeed; + if (pwm <= 0.0) { + pwm = 0; + motorStatus = MotorStatus_Off; + wemos_motor_setmotor(M1, _STOP, 0.0); + // change direction for next time, when motor turns on again + if (motorDirection == _CW) { + motorDirection = _CCW; + } else { + motorDirection = _CW; + } + } else { + wemos_motor_setmotor(M1, motorDirection, pwm); + } + break; + case MotorStatus_DemoMode: + default: + if (pwm > flashLightSpeed + 5.0) { + pwm = 0.0; // start again + stopped = false; + } else { + pwm += 0.1; + if (!stopped) { + wemos_motor_setmotor(M1, motorDirection, pwm); + LOG(LL_INFO, ("M1, pwm=%f", pwm)); + pubStatus("on", pwm); - wemos_motor_setmotor(M1, _CW, pwm); - LOG(LL_INFO, ("M1, pwm=%f", pwm)); - pubStatus("on", pwm); - - if (pwm > flashLightSpeed) { - wemos_motor_setmotor(M1, _STOP, 0.0); - stopped = true; - LOG(LL_INFO, ("Stopped")); - pubStatus("off", 0); - } + if (pwm > flashLightSpeed) { + wemos_motor_setmotor(M1, _STOP, 0.0); + stopped = true; + LOG(LL_INFO, ("Stopped")); + pubStatus("off", 0); + } + } + } + break; } (void) arg; } @@ -88,13 +134,13 @@ static void flashLightOn(struct mg_rpc_request_info *ri, void *cb_arg, json_printf(&out, "{result: 0, resultString: %Q}", "OK"); printf("FlashLight ON\n"); - wemos_motor_setmotor(M1, _CW, flashLightSpeed); + // wemos_motor_setmotor(M1, _CW, flashLightSpeed); + motorStatus = MotorStatus_RampUp; // this starts the motor on next timer callback pubStatus("on", flashLightSpeed); mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); ri = NULL; mbuf_free(&fb); - (void) cb_arg; (void) fi; @@ -119,7 +165,9 @@ static void flashLightOff(struct mg_rpc_request_info *ri, void *cb_arg, json_printf(&out, "{result: 0, resultString: %Q}", "OK"); printf("FlashLight OFF\n"); - wemos_motor_setmotor(M1, _STOP, 0); + // wemos_motor_setmotor(M1, _STOP, 0); + motorStatus = MotorStatus_RampDown; // this stops the motor on next timer callback + pubStatus("off", 0); mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); @@ -152,6 +200,88 @@ static void flashLightSetSpeed(struct mg_rpc_request_info *ri, void *cb_arg, mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); ri = NULL; mbuf_free(&fb); + recalcTimings(); + + (void) cb_arg; + (void) fi; + (void) args; +} + +static void flashLightSetRampupTime(struct mg_rpc_request_info *ri, void *cb_arg, + struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mbuf fb; + struct json_out out = JSON_OUT_MBUF(&fb); + + mbuf_init(&fb, 40); + + uint16_t rampUpTime_msec = 0; + + if (json_scanf(args.p, args.len, ri->args_fmt, &rampUpTime_msec) == 1) { + motorRampUpTime_msec = rampUpTime_msec; + printf("FlashLight set motor ramp up time to %d\n", rampUpTime_msec); + json_printf(&out, "{result: 0, resultString: %Q, rampUpTime_msec: %d}", "OK", rampUpTime_msec); + } else { + json_printf(&out, "{error: %Q}", "rampUpTime_msec is required"); + } + + mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); + ri = NULL; + mbuf_free(&fb); + recalcTimings(); + + (void) cb_arg; + (void) fi; + (void) args; +} + +static void flashLightSetRampdownTime(struct mg_rpc_request_info *ri, void *cb_arg, + struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mbuf fb; + struct json_out out = JSON_OUT_MBUF(&fb); + + mbuf_init(&fb, 40); + + uint16_t rampDownTime_msec = 0; + + if (json_scanf(args.p, args.len, ri->args_fmt, &rampDownTime_msec) == 1) { + motorRampDownTime_msec = rampDownTime_msec; + printf("FlashLight set motor ramp up time to %d\n", rampDownTime_msec); + json_printf(&out, "{result: 0, resultString: %Q, rampDownTime_msec: %d}", "OK", rampDownTime_msec); + } else { + json_printf(&out, "{error: %Q}", "rampDownTime_msec is required"); + } + + mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); + ri = NULL; + mbuf_free(&fb); + recalcTimings(); + + (void) cb_arg; + (void) fi; + (void) args; +} + +static void flashLightSetMotorUpdateTime(struct mg_rpc_request_info *ri, void *cb_arg, + struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mbuf fb; + struct json_out out = JSON_OUT_MBUF(&fb); + + mbuf_init(&fb, 40); + + uint16_t updateTime = 0; + + if (json_scanf(args.p, args.len, ri->args_fmt, &updateTime) == 1) { + motorUpdateTime_msec = updateTime; + printf("FlashLight set updateTime_msec tp %d\n", updateTime); + json_printf(&out, "{result: 0, resultString: %Q, motorUpdateTime_msec: %d}", "OK", updateTime); + } else { + json_printf(&out, "{error: %Q}", "motorUpdateTime_msec is required"); + } + + mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf); + ri = NULL; + mbuf_free(&fb); + recalcTimings(); (void) cb_arg; (void) fi; @@ -165,8 +295,6 @@ void net_changed(int ev, void *evd, void *arg) { (void) arg; } -#if 0 -#endif static void mqttCommandHandler(struct mg_connection *c, const char *topic, int topic_len, const char *msg, int msg_len, void *userdata) { LOG(LL_INFO, ("Got message on topic %.*s", topic_len, topic)); @@ -199,6 +327,9 @@ enum mgos_app_init_result mgos_app_init(void) { mg_rpc_add_handler(c, "FlashLight.On", NULL, flashLightOn, NULL); mg_rpc_add_handler(c, "FlashLight.Off", NULL, flashLightOff, NULL); mg_rpc_add_handler(c, "FlashLight.Speed", "{num: %d}", flashLightSetSpeed, NULL); + mg_rpc_add_handler(c, "FlashLight.RampUpTime_msec", "{num: %d}", flashLightSetRampupTime, NULL); + mg_rpc_add_handler(c, "FlashLight.RampDownTime_msec", "{num: %d}", flashLightSetRampdownTime, NULL); + mg_rpc_add_handler(c, "FlashLight.MotorUpdateTime_msec", "{num: %d}", flashLightSetMotorUpdateTime, NULL); mgos_event_add_group_handler(MGOS_EVENT_GRP_NET, net_changed, NULL); // add MQTT cmd subscription @@ -217,7 +348,7 @@ enum mgos_app_init_result mgos_app_init(void) { motorAddress = mgos_sys_config_get_flashLight_address(); wemos_motor_init(); wemos_motor_initMotor(M1, motorAddress, motorFrequency); - mgos_set_timer(100, MGOS_TIMER_REPEAT, motor_timer_cb, NULL); + mgos_set_timer(motorUpdateTime_msec, MGOS_TIMER_REPEAT, motor_timer_cb, NULL); return MGOS_APP_INIT_SUCCESS; }