اگر که توی حوزه IOT کار میکنید یا حداقل یه بار از کنارش رد شده باشید به احتمال زیاد اسم MQTT به گوشتون خورده ، پروتکلی تحت شبکه که خوراک بحث اینترنت اشیا هست و این روزها همه دارند به سمتش میرند. توی این آموزش مختصری این پروتکل رو توضیح داده و سپس سراغ پیاده سازی یک پروژه به کمک اون میریم ، پس با سیسوگ همراه باشید.
شاید برای شما مفید باشد: پروژه الکترونیک با میکروکنترلر های مختلف و آموزش 0 تا 100 راه اندازی پروژه
MQTT چگونه کار میکند ؟!
نمیدونم چرا تا قبل از نوشتن این مطلب MQTT برام خیلی ترسناک بود و فکر میکردم خیلی سخته (البته سراغشم نرفته بودم) ! برای همین سعی میکنم خیلی ساده توضیح بدم تا برای همه قابل فهم باشه .
به تصویر بالا نگاه کنید نقطه شروع ما دماسنج سمت چپ هست ، این دماسنج یک کلاینت mqtt هست که به صورت publisher عمل میکنه ، یعنی دیتا ارسال میکنه ، به سروری که به اون broker میگیم. حالا دماسنج اطلاعات رو به آدرس خاصی در بروکر ارسال میکنه ، میتونیم اون آدرس رو مثل یک کانال تلگرامی درنظر بگیریم ، حالا کلاینت هایی که میخواند دیتا رو دریافت کنند ، توی این کانال (به آدرسی که در اون ، اطلاعات ارسال میشه) عضو میشند و هر موقع که یک دیتای جدید اومد متوجه میشند ، این دریافت دیتا رو کتابخونه ای که شما استفاده میکنید نحوه کارش رو مشخص میکنه ، مثلا به شما یک تابع میده که هرموقع دیتا اومد اون تابع فراخوانی میشه. هر کلاینت میتونه هم به عنوان publisher و هم subscriber (دریافت کننده اطلاعات) عمل کنه.
برای یادگیری و اطلاعات بیشتر در رابطه با mqtt توصیه میکنم که این مطلب رو بررسی کنید:
حالا بریم سراغ پروژه خودمون! ما میخوایم از یک ماژول mc60 به عنوان mqtt client استفاده کنیم و هم دیتا ارسال کنیم به سرور و هم دریافت کنیم (publisherوsubscriber). این کار رو هم میخوایم به صورت open cpu انجام بدیم نه با at command. بعد از اون هم داشبوردی که به کمک پلتفرم thingsboard طراحی میکنیم و دیتاهای دریافتی رو توی اون نمایش میدیم.
این هم از کد برنامه:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | #define __CUSTOMER_CODE__ #ifdef __CUSTOMER_CODE__ #include "custom_feature_def.h" #include "ql_stdlib.h" #include "ql_common.h" #include "ql_system.h" #include "ql_type.h" #include "ql_trace.h" #include "ql_error.h" #include "ql_uart.h" #include "ql_timer.h" #include "ril_network.h" #include "ril_mqtt.h" #include "ril.h" #include "ril_util.h" #include "ril_system.h" #include "ql_iic.h" #include "oled.h" #include "sht20.h" /// MQTT //////////////////////////////////////////////////////////////////////// //define process state typedef enum { STATE_NW_QUERY_STATE, STATE_MQTT_CFG, STATE_MQTT_OPEN, STATE_MQTT_CONN, STATE_MQTT_SUB, STATE_MQTT_PUB, STATE_MQTT_TUNS, STATE_MQTT_CLOSE, STATE_MQTT_DISC, STATE_MQTT_TOTAL_NUM } Enum_ONENETSTATE; static u8 m_mqtt_state = STATE_NW_QUERY_STATE; //timer #define MQTT_TIMER_ID 0x200 #define MQTT_TIMER_PERIOD 500 //param MQTT_Urc_Param_t *mqtt_urc_param_ptr = NULL; ST_MQTT_topic_info_t mqtt_topic_info_t; bool DISC_flag = TRUE; bool CLOSE_flag = TRUE; //connect info Enum_ConnectID connect_id = ConnectID_0; u8 clientID[] = "mc60\0"; u8 username[] = "XXXXXXXXXXXXXXX\0"; u8 passwd[] = "\0"; //topic and data u32 pub_message_id = 0; u32 sub_message_id = 0; static u8 test_data[128] = "{\"temp\":5}\0"; //packet data static u8 pu_topic[128] = "v1/devices/me/telemetry\0"; //Publisher topic static u8 su_topic[128] = "v1/devices/me/attributes\0"; //Subscriber topic //////////////////////////////////////////////////////////////////////////////////// ///for GPRS //////////////////////////////////////////////////////////////// //APN #define APN "CMNET\0" #define USERID "" #define PASSWD "" //SERVER #define HOST_NAME "thingsboard.cloud" #define HOST_PORT 1883 ///////////////////////////////////////////////////////////////////////////// /// DEBUG AND UART /////////////////////////////////////////////////////////////////////////////////////////////////// #define SERIAL_RX_BUFFER_LEN 2048 #define DEBUG_PORT UART_PORT1 #define DBG_BUF_LEN 512 static char DBG_BUFFER[DBG_BUF_LEN]; #define APP_DEBUG(FORMAT, ...) \ { \ Ql_memset(DBG_BUFFER, 0, DBG_BUF_LEN); \ Ql_sprintf(DBG_BUFFER, FORMAT, ##__VA_ARGS__); \ Ql_UART_Write((Enum_SerialPort)(DEBUG_PORT), (u8 *)(DBG_BUFFER), Ql_strlen((const char *)(DBG_BUFFER))); \ } char m_RxBuf_Uart[SERIAL_RX_BUFFER_LEN]; static Enum_SerialPort m_myUartPort = UART_PORT1; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static void CallBack_UART_Hdlr(Enum_SerialPort port, Enum_UARTEventType msg, bool level, void *customizedPara); static void Callback_Timer(u32 timerId, void *param); static void mqtt_recv(u8 *buffer, u32 length); static void message(u8 *data); void proc_subtask1(s32 taskId) { u8 data[100] = ""; u8 temp[100] = ""; u32 step = 0; u32 ret = 0; while (1) { if (m_mqtt_state == STATE_MQTT_TOTAL_NUM) { step++; Ql_sprintf(data, "{\"temp\":%5.2f}\0", readTemperature()); set1X(); setCursor(0, 3); Ql_sprintf(temp, "Tem: %5.2f Hum: %5.2f \0", readTemperature(), readHumidity()); oledPrint(temp); pub_message_id++; // The range is 0-65535. It will be 0 only when<qos>=0. ret = RIL_MQTT_QMTPUB(connect_id, pub_message_id, QOS1_AT_LEASET_ONCE, 0, pu_topic, Ql_strlen(data), data); if (RIL_AT_SUCCESS == ret) { APP_DEBUG("//<Start publish a message to server\r\n"); } else { APP_DEBUG("//<Publish a message to server failure,ret = %d\r\n", ret); } } Ql_Sleep(3000); } } void proc_main_task(s32 taskId) { ST_MSG msg; s32 ret; //<Register & open UART port Ql_UART_Register(m_myUartPort, CallBack_UART_Hdlr, NULL); Ql_UART_Open(m_myUartPort, 115200, FC_NONE); APP_DEBUG("START PROGRAM MQTT Client(SISOOG.COM)\r\n"); //<register state timer Ql_Timer_Register(MQTT_TIMER_ID, Callback_Timer, NULL); //register MQTT recv callback ret = Ql_Mqtt_Recv_Register(mqtt_recv); APP_DEBUG("//<register recv callback,ret = %d\r\n", ret); //init i2c for oled and sht20 Ql_IIC_Init(0, PINNAME_RI, PINNAME_DCD, TRUE); Ql_IIC_Config(0, TRUE, SLAVE_ADDRESS, 300); //init oled display oledInit(); oledClear(); setFont(Adafruit5x7); while (TRUE) { Ql_OS_GetMessage(&msg); switch (msg.message) { case MSG_ID_RIL_READY: APP_DEBUG("//<RIL is ready\r\n"); Ql_RIL_Initialize(); break; case MSG_ID_URC_INDICATION: { switch (msg.param1) { case URC_SIM_CARD_STATE_IND: { APP_DEBUG("//<SIM Card Status:%d\r\n", msg.param2); if (SIM_STAT_READY == msg.param2) { Ql_Timer_Start(MQTT_TIMER_ID, MQTT_TIMER_PERIOD, TRUE); APP_DEBUG("//<state timer start,ret = %d\r\n", ret); } } break; case URC_MQTT_OPEN: { mqtt_urc_param_ptr = msg.param2; if (0 == mqtt_urc_param_ptr->result) { APP_DEBUG("//<Open a MQTT client successfully\r\n"); m_mqtt_state = STATE_MQTT_CONN; } else { APP_DEBUG("//<Open a MQTT client failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; case URC_MQTT_CONN: { mqtt_urc_param_ptr = msg.param2; if (0 == mqtt_urc_param_ptr->result) { APP_DEBUG("//<Connect to MQTT server successfully\r\n"); m_mqtt_state = STATE_MQTT_SUB; } else { APP_DEBUG("//<Connect to MQTT server failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; case URC_MQTT_SUB: { mqtt_urc_param_ptr = msg.param2; if ((0 == mqtt_urc_param_ptr->result) && (128 != mqtt_urc_param_ptr->sub_value[0])) { APP_DEBUG("//<Subscribe topics successfully\r\n"); m_mqtt_state = STATE_MQTT_PUB; } else { APP_DEBUG("//<Subscribe topics failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; case URC_MQTT_PUB: { mqtt_urc_param_ptr = msg.param2; if (0 == mqtt_urc_param_ptr->result) { APP_DEBUG("//<Publish messages to MQTT server successfully\r\n"); m_mqtt_state = STATE_MQTT_TOTAL_NUM; } else { APP_DEBUG("//<Publish messages to MQTT server failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; case URC_MQTT_CLOSE: { mqtt_urc_param_ptr = msg.param2; if (0 == mqtt_urc_param_ptr->result) { APP_DEBUG("//<Closed MQTT socket successfully\r\n"); } else { APP_DEBUG("//<Closed MQTT socket failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; case URC_MQTT_DISC: { mqtt_urc_param_ptr = msg.param2; if (0 == mqtt_urc_param_ptr->result) { APP_DEBUG("//<Disconnect MQTT successfully\r\n"); } else { APP_DEBUG("//<Disconnect MQTT failure,error = %d\r\n", mqtt_urc_param_ptr->result); } } break; default: break; } } break; default: break; } } } static void CallBack_UART_Hdlr(Enum_SerialPort port, Enum_UARTEventType msg, bool level, void *customizedPara) { } static void message(u8 *data) { set2X(); setCursor(10, 0); Ql_sprintf(data, "%s \0", data); oledPrint(data); APP_DEBUG("message: %s\r\n", data); } static void mqtt_recv(u8 *buffer, u32 length) { APP_DEBUG("//<data:%s,len:%d\r\n", buffer, length); u16 sec = 0; for (u32 i = 0; i < 100; i++) { if (buffer[i] == ',') { sec++; if (sec == 4) { u8 data[100] = ""; for (u32 y = 0; y < 100; y++) { data[y] = buffer[i + 10]; i++; if (data[y] == '"') { data[y] = '\0'; message(data); break; break; } } } } } } static void Callback_Timer(u32 timerId, void *param) { s32 ret; if (MQTT_TIMER_ID == timerId) { switch (m_mqtt_state) { case STATE_NW_QUERY_STATE: { s32 cgreg = 0; ret = RIL_NW_GetGPRSState(&cgreg); set2X(); setCursor(10, 0); oledPrint("Net check "); APP_DEBUG("//<Network State:cgreg = %d\r\n", cgreg); if ((cgreg == NW_STAT_REGISTERED) || (cgreg == NW_STAT_REGISTERED_ROAMING)) { //<Set PDP context 0 RIL_NW_SetGPRSContext(0); APP_DEBUG("//<Set PDP context 0 \r\n"); //<Set APN ret = RIL_NW_SetAPN(1, APN, USERID, PASSWD); APP_DEBUG("//<Set APN \r\n"); set2X(); setCursor(10, 0); oledPrint("Set APN "); //PDP activated ret = RIL_NW_OpenPDPContext(); if (ret == RIL_AT_SUCCESS) { set2X(); setCursor(10, 0); oledPrint("Act PDP "); APP_DEBUG("//<Activate PDP context,ret = %d\r\n", ret); m_mqtt_state = STATE_MQTT_CFG; } } break; } case STATE_MQTT_CFG: { RIL_MQTT_QMTCFG_Showrecvlen(connect_id, ShowFlag_1); //<This sentence must be configured. The configuration will definitely succeed, so there is no need to care about. ret = RIL_MQTT_QMTCFG_Version_Select(connect_id, Version_3_1_1); if (RIL_AT_SUCCESS == ret) { APP_DEBUG("//<Select version 3.1.1 successfully\r\n"); m_mqtt_state = STATE_MQTT_OPEN; } else { APP_DEBUG("//<Select version 3.1.1 failure,ret = %d\r\n", ret); } break; } case STATE_MQTT_OPEN: { ret = RIL_MQTT_QMTOPEN(connect_id, HOST_NAME, HOST_PORT); if (RIL_AT_SUCCESS == ret) { set2X(); setCursor(10, 0); oledPrint("open MQTT "); APP_DEBUG("//<Start opening a MQTT client\r\n"); if (FALSE == CLOSE_flag) CLOSE_flag = TRUE; m_mqtt_state = STATE_MQTT_TOTAL_NUM; } else { APP_DEBUG("//<Open a MQTT client failure,ret = %d-->\r\n", ret); } break; } case STATE_MQTT_CONN: { ret = RIL_MQTT_QMTCONN(connect_id, clientID, username, passwd); if (RIL_AT_SUCCESS == ret) { set2X(); setCursor(10, 0); oledPrint("con MQTT "); APP_DEBUG("//<Start connect to MQTT server\r\n"); if (FALSE == DISC_flag) DISC_flag = TRUE; m_mqtt_state = STATE_MQTT_TOTAL_NUM; } else { APP_DEBUG("//<connect to MQTT server failure,ret = %d\r\n", ret); } break; } case STATE_MQTT_SUB: { mqtt_topic_info_t.count = 1; mqtt_topic_info_t.topic[0] = (u8 *)Ql_MEM_Alloc(sizeof(u8) * 256); Ql_memset(mqtt_topic_info_t.topic[0], 0, 256); Ql_memcpy(mqtt_topic_info_t.topic[0], su_topic, Ql_strlen(su_topic)); mqtt_topic_info_t.qos[0] = QOS1_AT_LEASET_ONCE; sub_message_id++; //< 1-65535. ret = RIL_MQTT_QMTSUB(connect_id, sub_message_id, &mqtt_topic_info_t); Ql_MEM_Free(mqtt_topic_info_t.topic[0]); mqtt_topic_info_t.topic[0] = NULL; if (RIL_AT_SUCCESS == ret) { set2X(); setCursor(10, 0); oledPrint("sub MQTT "); APP_DEBUG("//<Start subscribe topic\r\n"); m_mqtt_state = STATE_MQTT_TOTAL_NUM; } else { APP_DEBUG("//<Subscribe topic failure,ret = %d\r\n", ret); } break; } case STATE_MQTT_PUB: { pub_message_id++; //< The range is 0-65535. It will be 0 only when<qos>=0. ret = RIL_MQTT_QMTPUB(connect_id, pub_message_id, QOS1_AT_LEASET_ONCE, 0, pu_topic, Ql_strlen(test_data), test_data); if (RIL_AT_SUCCESS == ret) { APP_DEBUG("//<Start publish a message to MQTT server\r\n"); m_mqtt_state = STATE_MQTT_TOTAL_NUM; } else { APP_DEBUG("//<Publish a message to MQTT server failure,ret = %d\r\n", ret); } break; } case STATE_MQTT_TOTAL_NUM: { break; } default: break; } } } #endif // __CUSTOMER_CODE__ |
همچنین لازمه که یک تسک به نام proc_subtask1
اضافه بشه به برنامه و کتابخانه های sht20 و oled هم به پروژه اضافه بشه.
توضیح کلیات کد
توی کد ما دو تسک اجرا میشه تسک اصلی وظیه راه اندازی بخش های مختلف و oled و … رو داره ، تسک دوم هم در صورتی که به سرور متصل باشیم هر 3 ثانیه دما رو برای سرور ارسال میکنه.
غیر از اون هم یه تایمر داریم که هر 500 میلی ثانیه اجرا میشه و مرحله به مرحله اتصال به سرور و راه اندازی mqtt رو انجام میده.
بعد از اتصال به سرور و subscribe شدن ماژول ، بعد از هر بار دریافت دیتا در تاپیک مورد نظر تابع mqtt_recv
صدا زده میشه ، من توی این تابع کدی نوشتم که بیاد و متن دریافت شده رو برای تابع message
ارسال کنه تا هم روی نمایشگر نشون داده بشه و هم توی سریال چاپ بشه.
HOST_NAME
مشخص کنید و توکنی رو هم که broker به شما میده توی متغیر username قرار بدید.
نکته:
نسخه ای sdk که من برای نوشتن این مطلب ازش استفاده کردم 1.8 هست. برای اینکه به درستی بتونید ازش جواب بگیرید لازم هست که حتما فریمور ماژول رو هم آپدیت کنید. نسخه مناسب این sdk ورژن MC60CAR01A15 هست که میتونید از باکس دانلود در آخر مطلب دریافتش کنید.
حالا بریم سراغ broker
من از thingsboard برای اینکار استفاده کردم که بتونم داشبوردی هم داخلش طراحی کنم و اطلاعات رو اونجا نمایش بدم. برای اینکار لازمه که یه اکانت داخلش بسازید (که رایگان هست) و بعد از اون دستگاه رو داخلش اضافه کرده و داشبورد رو طراحی کنید. این مراحل رو به صورت فیلم آماده کردم که میتونید استفاده کنید:
و این هم از تست ماژول و ارسال و دریافت دیتا
همونطور که در ویدئو بالا مشخص هست من از یک level shfter برای تغییر سطح ولتاژ i2c استفاده کردم تا بشه از oled و سنسور sht20 استفاده کرد.
کتابخونه های sht20 و oled رو هم خودم آماده کردم که میتونید توی فایل پروژه اونها رو هم پیدا کنید.
روند ساخت کتابخانه
روند ساخت این کتابخونه ها هم چندان مشکل نیست و شما میتونید هر ماژول دیگه ای رو حتی با پروتکل های دیگه به کتابخونه های open cpu ماژول اضافه کنید من روندی که برای ساخت این کتابخونه ها طی کردم رو میگم که شاید به درد شما هم بخوره:
- اول از همه یک کتابخونه سبک و کوچیک مرتبط با ماژولی که میخوام ازش استفاده کنم رو توی کتابخونه های آردوینو پیدا میکنم (این یکی از جاهایی هست که آردوینو توی کار حرفه ای کمکتون میکنه)
- بعد کد c++ رو به c تبدیل می کنم (چون معمولا کتابخونه های آردوینو با کمک شی گرایی نوشته شدند).
- حالا توابعی که وابسته به سخت افزار هستند رو تغییر میدم مثلا تابعی که اطلاعات i2c رو ارسال میکنه در آردوینو و mc60 متفاوت هستند ، پس لازمه که اونها دوباره نوشته بشند.
- مرحله آخر هم تست کتابخونه هست. من برای اینکار یکبار از آردوینو استفاده میکنم و با ماژول ارتباط میگیرم و با لاجیک آنالایزر پکت ها رو بررسی میکنم ، بعد از اون کتابخونه ای که خودم نوشتم رو اجرا کرده و همین تست رو تکرار میکنم و کد رو ویرایش میکنم (بعضا هم نیاز به کمک گرفتن از دیتاشیت ماژول میشه که مهارت دیتاشیت خوندن اینجا به کمکتون میاد).
کدی که در بالا آورده شد به کمک example ی که در sdk بود نوشته شده ، میتونه بهتر از این نوشته بشه پس بهتره که آستینتون رو بالا بزنید و یه ادیتی روش برید?. برای دست گرمی و اینکه بهتر درکش بکنید میتونید علاوه بر دما، رطوبت رو هم برای سرور ارسال کرده و توی یک باکس جدا نمایش بدید، یا اگه حرفه ای تر هستید اطلاعات مکان رو هم ارسال کنید و توی نقشه نشون بدید.
در این بخش میتونید به همه قسمتهای سری آموزش ماژول mc60 دسترسی پیدا کنید:
- کار با ماژول تمام عیار mc60 – قسمت اول – برد راه انداز
- کار با ماژول تمام عیار mc60 – قسمت دوم – راه اندازی OpenCPU
- کار با ماژول تمام عیار mc60 – قسمت سوم – ساخت ردیاب
- کار با ماژول تمام عیار mc60 – قسمت چهارم – OpenCPU و تکمیل ردیاب
- کار با ماژول تمام عیار mc60 – قسمت پنجم – ساخت MP3 Player
- کار با ماژول تمام عیار mc60 – قسمت ششم – نمایشگر oled
- کار با ماژول تمام عیار mc60 – قسمت هشتم – کدنویسی با Eclipse
با سلام ؛ ممنون از آموزش های خوبتون ، اول اینکه تا SD چند گیگا بایتی میشه متصل کرد به برد ارزیابی ماژول MC60 Quectel و هم چنین یک آموزش جهت راه انذازی W25Q16 آی سی فلش نصب شده بر روی بورد قرار دهید ممنون
سلام. داخل سمپل کد های خود mc60 کد لازم برای راه اندازی آیسی فلش وجود داره. توی این فایل:
example_spi.c
من از sdk1.8 و فریموری که داخل سایت گذاشته بودین استفاده کردم
بعد از اجرای دستور RIL_NW_SetGPRSContext(0) یکدفه آنتن میپره و ماژول از شبکه خارج میشه
لطفا راهنمایی کنید چطوری میتونم این مشکل بر طرف کنم
سلام
از چه بردی استفاده میکنید ؟
احتمال زیاد در زمان اتصال به شبکه ، ماژول ، تغذیه کم میاره
سلام وقت بخیر
من وقتی میخوام فریمور رو آپدیت کنم با Qflash4.0, بعد از حدود 200 ثانیه با همچین پیغامی مواجه میشم:
FAIL, COM:5, FlashToolError:3236, S_DA_GPS_DOWNLOAD_FAIL
به نظر شما مشکل چی میتونه باشه که آپدیت نمیشه.
سلام
باید پایه های سریال AUX و GPS رو به هم متصل کنید
مطابق چیزی که در قسمت اول سری آموزش گفته شده
سلام
من از این اموزش و SDK معرفی شده برای راه اندازی یک پروژه استفاده کردم ، اما به مشکل خوردم.
ماژول من هر بار که برنامه به اخر میرسد دوباره راه اندازی میشود .
اول فکر کردم شاید مشکل از کد من است ، اما بعد از این که از مثال خود SDK استفاده کردم دیدم هر بار که برنامه کار میکند بعد از گزشت چند ثانیه دوباره همان اتفاق رخ میدهد.
ایا این مشکل از فایل SDK است و شماهم همین مشکل را دارید؟
سلام
منظور از به آخر رسیدن برنامه چی هست ؟
و نکته دیگه اینکه شما کدتون باید توی یک حلقه while true اجرا بشه
و اینکه ما مشکل شما رو نداریم
منظور از به اخر رسیدن برنامه ، یعنی اخر حلقه While true هست ، که گاهی بعد از این که دیتا به سرور ارسال میشه و یا گاهی در همون اول برنامه قبل از این که اصلا بالا بیاد ، و وارد while بشه شروع میکنه به ری استارت شدن ، و ولی بعد از ری استارت تا چند دقیقه درست کار میکنه و دوباره همین اتفاق میوفته ، برد رو از نظر سخت افزار ی بررسی کردم ، حتی ولتاژ رو هم همینطور ( روی 4.2 ثابته) . ماژول با AT کامند درست کار میکنه ولی وقتی برنامه بهش میدم این مشکل پیش میاد ، ماژول رو هم عوض کردم ، اما باز هم همین آش و همین کاسه شد.
نمیدونم مشکل از کجاست و واقعا گیج شدم!
سلام برای ماژول M66 باید از کدوم sdk استفاده کرد ؟؟؟
من نسخه 2.4 دارم ولی بازم فایل های Mqtt داخلش نیس …. اضافه هم که میکنم ارور میده داخل فایل ql_system
سلام
پوزش بابت تاخیر
شما میتونید برای استفاده از mqtt در ماژول m66 از این نسخه sdk و فریمور استفاده کنید
https://dl.sisoog.com/software/V3S%D9%80training/M66FAR02A09BT.zip
https://dl.sisoog.com/software/V3S%D9%80training/M66_QuecOpen_GS3_SDK_V2.6.zip
سلام
من هم با این ارور روبرو شدم
//<Activate PDP context,ret = 0
//<Select version 3.1.1 successfully
//<Start opening a MQTT client
//<Open a MQTT client successfully
//<Start connect to MQTT server
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Connect to MQTT server failure,error = 2
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
کاملا طبق آموزش پیش رفتم و فریم ورک را هم آپدیت کردم
ایده ای دارید؟
سلام
اینطور که به نظر میاد به مشکل در سرور هست و پارامتر های سرور رو درست تنظیم نکردید
سلام، ممنون از آموزش خوبتون
من وقتی پیامی از mqtt به mc60 میفرستم خود به خود ریست میشه، دلیلش رو نمیتونم بفهمم، کد شمارو کپی کردم و اجرا کردم و ورژن sdk ام 1.8 هست، ایده ای ندارید که مشکل از کجا میتونه باشه؟ ممنون
سلام. خواهش میکنم
لازم هست که حتما فریمور خود ماژول رو هم آپدیت کنید
ممنون از شما، چجوری میتونم ورژن firmware دستگاهمو ببینم؟ و برای گرفتن ورژن جدید باید به تیم quectel ایمیل بدم یا جایی برای دانلودشون هست؟
با دستور ATI میتونید نسخه فریمور رو چک کنید.
لینک دانلود فریمور مورد نیاز ، داخل باکس دانلود در انتهای مطلب موجوده
سلام.
من فایل فریمور ماژول mc60 رو از کجا می تونم دانلود کنم. هر چی گشتم تو فایل های قابل دالود تو سایت تون نتوستم پیداش کنم.
سلام ، از طریق دانلود باکسی که در انتهای مطلب هست میتونید دانلود کنید ، اینجا هم دوباره لینکش رو میزارم:
http://dl.sisoog.com/Quectel/mc60_sdk_firmware.zip
ممنون از آموزش های خیلی خوبتون بنظرتون چرا خروجی من به این صورت هست ؟
به سرور هم با موفقیت متصل میشه
فقط سرور من ssl داره ولی کانکشن موفق میزنه بهش
نظرتون چی هست ؟؟
//<Set PDP context 0
//<Set APN
//<Activate PDP context,ret = 0
//<Select version 3.1.1 successfully
//<Start opening a MQTT client
//<Publish a message to server failure,ret = -1
//<Open a MQTT client successfully
//<Start connect to MQTT server
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
//<Publish a message to server failure,ret = -1
خواهش میکنم?
مطمئن بشید که تنظیمات مربوط به ssl رو انجام داده باشید
از این داکیومنت میتونید اطلاعات بیشتری کسب کنید:
https://sisoog.com/wp-content/uploads/2021/11/Quectel_GSM_MQTT_Application_Note_V1.3.pdf
سلام
کدام یک از محصولات کویکتل فقط GSM و GPRS را دارند. میخوام بدون بلوتوث و GPS باشه.البته در بازار هم موجود باشه
تشکر
سلام . از ماژول m65 میتونید استفاده کنید
توی این مطلب هم در موردش توضیح داده شده:
https://sisoog.com/2022/02/08/%da%a9%d8%a7%d8%b1-%d8%a8%d8%a7-%d9%85%d8%a7%da%98%d9%88%d9%84-m65/
تشکر
سلام و روز بخیر
من در کامپایل برنامه با تابع Ql_Mqtt_Recv_Register به مشکل خوردم.
لطف میکنید بفرمایید در کدام بخش تعریف شده این تابع؟
سلام
برای استفاده از این تابع حتما باید از نسخه 1.8 sdk استفاده کنید
من از Eclipse استفاده میکنم. متاسفانه SDK ورژن 1.8 رو نتونستم پیدا کنم.
اگر راهی باشه که بشه همین رو تبدیل کرد ممنون میشم راهنمایی بکنید.
یک راه دیگه که کمک میکنه اینه که اگر تابعی باشه که بشه به کمک اون وقتی پیغامی در بخش MSG_ID_URC_INDICATION میاد نمایش داد! میشه دیتاشو تحلیل کرد و چیزی که سرور میفرسته رو از داخلش درآورد
سلام ممنون از وقتی که میزارید و این مطالب را تهیه میکنید ببخشید فانکشن Ql_Mqtt_Recv_Register به صورت لیب هستش ؟اگر اره چه لیبی رو باید بزارم براش چون من پروژه رو جدا دارم و ورژن 1.3 هستم
سلام خواهش میکنم.??
فکر میکنم توی یکی از فایل های هدر فانکشنش معرفی شده باشه .
در هر صورت بهتون پیشنهاد میکنم اگر از mqtt میخواید استفاده کنید کدتون رو روی ورژن sdk 1.8 بیارید ، چون ممکنه به ارور هایی بر بخورید که هیچ دلیلی ندارند و نتونید دیباگ کنید
بله در یک هدری معرفی شده ولی چون اون لیب رو ندارم ارور میده باسه اون پرسیدم ولی اگر راهی نداره که میرم 1.8 ممنون
البته کارتون عالیه … ممنونم از زحماتتون ?
سلام … چرا از نمونه ایرانی تینگزبورد استفاده نکردین ؟
سلام نمونه های ایرانی را همینجا معرفی کنید تا بقیه هم ببینن
یکی از دوستان که تو همین سایت IOT Dashboard رو معرفی کرد و تینگز بورد رو توی یه هاست ایرانی راه اندازی کرد فکر کنم … اسم یایتش یادم نیست …
باسلام
هدف معرفی پلتفرم و نحوه راه اندازی بوده.
حالا میشه از سرویسی که در داخل سایت اصلی به صورت رایگان ارائه شده استفاده کرد و یا روی سرور شخصی راه اندازی کرد و یا از سایت های داخلی که این سرویس رو ارائه دادند استفاده کرد.
سلام
خیلی عالی بود لذت بردیم .
سلام
نظر لطفتون هست?