[مفتوح المصدر] غرفة تدريب ذكية

——من منتدى مطوري DWIN

في هذا العدد، نقدم لك حالة مفتوحة المصدر حائزة على جوائز لمنتدى مطوري DWIN - غرفة الزراعة الذكية.قام المهندسون بتنفيذ شاشة T5L الذكية للتحكم في وظائف التدفئة والتحكم في درجة حرارة المروحة من خلال بروتوكول Modbus.يمكن أيضًا تعديل مصدر الطاقة لمحاكاة وظيفة الإضاءة.يمكن تشغيل النظام تلقائيًا وفقًا للمعايير المحددة على الشاشة وحفظ سجلات محفوظات الأخطاء.

1.عرض مواد واجهة المستخدم

اسفدفب (2)
اسفدفب (1)

2. تصميم واجهة المستخدم

اسفدفب (3)

1.C51 التصميم

فيما يلي الرموز الرئيسية للحصول على البيانات وتحديثها مثل درجة الحرارة والرطوبة والارتفاع على الواجهة الرئيسية، واستخدام modbus rtu للتحكم في وحدات التحكم في درجة الحرارة والمحركات واكتشاف الإنذارات والآلات التابعة الأخرى

مرجع رمز الواجهة الرئيسية:

#تتضمن "main_win.h"

#تشمل "modbus.h"

#تتضمن "sys_params.h"

#تتضمن "func_handler.h"

#تشمل "uart2.h"

#يشمل

#يشمل

#تعريف TEMP_HUM_SLAVE_ADDR 2

#حدد TEMP_HUM_VAL_MAX_NUM 2

#حدد ALERT_BIT_MAX_NUM 30

#تعريف 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 {

تاريخ الحرف[17]؛

u8 تنازلي؛

}يُحذًِر؛

#تعريف ALERT_TABLE_LEN 20

ثابت 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_BYTE_NUM] = {0};

u8 old_alert_val[ALERT_BYTE_NUM] = {0};

تنبيه تنبيه_الجدول[ALERT_TABLE_LEN]؛

u16alert_num = 0;

البت is_main_win = 0؛

باطلة main_win_update()

{

}

باطلة main_win_disp_date()

{

u8 لين؛

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

}

باطلة main_win_process_alert ()

{

u8 ط؛

ل(i=0;i

{

إذا (GET_ALERT_BIT(old_alert_val, i))

يكمل؛

إذا (GET_ALERT_BIT (alert_val، i))

{

إذا (alert_num>=ALERT_TABLE_LEN)

تنبيه_رقم = ALERT_TABLE_LEN-1؛

تنبيه_الجدول[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]

);

تنبيه_رقم++;

}

}

memcpy(old_alert_val,alert_val,sizeof(alert_val));

}

باطلة main_win_disp_alert ()

{

u16 ط؛

u16 فال؛

u16 لين = 0;

common_buf[0] = 0;

ل(i=0;i

{

فال = 0؛

اذا انا

{

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

}

باطلة main_win_init ()

{

تعويم ثابت_فال؛

u8 ط؛

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

ل(i=0;i

{

إذا (ط == 0)

يكمل؛

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

}

باطلة main_win_click_handler (u16 btn_val)

{

مؤشر u8؛

إذا (btn_val==0x0B)

{

main_win_disp_alert();

يعود؛

}

الفهرس = btn_val-1؛

btn_sta[index] = !btn_sta[index];

إذا((الفهرس==3)||(الفهرس==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);

إذا (الفهرس == 9)

is_main_win = 0;

وإلا إذا ((الفهرس==3)||(الفهرس==7))

{

while(sys_get_touch_sta());

modbus_write_bit(btn_addr[index], 0x0000);

}

}

باطلة 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 ط؛

إزاحة u8؛

msg_len = msg_len;

إذا (!is_main_win)

يعود؛

إذا ((f_code==MODBUS_FUNC_CODE_03)&&(data_len==MAIN_WIN_VAL_MAX_NUM*2))

{

إزاحة = MODBUS_RESPOND_POS_DATA؛

ل(i=0;i

{

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

إزاحة += 2;

}

main_win_update();

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

{

إزاحة = MODBUS_RESPOND_POS_DATA؛

ل(i=0;i

{

Alert_val = msg[offset];

إزاحة++;

}

main_win_process_alert();

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

{

إزاحة = MODBUS_RESPOND_POS_DATA؛

ل(i=0;i

{

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

إزاحة += 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))

{

إزاحة = MODBUS_RESPOND_POS_DATA؛

ل(i=0;i

{

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

إزاحة += 2;

}

main_win_disp_date();

}

}

باطلة 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

}

باطلة main_win_handler ()

{

علامة u8 ثابتة = 0؛

إذا (is_main_win)

{

إذا (alert_read_period==ALERT_READ_PERIOD)

{

تنبيه_قراءة_فترة = 0؛

modbus_read_bits(510, ALERT_BIT_MAX_NUM);

يعود؛

}

إذا (date_update_period==DATE_UPDATE_PERIOD)

{

date_update_period = 0;

modbus_read_words(180, MAIN_WIN_DATE_MAX_NUM);

يعود؛

}

علم =!علم;

إذا (العلم)

modbus_read_words(0, MAIN_WIN_VAL_MAX_NUM);

آخر

main_win_read_temp_hum();

}

}

مرجع كود modbus rtu:

#تشمل "modbus.h"

#تشمل "crc16.h"

#تتضمن "sys_params.h"

#define UART_INCLUDE "uart2.h"

#define UART_INIT uart2_init

#define UART_SEND_BYTES uart2_send_bytes

#تعريف UART_BAUD 9600

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

#تعريف MODBUS_SEND_INTERVAL 150

#تتضمن UART_INCLUDE

البت الثابت is_modbus_recv_complete = 0;

ثابت u8 modbus_recv_buff[270];

static u16 modbus_recv_len = 0;// إجمالي طول البايتات المقبولة

static u8 modbus_recv_timeout = 0;// قبول وقت الفائض

ثابت u16 modbus_send_interval = 0;

حزمة MODBUS_PACKET؛

modbus_init () باطلة

{

UART_INIT(UART_BAUD);

}

modbus_send_bytes باطلة (u8 * بايت، u16 لين)

{

UART_SEND_BYTES(بايت,لين);

}

باطلة modbus_recv_byte (u8 بايت)

{

إذا (is_modbus_recv_Complete)

يعود؛

إذا (modbus_recv_len

modbus_recv_buff[modbus_recv_len++] = بايت;

}

باطلة modbus_check_recv_timeout ()

{

إذا (modbus_recv_timeout)

{

modbus_recv_timeout--;

إذا (modbus_recv_timeout==0)

{

is_modbus_recv_complete = 1;

}

}

}

u8 modbus_send_packet(u8 *حزمة)

{

u16 لين؛

u16 اتفاقية حقوق الطفل;

u8 func_code = packet[1];

بينما (modbus_send_interval)؛

إذا (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;

}آخر

{

len = sizeof(MODBUS_PACKET);

}

اتفاقية حقوق الطفل = 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;

إرجاع 0;//Success

}

الفراغ الخارجي modbus_msg_handler(u8 *msg,u16 msg_len);

باطلة modbus_handler ()

{

u16 اتفاقية حقوق الطفل;

إذا (!is_modbus_recv_Complete)

يعود؛

//تحقق من قيمة اتفاقية حقوق الطفل

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

إذا (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;//رمز الوظيفة

packet.start_addr = addr;//Address

packet.data_len = len;// القيمة المكتوبة

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

عودة لين؛

}


وقت النشر: 12 يناير 2024