——Fra DWIN Developer Forum
I dette nummer introducerer vi det prisvindende open source-case fra DWIN Developer Forum - det smarte dyrkningsrum. Ingeniører implementerede T5L-smartskærmen til at styre varme- og blæsertemperaturstyringsfunktioner gennem Modbus-protokollen. Strømforsyningen kan også justeres for at simulere belysningsfunktionen. Systemet kan automatisk køre i henhold til parametrene indstillet på skærmen og gemme fejlhistorikregistreringer.
1. UI Materiale Display
![asvdfb (2)](https://ecdn6.globalso.com/upload/p/1355/source/2024-03/65f96ba08612736786.jpg)
![asvdfb (1)](https://ecdn6.globalso.com/upload/p/1355/source/2024-03/65f96ba210c7924337.jpg)
2.UI Design
1.C51 Design
Hovedkoderne til indhentning og opdatering af data såsom temperatur, fugtighed og højde på hovedgrænsefladen og brug af modbus rtu til at styre temperaturkontrolmoduler, motorer, alarmdetektering og andre slavemaskiner er som følger
Hovedgrænsefladekodereference:
#include "main_win.h"
#include "modbus.h"
#include "sys_params.h"
#include "func_handler.h"
#inkluder "uart2.h"
#omfatte
#omfatte
#define TEMP_HUM_SLAVE_ADDR 2
#define TEMP_HUM_VAL_MAX_NUM 2
#define ALERT_BIT_MAX_NUM 30
#define ALERT_BYTE_NUM (ALERT_BIT_MAX_NUM/8+((ALERT_BIT_MAX_NUM%8)!=0))
#define GET_ALERT_BIT(val, pos) ((val[pos/8]>>(pos%8))&0x01)
typedef struct{
char dato[17];
u8 beskrivelse;
}ALERT;
#define ALERT_TABLE_LEN 20
statisk u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};
statisk u8 btn_addr[MAIN_WIN_BTN_MAX_NUM] = {50, 51, 52, 69, 53, 54, 55, 70, 56, 57, 58, 59};
u16 main_win_val[MAIN_WIN_VAL_MAX_NUM];
u16 temp_hum_val[TEMP_HUM_VAL_MAX_NUM] = {0};
u16 date_val[MAIN_WIN_DATE_MAX_NUM] = {0};
u8 alert_val[ALERT_BYTE_NUM] = {0};
u8 old_alert_val[ALERT_BYTE_NUM] = {0};
ALERT alert_table[ALERT_TABLE_LEN];
u16 alert_num = 0;
bit is_main_win = 0;
void main_win_update()
{
}
void main_win_disp_date()
{
kun u8;
len = sprintf(common_buf, "%u:%u", (u16)dato_val[3], (u16)dato_val[4]);
almindelig_buf[len+1] = 0;
sys_write_vp(MAIN_WIN_DATE_VP, common_buf, len/2+2);
}
void main_win_process_alert()
{
u8 i;
for(i=0;i
{
if(GET_ALERT_BIT(gammel_advarselsværdi, i))
Blive ved;
if(GET_ALERT_BIT(alert_val, i))
{
if(alert_num>=ALERT_TABLE_LEN)
alert_num = ALERT_TABLE_LEN-1;
alert_table[alert_num].desc = i+1;
sprintf(alert_table[alert_num].date, "%u/%u/%u %u:%u",
date_val[0], dato_val[1], dato_val[2], dato_val[3], dato_val[4]
);
alarm_num++;
}
}
memcpy(old_alert_val, alert_val, sizeof(alert_val));
}
void main_win_disp_alert()
{
u16 og;
med u16;
kun u16 = 0;
almindelig_buf[0] = 0;
for(i=0;i
{
val = 0;
hvis jeg
{
val = alert_table.desc;
len += sprintf(common_buf+len, "%s\r\n", alert_table.date);
}
sys_write_vp(ALERT_WIN_DESC_START_VP+i, (u8*)&val, 1);
}
almindelig_buf[len+1] = 0;
sys_write_vp(ALERT_WIN_DATE_VP, common_buf, len/2+2);
}
void main_win_init()
{
float fixed_val;
u8 i;
is_main_win = 1;
main_win_val[5] = (u16)(temp_hum_val[0]/10.0+0.5f);
main_win_val[6] = (u16)(temp_hum_val[1]/10.0+0.5f);
for(i=0;i
{
hvis(i==0)
Blive ved;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP+MAIN_WIN_VAL_OFFSET*i, (u8*)&main_win_val, 1);
}
fixed_val = main_win_val[0]/WIND_SPEED_SCALE+FLOAT_FIX_VAL;
sys_write_vp(MAIN_WIN_WIND_SPEED_VP, (u8*)&fixed_val, 2);
}
void main_win_click_handler(u16 btn_val)
{
u8 indeks;
if(btn_val==0x0B)
{
main_win_disp_alert();
Vend tilbage;
}
indeks = btn_val-1;
btn_sta[indeks] = !btn_sta[indeks];
if((indeks==3)||(indeks==7))
btn_sta[indeks] = 1;
modbus_write_bit(btn_addr[indeks], btn_sta[indeks]?0xFF00:0x0000);
btn_val = btn_sta[indeks];
sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*indeks, (u8*)&btn_val, 1);
if(indeks==9)
is_main_win = 0;
andet if((indeks==3)||(indeks==7))
{
while(sys_get_touch_sta());
modbus_write_bit(btn_addr[indeks], 0x0000);
}
}
void main_win_msg_handler(u8 *msg,u16 msg_len)
{
u8 f_code = msg[MODBUS_RESPOND_POS_FUNC_CODE];
u8 data_len = msg[MODBUS_RESPOND_POS_DATA_LEN];
u8 i;
u8 offset;
msg_len = msg_len;
if(!er_main_win)
Vend tilbage;
if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))
{
offset = MODBUS_RESPOND_POS_DATA;
for(i=0;i
{
main_win_val = SYS_GET_U16(msg[offset], msg[offset+1]);
offset += 2;
}
main_win_update();
}else if((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))
{
offset = MODBUS_RESPOND_POS_DATA;
for(i=0;i
{
alert_val = msg[offset];
offset++;
}
main_win_process_alert();
}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))
{
offset = MODBUS_RESPOND_POS_DATA;
for(i=0;i
{
temp_hum_val = SYS_GET_U16(msg[offset], msg[offset+1]);
offset += 2;
modbus_write_word(5+i, temp_hum_val);
}
main_win_update();
}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))
{
offset = MODBUS_RESPOND_POS_DATA;
for(i=0;i
{
dato_val = SYS_GET_U16(msg[offset], msg[offset+1]);
offset += 2;
}
main_win_disp_date();
}
}
void main_win_read_temp_hum()
{
u8 old_slave_addr = SLAVE_ADDR;
sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;
modbus_read_words(0, TEMP_HUM_VAL_MAX_NUM);
sys_params.user_config[5] = old_slave_addr;//Revert
}
void main_win_handler()
{
statisk u8 flag = 0;
if(er_main_win)
{
if(alert_read_period==ALERT_READ_PERIOD)
{
advarselslæseperiode = 0;
modbus_read_bits(510, ALERT_BIT_MAX_NUM);
Vend tilbage;
}
if(date_update_period==DATE_UPDATE_PERIOD)
{
dato_opdateringsperiode = 0;
modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);
Vend tilbage;
}
flag = !flag;
hvis (flag)
modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);
andet
main_win_read_temp_hum();
}
}
modbus rtu kode reference:
#include "modbus.h"
#include "crc16.h"
#include "sys_params.h"
#define UART_INCLUDE "uart2.h"
#define UART_INIT uart2_init
#define UART_SEND_BYTES uart2_send_bytes
#define UART_BAUD 9600
#define MODBUS_RECV_TIMEOUT (u8)(35000.0f/UART_BAUD+2)
#define MODBUS_SEND_INTERVAL 150
#inkluder UART_INCLUDE
statisk bit is_modbus_recv_complete = 0;
statisk u8 modbus_recv_buff[270];
statisk u16 modbus_recv_len = 0;//Total længde af bytes accepteret
statisk u8 modbus_recv_timeout = 0;//Accepter overløbstid
statisk flygtig u16 modbus_send_interval = 0;
MODBUS_PACKET pakke;
void modbus_init()
{
UART_INIT(UART_BAUD);
}
void modbus_send_bytes(u8 *bytes,u16 len)
{
UART_SEND_BYTES(bytes,len);
}
void modbus_recv_byte(u8 byte)
{
if(er_modbus_recv_complete)
Vend tilbage;
if(modbus_recv_len
modbus_recv_buff[modbus_recv_len++] = byte;
}
void modbus_check_recv_timeout()
{
if(modbus_recv_timeout)
{
modbus_recv_timeout--;
if(modbus_recv_timeout==0)
{
is_modbus_recv_complete = 1;
}
}
}
u8 modbus_send_packet(u8 *pakke)
{
kun u16;
u16 crc;
u8 func_code = pakke[1];
while(modbus_send_interval);
if(func_code==MODBUS_FUNC_CODE_10)
{
((MODBUS_10_PACKET*)packet)->byte_num = ((MODBUS_10_PACKET*)packet)->word_num*2;
len = 9+((MODBUS_10_PACKET*)pakke)->byte_num;
}else if(func_code==MODBUS_FUNC_CODE_0F)
{
len = ((MODBUS_0F_PACKET*)pakke)->bit_num;
((MODBUS_0F_PACKET*)pakke)->byte_num = len/8+(len%8?1:0);
len = 9+((MODBUS_0F_PACKET*)pakke)->byte_num;
}andet
{
len = sizeof(MODBUS_PACKET);
}
crc = crc16(pakke,len-2);
pakke[len-2] = (u8)(crc>>8);
pakke[len-1] = (u8)crc;
modbus_send_bytes(pakke,len);
modbus_send_interval = MODBUS_SEND_INTERVAL;
returner 0;//Succes
}
ekstern void modbus_msg_handler(u8 *msg,u16 msg_len);
void modbus_handler()
{
u16 crc;
if(!er_modbus_recv_complete)
Vend tilbage;
//Tjek crc-værdien
crc = ((u16)modbus_recv_buff[modbus_recv_len-2]
if(crc16(modbus_recv_buff,modbus_recv_len-2)==crc)
{
modbus_msg_handler(modbus_recv_buff, modbus_recv_len);
}
modbus_recv_len = 0;
is_modbus_recv_complete = 0;
}
u8 modbus_send_fcode(u8 fcode, u16 adr, u16 len)
{
packet.slave_addr = SLAVE_ADDR;
packet.func_code = fcode;//Funktionskode
packet.start_addr = addr;//Adresse
packet.data_len = len;//Værdi skrevet
len = modbus_send_packet((u8*)&pakke);
returnere len;
}
Indlægstid: Jan-12-2024