[Código Aberto] Sala de Treinamento Inteligente

——Do Fórum de Desenvolvedores DWIN

Nesta edição, apresentamos o premiado projeto de código aberto do Fórum de Desenvolvedores DWIN: a sala de cultivo inteligente. Os engenheiros implementaram a tela inteligente T5L para controlar as funções de aquecimento e temperatura do ventilador por meio do protocolo Modbus. A fonte de alimentação também pode ser ajustada para simular a função de iluminação. O sistema pode operar automaticamente de acordo com os parâmetros definidos na tela e salvar o histórico de falhas.

1. Exibição de Material Design da Interface do Usuário

asvdfb (2)
asvdfb (1)

2. Design de interface do usuário

asvdfb (3)

1.C51 Projeto

Os principais códigos para aquisição e atualização de dados como temperatura, umidade e altitude na interface principal, e para uso do Modbus RTU no controle de módulos de controle de temperatura, motores, detecção de alarmes e outras máquinas escravas, são os seguintes:

Referência do código da interface principal:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.h"

#incluir

#incluir

#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 date[17];

u8 desc;

}ALERTA;

#define ALERT_TABLE_LEN 20

static u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

static 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};

ALERTA alert_table[ALERT_TABLE_LEN];

u16 alert_num = 0;

bit is_main_win = 0;

void main_win_update()

{

}

void main_win_disp_date()

{

Apenas para menores de 8 anos;

len = sprintf(common_buf, "%u:%u", (u16)date_val[3], (u16)date_val[4]);

common_buf[len+1] = 0;

sys_write_vp(MAIN_WIN_DATE_VP, common_buf, len/2+2);

}

void main_win_process_alert()

{

u8 i;

para(i=0;i

{

se(GET_ALERT_BIT(old_alert_val, i))

continuar;

se(GET_ALERT_BIT(alert_val, i))

{

se (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], date_val[1], date_val[2], date_val[3], date_val[4]

);

alert_num++;

}

}

memcpy(old_alert_val, alert_val, sizeof(alert_val));

}

void main_win_disp_alert()

{

em 16 e;

parede sub-16;

u16 apenas = 0;

common_buf[0] = 0;

para(i=0;i

{

val = 0;

se(i

{

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);

}

common_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);

para(i=0;i

{

se(i==0)

continuar;

sys_write_vp(MAIN_WIN_WIND_SPEED_VP+MAIN_WIN_VAL_OFFSET*i, (u8*)&main_win_val, 1);

}

valor_fixo = valor_ganho_principal[0]/ESCALA_VELOCIDADE_DO_VENTO+VALOR_FIXO_FLOAT;

sys_write_vp(MAIN_WIN_WIND_SPEED_VP, (u8*)&fixed_val, 2);

}

void main_win_click_handler(u16 btn_val)

{

índice u8;

se(btn_val==0x0B)

{

main_win_disp_alert();

retornar;

}

índice = btn_val-1;

btn_sta[index] = !btn_sta[index];

se((índice==3)||(índice==7))

btn_sta[index] = 1;

modbus_write_bit(btn_addr[index], btn_sta[index]?0xFF00:0x0000);

btn_val = btn_sta[index];

sys_write_vp(MAIN_WIN_BTN_STA_START_VP+MAIN_WIN_BTN_STA_OFFSET*index, (u8*)&btn_val, 1);

se(índice==9)

is_main_win = 0;

senão se((índice==3)||(índice==7))

{

enquanto(sys_get_touch_sta());

modbus_write_bit(btn_addr[index], 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;

Deslocamento u8;

msg_len = msg_len;

se(!é_major_vencedor)

retornar;

se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))

{

deslocamento = MODBUS_RESPOND_POS_DATA;

para(i=0;i

{

main_win_val = SYS_GET_U16(msg[offset], msg[offset+1]);

deslocamento += 2;

}

main_win_update();

} senão se((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

deslocamento = MODBUS_RESPOND_POS_DATA;

para(i=0;i

{

alert_val = msg[offset];

deslocamento++;

}

main_win_process_alert();

} senão se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

deslocamento = MODBUS_RESPOND_POS_DATA;

para(i=0;i

{

temp_hum_val = SYS_GET_U16(msg[offset], msg[offset+1]);

deslocamento += 2;

modbus_write_word(5+i, temp_hum_val);

}

main_win_update();

} senão se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

deslocamento = MODBUS_RESPOND_POS_DATA;

para(i=0;i

{

date_val = SYS_GET_U16(msg[offset], msg[offset+1]);

deslocamento += 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;//Reverter

}

void main_win_handler()

{

flag u8 estática = 0;

se(é_major_vencedor)

{

se (alert_read_period==ALERT_READ_PERIOD)

{

alert_read_period = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

retornar;

}

se(date_update_period==DATE_UPDATE_PERIOD)

{

date_update_period = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

retornar;

}

flag = !flag;

se(flag)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

outro

main_win_read_temp_hum();

}

}

Código de referência Modbus RTU:

#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

#definir UART_BAUD 9600

#define MODBUS_RECV_TIMEOUT (u8)(35000.0f/UART_BAUD+2)

#define MODBUS_SEND_INTERVAL 150

#include UART_INCLUDE

bit estático is_modbus_recv_complete = 0;

static u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0; // Comprimento total de bytes aceitos

static u8 modbus_recv_timeout = 0; // Aceita tempo limite de estouro

static volatile u16 modbus_send_interval = 0;

Pacote MODBUS_PACKET;

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)

{

se(é_modbus_recebido_completo)

retornar;

se(modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = byte;

}

void modbus_check_recv_timeout()

{

se(modbus_recv_timeout)

{

modbus_recv_timeout--;

se(modbus_recv_timeout==0)

{

is_modbus_recv_complete = 1;

}

}

}

u8 modbus_send_packet(u8 *packet)

{

Apenas para menores de 16 anos;

u16 crc;

u8 func_code = pacote[1];

enquanto(intervalo_de_envio_modbus);

se(func_code==MODBUS_FUNC_CODE_10)

{

((MODBUS_10_PACKET*)packet)->byte_num = ((MODBUS_10_PACKET*)packet)->word_num*2;

len = 9+((MODBUS_10_PACKET*)pacote)->byte_num;

} senão se(func_code==MODBUS_FUNC_CODE_0F)

{

len = ((MODBUS_0F_PACKET*)pacote)->bit_num;

((MODBUS_0F_PACKET*)packet)->byte_num = len/8+(len%8?1:0);

len = 9+((MODBUS_0F_PACKET*)pacote)->byte_num;

}outro

{

len = sizeof(MODBUS_PACKET);

}

crc = crc16(pacote,len-2);

pacote[len-2] = (u8)(crc>>8);

pacote[comprimento-1] = (u8)crc;

modbus_send_bytes(pacote,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

retornar 0;//Sucesso

}

extern void modbus_msg_handler(u8 *msg,u16 msg_len);

void modbus_handler()

{

u16 crc;

se(!is_modbus_recv_complete)

retornar;

//Verificar valor CRC

crc = ((u16)modbus_recv_buff[modbus_recv_len-2]

se(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 addr, u16 len)

{

packet.slave_addr = SLAVE_ADDR;

packet.func_code = fcode;//Código da função

packet.start_addr = addr;//Endereço

packet.data_len = len; // Valor escrito

len = modbus_send_packet((u8*)&packet);

retornar len;

}


Data da publicação: 12 de janeiro de 2024