[Open Source]Intelligent Training Room

——From DWIN Developer Forum

In this issue, we introduce to you the award-winning open source case of the DWIN Developer Forum - the smart cultivation room. Engineers implemented the T5L smart screen to control heating and fan temperature control functions through the Modbus protocol. The power supply can also be adjusted to simulate the lighting function. The system can automatically run according to the parameters set on the screen and save fault history records.

1.UI Material Display

asvdfb (2)
asvdfb (1)

2.UI Design

asvdfb (3)

1.C51 Design

The main codes for acquiring and updating data such as temperature, humidity, and altitude on the main interface, and using modbus rtu to control temperature control modules, motors, alarm detection, and other slave machines are as follows

Main interface code reference:

#include "main_win.h"

#include "modbus.h"

#include "sys_params.h"

#include "func_handler.h"

#include "uart2.h"

#include <stdio.h>

#include <string.h>

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

}ALERT;

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

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;

for(i=0;i<ALERT_BIT_MAX_NUM;i++)

{

if(GET_ALERT_BIT(old_alert_val, i))

continue;

if(GET_ALERT_BIT(alert_val, i))

{

if(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()

{

u16 i;

u16 val;

u16 len = 0;

common_buf[0] = 0;

for(i=0;i<ALERT_TABLE_LEN;i++)

{

val = 0;

if(i<alert_num)

{

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

for(i=0;i<MAIN_WIN_VAL_MAX_NUM;i++)

{

if(i==0)

continue;

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)

{

u8 index;

if(btn_val==0x0B)

{

main_win_disp_alert();

return;

}

index = btn_val-1;

btn_sta[index] = !btn_sta[index];

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

u8 offset;

msg_len = msg_len;

if(!is_main_win)

return;

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

{

offset = MODBUS_RESPOND_POS_DATA;

for(i=0;i<MAIN_WIN_VAL_MAX_NUM;i++)

{

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

offset += 2;

}

main_win_update();

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

{

offset = MODBUS_RESPOND_POS_DATA;

for(i=0;i<ALERT_BYTE_NUM;i++)

{

alert_val = msg[offset];

offset++;

}

main_win_process_alert();

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

{

offset = MODBUS_RESPOND_POS_DATA;

for(i=0;i<TEMP_HUM_VAL_MAX_NUM;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();

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

{

offset = MODBUS_RESPOND_POS_DATA;

for(i=0;i<MAIN_WIN_DATE_MAX_NUM;i++)

{

date_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;//Revert

}

void main_win_handler()

{

static u8 flag = 0;

if(is_main_win)

{

if(alert_read_period==ALERT_READ_PERIOD)

{

alert_read_period = 0;

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

return;

}

if(date_update_period==DATE_UPDATE_PERIOD)

{

date_update_period = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

return;

}

flag = !flag;

if(flag)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

else

main_win_read_temp_hum();

}

}

modbus rtu code reference:

#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

static bit is_modbus_recv_complete = 0;

static u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;//Total length of bytes accepted

static u8 modbus_recv_timeout = 0;//Accept overflow time

static volatile u16 modbus_send_interval = 0;

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

{

if(is_modbus_recv_complete)

return;

if(modbus_recv_len<sizeof(modbus_recv_buff))

modbus_recv_buff[modbus_recv_len++] = byte;

}

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

{

u16 len;

u16 crc;

u8 func_code = packet[1];

while(modbus_send_interval);

if(func_code==MODBUS_FUNC_CODE_10)

{

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

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

}else if(func_code==MODBUS_FUNC_CODE_0F)

{

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

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

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

}else

{

len = sizeof(MODBUS_PACKET);

}

crc = crc16(packet,len-2);

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

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

modbus_send_bytes(packet,len);

modbus_send_interval = MODBUS_SEND_INTERVAL;

return 0;//Success

}

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

void modbus_handler()

{

u16 crc;

if(!is_modbus_recv_complete)

return;

//Check crc value

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;//Function code

packet.start_addr = addr;//Address

packet.data_len = len;//Value written

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

return len;

}


Post time: Jan-12-2024