[Odprta koda] Inteligentna vadbena soba

——Iz foruma razvijalcev DWIN

V tej številki vam predstavljamo nagrajeni odprtokodni primer foruma za razvijalce DWIN - pametno sobo za gojenje.Inženirji so uvedli pametni zaslon T5L za nadzor funkcij ogrevanja in temperature ventilatorja prek protokola Modbus.Napajanje je mogoče prilagoditi tudi za simulacijo funkcije osvetlitve.Sistem lahko samodejno deluje v skladu s parametri, nastavljenimi na zaslonu, in shranjuje zapise zgodovine napak.

1.UI Material Display

asvdfb (2)
asvdfb (1)

2. Oblikovanje uporabniškega vmesnika

asvdfb (3)

1.C51 Oblikovanje

Glavne kode za pridobivanje in posodabljanje podatkov, kot so temperatura, vlažnost in nadmorska višina, na glavnem vmesniku ter uporabo modbus rtu za nadzor modulov za nadzor temperature, motorjev, zaznavanja alarmov in drugih podrejenih strojev so naslednje

Referenca kode glavnega vmesnika:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.h"

#vključi

#vključi

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

u8 desc;

}OPOZORILO;

#define ALERT_TABLE_LEN 20

statični u8 btn_sta[MAIN_WIN_BTN_MAX_NUM] = {0};

statični 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 tabela_opozoril [ALERT_TABLE_LEN];

u16 alert_num = 0;

bit is_main_win = 0;

void main_win_update()

{

}

void main_win_disp_date()

{

u8 len;

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

skupni_buf[len+1] = 0;

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

}

void main_win_process_alert()

{

u8 i;

za(i=0;i

{

if(GET_ALERT_BIT(old_alert_val, i))

nadaljevati;

if(GET_ALERT_BIT(alert_val, i))

{

if(alert_num>=ALERT_TABLE_LEN)

alert_num = ALERT_TABLE_LEN-1;

opozorilna_tabela[opozorilna_številka].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()

{

u16 i;

u16 val;

u16 len = 0;

skupni_buf[0] = 0;

za(i=0;i

{

val = 0;

če jaz

{

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

}

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

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

za(i=0;i

{

če(i==0)

nadaljevati;

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)

{

indeks u8;

če(btn_val==0x0B)

{

main_win_disp_alert();

vrnitev;

}

indeks = btn_val-1;

btn_sta[indeks] = !btn_sta[indeks];

če((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);

če(indeks==9)

is_main_win = 0;

sicer če((indeks==3)||(indeks==7))

{

medtem ko(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 odmik;

msg_len = msg_len;

if(!is_main_win)

vrnitev;

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

{

odmik = MODBUS_RESPOND_POS_DATA;

za(i=0;i

{

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

odmik += 2;

}

main_win_update();

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

{

odmik = MODBUS_RESPOND_POS_DATA;

za(i=0;i

{

alert_val = sporočilo[odmik];

odmik++;

}

main_win_process_alert();

}drugače če((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

odmik = MODBUS_RESPOND_POS_DATA;

za(i=0;i

{

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

odmik += 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))

{

odmik = MODBUS_RESPOND_POS_DATA;

za(i=0;i

{

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

odmik += 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;//Povrni

}

void main_win_handler()

{

statična zastavica u8 = 0;

če(je_glavna_zmaga)

{

if(alert_read_period==ALERT_READ_PERIOD)

{

alert_read_period = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

vrnitev;

}

if(date_update_period==DATE_UPDATE_PERIOD)

{

datumsko_obdobje_posodobitve = 0;

modbus_read_words (180, MAIN_WIN_DATE_MAX_NUM);

vrnitev;

}

zastava = !zastava;

če (zastavica)

modbus_read_words (0, MAIN_WIN_VAL_MAX_NUM);

drugače

main_win_read_temp_hum();

}

}

referenca kode 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

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

#define MODBUS_SEND_INTERVAL 150

#vključi UART_INCLUDE

statični bit is_modbus_recv_complete = 0;

statični u8 modbus_recv_buff[270];

statični u16 modbus_recv_len = 0;//Skupna dolžina sprejetih bajtov

statični u8 modbus_recv_timeout = 0;//Sprejmi čas prekoračitve

statični volatilni u16 modbus_send_interval = 0;

paket MODBUS_PACKET;

void modbus_init()

{

UART_INIT(UART_BAUD);

}

void modbus_send_bytes(u8 *bajti,u16 len)

{

UART_SEND_BYTES(bajti,len);

}

void modbus_recv_byte (u8 bajt)

{

if(is_modbus_recv_complete)

vrnitev;

če(modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = bajt;

}

void modbus_check_recv_timeout()

{

if(modbus_recv_timeout)

{

modbus_recv_timeout--;

če(modbus_recv_timeout==0)

{

is_modbus_recv_complete = 1;

}

}

}

u8 modbus_send_packet(u8 *paket)

{

u16 len;

u16 crc;

u8 koda_funkcije = paket[1];

medtem ko(modbus_send_interval);

if(func_code==MODBUS_FUNC_CODE_10)

{

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

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

}drugače če(func_code==MODBUS_FUNC_CODE_0F)

{

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

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

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

}drugo

{

len = sizeof(MODBUS_PAKET);

}

crc = crc16(paket,len-2);

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

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

modbus_send_bytes(paket,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

vrni 0;//Uspeh

}

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

void modbus_handler()

{

u16 crc;

if(!is_modbus_recv_complete)

vrnitev;

//Preveri vrednost crc

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 = fcode;//Koda funkcije

packet.start_addr = addr;//Naslov

packet.data_len = len;//Zapisana vrednost

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

povratna len;

}


Čas objave: 12. januarja 2024