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

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

    Русскоязычный форум
    1
    1
    7.5k
    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
      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
      • First post
        Last post