Lesson 22. Modules. SIM800L



  • The purpose of this lesson

    Hi! Today we will get acquainted with the excellent module SIM800L and learn how to receive SMS-messages (figure 1).

    Figure 1

    This lesson will teach: to exchange UART data with the module; to initialize and configure the module; to receive and read text SMS.

    Short help

    • Purpose: apply for receiving cellular services
    • Scope: agriculture, smart home and others
    • Connection interface: UART2 (MBUS)
    • Supply voltage: 3.4 to 4.4 V
    • Compatibility: M5STACK and M5FIRE (with GO module removed)
    • Form factor: STACK

    Brief overview

    SIM800L - one of the large family of additional modules (MODULES), designed primarily for M5STASK. This module is supplied in a plastic case (figure 2).

    Figure 2

    On the front side of the module there is a MBUS bus plug, a slot for MicroSIM, a groove for the antenna-spring (figure 3).

    Note: contacts: G5 - > RST, G16 - > TXD, G17 - > RXD (Serial2).

    Figure 3

    Note: if the module is connected to the M5, the SIM card cannot be inserted or removed.

    On the reverse side of the module there is an MBUS bus socket, SIM800L module, a spring antenna for GSM-band, a connector (3.5 mm mini-jack) for headphones and a built-in microphone (figure 4).

    Figure 4

    Let's start!

    Blockly (UI Flow)

    In order to start using our module, it is necessary to initialize it (figure 5). It will take some time (about 1 minute). At this time, you can not disturb the modem and perform any operations with it, so we temporarily to light the LED BAR red. With the InitSIM800L function, we will inform the modem of some parameters that are interesting to us in the future. Note on the variable isMessage that takes the value 0. For what it is necessary - consider below.

    Figure 5

    It takes approximately 10 seconds for the modem to respond to external commands after power is supplied. Next, we need to initialize the UART interface on the corresponding contacts of the device using the set UART block.

    Please note: TX 17, RX 16

    Then, using the read UART available block in the loop, make sure that there is some garbage in the UART buffer and consider it symbolically using the read UART block. Great! The port is ready for operation. Now restart the module by sending the command AT+CFUN=1,1\r using the block write. Let's give the modem a normal run of 45 seconds. Turn off the ECHO using ATE0\r. Set the text mode GSM encoding to AT+CSCS="GSM"\r. Turn on text mode AT+CMGF=1\r. Clear the message memory AT+CMGD=1.4\r. Ask the module to read incoming messages when receiving AT+CNMI=1,2,2,1,0\r. Again, clear the buffer of possible debris. That's all, the module is ready to work (figure 5.1).

    Figure 5.1

    Function LiveSIM800L will always be called from a loop Loop (figure 5.2). In it we will look if there is incoming data from the module. If so, we consider and bring them to the string form. Now let's see if there is a flag CMT:, if there is, then this incoming message put the flag isMessage in the state 1, we need this in order to read the text of the message. Remember the function parseString, which we have written in previous tutorials for the Arduino IDE? We're gonna need it here. I translated it to MicroPython, and You just need to copy and paste it into your project ;)

    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
    

    For those who do not remember or have not read past lessons - the parseString function takes three arguments and returns a line segment located between the delimiters: idSeparator (int), separator (char), str2 (String). Where idSeparator - separator sequence number; separator - separator; str2 - string from which we extract the substring.

    For example:

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

    Will be displayed:

    +7XXXXXX0001
    

    And if you do so:

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

    That will be displayed:

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

    Figure 5.2

    Unfortunately Blockly does not allow us to implement our function normally today, but it's okay - there is a workaround to make MicroPython-insert (figure 5.3 - 5.3.1).

    Figure 5.3

    Figure 5.3.1

    When will come SMS to call feature-event IncomingSms. And the sender number and message text will be in the global variables IncomingSmsPhone and IncomingSmsMessage, respectively.

    Figure 5.4

    The lesson is finished! :)

    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)

    Example not yet written ^_^

    Downloads

    Alas, there is nothing here today :)



  • Is there Arduino code available? I have some problems with the examples added to the library.