Initial version (test / feasibility on esp32 and esp8266)
This commit is contained in:
commit
8ab81f735e
|
@ -0,0 +1,4 @@
|
||||||
|
.vscode
|
||||||
|
build
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Thermo Printer Interface / Remote Control
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This is about a device that can be called by WLAN / TCP/IP and prints on a cheap thermo printer using paper rolls.
|
||||||
|
|
||||||
|
Hardware used:
|
||||||
|
- ESP-CPU:
|
||||||
|
-- Wemos ESP32 LoLin (any ESP32 should work), we are using UART1 (GPIO26=Tx)
|
||||||
|
-- Wemos ESP8266 (any should work), we are using UART1 Tx only (GPIO2=Tx)
|
||||||
|
- GOOJPRT QR204 Micro Embedded Printer with RS232/TTL and USB-Interface
|
||||||
|
-- TX, RX, GND connected to ESP32
|
||||||
|
-- POWER connected to seperate power supply (+5V/GND)
|
||||||
|
|
||||||
|
|
||||||
|
## How to install this app
|
||||||
|
|
||||||
|
- Install and start [mos tool](https://mongoose-os.com/software.html)
|
||||||
|
- Switch to the Project page, find and import this app, build and flash it:
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://mongoose-os.com/images/app1.gif" width="75%">
|
||||||
|
</p>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome to the empty project</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,90 @@
|
||||||
|
author: Dirk Jahnke
|
||||||
|
description: Thermo Printer Remote Controller
|
||||||
|
version: 1.0
|
||||||
|
|
||||||
|
libs_version: ${mos.version}
|
||||||
|
modules_version: ${mos.version}
|
||||||
|
mongoose_os_version: ${mos.version}
|
||||||
|
# platform: esp8266
|
||||||
|
# platform: esp32
|
||||||
|
|
||||||
|
# Optional. List of tags for online search.
|
||||||
|
tags:
|
||||||
|
- c
|
||||||
|
|
||||||
|
# List of files / directories with C sources. No slashes at the end of dir names.
|
||||||
|
sources:
|
||||||
|
- src
|
||||||
|
|
||||||
|
# List of dirs. Files from these dirs will be copied to the device filesystem
|
||||||
|
filesystem:
|
||||||
|
- fs
|
||||||
|
|
||||||
|
# Custom configuration entries, settable via "device configuration"
|
||||||
|
# Below is a custom firmware configuration example.
|
||||||
|
# Uncomment and modify according to your needs:
|
||||||
|
|
||||||
|
config_schema:
|
||||||
|
# - ["my_app", "o", {title: "My app custom settings"}]
|
||||||
|
# - ["my_app.bool_value", "b", false, {title: "Some boolean value"}]
|
||||||
|
# - ["my_app.string_value", "s", "", {title: "Some string value"}]
|
||||||
|
# - ["my_app.int_value", "i", 123, {title: "Some integer value"}]
|
||||||
|
- ["i2c.enable", true]
|
||||||
|
- ["i2c.freq", 400]
|
||||||
|
- ["i2c.sda_gpio", 4] # D2
|
||||||
|
- ["i2c.scl_gpio", 5] # D1
|
||||||
|
- ["flashLight", "o", {title: "Flash light / alarm light settings"}]
|
||||||
|
- ["flashLight.address", "i", 0x30, {title: "i2c address of motor controller TB6612 (e.g. WEMOS)"}]
|
||||||
|
- ["flashLight.motorFrequency", "i", 500, {title: "Frequency of PWM in Hz"}]
|
||||||
|
- ["flashLight.motorUpdateTime", "i", 50, {title: "Time between motor updates in msec"}]
|
||||||
|
- ["flashLight.mqttCtrlTopic", "s", "flashLight/%s/ctrl", {title: "MQTT channel to subscribe to receive commands; %s is replaced by clientId"}]
|
||||||
|
- ["flashLight.mqttStatusTopic", "s", "flashLight/%s/status", {title: "MQTT channel to publish to send status change infos; %s is replaced by clientId"}]
|
||||||
|
- ["mqtt.enable", true]
|
||||||
|
- ["mqtt.server", "mqtt.pmpark.de:1883"]
|
||||||
|
- ["mqtt.user", "default"]
|
||||||
|
- ["mqtt.pass", "12345678"]
|
||||||
|
- ["mqtt.will_message", "offline"]
|
||||||
|
- ["mqtt.will_topic", "flashLight/"]
|
||||||
|
|
||||||
|
- ["sntp.enable", true]
|
||||||
|
- ["sntp.server", "time.google.com"]
|
||||||
|
|
||||||
|
|
||||||
|
# These settings get compiled into the C structure, and can be accessed
|
||||||
|
# from the C code this way:
|
||||||
|
#
|
||||||
|
# printf("Hello from %s!\n", mgos_sys_config_get_device_id());
|
||||||
|
#
|
||||||
|
# Settings are cool: can be modified remotely without full firmware upgrade!
|
||||||
|
#
|
||||||
|
# To see all available compiled settings, buid the firmware and open
|
||||||
|
# build/gen/mgos_config.h file.
|
||||||
|
#
|
||||||
|
# Also, in this config_schema section, you can override existing
|
||||||
|
# settings that has been created by other libraries. For example, debug log
|
||||||
|
# level is 2 by default. For this firmware we can override it to 3:
|
||||||
|
#
|
||||||
|
# config_schema:
|
||||||
|
# - ["debug.level", 3]
|
||||||
|
|
||||||
|
|
||||||
|
# List of libraries used by this app, in order of initialisation
|
||||||
|
libs:
|
||||||
|
- origin: https://github.com/mongoose-os-libs/ca-bundle
|
||||||
|
- origin: https://github.com/mongoose-os-libs/i2c
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-service-config
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-service-fs
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-uart
|
||||||
|
- origin: https://github.com/mongoose-os-libs/spi
|
||||||
|
- origin: https://github.com/mongoose-os-libs/wifi
|
||||||
|
- origin: https://github.com/mongoose-os-libs/http-server
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-loopback
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-mqtt
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-service-ota
|
||||||
|
- origin: https://github.com/mongoose-os-libs/rpc-service-cron
|
||||||
|
- origin: https://github.com/mongoose-os-libs/crontab
|
||||||
|
- origin: https://github.com/mongoose-os-libs/dash
|
||||||
|
- origin: https://github.com/mongoose-os-libs/sntp
|
||||||
|
|
||||||
|
# Used by the mos tool to catch mos binaries incompatible with this file format
|
||||||
|
manifest_version: 2017-05-18
|
|
@ -0,0 +1,72 @@
|
||||||
|
#include "QR204.h"
|
||||||
|
|
||||||
|
static bool initialized = false;
|
||||||
|
static uint8_t uart = 0;
|
||||||
|
|
||||||
|
static const char initCmd[] = { 0x1b, '@' };
|
||||||
|
|
||||||
|
// ***** INIT *****
|
||||||
|
void tp_init(uint8_t uartNo) {
|
||||||
|
if (!initialized) {
|
||||||
|
uart = uartNo;
|
||||||
|
mgos_uart_write(uart, initCmd, sizeof(initCmd));
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ***** End of INIT *****
|
||||||
|
|
||||||
|
// ***** MODE Handling *****
|
||||||
|
static uint8_t currentMode = 0;
|
||||||
|
|
||||||
|
void tp_set_mode(uint8_t addModes) {
|
||||||
|
currentMode |= addModes;
|
||||||
|
char setModeCmd[3] = {0x1b, '!', currentMode};
|
||||||
|
mgos_uart_write(uart, setModeCmd, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tp_reset_mode(uint8_t removeModes) {
|
||||||
|
currentMode &= ~removeModes;
|
||||||
|
char setModeCmd[3] = {0x1b, '!', currentMode};
|
||||||
|
mgos_uart_write(uart, setModeCmd, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tp_reverse_feed(uint8_t numLines) {
|
||||||
|
char cmd[3] = { 0x1b, 'e', numLines };
|
||||||
|
mgos_uart_write(uart, cmd, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tp_linefeed(uint8_t numLines) {
|
||||||
|
char cmd[3] = { 0x1b, 'd', numLines };
|
||||||
|
mgos_uart_write(uart, cmd, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tp_cutpaper(bool fullcut) {
|
||||||
|
char cmd[3] = { 0x1d, 'V', fullcut ? '0' : '1' };
|
||||||
|
mgos_uart_write(uart, cmd, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ***** End of MODE Handling *****
|
||||||
|
|
||||||
|
/*
|
||||||
|
PRINT #1, CHR$(&H1B);"@"; 'Initializes the printer (ESC @)
|
||||||
|
PRINT #1, CHR$(&H1B);"a";CHR$(1);'Specifies a centered printing position (ESC a)
|
||||||
|
PRINT #1, CHR$(&H1B);"!";CHR$(0); 'Specifies font A (ESC !)
|
||||||
|
PRINT #1, "January 14, 2002 15:00";
|
||||||
|
PRINT #1, CHR$(&H1B);"d";CHR$(3); 'Prints and 3 line feeding (ESC d)
|
||||||
|
PRINT #1, CHR$(&H1B);"a";CHR$(0); 'Selects the left print position (ESC a)
|
||||||
|
PRINT #1, CHR$(&H1B);"!";CHR$(1); 'Selects font B
|
||||||
|
PRINT #1, "TM-U210B"
|
||||||
|
PRINT #1, "TM-U210D"
|
||||||
|
PRINT #1, "PS-170"
|
||||||
|
PRINT #1, CHR$(&HA);
|
||||||
|
$20.00";CHR$(&HA); $21.00";CHR$(&HA); $17.00";CHR$(&HA);
|
||||||
|
'Line feeding (LF)
|
||||||
|
PRINT #1, CHR$(&H1B);"!";CHR$(17); 'Selects double-height mode
|
||||||
|
PRINT #1, "TOTAL $58.00"; CHR$(&HA);
|
||||||
|
PRINT #1, CHR$(&H1B);"!";CHR$(0); 'Cancels double-height mode
|
||||||
|
PRINT #1, "------------------------------";CHR$(&HA); PRINT #1, "PAID $60.00";CHR$(&HA); PRINT #1, "CHANGE $ 2.00";CHR$(&HA);
|
||||||
|
PRINT #1, CHR$(&H1D);"V";CHR$(66);CHR$(0); 'Feeds paper & cut
|
||||||
|
’Drawer Kick (ESC p)
|
||||||
|
PRINT #1, CHR$(&H1B); CHR$(&H70); CHR$(&H0); CHR$(60); CHR$(120);
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
#ifndef __QR204_H
|
||||||
|
#define __QR204_H
|
||||||
|
|
||||||
|
#include "mgos.h"
|
||||||
|
#include "mgos_system.h"
|
||||||
|
#include "mgos_uart.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TP_MODE_ALTERNATEFONT 0x01
|
||||||
|
#define TP_MODE_EMPFHASIZED 0x08
|
||||||
|
#define TP_MODE_DOUBLEHEIGHT 0x10
|
||||||
|
#define TP_MODE_DOUBLEWIDTH 0x20
|
||||||
|
#define TP_MODE_UNDERLINED 0x80
|
||||||
|
#define TP_MODE_ALL 0xff
|
||||||
|
|
||||||
|
#define tp_print mgos_uart_printf
|
||||||
|
|
||||||
|
extern void tp_init(uint8_t uartNo);
|
||||||
|
extern void tp_set_mode(uint8_t addModes);
|
||||||
|
extern void tp_reset_mode(uint8_t removeModes);
|
||||||
|
extern void tp_reverse_feed(uint8_t numLines);
|
||||||
|
extern void tp_linefeed(uint8_t numLines);
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,500 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "mgos.h"
|
||||||
|
#include "mgos_app.h"
|
||||||
|
#include "mgos_gpio.h"
|
||||||
|
#include "mgos_system.h"
|
||||||
|
#include "mgos_timers.h"
|
||||||
|
#include "mgos_uart.h"
|
||||||
|
#include "mgos_rpc.h"
|
||||||
|
#include "mgos_sys_config.h"
|
||||||
|
#include "mgos_mqtt.h"
|
||||||
|
#include "mgos_net.h"
|
||||||
|
#include "mgos_crontab.h"
|
||||||
|
#include "common/mbuf.h"
|
||||||
|
#include "common/platform.h"
|
||||||
|
#include "common/cs_dbg.h"
|
||||||
|
#include "common/json_utils.h"
|
||||||
|
#include "common/mg_str.h"
|
||||||
|
#include "common/str_util.h"
|
||||||
|
#if CS_PLATFORM == CS_P_ESP32
|
||||||
|
#include <esp_system.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "QR204.h"
|
||||||
|
|
||||||
|
static bool doPrint = false;
|
||||||
|
|
||||||
|
#if CS_PLATFORM == CS_P_ESP32
|
||||||
|
#define UART_NO 1
|
||||||
|
int esp32_uart_rx_fifo_len(int uart_no);
|
||||||
|
extern uint8_t temprature_sens_read();
|
||||||
|
extern uint32_t hall_sens_read();
|
||||||
|
static int tempOffset = 17;
|
||||||
|
#elif CS_PLATFORM == CS_P_ESP8266
|
||||||
|
#define UART_NO 1
|
||||||
|
#else
|
||||||
|
#error Unsupported platform
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void timer_cb(void *arg) {
|
||||||
|
/*
|
||||||
|
* Note: do not use mgos_uart_write to output to console UART (0 in our case).
|
||||||
|
* It will work, but output may be scrambled by console debug output.
|
||||||
|
*/
|
||||||
|
printf("Timer loop!\n");
|
||||||
|
|
||||||
|
if (doPrint) {
|
||||||
|
tp_reset_mode(TP_MODE_ALL);
|
||||||
|
tp_print(UART_NO, "Timer loop!\n");
|
||||||
|
tp_set_mode(TP_MODE_UNDERLINED);
|
||||||
|
tp_print(UART_NO, "0,123456789\n");
|
||||||
|
}
|
||||||
|
/* tp_print(UART_NO, "- -\n");
|
||||||
|
tp_print(UART_NO, " - - \n");
|
||||||
|
tp_reverse_feed(2);
|
||||||
|
tp_print(UART_NO, " - - \n");
|
||||||
|
tp_print(UART_NO, "- -\n");*/
|
||||||
|
|
||||||
|
|
||||||
|
#if CS_PLATFORM == CS_P_ESP32
|
||||||
|
uint32_t hall = hall_sens_read();
|
||||||
|
uint8_t temp = temprature_sens_read();
|
||||||
|
esp_chip_info_t ci;
|
||||||
|
esp_chip_info(&ci);
|
||||||
|
tp_print(UART_NO, "t=%.1f C, h=%ld mH, tasks=%d\n", (float) (temp-32)/1.8 - tempOffset, hall, uxTaskGetNumberOfTasks());
|
||||||
|
#elif CS_PLATFORM == CS_P_ESP8266
|
||||||
|
tp_print(UART_NO, "xyz\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void) arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void printSystemInfo() {
|
||||||
|
#if CS_PLATFORM == CS_P_ESP32
|
||||||
|
esp_chip_info_t ci;
|
||||||
|
esp_chip_info(&ci);
|
||||||
|
tp_print(UART_NO,
|
||||||
|
"ESP32 mod=%d, cores=%d, rev=%d\n",
|
||||||
|
ci.model, ci.cores, ci.revision);
|
||||||
|
#elif CS_PLATFORM == CS_P_ESP8266
|
||||||
|
tp_print(UART_NO,
|
||||||
|
"ESP8266: cpu=%d MHz\n",
|
||||||
|
(int) mgos_get_cpu_freq() / 1000000);
|
||||||
|
tp_print(UART_NO,
|
||||||
|
"mem=%d kB, free=%d kB, fs=%d kB\n",
|
||||||
|
(int) mgos_get_heap_size()/1024,
|
||||||
|
(int) mgos_get_free_heap_size()/1024,
|
||||||
|
(int) mgos_get_fs_size()/1024);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mgos_app_init_result mgos_app_init(void) {
|
||||||
|
struct mgos_uart_config ucfg;
|
||||||
|
mgos_uart_config_set_defaults(UART_NO, &ucfg);
|
||||||
|
/*
|
||||||
|
* At this point it is possible to adjust baud rate, pins and other settings.
|
||||||
|
* 115200 8-N-1 is the default mode, but we set it anyway
|
||||||
|
*/
|
||||||
|
ucfg.baud_rate = 9600;
|
||||||
|
ucfg.num_data_bits = 8;
|
||||||
|
ucfg.parity = MGOS_UART_PARITY_NONE;
|
||||||
|
ucfg.stop_bits = MGOS_UART_STOP_BITS_1;
|
||||||
|
if (!mgos_uart_configure(UART_NO, &ucfg)) {
|
||||||
|
LOG(LL_ERROR,("ERROR: Cannot configure uart %d", UART_NO));
|
||||||
|
return MGOS_APP_INIT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Initial printer operation");
|
||||||
|
tp_init(UART_NO);
|
||||||
|
mgos_set_timer(60000 /* ms */, true /* repeat */, timer_cb, NULL /* arg */);
|
||||||
|
|
||||||
|
mgos_uart_set_rx_enabled(UART_NO, false);
|
||||||
|
|
||||||
|
tp_reset_mode(TP_MODE_ALL);
|
||||||
|
tp_print(UART_NO, "TEST Print\r");
|
||||||
|
tp_print(UART_NO, "----------\n");
|
||||||
|
printSystemInfo();
|
||||||
|
|
||||||
|
return MGOS_APP_INIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* =======================================
|
||||||
|
|
||||||
|
static void recalcTimings() {
|
||||||
|
flashLightRampUp_deltaSpeed = (flashLightSpeed * motorUpdateTime_msec) / motorRampUpTime_msec;
|
||||||
|
flashLightRampDown_deltaSpeed = (flashLightSpeed * motorUpdateTime_msec) / motorRampDownTime_msec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pubStatus(const char *statusString, double percentage) {
|
||||||
|
struct mbuf fb;
|
||||||
|
struct json_out out = JSON_OUT_MBUF(&fb);
|
||||||
|
|
||||||
|
if (!mqttConnected) return;
|
||||||
|
|
||||||
|
mbuf_init(&fb, 30);
|
||||||
|
if (mgos_mqtt_global_connect()) {
|
||||||
|
json_printf(&out, "{statusString: %Q, speed: %f}", statusString, percentage);
|
||||||
|
mgos_mqtt_pub(pubStatusTopic, fb.buf, fb.len, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void motor_timer_cb(void *arg) {
|
||||||
|
static bool stopped = false;
|
||||||
|
|
||||||
|
switch (motorStatus) {
|
||||||
|
case MotorStatus_Off:
|
||||||
|
wemos_motor_stop(M1);
|
||||||
|
break;
|
||||||
|
case MotorStatus_On:
|
||||||
|
wemos_motor_setmotor(M1, motorDirection, pwm);
|
||||||
|
break;
|
||||||
|
case MotorStatus_RampUp:
|
||||||
|
pwm += flashLightRampUp_deltaSpeed;
|
||||||
|
if (pwm >= flashLightSpeed) {
|
||||||
|
LOG(LL_INFO, ("MotorStatus_RampUp: Speed target reached"));
|
||||||
|
pwm = flashLightSpeed;
|
||||||
|
motorStatus = MotorStatus_On;
|
||||||
|
}
|
||||||
|
wemos_motor_setmotor(M1, motorDirection, pwm);
|
||||||
|
// LOG(LL_INFO, ("M1, dir=%d, pwm=%f", motorDirection, pwm));
|
||||||
|
break;
|
||||||
|
case MotorStatus_RampDown:
|
||||||
|
pwm -= flashLightRampDown_deltaSpeed;
|
||||||
|
if (pwm <= flashLightTargetSpeed) {
|
||||||
|
if (pwm <= 0.0) {
|
||||||
|
motorStatus = MotorStatus_Off;
|
||||||
|
pwm = 0.0;
|
||||||
|
wemos_motor_stop(M1);
|
||||||
|
// change direction for next time, when motor turns on again
|
||||||
|
if (motorDirection == _CW) {
|
||||||
|
motorDirection = _CCW;
|
||||||
|
} else {
|
||||||
|
motorDirection = _CW;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pwm = flashLightTargetSpeed;
|
||||||
|
LOG(LL_INFO, ("MotorStatus_RampDown: Speed target reached"));
|
||||||
|
motorStatus = MotorStatus_On;
|
||||||
|
wemos_motor_setmotor(M1, motorDirection, pwm);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wemos_motor_setmotor(M1, motorDirection, pwm);
|
||||||
|
// LOG(LL_INFO, ("M1, dir=%d, pwm=%f", 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, dir=%d, pwm=%f", motorDirection, pwm));
|
||||||
|
pubStatus("on", pwm);
|
||||||
|
|
||||||
|
if (pwm > flashLightSpeed) {
|
||||||
|
// wemos_motor_setmotor(M1, _STOP, 0.0);
|
||||||
|
wemos_motor_setmotor(M1, _STANDBY, pwm);
|
||||||
|
stopped = true;
|
||||||
|
LOG(LL_INFO, ("Stopped/Standby"));
|
||||||
|
pubStatus("off", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flashLightOn() {
|
||||||
|
LOG(LL_INFO, ("FlashLight ON\n"));
|
||||||
|
flashLightTargetSpeed = flashLightSpeed;
|
||||||
|
motorStatus = MotorStatus_RampUp; // this starts the motor on next timer callback
|
||||||
|
pubStatus("on", flashLightSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_flashLightOn(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);
|
||||||
|
|
||||||
|
flashLightOn();
|
||||||
|
mbuf_init(&fb, 100);
|
||||||
|
json_printf(&out, "{result: 0, resultString: %Q}", "OK");
|
||||||
|
mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf);
|
||||||
|
ri = NULL;
|
||||||
|
mbuf_free(&fb);
|
||||||
|
|
||||||
|
(void) cb_arg;
|
||||||
|
(void) fi;
|
||||||
|
(void) args;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cron_flashLightOn(struct mg_str action, struct mg_str payload, void *userdata) {
|
||||||
|
LOG(LL_INFO, ("Crontab flashLightOn fired"));
|
||||||
|
flashLightOn();
|
||||||
|
(void) action;
|
||||||
|
(void) payload;
|
||||||
|
(void) userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flashLightOff() {
|
||||||
|
LOG(LL_INFO, ("FlashLight OFF\n"));
|
||||||
|
flashLightTargetSpeed = 0.0;
|
||||||
|
motorStatus = MotorStatus_RampDown; // this stops the motor on next timer callback
|
||||||
|
pubStatus("off", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_flashLightOff(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);
|
||||||
|
|
||||||
|
flashLightOff();
|
||||||
|
mbuf_init(&fb, 100);
|
||||||
|
json_printf(&out, "{result: 0, resultString: %Q}", "OK");
|
||||||
|
mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf);
|
||||||
|
ri = NULL;
|
||||||
|
mbuf_free(&fb);
|
||||||
|
|
||||||
|
(void) cb_arg;
|
||||||
|
(void) fi;
|
||||||
|
(void) args;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cron_flashLightOff(struct mg_str action, struct mg_str payload, void *userdata) {
|
||||||
|
LOG(LL_INFO, ("Crontab flashLightOff fired"));
|
||||||
|
flashLightOff();
|
||||||
|
(void) action;
|
||||||
|
(void) payload;
|
||||||
|
(void) userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cron_init() {
|
||||||
|
mgos_crontab_register_handler(mg_mk_str("FlashLightOn"), cron_flashLightOn, NULL);
|
||||||
|
mgos_crontab_register_handler(mg_mk_str("FlashLightOff"), cron_flashLightOff, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flashLightSetSpeed(uint16_t newSpeed) {
|
||||||
|
flashLightTargetSpeed = (double) newSpeed;
|
||||||
|
flashLightSpeed = flashLightTargetSpeed;
|
||||||
|
if (pwm < flashLightTargetSpeed) {
|
||||||
|
motorStatus = MotorStatus_RampUp;
|
||||||
|
} else if (pwm > flashLightTargetSpeed) {
|
||||||
|
motorStatus = MotorStatus_RampDown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_flashLightSetSpeed(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, 100);
|
||||||
|
|
||||||
|
int speed = 0;
|
||||||
|
|
||||||
|
if (json_scanf(args.p, args.len, ri->args_fmt, &speed) == 1) {
|
||||||
|
printf("FlashLight set speed to %d\n", speed);
|
||||||
|
json_printf(&out, "{result: 0, resultString: %Q, speed: %d}", "OK", speed);
|
||||||
|
flashLightSetSpeed(speed);
|
||||||
|
} else {
|
||||||
|
json_printf(&out, "{error: %Q}", "speed 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 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, 100);
|
||||||
|
|
||||||
|
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_ms: %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, 100);
|
||||||
|
|
||||||
|
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_ms: %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, 100);
|
||||||
|
|
||||||
|
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, udateTime_ms: %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;
|
||||||
|
(void) args;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void flashLightGetSettings(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, 1024);
|
||||||
|
|
||||||
|
json_printf(&out, "{pwm: %f, speed: %f, rampupTime_ms: %d, rampdownTime_ms: %d, updateTime_ms: %d, rampupDeltaSpeed: %f, rampdownDeltaSpeed: %f, motorDirection: %d, clientId: %Q, commandTopic: %Q, statusTopic: %Q, mqttConnected: %Q, motorStatus: %d}",
|
||||||
|
pwm, flashLightSpeed, motorRampUpTime_msec, motorRampDownTime_msec, motorUpdateTime_msec, flashLightRampUp_deltaSpeed, flashLightRampDown_deltaSpeed,
|
||||||
|
motorDirection, clientId, commandTopic, pubStatusTopic, mqttConnected ? "true" : "false", motorStatus);
|
||||||
|
|
||||||
|
mg_rpc_send_responsef(ri, "%.*s", fb.len, fb.buf);
|
||||||
|
ri = NULL;
|
||||||
|
mbuf_free(&fb);
|
||||||
|
|
||||||
|
(void) cb_arg;
|
||||||
|
(void) fi;
|
||||||
|
(void) args;
|
||||||
|
}
|
||||||
|
|
||||||
|
void net_changed(int ev, void *evd, void *arg) {
|
||||||
|
if (ev != MGOS_NET_EV_IP_ACQUIRED) return;
|
||||||
|
// call_peer();
|
||||||
|
(void) evd;
|
||||||
|
(void) arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
(void) c;
|
||||||
|
(void) topic;
|
||||||
|
(void) topic_len;
|
||||||
|
(void) msg;
|
||||||
|
(void) msg_len;
|
||||||
|
(void) userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
// void onMqttConnection(struct mg_connection *c, const char *client_id, struct mg_send_mqtt_handshake_opts *opts, void *fn_arg) {
|
||||||
|
void onMqttConnection(struct mg_connection *c, const char *client_id, struct mg_send_mqtt_handshake_opts *opts, void *fn_arg) {
|
||||||
|
// add MQTT cmd subscription
|
||||||
|
LOG(LL_INFO, ("onMqttConnection handler called with clientId=%s", client_id));
|
||||||
|
#if 0
|
||||||
|
#endif
|
||||||
|
mgos_mqtt_sub(commandTopic, mqttCommandHandler, NULL);
|
||||||
|
mqttConnected = true;
|
||||||
|
|
||||||
|
(void) c;
|
||||||
|
(void) client_id;
|
||||||
|
(void) opts;
|
||||||
|
(void) fn_arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mgos_app_init_result mgos_app_init(void) {
|
||||||
|
struct mg_rpc *c = mgos_rpc_get_global();
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.On", NULL, rpc_flashLightOn, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.Off", NULL, rpc_flashLightOff, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.Speed", "{speed: %d}", rpc_flashLightSetSpeed, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.RampUpTime_msec", "{rampUpTime_ms: %d}", flashLightSetRampupTime, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.RampDownTime_msec", "{rampDownTime_ms: %d}", flashLightSetRampdownTime, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.MotorUpdateTime_msec", "{uptdateTime_ms: %d}", flashLightSetMotorUpdateTime, NULL);
|
||||||
|
mg_rpc_add_handler(c, "FlashLight.GetSettings", NULL, flashLightGetSettings, NULL);
|
||||||
|
mgos_event_add_group_handler(MGOS_EVENT_GRP_NET, net_changed, NULL);
|
||||||
|
|
||||||
|
// enable crontab
|
||||||
|
cron_init();
|
||||||
|
|
||||||
|
// add MQTT cmd subscription
|
||||||
|
LOG(LL_INFO, ("Initializing MQTT"));
|
||||||
|
clientId = mgos_sys_config_get_mqtt_client_id();
|
||||||
|
clientId = clientId ? clientId : mgos_sys_config_get_device_id();
|
||||||
|
LOG(LL_INFO, ("clientId=%s", clientId));
|
||||||
|
LOG(LL_INFO, ("cmdTopic=%s", mgos_sys_config_get_flashLight_mqttCtrlTopic()));
|
||||||
|
LOG(LL_INFO, ("pubStatusTopic=%s", mgos_sys_config_get_flashLight_mqttStatusTopic()));
|
||||||
|
c_snprintf(commandTopic, sizeof(commandTopic), mgos_sys_config_get_flashLight_mqttCtrlTopic(), clientId);
|
||||||
|
c_snprintf(pubStatusTopic, sizeof(pubStatusTopic), mgos_sys_config_get_flashLight_mqttStatusTopic(), clientId);
|
||||||
|
LOG(LL_INFO, ("cmdTopic=%s", commandTopic));
|
||||||
|
LOG(LL_INFO, ("pubStatusTopic=%s", pubStatusTopic));
|
||||||
|
mgos_mqtt_set_connect_fn(onMqttConnection, NULL);
|
||||||
|
|
||||||
|
motorFrequency = mgos_sys_config_get_flashLight_motorFrequency();
|
||||||
|
LOG(LL_INFO, ("motorFrequency=%d Hz", motorFrequency));
|
||||||
|
motorAddress = mgos_sys_config_get_flashLight_address();
|
||||||
|
LOG(LL_INFO, ("motorAddress=%d", motorAddress));
|
||||||
|
LOG(LL_INFO, ("Initializing motor controller"));
|
||||||
|
recalcTimings();
|
||||||
|
wemos_motor_init();
|
||||||
|
LOG(LL_INFO, ("Initializing motor M1"));
|
||||||
|
wemos_motor_initMotor(M1, motorAddress, motorFrequency);
|
||||||
|
LOG(LL_INFO, ("Setting up timer"));
|
||||||
|
motorUpdateTime_msec = mgos_sys_config_get_flashLight_motorUpdateTime();
|
||||||
|
mgos_set_timer(motorUpdateTime_msec, MGOS_TIMER_REPEAT, motor_timer_cb, NULL);
|
||||||
|
LOG(LL_INFO, ("Initialization done"));
|
||||||
|
return MGOS_APP_INIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
======================================= */
|
||||||
|
|
Loading…
Reference in New Issue