[Malferma Fonto]Inteligenta Trejnejo

——El Forumo pri Programistoj de DWIN

En ĉi tiu numero, ni prezentas al vi la premiitan malfermfontan kazon de la Forumo por Programistoj DWIN - la inteligenta kultivadĉambro.Inĝenieroj efektivigis la inteligentan ekranon T5L por kontroli funkciojn de hejtado kaj ventumila temperaturkontrolo per la Modbus-protokolo.La nutrado ankaŭ povas esti ĝustigita por simuli la lumfunkcion.La sistemo povas aŭtomate funkcii laŭ la parametroj fiksitaj sur la ekrano kaj konservi mishistoriajn rekordojn.

1.UI Materiala Ekrano

asvdfb (2)
asvdfb (1)

2.UI-Dezajno

asvdfb (3)

1.C51 Dezajno

La ĉefaj kodoj por akiri kaj ĝisdatigi datumojn kiel temperaturo, humideco kaj alteco sur la ĉefa interfaco, kaj uzi modbus rtu por kontroli temperaturkontrolajn modulojn, motorojn, alarm-detekton kaj aliajn sklavajn maŝinojn estas jenaj.

Referenco pri ĉefa interfaco:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.h"

#inkluzivi

#inkluzivi

#difini TEMP_HUM_SLAVE_ADDR 2

#difini TEMP_HUM_VAL_MAX_NUM 2

#difini ALERT_BIT_MAX_NUM 30

#difini ALERT_BYTE_NUM (ALERT_BIT_MAX_NUM/8+((ALERT_BIT_MAX_NUM%8)!=0))

#difini GET_ALERT_BIT(val, pos) ((val[pos/8]>>(pos%8))&0x01)

typedef struktur {

char dato[17];

u8 desc;

}ALERTO;

#define ALERT_TABLE_LEN 20

statika u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

statika 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 dato_val[MAIN_WIN_DATE_MAX_NUM] = {0};

u8 alert_val[ALERT_BYTE_NUM] = {0};

u8 old_alert_val[ALERT_BYTE_NUM] = {0};

ALERT tabelo_alerta[ALERT_TABLE_LEN];

u16 alert_num = 0;

bito is_main_win = 0;

malplena ĉefa_gajno_ĝisdatigo ()

{

}

malplena ĉefa_gajno_disp_dato ()

{

u8 len;

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

komuna_buf[len+1] = 0;

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

}

malplenigi ĉefa_gajno_procezo_alert()

{

u8 i;

por(i=0;i

{

if(GET_ALERT_BIT(malnova_alerta_val, i))

daŭrigi;

if(GET_ALERT_BIT(alerto_val, i))

{

if(alerta_num>=ALERT_TABLE_LEN)

alert_num = ALERT_TABLE_LEN-1;

atentiga_tabelo[alerto_num].desc = i+1;

sprintf(alerta_tablo[alerta_num].dato, "%u/%u/%u %u:%u",

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

);

alarm_num++;

}

}

memcpy(malnova_alerta_val, alert_val, sizeof(alerta_val));

}

void main_win_disp_alert ()

{

u16 i;

u16 val;

u16 len = 0;

komuna_buf[0] = 0;

por(i=0;i

{

val = 0;

se mi

{

val = alert_table.desc;

len += sprintf(komuna_buf+len, "%s\r\n", alert_table.date);

}

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

}

komuna_buf[len+1] = 0;

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

}

void main_win_init ()

{

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

por(i=0;i

{

se (i==0)

daŭrigi;

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

}

fiksita_val = ĉefa_gajno_val[0]/VENTO_SPEED_SCALE+FLOAT_FIX_VAL;

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

}

malplenigi main_win_click_handler (u16 btn_val)

{

u8 indekso;

se (btn_val==0x0B)

{

ĉefa_win_disp_alert();

reveni;

}

indekso = btn_val-1;

btn_sta[indekso] = !btn_sta[indekso];

se((indekso==3)||(indekso==7))

btn_sta[indekso] = 1;

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

btn_val = btn_sta[indekso];

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

se(indekso==9)

is_main_win = 0;

alie se((indekso==3)||(indekso==7))

{

dum(sys_get_touch_sta());

modbus_write_bit (btn_addr[indekso], 0x0000);

}

}

void main_win_msg_handler (u8 *msg,u16 msg_len)

{

u8 f_kodo = msg[MODBUS_RESPOND_POS_FUNC_CODE];

u8 data_len = msg[MODBUS_RESPOND_POS_DATA_LEN];

u8 i;

u8 ofseto;

msg_len = msg_len;

se(!estas_ĉefa_venko)

reveni;

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

{

ofseto = MODBUS_RESPOND_POS_DATA;

por(i=0;i

{

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

ofseto += 2;

}

ĉefa_gajno_ĝisdatigo();

}else if((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

ofseto = MODBUS_RESPOND_POS_DATA;

por(i=0;i

{

alert_val = msg[offset];

ofseto++;

}

ĉefa_gajna_procezo_alerto();

}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

ofseto = MODBUS_RESPOND_POS_DATA;

por(i=0;i

{

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

ofseto += 2;

modbus_skribi_vorton(5+i, temp_hum_val);

}

ĉefa_gajno_ĝisdatigo();

}else if((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

ofseto = MODBUS_RESPOND_POS_DATA;

por(i=0;i

{

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

ofseto += 2;

}

ĉefa_gajno_disp_dato();

}

}

void main_win_read_temp_hum ()

{

u8 old_slave_addr = SLAVE_ADDR;

        

sys_params.user_config[5] = TEMP_HUM_SLAVE_ADDR;

modbus_legeblaj_vortoj (0, TEMP_HUM_VAL_MAX_NUM);

sys_params.user_config[5] = old_slave_addr;//Reverti

}

malplenigi ĉefa_gajna_traktilo ()

{

statika u8 flago = 0;

se (estas_ĉefa_venki)

{

if(alerta_lega_periodo==ALERT_READ_PERIODO)

{

atentiga_legita_periodo = 0;

modbus_read_bits (510, ALERT_BIT_MAX_NUM);

reveni;

}

if(dato_ĝisdatiga_periodo==DATO_ĝisdatigita_PERIODO)

{

dato_ĝisdatigo_periodo = 0;

modbus_read_words (180, MAIN_WIN_DATE_MAX_NUM);

reveni;

}

flago = !flago;

se (flago)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

alie

ĉefa_gajno_legi_temp_hum ();

}

}

Referenco de kodo 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

#define UART_BAUD 9600

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

#define MODBUS_SEND_INTERVAL 150

#include UART_INCLUDE

statika bito is_modbus_recv_complete = 0;

statika u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;//Suma longo de bajtoj akceptitaj

static u8 modbus_recv_timeout = 0;//Akceptu superfluan tempon

statika volatila u16 modbus_send_interval = 0;

MODBUS_PACKET pako;

malplena modbus_init()

{

UART_INIT(UART_BAUD);

}

malplena modbus_send_bytes (u8 *bajtoj, u16 len)

{

UART_SEND_BYTES(bajtoj,len);

}

malplena modbus_recv_bajto (u8 bajto)

{

if(estas_modbus_recv_kompleta)

reveni;

if(modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = bajto;

}

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 *pako)

{

u16 len;

u16 crc;

u8 func_code = pako[1];

dum(modbus_send_intervalo);

if(func_code==MODBUS_FUNC_CODE_10)

{

((MODBUS_10_PACKET*)pako)->bajto_num = ((MODBUS_10_PACKET*)pako)->vorto_num*2;

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

}else if(func_code==MODBUS_FUNC_CODE_0F)

{

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

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

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

}alie

{

len = grandeco de (MODBUS_PACKET);

}

crc = crc16(pako,len-2);

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

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

modbus_send_bytes(pako,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

redonu 0;//Sukceso

}

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

malplena modbus_handler ()

{

u16 crc;

se(!estas_modbus_recv_kompleta)

reveni;

//Kontrolu crc-valoron

crc = ((u16)modbus_recv_buff[modbus_recv_len-2]<<8)+modbus_recv_buff[modbus_recv_len-1];

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

{

packet.slave_addr = SLAVE_ADDR;

packet.func_code = fkodo;//Funkcia kodo

packet.start_addr = addr;//Adreso

packet.data_len = len;//Valoro skribita

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

return len;

}


Afiŝtempo: Jan-12-2024