<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Урок 22. Модуль SIM800L]]></title><description><![CDATA[<h3>Цель урока</h3>
<p dir="auto">Привет! Сегодня мы познакомимся с отличным модулем SIM800L и научимся принимать  SMS-сообщения (рисунок 1).</p>
<p dir="auto"><img src="https://pp.userapi.com/c851128/v851128058/9bcac/Gb95FpczwxA.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 1</p>
<p dir="auto">Этот урок научит: обмениваться данными по UART с модулем; производить инициализацию и конфигурацию модуля; получать и читать текстовые SMS.</p>
<h3>Краткая справка</h3>
<ul>
<li>Назначение: применяют получения услуг сотовой связи</li>
<li>Сфера применения: сельское хозяйство, умный дом и другие</li>
<li>Интерфейс подключения: UART2 (MBUS)</li>
<li>Напряжение питания: от 3.4 до 4.4 В</li>
<li>Совместимость: M5STACK и M5FIRE (со снятым GO-модулем)</li>
<li>Форм-фактор: STACK</li>
</ul>
<h3>Краткий обзор</h3>
<p dir="auto">SIM800L — один из большого семейства дополнительных модулей (MODULES), предназначенных прежде всего для М5STACK. Поставляется данный модуль в пластиковом футляре (рисунок 2).</p>
<p dir="auto"><img src="https://pp.userapi.com/c851128/v851128058/9bceb/Kw1q5RT6M6o.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 2</p>
<p dir="auto">На лицевой стороне модуля имеется вилка шины MBUS, слот для MicroSIM, канавка под антенну-пружинку (рисунок 3).</p>
<blockquote>
<p dir="auto">Примечание: контакты: G5 -&gt; RST, G16 -&gt; TXD, G17 -&gt; RXD (Serial2).</p>
</blockquote>
<p dir="auto"><img src="https://pp.userapi.com/c846219/v846219151/18078e/TBocCGixxkU.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 3</p>
<blockquote>
<p dir="auto">Примечание: если модуль присоединён к М5, то вставить и извлечь SIM-карту нельзя.</p>
</blockquote>
<p dir="auto">На обратной стороне модуля имеется розетка шины MBUS, модуль SIM800L, антенна-пружинка на GSM-диапазон, разъём (3.5 мм mini-jack) для подключения наушников и встроенный микрофон (рисунок 4).</p>
<p dir="auto"><img src="https://pp.userapi.com/c844616/v844616151/18a9cd/W4pffgehXtM.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 4</p>
<h2>Начнём!</h2>
<h3>Blockly (<a href="http://flow.m5stack.com" target="_blank" rel="noopener noreferrer nofollow ugc">UI Flow</a>)</h3>
<p dir="auto">Для того, чтобы приступить к использованию нашего модуля необходимо его инициализировать (рисунок 5). Это займет некоторое время (приблизительно около 1 минуты). В это время нельзя беспокоить модем и выполнять какие-либо операции с ним, поэтому мы временно окрасим LED BAR красным цветом. С помощью функции <strong>InitSIM800L</strong> мы сообщим модему некоторые параметры работы, которые интересны нам в будущем. Обратите внимание на переменную <strong>isMessage</strong>, которая принимает значение <strong>0</strong>. Для чего она нужна - рассмотрим далее.</p>
<p dir="auto"><img src="https://pp.userapi.com/c847219/v847219020/183ab1/JLe3YmCNveg.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5</p>
<p dir="auto">Для того, чтобы модем начал реагировать на внешние команды после подачи питания ему потребуется приблизительно 10 секунд. Далее нам необходимо инициализировать UART-интерфейс на соответсвующих контактах устройства с помощью блока <strong>set UART</strong>.</p>
<blockquote>
<p dir="auto">Обратите внимание: TX 17, RX 16</p>
</blockquote>
<p dir="auto">Затем с помощью блока <strong>read UART available</strong> в цикле убедимся, что есть какой-то мусор в UART-буфере и считаем его посимвольно с помощью блока <strong>read UART</strong>. Отлично! Порт готов к работе. Теперь перезагрузим модуль, отправив команду <strong>AT+CFUN=1,1\r</strong> с помощью блока <strong>write</strong>. Дадим модему на нормальный запуск 45 секунд. Выключим ЭХО с помощью <strong>ATE0\r</strong>. Установим GSM-кодировку текстового режима <strong>AT+CSCS="GSM"\r</strong>. Включим текстовый режим <strong>AT+CMGF=1\r</strong>. Очистим память сообщений <strong>AT+CMGD=1,4\r</strong>. Попросим модуль читать входящие сообщения при получении <strong>AT+CNMI=1,2,2,1,0\r</strong>. Опять очистим буфер от возможного мусора. Всё, на этом модуль полностью готов к работе (рисунок 5.1).</p>
<p dir="auto"><img src="https://pp.userapi.com/c847219/v847219020/183a92/0D6mKv0zwi0.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5.1</p>
<p dir="auto">Функция <strong>LiveSIM800L</strong> будет постоянно вызываться из цикла <strong>Loop</strong> (рисунок 5.2). В ней мы будем смотреть если ли входящие данные от модуля. Если есть, то считаем и приведем их к строковому виду. Теперь посмотрим есть ли флаг  <strong>CMT:</strong>, если есть, то это входящее сообщение поставим флаг <strong>isMessage</strong> в состояние <strong>1</strong>, это нам необходимо для того, чтобы прочесть текст сообщения. Помните функцию <strong>parseString</strong>, которую мы писали в прошлых уроках для Arduino IDE? Она отлично нам пригодится здесь. Я её перевел на MicroPython, а Вам её необходимо просто скопировать и вставить в Ваш проект ;)</p>
<pre><code>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 &gt; idSeparator:
                break
    return parseStringGlobalVar1
</code></pre>
<p dir="auto">Для тех, кто не помнит или не читал прошлые уроки - функция <strong>parseString</strong> принимает три аргумента и возращает участок строки, расположенный между разделителями: <strong>idSeparator</strong> (int), <strong>separator</strong> (char), <strong>str2</strong> (String). Где  <strong>idSeparator</strong> - порядковый номер разделителя; <strong>separator</strong> - разделитель; <strong>str2</strong> - строка из которой извлекаем подстроку.</p>
<p dir="auto">Например:</p>
<pre><code>cmtStr = '+CMT: "+7XXXXXX0001","","01/01/01,09:30:00+12"\r\n';
print(parseStr(1, '"', cmtStr))
</code></pre>
<p dir="auto">Будет выведено:</p>
<pre><code>+7XXXXXX0001
</code></pre>
<p dir="auto">А если сделать так:</p>
<pre><code>print(parseStr(3, '"', cmtStr))
</code></pre>
<p dir="auto">То будет выведено:</p>
<pre><code>01/01/01,09:30:00+12
</code></pre>
<p dir="auto"><img src="https://pp.userapi.com/c847219/v847219020/183a9b/Tnr6hMcwV-s.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5.2</p>
<p dir="auto">К сожалению Blockly не позволяет сегодня нам нормально реализовать нашу функцию, но ничего страшного - есть обходной вариант сделать MicroPython-вставку (рисунок 5.3.1).</p>
<p dir="auto"><img src="https://pp.userapi.com/c847219/v847219020/183aaa/U9EkGRkVE3I.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5.3</p>
<p dir="auto"><img src="https://pp.userapi.com/c845522/v845522129/187801/MIb1oyIIkCw.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5.3.1</p>
<p dir="auto">Когда будут приходить SMS будет вызываться функция-событие <strong>IncomingSms</strong>. А номер отправителя и текст сообщения будет находиться в глобальных переменных IncomingSmsPhone и IncomingSmsMessage, соответственно.</p>
<p dir="auto"><img src="https://pp.userapi.com/c847219/v847219020/183aa2/2SptatHsF98.jpg" alt="" class=" img-fluid img-markdown" /></p>
<p dir="auto">Рисунок 5.4</p>
<p dir="auto">На этом урок закончен! :)</p>
<h3>MicroPython (<a href="http://flow.m5stack.com" target="_blank" rel="noopener noreferrer nofollow ugc">UI Flow</a>)</h3>
<pre><code>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 &gt; 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)
</code></pre>
<h3>C &amp; C++ (<a href="https://www.arduino.cc/en/Main/Software" target="_blank" rel="noopener noreferrer nofollow ugc">Arduino IDE</a>)</h3>
<p dir="auto">Пример ещё не написан ^_^</p>
<h3>Downloads</h3>
<p dir="auto">Увы, тут сегодня ничего нет :)</p>
]]></description><link>https://community.m5stack.com/topic/538/урок-22-модуль-sim800l</link><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 14:13:00 GMT</lastBuildDate><atom:link href="https://community.m5stack.com/topic/538.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 25 Jan 2019 06:12:05 GMT</pubDate><ttl>60</ttl></channel></rss>