shuichan_old/V1.5/STM32F103_App1/HardWare/FEED_SCALE/feed_scale.c

415 lines
13 KiB
C
Raw Normal View History

/* feed_scale.c - 485 ι<>ϳӿ<CFB3><D3BF><EFBFBD>
*
* Ӳ<EFBFBD><EFBFBD>: USART2 <EFBFBD><EFBFBD> RS485 <EFBFBD><EFBFBD><EFBFBD>Ӵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PA2(TX), PA3(RX)<EFBFBD><EFBFBD>9600-8N1
* Э<EFBFBD><EFBFBD>: <EFBFBD><EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B}
* Ӧ<EFBFBD><EFBFBD>: 9 <EFBFBD>ֽ<EFBFBD>(<EFBFBD><EFBFBD>ַ1 + <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1 + <EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD>1 + <EFBFBD><EFBFBD><EFBFBD><EFBFBD>4 + CRC2)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>[3..6]<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD> float<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ KG<EFBFBD><EFBFBD>
* ҵ<EFBFBD><EFBFBD>: ƽ̨<EFBFBD>·<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷι<EFBFBD><EFBFBD> onceWt(0.1KG <EFBFBD><EFBFBD>λ)<EFBFBD><EFBFBD><EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD> 1 <EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD>ʼͶι<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD> <EFBFBD><EFBFBD>ʼʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> >= <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷι<EFBFBD><EFBFBD> ʱֹͣ<EFBFBD><EFBFBD>
*/
#include "feed_scale.h"
#include "relay.h"
#include "uart.h"
#include "log.h"
#include "network.h"
#include "24c02.h"
#include <string.h>
#include <stdio.h>
/* <20><>ѯ<EFBFBD>ӵ<EFBFBD> Modbus <20><><EFBFBD><EFBFBD> */
static const uint8_t RS485_WEIGHT_CMD[8] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0xC4, 0x0B};
/* <20><><EFBFBD><EFBFBD>״̬ */
static FeedScaleState feed_state = FEED_IDLE;
static uint16_t once_weight = 0; /* <20><><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9><EFBFBD><EFBFBD>0.1KG <20><>λ<EFBFBD><CEBB><EFBFBD><EFBFBD> EEPROM <20><>ȡ */
static uint16_t start_weight = 0; /* <20><><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9>ʼʱ<CABC><CAB1>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static uint16_t last_weight = 0; /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>أ<EFBFBD><D8A3><EFBFBD>ȥƤ<C8A5><C6A4> */
static uint16_t last_raw_weight = 0; /* <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> 485 ԭʼë<CABC>أ<EFBFBD>δȥƤ<C8A5><C6A4> */
static uint16_t reduced_weight = 0; /* <20><><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9><EFBFBD>ٵ<EFBFBD><D9B5><EFBFBD><EFBFBD><EFBFBD> */
static uint16_t zero_weight = 0; /* ȥƤ<C8A5><C6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>EEPROM <20><><EFBFBD><EFBFBD><E7B1A3> */
/* <20><>ѯ<EFBFBD><D1AF>ʱ */
static uint32_t last_query_tick = 0;
static uint32_t feed_start_tick = 0; /* Ͷι<CDB6><CEB9>ʼʱ<CABC>̣<EFBFBD><CCA3><EFBFBD><EFBFBD>ڳ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
static uint8_t first_query_sent = 0; /* <20>״<EFBFBD><D7B4>ϵ<EFBFBD><CFB5><EFBFBD>ѯ<EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD> */
static uint8_t first_query_reported = 0; /* <20>״<EFBFBD><D7B4>ϵ<EFBFBD><CFB5><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD> */
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ECB3A3><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD> */
static uint8_t add_weight_count = 0;
#define FEED_ADD_WEIGHT_LIMIT 20u /* <20><><EFBFBD><EFBFBD>Լ 10s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD>Ͷι */
/* <20><><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9>ʱ 10 <20><><EFBFBD><EFBFBD> */
#define FEED_TIMEOUT_MS (10u * 60u * 1000u)
/* EEPROM <20>б<EFBFBD><D0B1><EFBFBD>ȥƤ<C8A5><C6A4><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD>Ͷι<CDB6><CEB9><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>(<28><> MqttInfoStr ֮<><D6AE>) */
#define FEED_SCALE_ZERO_ADDR 120u
#define FEED_SCALE_ONCEWT_ADDR 122u
#define FEED_SCALE_INIT_FLAG_ADDR 124u
#define FEED_SCALE_INIT_FLAG 0xA5u
/* <20><><EFBFBD><EFBFBD> CRC16 У<><D0A3> (Modbus) */
static uint16_t crc16_modbus(const uint8_t *data, uint16_t len)
{
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < len; i++) {
crc ^= data[i];
for (uint8_t j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc >>= 1;
}
}
}
return crc;
}
/* 485 ԭʼ֡ hex <20><>ӡ<EFBFBD><D3A1><EFBFBD>Ų<EFBFBD><C5B2>ã<EFBFBD><C3A3>յ<EFBFBD>ʲô<CAB2><C3B4>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static void feed_scale_dump_frame(const uint8_t *buf, uint16_t len)
{
char hex[3 * 24 + 1] = {0};
uint16_t n = len > 24 ? 24 : len;
for (uint16_t i = 0; i < n; i++) {
snprintf(hex + i * 3, 4, "%02X ", buf[i]);
}
log_info("> FEED: 485 <20>յ<EFBFBD> %d <20>ֽ<EFBFBD>: %s", (int)len, hex);
}
/* <20><> 485 Ӧ<><D3A6><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6> 9 <20>ֽ<EFBFBD>: 01 03 04 41 97 30 33 0B F6 */
static int feed_scale_parse_weight(const uint8_t *buf, uint16_t len, uint16_t *weight_100g)
{
feed_scale_dump_frame(buf, len);
if (len < 9) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><><D6A1><EFBFBD>ȹ<EFBFBD><C8B9><EFBFBD>(%d<9),<2C><><EFBFBD>ܲ<EFBFBD><DCB2><EFBFBD><EFBFBD>ʲ<EFBFBD><CAB2>Ի<EFBFBD><D4BB><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD>", (int)len);
return -1;
}
if (buf[0] != RS485_WEIGHT_CMD[0]) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><>Ų<EFBFBD><C5B2><EFBFBD>(<28><>0x%02X <20><><EFBFBD><EFBFBD>0x%02X)", buf[0], RS485_WEIGHT_CMD[0]);
return -3;
}
if (buf[1] == (RS485_WEIGHT_CMD[1] | 0x80)) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>-<2D>ӷ<EFBFBD><D3B7><EFBFBD><EFBFBD>쳣֡(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x%02X <20><EFBFBD><ECB3A3>0x%02X),<2C>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?", buf[1], buf[2]);
return -4;
}
if (buf[1] != RS485_WEIGHT_CMD[1]) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBB2BB>(<28><>0x%02X <20><><EFBFBD><EFBFBD>0x%02X)", buf[1], RS485_WEIGHT_CMD[1]);
return -5;
}
uint16_t calc_crc = crc16_modbus(buf, 7); /* ǰ 7 <20>ֽڲ<D6BD><DAB2><EFBFBD> CRC <20><><EFBFBD><EFBFBD> */
uint16_t recv_crc = (uint16_t)buf[8] << 8 | buf[7]; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>Ϊ CRC */
if (calc_crc != recv_crc) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>-CRC У<><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(calc=0x%04X recv=0x%04X),<2C><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><>߽<EFBFBD><DFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", calc_crc, recv_crc);
return -2;
}
/* <20><><EFBFBD><EFBFBD> float: <20><><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>[3]=MSB, [6]=LSB<53><42><EFBFBD>ο<EFBFBD> APP12 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ */
float fweight;
uint8_t *p = (uint8_t *)&fweight;
p[0] = buf[6];
p[1] = buf[5];
p[2] = buf[4];
p[3] = buf[3];
/* ת<><D7AA> 0.1KG <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD>Ʒ<EFBFBD>Χ */
int32_t wt = (int32_t)(fweight * 10.0f);
if (wt < 0) wt = 0;
if (wt > FEED_SCALE_WEIGHT_MAX) wt = FEED_SCALE_WEIGHT_MAX;
*weight_100g = (uint16_t)wt;
log_info("> FEED: 485 ԭʼë<CABC><C3AB>=%.1fKG (0.1kg=%d)", fweight, *weight_100g);
return 0;
}
/* ͨ<><CDA8> USART2 <20><><EFBFBD><EFBFBD> 485 <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD> */
static void feed_scale_send_query(void)
{
HAL_UART_Transmit(&huart2, (uint8_t *)RS485_WEIGHT_CMD, sizeof(RS485_WEIGHT_CMD), 100);
}
/* <20><>ȡ 485 <20><><EFBFBD><EFBFBD>֡ */
static int feed_scale_read_frame(uint8_t *buf, uint16_t max_len)
{
uint16_t len = USART2_GetFrame(buf, max_len);
if (len == 0) return 0;
return (int)len;
}
/* <20>ϱ<EFBFBD><CFB1><EFBFBD>ǰ״̬<D7B4><CCAC>ƽ̨: <20><><EFBFBD>ء<EFBFBD><D8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥƤ<C8A5><C6A4><EFBFBD><EFBFBD> */
static void feed_scale_report_weight(const char *header)
{
(void)header;
/* <20><>ƽ̨<C6BD><CCA8>ģ<EFBFBD><C4A3><EFBFBD>ֶΣ<D6B6>weight=ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)<29><>zero=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(ȥƤ)<29><>onceWt=<3D><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD> */
/* sw1 <20><> feeding <20><><EFBFBD>ϱ<EFBFBD><CFB1>̵<EFBFBD><CCB5><EFBFBD> 1 ״̬<D7B4><CCAC>ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><D8B6><EFBFBD>ͬ<EFBFBD><CDAC>ˢ<EFBFBD><CBA2> */
NET_publish_status(
MqttInfoStr.Relay_State[1] ? 1 : 0,
MqttInfoStr.Relay_State[1] ? 1 : 0,
MqttInfoStr.Relay_State[2] ? 1 : 0,
MqttInfoStr.Relay_State[3] ? 1 : 0,
MqttInfoStr.Relay_State[4] ? 1 : 0,
(float)zero_weight / 10.0f,
(float)once_weight / 10.0f,
(float)last_weight / 10.0f);
log_info("> FEED: <20><><EFBFBD><EFBFBD>=%.1fKG <20><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>=%.1fKG ȥƤ=%.1fKG",
(float)last_weight / 10.0f,
(float)once_weight / 10.0f,
(float)zero_weight / 10.0f);
}
uint8_t g_feed_scale_on = 0;
/* <20><><EFBFBD>ز<EFBFBD>Ʒģʽ<C4A3><CABD>EEPROM <20>հ<EFBFBD>ʱ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ֵ */
void feed_scale_load_mode(void)
{
uint8_t v = 0xFF;
eepromReadData(FEED_SCALE_MODE_ADDR, &v, 1);
if (v > 1) v = PRODUCT_WITH_FEED_SCALE;
g_feed_scale_on = v;
log_info("> <20><>Ʒģʽ: %s", v ? "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD>)" : "<EFBFBD><EFBFBD>·<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>(<28>޳<EFBFBD>)");
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD>Ʒģʽ<C4A3><CABD>д EEPROM<4F><4D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>Ч<EFBFBD><D0A7> */
void feed_scale_set_mode(uint8_t on)
{
on = on ? 1 : 0;
g_feed_scale_on = on;
eepromWriteData(FEED_SCALE_MODE_ADDR, &on, 1);
}
void feedScaleInit(void)
{
uint8_t tmp[2] = {0};
/* <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>ǿհ<C7BF>/<2F><>ˢ<EFBFBD><CBA2><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><C7BF>д<EFBFBD><D0B4>Ĭ<EFBFBD><C4AC> 1.0KG */
eepromReadData(FEED_SCALE_INIT_FLAG_ADDR, tmp, 1);
if (tmp[0] != FEED_SCALE_INIT_FLAG) {
tmp[0] = FEED_SCALE_INIT_FLAG;
eepromWriteData(FEED_SCALE_INIT_FLAG_ADDR, tmp, 1);
zero_weight = 10; /* Ĭ<><C4AC>ȥƤ 1.0KG */
once_weight = 10; /* Ĭ<>ϵ<EFBFBD><CFB5><EFBFBD>Ͷ<EFBFBD><CDB6> 1.0KG */
tmp[0] = (uint8_t)(zero_weight & 0xFF);
tmp[1] = (uint8_t)(zero_weight >> 8);
eepromWriteData(FEED_SCALE_ZERO_ADDR, tmp, 2);
tmp[0] = (uint8_t)(once_weight & 0xFF);
tmp[1] = (uint8_t)(once_weight >> 8);
eepromWriteData(FEED_SCALE_ONCEWT_ADDR, tmp, 2);
log_info("> FEED: <20>״γ<D7B4>ʼ<EFBFBD><CABC>, <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC> ȥƤ=1.0KG, <20><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>=1.0KG");
} else {
eepromReadData(FEED_SCALE_ZERO_ADDR, tmp, 2);
zero_weight = (uint16_t)tmp[0] | ((uint16_t)tmp[1] << 8);
if (zero_weight == 0 || zero_weight > FEED_SCALE_WEIGHT_MAX) {
zero_weight = 10; /* Ĭ<><C4AC>ȥƤ 1.0KG */
}
eepromReadData(FEED_SCALE_ONCEWT_ADDR, tmp, 2);
once_weight = (uint16_t)tmp[0] | ((uint16_t)tmp[1] << 8);
if (once_weight == 0 || once_weight > FEED_SCALE_WEIGHT_MAX) {
once_weight = 10; /* Ĭ<>ϵ<EFBFBD><CFB5><EFBFBD>Ͷ<EFBFBD><CDB6> 1.0KG */
}
}
if (g_feed_scale_on) {
log_info("> FEED: <20><>ʼ<EFBFBD><CABC>, ȥƤ=%.1fKG, <20><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6>=%.1fKG",
(float)zero_weight / 10.0f, (float)once_weight / 10.0f);
}
}
void feedScaleSetZero(uint16_t zero_100g)
{
if (zero_100g > FEED_SCALE_WEIGHT_MAX) return;
zero_weight = zero_100g;
/* ƽ̨<C6BD>·<EFBFBD><C2B7>¿<EFBFBD><C2BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼë<CABC><C3AB><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (last_raw_weight >= zero_weight) {
last_weight = last_raw_weight - zero_weight;
} else {
last_weight = 0;
}
uint8_t tmp[2] = { (uint8_t)(zero_weight & 0xFF), (uint8_t)(zero_weight >> 8) };
eepromWriteData(FEED_SCALE_ZERO_ADDR, tmp, 2);
log_info("> FEED: <20><><EFBFBD><EFBFBD>ȥƤ=%.1fKG, <20><><EFBFBD><EFBFBD><E3BEBB>=%.1fKG",
(float)zero_weight / 10.0f, (float)last_weight / 10.0f);
}
void feedScaleSetOnceWeight(uint16_t once_wt_100g)
{
if (once_wt_100g > FEED_SCALE_WEIGHT_MAX) return;
once_weight = once_wt_100g;
uint8_t tmp[2] = { (uint8_t)(once_weight & 0xFF), (uint8_t)(once_weight >> 8) };
eepromWriteData(FEED_SCALE_ONCEWT_ADDR, tmp, 2);
log_info("> FEED: <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>Ͷ<EFBFBD><CDB6>=%.1fKG", (float)once_weight / 10.0f);
}
uint16_t feedScaleGetOnceWeight(void)
{
return once_weight;
}
uint16_t feedScaleGetWeight(void)
{
return last_weight;
}
uint16_t feedScaleGetZero(void)
{
return zero_weight;
}
/* <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> 485 ԭʼë<CABC>أ<EFBFBD>δȥƤ<C8A5><C6A4>0.1KG <20><>λ<EFBFBD><CEBB> */
uint16_t feedScaleGetRawWeight(void)
{
return last_raw_weight;
}
FeedScaleState feedScaleGetState(void)
{
return feed_state;
}
uint16_t feedScaleGetReduced(void)
{
return reduced_weight;
}
void feedScaleStart(uint16_t once_wt_100g)
{
if (once_wt_100g < FEED_SCALE_ONCEWT_MIN || once_wt_100g > FEED_SCALE_ONCEWT_MAX) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч=%.1fKG", (float)once_wt_100g / 10.0f);
return;
}
if (feed_state == FEED_RUNNING) {
log_warn("> FEED: <20><><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9>, <20><><EFBFBD>Ա<EFBFBD><D4B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
if (first_query_reported == 0) {
log_warn("> FEED: <20><>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>, <20>޷<EFBFBD><DEB7><EFBFBD>ʼͶι");
return;
}
if (last_weight == 0) {
log_warn("> FEED: ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 0, <20>޷<EFBFBD><DEB7><EFBFBD>ʼͶι");
return;
}
once_weight = once_wt_100g;
start_weight = last_weight; /* ȡ<><C8A1><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD> */
reduced_weight = 0;
add_weight_count = 0;
feed_start_tick = HAL_GetTick();
feed_state = FEED_RUNNING;
relaySet(1, 1);
eepromWriteData(102, &MqttInfoStr.Relay_State[0], 7);
log_info("> FEED: <20><>ʼͶι <20><><EFBFBD><EFBFBD>=%.1fKG, <20><>ʼ=%.1fKG, <20>̵<EFBFBD><CCB5><EFBFBD>1=<3D><>",
(float)once_weight / 10.0f, (float)start_weight / 10.0f);
/* Ͷι<CDB6><CEB9>ʼʱ<CABC><CAB1><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>һ<EFBFBD><D2BB>״̬ */
feed_scale_report_weight("iot.prop.post");
}
void feedScaleStop(void)
{
if (feed_state == FEED_IDLE) return;
relaySet(1, 0);
eepromWriteData(102, &MqttInfoStr.Relay_State[0], 7);
feed_state = FEED_DONE;
log_info("> FEED: ֹͣͶι, <20>Ѽ<EFBFBD><D1BC><EFBFBD>=%.1fKG", (float)reduced_weight / 10.0f);
relayRequestReport();
}
static void feed_scale_finish_error(const char *reason)
{
relaySet(1, 0);
eepromWriteData(102, &MqttInfoStr.Relay_State[0], 7);
feed_state = FEED_ERROR;
log_warn("> FEED: <20>쳣ֹͣ, %s", reason);
relayRequestReport();
}
void feedScaleProcess(void)
{
if (!g_feed_scale_on) return;
uint8_t rx_buf[32];
int len;
uint16_t cur_weight;
int32_t diff;
/* <20><><EFBFBD><EFBFBD> USART2 ֡<><D6A1>ʱ<EFBFBD>Զ<EFBFBD><D4B6>ύ */
USART2_Tick();
/* <20><><EFBFBD><EFBFBD>ʱ 10s <20><>ѯһ<D1AF><D2BB>; Ͷιʱ 1s <20><>ѯһ<D1AF><D2BB>;
<EFBFBD><EFBFBD><EFBFBD>ۼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ©<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һֱˢ<EFBFBD><EFBFBD>ʱ */
uint32_t query_interval = (feed_state == FEED_RUNNING) ? FEED_SCALE_QUERY_RUN_MS : FEED_SCALE_QUERY_IDLE_MS;
if (first_query_sent == 0 || (HAL_GetTick() - last_query_tick) >= query_interval) {
last_query_tick = HAL_GetTick();
feed_scale_send_query();
if (first_query_sent == 0) {
first_query_sent = 1;
log_info("> FEED: <20>״β<D7B4>ѯ<EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD>");
}
}
/* <20><>ȡ 485 <20><><EFBFBD><EFBFBD> */
len = feed_scale_read_frame(rx_buf, sizeof(rx_buf));
if (len > 0) {
if (feed_scale_parse_weight(rx_buf, len, &cur_weight) == 0) {
last_raw_weight = cur_weight; /* <20><><EFBFBD><EFBFBD>ԭʼë<CABC><C3AB> */
last_weight = cur_weight > zero_weight ? (cur_weight - zero_weight) : 0; /* <20><><EFBFBD><EFBFBD> */
if (!first_query_reported) {
/* <20>״<EFBFBD><D7B4>ϵ<EFBFBD>: <20><>ѯ<EFBFBD><D1AF>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>ƽ̨ */
first_query_reported = 1;
feed_scale_report_weight("iot.prop.post");
log_info("> FEED: <20>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>");
}
if (feed_state == FEED_RUNNING) {
/* Ͷι<CDB6>ڼ䣺ÿ<E4A3BA><C3BF><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>ƽ̨<C6BD><CCA8><EFBFBD><EFBFBD>֤ʵʱ */
feed_scale_report_weight("iot.prop.post");
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD> */
diff = (int32_t)start_weight - (int32_t)last_weight;
if (diff < 0) diff = -diff;
reduced_weight = (uint16_t)diff;
log_info("> FEED: Ͷι<CDB6><CEB9> <20><>ʼ=%.1f <20><>ǰ=%.1f <20>Ѽ<EFBFBD>=%.1f <20><><EFBFBD><EFBFBD>=%.1f",
(float)start_weight / 10.0f, (float)last_weight / 10.0f,
(float)reduced_weight / 10.0f, (float)once_weight / 10.0f);
/* <20><><EFBFBD><EFBFBD>1: <20>ﵽ/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͷι<CDB6><CEB9><EFBFBD><EFBFBD>ֹͣ */
if (reduced_weight >= once_weight) {
log_info("> FEED: <20>ﵽĿ<EFB5BD><C4BF>Ͷι<CDB6><CEB9>, ֹͣ");
feedScaleStop();
return;
}
/* <20><><EFBFBD><EFBFBD>2: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD><D3A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڼ<EFBFBD><DABC>ϣ<EFBFBD><CFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
if (last_weight > start_weight) {
add_weight_count++;
if (add_weight_count >= FEED_ADD_WEIGHT_LIMIT) {
feed_scale_finish_error("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
return;
}
} else {
add_weight_count = 0;
}
/* <20><><EFBFBD><EFBFBD>3: Ͷι<CDB6><CEB9>ʱ 5 <20><><EFBFBD><EFBFBD> */
if (HAL_GetTick() - feed_start_tick > FEED_TIMEOUT_MS) {
feed_scale_finish_error("Ͷι<EFBFBD><EFBFBD>ʱ");
return;
}
}
}
}
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD>ⲿģ<E2B2BF><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һѭ<D2BB><D1AD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD> */
if (feed_state == FEED_DONE || feed_state == FEED_ERROR) {
/* ״̬<D7B4><CCAC><EFBFBD><EFBFBD>һ<EFBFBD>Σ<EFBFBD><CEA3><EFBFBD> relay ״̬<D7B4><CCAC><EFBFBD>ϱ<EFBFBD> */
}
}