ارسال نتیجه AT command به موبایل با پیامک

8 ماه قبل
95 بازدید

0

سلام و پوزش بابت سوالات زیاد. چطور میتوانم پاسخ دستوراتی که در سریال مانیتور ارسال میکنم را به موبایل ارسال کنم؟ به عنوان مثال دستورات زیر را برای ولتاژ sim800 ارسال میکنم میخوام نتیجه اش را در موبایل ببینم:

if (inputString.indexOf("CBC") > 0){

      gsmSerial.println("AT+CBC");

     }

یعنی میخوام نتیجه at+cbc که در سریال مانیتور نمایش داده میشود به موبایل هم پیامک شود و در موبایل هم نتیجه را ببینم، برای این منظور از چه دستوراتی باید استفاده کنم؟

 

29 مرداد 02 در 09:26
راحله
1

افزودن دیدگاه

2 پاسخ ثبت شده است
1

با سلام

از همان دستوری که برای ارسال پیامک ارسال میکنید استفاده کرده.

در جایی از دستور های خود gsmSerial.readدارید میکنید.

به جای کامند read از دستور readStringUntil('\n') استفاده کنید و کل تابع را در یک متغییر String بریزید.

آن متغییر را می توانید به عنوان متن پیام از طریق دستور پیام ارسال کنید.

البته قبل از ارسال بررسی کنید متن ذخیره شده در این مقدار درست می باشد. چون این دستور هر خط را به صورت حلقه های جدا جدا دریافت و overwrite میکند. از این رو میتوانید از دستور lenght برای بررسی طول پیام یا startWith("مقدار اولی") بررسی کنید که ابتدای پیام دریافتی با چیزی که انتظار داشتید یکی می باشد یا خیر.

در این صورت دستورات ارسال پیام را انجام بدهید.

 

ویرایش اول:

به صورت زیر یک متغییر ایجاد میکنید و سپس مقدار را میخوانید و در آن میریزید. و سپس به از طریق سریال مانیتور نمایش میدهید.

 if (inputString.indexOf("CBC") > 0)
    {

      gsmSerial.println("AT+CBC");
      delay(50);
      String value = gsmSerial.readStringUntil('\n');
      Serial.print("1.");
      Serial.println(value);
      value = gsmSerial.readStringUntil('\n');
      Serial.print("2.");
      Serial.println(value);
      value = gsmSerial.readStringUntil('\n');
      Serial.print("3.");
      Serial.println(value);
    }

زمانی که دستور شما مشخص شد کدام خط می باشد و به چه صورت شروع می شود (با توجه به این سایت مقدار جواب را تنظیم کردم و کد را به صورت زیر تغییر میدهید).

در این کد در یک حلقه منتظر می شود تا دیتا دریافتی با +CBC شروع شود و در صورت تایید کل مقدار را نمایش میدهد و سایر دستور ها را به آن میدهید و با دستور break از حلقه خارج می شوید.

if (inputString.indexOf("CBC") > 0)
    {

      gsmSerial.println("AT+CBC");
      delay(50);
      String value = "";
      while (true)
      {
        value = gsmSerial.readStringUntil('\n');
        if (value.startsWith("+CBC"))
        {
          Serial.println(value);
          //دستور ارسال پیام
          break;
        }
      }
    }

باز به خطی که میخواهید بخوانید برمیگردد. و میتوانید این کد را تغییر بدهید.

در صورتی که میخواهید چند خط بعد را بخوانید می توانید داخل if از دستور 

value = value+ gsmSerial.readStringUntil('\n');

برای جمع آوری یک خط استفاده کنید (میتوانید تکرار کنید تا خط های بیشتری را بگیرید).

نکته این سیستم خط شروع می باشد که مقدار ثابت آن را استفاده میکنید.

در صورتی که کل پیام را میخواهید باید از کلمه OK که در پایان می آید استفاده کنید و دستور خود را به صورت زیر تغییر بدهید.

if (inputString.indexOf("CBC") > 0)
    {

      gsmSerial.println("AT+CBC");
      delay(50);
      String value = "";
      String output = "";
      while (true)
      {
        value = gsmSerial.readStringUntil('\n');
        if (value.startsWith("OK"))
        {
          Serial.println(output);
          //دستور ارسال پیام 
          break;
        }
        else
        {
          output = output + value + "\n";
        }
      }
    }

تمامی این موارد پردازش مقدار String می باشد که در سمت ورودی دریافت می شود. پیشنهاد میکنم تمامی فانکشن های مربوط به این متغییر را بخوانید. همچنین با دستور های شرطی نیز آشنا تر بشوید و از آنها استفاده کنید.

29 مرداد 02 در 01:07
محمد دمیرچی
3670

سلام ببخشید این روش‌که فرمودید را امتحان کردم اما نشد، خیلی ام روش‌کار کردم و نهایتا منجر پیامک خال میفرستاد، اگر امکان داره خط دستوراتش رو بفرمایید ممنون میشم. لطفا کمکم کنید، برای پروژه دوره به این موضوع نیاز دارم و دو ماهه درگیرشم اما موفق نمیشم!  – راحله 02-07-05 در 07:20

پاسخ ویرایش شد  – محمد دمیرچی 02-07-08 در 05:17

ممنون، اشتباه من در استفاده از true بود. برخی از دستورات مانند استعلام شارژ سیمکارت اجرا نمیشود و به "" های دستور AT+CUSD=1,"*140*1#" وقتی جایگزین at+cnc میذارم میگیرد و آپلود نمیشود! چطور این مسکل رفع میشود و میتوان استعلام شارژ بگیرم؟  – راحله 02-07-09 در 09:00

برای اینکه " را داخل کد C خود قرار بدهید به صورت \" قرار بدهید. مشابه \n که در بالا آماده است باید قرار بدهید تا به عنوان پایان متن String حساب نکند. برای مثال "\"" می شود یک عدد " در زبان C  – محمد دمیرچی 02-07-09 در 10:32

سلام. در این برنامه ای که فرمودید دستور while (true) باعث هنگ کردن آردینو میشه، البته ممکنه از هر ۱۰ بار یکبار جواب بده اما بیشتر هنگ میکنه، خیلی بررسی کردم تا متوجه شدم دلیل هنگی از کدام بخش هست! نمیشه این دستور را با if پیاده سازی کرد؟ چون تست کردم با if هنگ نمیکنه اما هدفی که از برنامه داریم انحام نمیشه و به هر صورت if را نوشتم هنگ نکرد اما کاری هک که این بخش از برنامه باید انجام بده انجام نشد!  – راحله 02-07-16 در 08:04

برنامه در اینجا هنگ نمیکند. انقدر سریال را میخواند تا دستور OK را مشاهده کند. و با مشاهده این دستور با دستور break; از حلقه خارج می شود. دستور while یک دستور حلقه می باشد نه شرطی که بتوانید با if عوض کنید. می توانید با for عوض کنید و بگویید اگر n بار حلقه زده شد و مقدار مورد نظر پیدا نشد خارج شود، یا حتی داخل همین while یک شمارنده قرار بدهید به همراه if که تعداد از یک حدی بالاتر رفت بیاید بیرون. اما این حل مشکل نمی باشد، باید بررسی کنید چرا جوابی از سوی ماژول GSM به درستی دریافت نمی شود و پیام OK را در سمت میکرو مشاهده نمیکنید.  – محمد دمیرچی 02-07-16 در 11:10

آخه به محض اینکه while را غیر فعال میکنم دیگه هنگ نمیکنه، ببخشید در مورد if هم حق باشماست ، اشتباه تایپی بود، منظورم همان for هست، نمیدونم چرا موقع نوشتن if در ذهنم اومده!!  – راحله 02-07-16 در 11:37

تعداد حلقه for رو بیشتر کردم برنامه درست اجرا میشه و مشکل هنگی هم با for برطرف میشه  – راحله 02-07-16 در 04:11

باز هم عرض کردم، این روش درستی نیست. بهتر هست جوابی رو بررسی کنید که به چه دلیل داخل if خروجی نمیرود.  – محمد دمیرچی 02-07-17 در 06:48

سلام وقت بخیر‌ممنون از پیگیری و توجه شما. ببخشید متوجه منظورتون نشدم, ifکجا؟  – راحله 02-07-17 در 10:56

افزودن دیدگاه

0

اگر به این بخش از کد توجه کنید

while (true)
      {
        value = gsmSerial.readStringUntil('\n');
        if (value.startsWith("OK"))
        {
          Serial.println(output);
          //دستور ارسال پیام 
          break;
        }
        else
        {
          output = output + value + "\n";
        }

ما یک حلقه بینهایت ساخته ایم که به صورت یکسره سریال مانیتور را میخواند و به صورت خط به خط داخل مقدار value میریزید.

زمانی که این مقدار برابر با OK باشد این حلقه بینهایت شکسته می شود و بیرون می آید.

در غیر این صورت مقدار ها را جمع کرده با هم و در زمانی که حلقه شکسته شود نمایش داده شود.

حال برای بررسی اینکه چرا این حلقه برای شما کار نمیکند ابتدا این فاکنشن را در انتهای کد خود قرار بدهید تا مورد بررسی قرار بدهیم.

void debug()
{
    Serial.println("\ndebug mode");
    while (true)
    {
        while (Serial.available())
        {
            gsmSerial.write(Serial.read()); // Forward what Serial received to Software Serial Port
        }
        while (gsmSerial.available())
        {
            Serial.write(gsmSerial.read()); // Forward what Software Serial received to Serial Port
        }
    }
}

حال پس از خط

gsmSerial.println("AT+CBC");

دستور

debug();

را بزنید تا برنامه در این بخش وارد فانکشن دیباگ بود.

حال بررسی کنید در سریال مانیتور به چه صورت دیتا برای شما می آید.

منظور بنده از بررسی این می باشد که بعد از ارسال دستور AT+CBC ماژول دقیقا چه چیز هایی را به شما برمیگرداند.

اگر OK برگشتی وجود دارد که یک مساله این می باشد که قبل و بعد این OK آیا Space اضافه وجود دارد یا خیر؟

در صورت وجود می توانید با دستور زیر این مشکل را حل کنید.

value = gsmSerial.readStringUntil('\n');
value.trim();

در صورتی که کلمه OK برای شما نمی آید به احتمال زیاد دستور +CBC برای شما می آید.

که می توانید از طریق همین کلمه کلیدی به جای OK به ادامه برنامه بپردازید.

 

نکته:

توجه داشته باشید که بعد از قرار دادن دستور debug برنامه اصلی شما در آن نقطه قفل شده و برد شما به عنوان USB-TTL عمل میکند و هر داده ای را در سریال مانیتور ارسال کنید را مستقیم به ماژول GSM ارسال کرده و به صورت برعکس به شما داده را میدهد.

از این رو پیشنهاد میکنم که برای بررسی دستور های AT Command از این دستور استفاده کنید و در پایین این دستور را از کد خود پاک کنید تا برنامه شما به درستی کار کند.

البته برای سیستم کلی پیشنهاد میکنم کل ارسال و دریافت های خود را از طریق یک فانکشن که همه این سیستم را برای شما انجام میدهد استفاده کنید.

مانند این فانکشن

String serialRead(String value, String startOrEndWith, bool startOrEnd)
{
    flush();
    Serial2.println(value);
    delay(50);
    while (true)
    {
        cunter++;
        if (Serial2.available())
        {
            checker = Serial2.readStringUntil('\n');
            checker.trim();
            if (startOrEnd)
            {
                if (checker.startsWith(startOrEndWith))
                {
                    return checker;
                }
            }
            else
            {
                if (checker.endsWith(startOrEndWith))
                {
                    return checker;
                }
            }
        }
        delay(50);
        if (cunter == 100)
        {
            cunter = 0;
            Serial2.flush();
            return "Null";
        }
    }
}

void flush()
{
    Serial2.readStringUntil('\n');
    Serial2.readStringUntil('\n');
    Serial2.flush();
}

برای مثال برای استفاده از این فانکشن در برنامه خودتان به صورت زیر می شود

Serial.println(serialRead("AT+CBC","+CBC",true));

مقدار خروجی دستور را به صورت String به شما برمیگرداند.

توجه داشته باشید که در این کد به دلیل استفاده از ESP32 از دستور Serial2 استفاده شده است و شما برای کد خود نیاز دارید به gsmSerial تغییر بدهید

 

18 مهر 02 در 04:58
محمد دمیرچی
3670

افزودن دیدگاه


انجمن کافه‌ربات © 1400