[Código aberto] Sala de formación intelixente

——Do Foro de desenvolvedores de DWIN

Neste número, presentámosvos o caso de código aberto galardoado do Foro de Desenvolvedores de DWIN: a sala de cultivo intelixente. Os enxeñeiros implementaron a pantalla intelixente T5L para controlar as funcións de calefacción e control da temperatura do ventilador a través do protocolo Modbus. A fonte de alimentación tamén se pode axustar para simular a función de iluminación. O sistema pode funcionar automaticamente segundo os parámetros configurados na pantalla e gardar rexistros do historial de fallos.

1. Visualización de materiais da IU

asvdfb (2)
asvdfb (1)

2. Deseño da interface de usuario

asvdfb (3)

Deseño 1.C51

Os códigos principais para adquirir e actualizar datos como temperatura, humidade e altitude na interface principal e usar Modbus RTU para controlar módulos de control de temperatura, motores, detección de alarmas e outras máquinas escravas son os seguintes:

Referencia do código da interface principal:

#include "main_win.h"

#incluír "modbus.h"

#incluír "sys_params.h"

#incluír "func_handler.h"

#incluír "uart2.h"

#incluír

#incluír

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

estrutura typedef{

data do carácter[17];

u8 desc;

}ALERTA;

#define ALERT_TABLE_LONG 20

estático u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

estático u8 btn_addr[NÚMERO_MÁXIMO_DE_BOTN_DAS_PRINCIPAIS] = {50, 51, 52, 69, 53, 54, 55, 70, 56, 57, 58, 59};

u16 valor_principal_de_vinha[VAL_PRINCIPAL_DE_VINHA_MAX_NUM];

u16 valor_humididade_temperatura[VAL_HUMIDIDADE_TEMP_MAX_NUM] = {0};

u16 data_val[MAIN_WIN_DATE_MAX_NUM] = {0};

u8 alert_val[ALERT_BYTE_NUM] = {0};

u8 val_de_alerta_antiga[ALERTA_BYTE_NUM] = {0};

ALERTA táboa_alertas[ALERT_TABLE_LONG];

u16 núm_alerta = 0;

bit é_principal_win = 0;

actualización_de_main_win() baleira

{

}

baleiro data_de_disposición_de_main_win()

{

só sub-8;

len = sprintf(buf_común, "%u:%u", (u16)val_data[3], (u16)val_data[4]);

buf_común[len+1] = 0;

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

}

baleiro alerta_de_proceso_de_viña_principal()

{

u8 i;

para (i=0;i

{

se(GET_ALERT_BIT(val_de_alerta_antigo, i))

continuar;

se(OBTER_ALERTA_BIT(alerta_val, i))

{

se (número_de_alerta>=LONGITUDE_DA_TABELA_DE_ALERTAS)

núm_alerta = ALERT_TABLE_LEN-1;

táboa_de_alertas[número_de_alertas].desc = i+1;

sprintf(táboa_de_alertas[número_de_alertas].data, "%u/%u/%u %u:%u",

data_val[0], data_val[1], data_val[2], data_val[3], data_val[4]

);

número_de_alerta++;

}

}

memcpy(val_de_alerta_antigo, val_de_alerta, tamaño_de(val_de_alerta));

}

baleiro alerta_de_disposición_de_main_win()

{

en16 e;

muro sub-16;

só u16 = 0;

buf_común[0] = 0;

para (i=0;i

{

valor = 0;

se (i

{

val = táboa_de_alertas.desc;

len += sprintf(buf_común+len, "%s\r\n", táboa_de_alertas.data);

}

sys_write_vp(ALERT_WIN_DESC_START_VP+i, (u8*)&val, 1);

}

buf_común[len+1] = 0;

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

}

baleiro main_win_init()

{

float fixo_val;

u8 i;

é_win_principal = 1;

 

val_principal_de_venta[5] = (u16)(val_humedad_temperatura[0]/10.0+0.5f);

val_principal_de_venta[6] = (u16)(val_humedad_temperatura[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_principal_de_win[0]/ESCALA_VELOCIDADE_VENTO+VAL_FLOTANTE_FIXO;

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

}

baleiro main_win_click_handler(u16 btn_val)

{

índice u8;

se (val_boto==0x0B)

{

alerta_de_disposición_de_vínculos_principais();

retorno;

}

índice = btn_val-1;

btn_sta[índice] = !btn_sta[índice];

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

btn_sta[índice] = 1;

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

btn_val = btn_sta[índice];

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

se (índice==9)

é_win_principal = 0;

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

{

mentres(sys_get_touch_sta());

modbus_write_bit(btn_addr[índice], 0x0000);

}

}

baleiro controlador_de_mensaxes_de_main_win(u8 *mensaxe,u16 lonxitude_mensaxe)

{

u8 código_f = mensaxe[CODIGO_FUNCIÓN_POS_RESPOND_MODBUS];

u8 lonxitude_datos = mensaxe[LEN_DATOS_MODBUS_RESPOND_POS];

u8 i;

desprazamento u8;

msg_len = msg_len;

se(!é_gaña_principal)

retorno;

se ((código_f==CODIGO_FUNCIÓN_MODBUS_03)&&(len_datos==VAL_PRINCIPAL_DE_VINHA_MAX_NUM*2))

{

desprazamento = MODBUS_RESPOND_POS_DATA;

para (i=0;i

{

valor_principal_de_win = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);

desprazamento += 2;

}

actualización_de_principal_win();

}senón se((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

desprazamento = MODBUS_RESPOND_POS_DATA;

para (i=0;i

{

alert_val = msg[offset];

desprazamento++;

}

alerta_do_proceso_de_viña_principal();

}senón se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

desprazamento = MODBUS_RESPOND_POS_DATA;

para (i=0;i

{

valor_humididade_temp = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);

desprazamento += 2;

modbus_write_word(5+i, temp_hum_val);

}

actualización_de_principal_win();

}senón se((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

desprazamento = MODBUS_RESPOND_POS_DATA;

para (i=0;i

{

data_val = SYS_GET_U16(mensaxe[desprazamento], mensaxe[desprazamento+1]);

desprazamento += 2;

}

data_de_display_de_principal_win();

}

}

baleiro main_win_read_temp_hum()

{

u8 dirección_escrava_vella = dirección_ESCRAVO;

        

sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;

modbus_read_words(0, TEMP_HUM_VAL_MAX_NUM);

sys_params.user_config[5] = dirección_escrava_antiga;//Reverter

}

baleiro controlador_de_viñas_principais()

{

indicador u8 estático = 0;

se(é_principal_gaña)

{

se (período_de_lectura_de_alerta==PERÍODO_DE_LECTURA_DE_ALERTA)

{

período_de_lectura_de_alerta = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

retorno;

}

se (período_de_actualización_da_data==PERÍODO_DE_ACTUALIZACIÓN_DA_DATA)

{

período_de_actualización_da_data = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

retorno;

}

bandeira = !bandeira;

se (bandeira)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

outra cousa

main_win_read_temp_hum();

}

}

referencia do código Modbus RTU:

#incluír "modbus.h"

#incluír "crc16.h"

#incluír "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

#incluír UART_INCLUDE

bit estático is_modbus_recv_complete = 0;

estático u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;//Lonxitude total dos bytes aceptados

static u8 modbus_recv_timeout = 0;//Aceptar o tempo de desbordamento

estático volátil u16 modbus_send_interval = 0;

Paquete MODBUS_PACKET;

baleiro modbus_init()

{

UART_INICIO(UART_BAUD);

}

baleiro modbus_send_bytes(u8 *bytes,u16 lonxitude)

{

UART_SEND_BYTES(bytes,len);

}

baleiro modbus_recv_byte(u8 byte)

{

se (está_recibida_de_modbus_completa)

retorno;

se (longitude_recepcion_modbus

modbus_recv_buff[modbus_recv_len++] = byte;

}

tempo_de_espera_de_modbus_check_recv() baleiro

{

se (tempo_de_espera_recepción_modbus)

{

tempo_espera_recepción_modbus--;

se (tempo_de_espera_recepción_modbus==0)

{

is_modbus_recv_complete = 1;

}

}

}

u8 modbus_send_packet(u8 *paquete)

{

só sub-16;

CRC sub-16;

u8 código_función = paquete[1];

mentres(intervalo_envío_modbus);

se (código_función==CÓDIGO_FUNCIÓN_MODBUS_10)

{

((MODBUS_10_PACKET*)paquete)->número_de_bytes = ((MODBUS_10_PACKET*)paquete)->número_de_palabras*2;

len = 9+((MODBUS_10_PACKET*)paquete)->número_de_bytes;

}senón se(código_función==CODIGO_FUNCIÓN_MODBUS_0F)

{

len = ((MODBUS_0F_PACKET*)paquete)->número_de_bits;

((MODBUS_0F_PACKET*)paquete)->número_de_bytes = len/8+(len%8?1:0);

len = 9+((MODBUS_0F_PACKET*)paquete)->número_de_bytes;

}senón

{

lonxitude = tamaño de(PAQUETE_MODBUS);

}

crc = crc16(paquete,len-2);

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

paquete[len-1] = (u8)crc;

modbus_send_bytes(paquete,len);

intervalo_envío_modbus = INTERVALO_ENVÍO_MODBUS;

devolver 0; //Éxito

}

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

baleiro modbus_handler()

{

CRC sub-16;

se (!é_recepción_de_modbus_completa)

retorno;

//Comprobar o valor do CRC

crc = ((u16)buff_recepción_modbus[len_recepción_modbus-2]

se(crc16(buff_recepción_modbus,lenda_recepción_modbus-2)==crc)

{

manexador_msg_modbus(buff_recepción_modbus,lenda_recepción_modbus);

}

modbus_recv_len = 0;

is_modbus_recv_complete = 0;

}

código_f de envío_modbus_u8(código_f u8, enderezo_u16, lonxitude_u16)

{

paquete.dirección_escrava = ENDEREZO_ESCRAVO;

paquete.func_code = fcode;//Código da función

paquete.addr_inicial = addr;//Enderezo

paquete.len_datos = len;//Valor escrito

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

devolver lonxitude;

}


Data de publicación: 12 de xaneiro de 2024