🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    Урок 22. Модуль SIM800L

    Scheduled Pinned Locked Moved Русскоязычный форум
    1 Posts 1 Posters 8.4k Views 1 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DimiD Offline
      Dimi
      last edited by

      Цель урока

      Привет! Сегодня мы познакомимся с отличным модулем SIM800L и научимся принимать SMS-сообщения (рисунок 1).

      Рисунок 1

      Этот урок научит: обмениваться данными по UART с модулем; производить инициализацию и конфигурацию модуля; получать и читать текстовые SMS.

      Краткая справка

      • Назначение: применяют получения услуг сотовой связи
      • Сфера применения: сельское хозяйство, умный дом и другие
      • Интерфейс подключения: UART2 (MBUS)
      • Напряжение питания: от 3.4 до 4.4 В
      • Совместимость: M5STACK и M5FIRE (со снятым GO-модулем)
      • Форм-фактор: STACK

      Краткий обзор

      SIM800L — один из большого семейства дополнительных модулей (MODULES), предназначенных прежде всего для М5STACK. Поставляется данный модуль в пластиковом футляре (рисунок 2).

      Рисунок 2

      На лицевой стороне модуля имеется вилка шины MBUS, слот для MicroSIM, канавка под антенну-пружинку (рисунок 3).

      Примечание: контакты: G5 -> RST, G16 -> TXD, G17 -> RXD (Serial2).

      Рисунок 3

      Примечание: если модуль присоединён к М5, то вставить и извлечь SIM-карту нельзя.

      На обратной стороне модуля имеется розетка шины MBUS, модуль SIM800L, антенна-пружинка на GSM-диапазон, разъём (3.5 мм mini-jack) для подключения наушников и встроенный микрофон (рисунок 4).

      Рисунок 4

      Начнём!

      Blockly (UI Flow)

      Для того, чтобы приступить к использованию нашего модуля необходимо его инициализировать (рисунок 5). Это займет некоторое время (приблизительно около 1 минуты). В это время нельзя беспокоить модем и выполнять какие-либо операции с ним, поэтому мы временно окрасим LED BAR красным цветом. С помощью функции InitSIM800L мы сообщим модему некоторые параметры работы, которые интересны нам в будущем. Обратите внимание на переменную isMessage, которая принимает значение 0. Для чего она нужна - рассмотрим далее.

      Рисунок 5

      Для того, чтобы модем начал реагировать на внешние команды после подачи питания ему потребуется приблизительно 10 секунд. Далее нам необходимо инициализировать UART-интерфейс на соответсвующих контактах устройства с помощью блока set UART.

      Обратите внимание: TX 17, RX 16

      Затем с помощью блока read UART available в цикле убедимся, что есть какой-то мусор в UART-буфере и считаем его посимвольно с помощью блока read UART. Отлично! Порт готов к работе. Теперь перезагрузим модуль, отправив команду AT+CFUN=1,1\r с помощью блока write. Дадим модему на нормальный запуск 45 секунд. Выключим ЭХО с помощью ATE0\r. Установим GSM-кодировку текстового режима AT+CSCS="GSM"\r. Включим текстовый режим AT+CMGF=1\r. Очистим память сообщений AT+CMGD=1,4\r. Попросим модуль читать входящие сообщения при получении AT+CNMI=1,2,2,1,0\r. Опять очистим буфер от возможного мусора. Всё, на этом модуль полностью готов к работе (рисунок 5.1).

      Рисунок 5.1

      Функция LiveSIM800L будет постоянно вызываться из цикла Loop (рисунок 5.2). В ней мы будем смотреть если ли входящие данные от модуля. Если есть, то считаем и приведем их к строковому виду. Теперь посмотрим есть ли флаг CMT:, если есть, то это входящее сообщение поставим флаг isMessage в состояние 1, это нам необходимо для того, чтобы прочесть текст сообщения. Помните функцию parseString, которую мы писали в прошлых уроках для Arduino IDE? Она отлично нам пригодится здесь. Я её перевел на MicroPython, а Вам её необходимо просто скопировать и вставить в Ваш проект ;)

      def parseString(idSeparator, separator, str2):
          global parseStringGlobalVar1
          parseStringGlobalVar1 = ''
          separatorCount = 0
          for i in range(len(str2)):
              if str2[i] == separator:
                  separatorCount += 1
              else:
                  if separatorCount == idSeparator:
                      parseStringGlobalVar1 += str2[i]
                  elif separatorCount > idSeparator:
                      break
          return parseStringGlobalVar1
      

      Для тех, кто не помнит или не читал прошлые уроки - функция parseString принимает три аргумента и возращает участок строки, расположенный между разделителями: idSeparator (int), separator (char), str2 (String). Где idSeparator - порядковый номер разделителя; separator - разделитель; str2 - строка из которой извлекаем подстроку.

      Например:

      cmtStr = '+CMT: "+7XXXXXX0001","","01/01/01,09:30:00+12"\r\n';
      print(parseStr(1, '"', cmtStr))
      

      Будет выведено:

      +7XXXXXX0001
      

      А если сделать так:

      print(parseStr(3, '"', cmtStr))
      

      То будет выведено:

      01/01/01,09:30:00+12
      

      Рисунок 5.2

      К сожалению Blockly не позволяет сегодня нам нормально реализовать нашу функцию, но ничего страшного - есть обходной вариант сделать MicroPython-вставку (рисунок 5.3.1).

      Рисунок 5.3

      Рисунок 5.3.1

      Когда будут приходить SMS будет вызываться функция-событие IncomingSms. А номер отправителя и текст сообщения будет находиться в глобальных переменных IncomingSmsPhone и IncomingSmsMessage, соответственно.

      Рисунок 5.4

      На этом урок закончен! :)

      MicroPython (UI Flow)

      from m5stack import *
      from m5ui import *
      import machine
      clear_bg(0xffffff)
      
      
      rgb = RGB_Bar()
      btnA = M5Button(name="ButtonA", text="ButtonA", visibility=False)
      btnB = M5Button(name="ButtonB", text="ButtonB", visibility=False)
      btnC = M5Button(name="ButtonC", text="ButtonC", visibility=False)
      label1 = M5TextBox(18, 90, "...", lcd.FONT_DejaVu24, 0x000000)
      label2 = M5TextBox(22, 192, "...", lcd.FONT_DejaVu18, 0x000000)
      title0 = M5Title(title="SIM800L Module", fgcolor=0xFFFFFF, bgcolor=0x000000)
      label4 = M5TextBox(24, 48, "Phone number:", lcd.FONT_DejaVu24, 0x000000)
      label3 = M5TextBox(48, 145, "Message:", lcd.FONT_DejaVu24, 0x000000)
      
      from numbers import Number
      
      idSeparator = None
      separator = None
      str2 = None
      parseStringGlobalVar1 = None
      IncomingSmsPhone = None
      uart = None
      buf = None
      IncomingSmsMessage = None
      isMessage = None
      
      def parseString(idSeparator, separator, str2):
          global parseStringGlobalVar1
          parseStringGlobalVar1 = ''
          separatorCount = 0
          for i in range(len(str2)):
              if str2[i] == separator:
                  separatorCount += 1
              else:
                  if separatorCount == idSeparator:
                      parseStringGlobalVar1 += str2[i]
                  elif separatorCount > idSeparator:
                      break
          return parseStringGlobalVar1
      
      def IncomingSms():
        global idSeparator, separator, str2, parseStringGlobalVar1, IncomingSmsPhone, uart, buf, IncomingSmsMessage, isMessage
        label1.setText(str(IncomingSmsPhone))
        label2.setText(str(IncomingSmsMessage))
        speaker.volume(1)
        for count in range(4):
          rgb.set_all(0x00cccc)
          speaker.sing(659, 1/8)
          wait(0.125)
          rgb.set_all(0x000000)
          wait(0.125)
      
      def InitSIM800L():
        global idSeparator, separator, str2, parseStringGlobalVar1, IncomingSmsPhone, uart, buf, IncomingSmsMessage, isMessage
        wait(10)
        uart = machine.UART(1, tx=17, rx=16)
        uart.init(115200, bits=8, parity=None, stop=1)
        while uart.any():
          if uart.read(1):
            pass
        uart.write('AT+CFUN=1,1\r')
        wait(45)
        uart.write('ATE0\r')
        wait(1)
        uart.write('AT+CSCS="GSM"\r')
        wait(1)
        uart.write('AT+CMGF=1\r')
        wait(1)
        uart.write('AT+CMGD=1,4\r')
        wait(1)
        uart.write('AT+CNMI=1,2,2,1,0\r')
        wait(1)
        while uart.any():
          if uart.read(1):
            pass
      
      def LiveSIM800L():
        global idSeparator, separator, str2, parseStringGlobalVar1, IncomingSmsPhone, uart, buf, IncomingSmsMessage, isMessage
        if uart.any():
          buf = str((uart.readline()))
          if isMessage == 0:
            if buf.count('CMT:') == 1:
              isMessage = (isMessage if isinstance(isMessage, Number) else 0) + 1
              IncomingSmsPhone = parseString(1, '"', buf)
          else:
            if buf.count('\\x') == 0:
              isMessage = (isMessage if isinstance(isMessage, Number) else 0) + 0
              buf = buf[2:-5]
              if buf.count('CMT:') == 0 and len(buf) != 0:
                IncomingSmsMessage = buf
                IncomingSms()
          wait(1)
      
      
      
      rgb.set_all(0xff0000)
      InitSIM800L()
      rgb.set_all(0x000000)
      isMessage = (isMessage if isinstance(isMessage, Number) else 0) + 0
      while True:
        LiveSIM800L()
        wait(0.001)
      

      C & C++ (Arduino IDE)

      Пример ещё не написан ^_^

      Downloads

      Увы, тут сегодня ничего нет :)

      1 Reply Last reply Reply Quote 0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      • First post
        Last post