[Open Source]Sală de instruire inteligentă

——De la DWIN Developer Forum

În acest număr, vă prezentăm cazul premiat open source al Forumului pentru dezvoltatori DWIN - camera de cultivare inteligentă.Inginerii au implementat ecranul inteligent T5L pentru a controla funcțiile de încălzire și de control al temperaturii ventilatorului prin protocolul Modbus.Sursa de alimentare poate fi, de asemenea, ajustată pentru a simula funcția de iluminare.Sistemul poate rula automat în funcție de parametrii setați pe ecran și poate salva înregistrările istoricului defecțiunilor.

1.Afișaj material UI

asvdfb (2)
asvdfb (1)

2.UI Design

asvdfb (3)

1.C51 Design

Codurile principale pentru achiziționarea și actualizarea datelor precum temperatura, umiditatea și altitudinea pe interfața principală și utilizarea modbus rtu pentru a controla modulele de control al temperaturii, motoarele, detectarea alarmei și alte mașini slave sunt următoarele

Referința codului interfeței principale:

#include „main_win.h”

#include „modbus.h”

#include „sys_params.h”

#include „func_handler.h”

#include „uart2.h”

#include

#include

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

data char[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 data_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()

{

u8 len;

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;

pentru(i=0;i

{

if(GET_ALERT_BIT(old_alert_val, i))

continua;

if(GET_ALERT_BIT(alert_val, i))

{

if(alert_num>=ALERT_TABLE_LEN)

alert_num = ALERT_TABLE_LEN-1;

tabel_alerte[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()

{

u16 i;

u16 val;

u16 len = 0;

common_buf[0] = 0;

pentru(i=0;i

{

val = 0;

dacă eu

{

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

pentru(i=0;i

{

dacă(i==0)

continua;

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)

{

indicele u8;

if(btn_val==0x0B)

{

main_win_disp_alert();

întoarcere;

}

index = btn_val-1;

btn_sta[index] = !btn_sta[index];

dacă((index==3)||(index==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);

if(index==9)

is_main_win = 0;

else if((index==3)||(index==7))

{

while(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;

offset u8;

msg_len = msg_len;

dacă(!este_principal_win)

întoarcere;

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

{

offset = MODBUS_RESPOND_POS_DATA;

pentru(i=0;i

{

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

offset += 2;

}

main_win_update();

}altfel dacă((f_code==MODBUS_FUNC_CODE_01)&&(data_len==ALERT_BYTE_NUM))

{

offset = MODBUS_RESPOND_POS_DATA;

pentru(i=0;i

{

alert_val = msg[offset];

offset++;

}

main_win_process_alert();

}altfel dacă((f_code==MODBUS_FUNC_CODE_03)&&(data_len==TEMP_HUM_VAL_MAX_NUM*2))

{

offset = MODBUS_RESPOND_POS_DATA;

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

}altfel dacă((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_DATE_MAX_NUM*2))

{

offset = MODBUS_RESPOND_POS_DATA;

pentru(i=0;i

{

data_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;//Return

}

void main_win_handler()

{

flag static u8 = 0;

if(is_main_win)

{

if(alert_read_period==ALERT_READ_PERIOD)

{

alert_read_period = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

întoarcere;

}

if(data_update_period==DATE_UPDATE_PERIOD)

{

data_update_period = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

întoarcere;

}

steag = !steagul;

dacă (steagul)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

altfel

main_win_read_temp_hum();

}

}

Referința codului 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

#include UART_INCLUDE

bit static is_modbus_recv_complete = 0;

static u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;//Lungimea totală a octeților acceptați

static u8 modbus_recv_timeout = 0;//Acceptă timpul de depășire

static volatil u16 modbus_send_interval = 0;

pachet MODBUS_PACKET;

void modbus_init()

{

UART_INIT(UART_BAUD);

}

void modbus_send_bytes(u8 *bytes,u16 len)

{

UART_SEND_BYTES(octeți,len);

}

void modbus_recv_byte(u8 octet)

{

if(este_modbus_recv_complete)

întoarcere;

if(modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = octet;

}

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

{

u16 len;

u16 crc;

u8 func_code = pachet[1];

while(modbus_send_interval);

if(func_code==MODBUS_FUNC_CODE_10)

{

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

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

}altfel dacă(func_code==MODBUS_FUNC_CODE_0F)

{

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

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

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

}altfel

{

len = sizeof(MODBUS_PACKET);

}

crc = crc16(pachet,len-2);

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

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

modbus_send_bytes(pachet,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

returnează 0;//Succes

}

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

void modbus_handler()

{

u16 crc;

if(!is_modbus_recv_complete)

întoarcere;

//Verificați valoarea 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;//Cod funcție

packet.start_addr = adresa;//Adresa

packet.data_len = len;//Valoare scrisă

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

return len;

}


Ora postării: 12-ian-2024