• Experience with GSM modem SIM900. GSM module control with AVR

    So, after a long time of lighting up the intricacies of working with GSM module SIM900D we announce the first working project that combines a security system with the ability remote control. In short, the device is capable of sending informing SMS if the intrusion sensor is triggered, making calls to enable audio monitoring of the room, monitoring the temperature and sending it via SMS upon request, as well as controlling some load based on a command sent via SMS.

    Anyone who has followed this topic knows that I have a GSM module and a control module for it - two different boards, connected by a sandwich (see board with SIM900D and control board). On the control board, in addition to the ATmega32a microcontroller, there is a power module made on an LM2596 converter; it powers the circuit constant voltage 3.5 volts. In principle, any other power source will do, the main thing is that it is capable of briefly drawing up to 2 amperes (this is exactly the consumption of the GSM module at the time of registration).

    For the sake of convenience, a display from a Nokia3310 phone is connected to the control board, the methods of working with which have already been described more than once on this site. Thanks to the display, you can quickly determine the status of the device and the value of the sensors.

    As a result, the resulting connection diagram looked like this (clickable):

    The numbering of the microcontroller pins in the diagram is given for a DIP package, so if you repeat the circuit using a microcontroller in a TQFP package, be careful, the pin numbering is different. The microcontroller is clocked from an external quartz at 16 MHz.

    Line Control going from the collector of transistor Q2 to the PortD.4 pin of the microcontroller was added for reinsurance and is needed to monitor whether the module is turned on. Since the shutdown threshold for SIM900 is 3.2 volts, even with a slight voltage drop, the module will automatically turn off, while the microcontroller will continue to work and execute the program (the reset threshold for ATmega32a is 2.7 volts). In working condition on this line is low level. If the microcontroller detects that this line is high, the function will be executed restart GSM module.

    And this is what it looks like in action at the moment.

    After the final testing of the program, all this will be stuffed into the case, and the detachable connections will be sealed for reliability.

    The display shows basic information about the status of the device: the name of the operator, the quality of the communication signal, the temperature value from the 18b20 sensor, the status of the load output and the intrusion sensor, as well as the time and date.

    Video of module activation

    The time and date are taken from the clock built into the GSM module. For their operation, it is necessary to have a 3-volt battery connected to pin 15 (VRTC). It is recommended to install diode D1 with a low voltage drop, for example Schottky. Setting the clock and date is done manually, the commands were described earlier

    The date is displayed on the display in the format as received from the module, that is, first the year, then the month and date. I haven't changed anything here yet.

    The DS18B20 sensor is responsible for temperature measurement; it is connected to the PortD.3 pin of the microcontroller.

    You can connect any load to PortD.6 and control it via SMS commands. I now have an LED hanging - D4 on the diagram. But nothing prevents you from hanging a relay or triac here and controlling something more serious.

    For security purposes, it is planned to use a motion sensor HC-SR501, purchased on E-bay. If triggered, a logical one appears at the sensor output. Having caught it, the microcontroller will give a command to send SMS messages By phone number specified in the program.

    The sensor output is connected to the PortD.7 pin of the microcontroller; in the diagram, the sensor is conventionally replaced with a button.

    Instead of a motion sensor, you can install any other means of intrusion detection - window and door opening sensors, glass break sensors, photoelectric sensors, etc. in general, everything your imagination can do.

    In order to prevent repeated sending of warning SMS in the event of a sensor activation, a restriction has been introduced into the program: after the first SMS sent, a ban is placed on subsequent sending. To re-enable the sending of notification messages when the sensor is triggered, you need to send an SMS with a specific command to the module. When sending SMS is prohibited, an exclamation mark will appear on the display next to the sensor status.

    List of commands

    And here is the list of commands in SMS that the module processes. For convenience and simplicity, the commands are digital, possibly in next versions the firmware will have more meaningful command names :)

    0 – Load disconnection (pin PortD.6 is set to logical 0)

    1 – Turn on the load (pin PortD.6 is set to logical 1)

    2 – Having accepted this command, the module will call back the telephone number specified in the program

    3 – Request your balance and send it via SMS back to the specified number. There's one here important nuance– answers to USSD requests must come in Latin. Otherwise, instead of meaningful text, the response will be a message in hexadecimal encoding. You need to check with your operator how to convert USSD to Latin. For example, on the SIM card I use from Smarts, you need to enter *102*1# (in the megaphone *105*0#)

    4 – Temperature request. The temperature value will be sent to us via SMS.

    5 – Allow sending messages if the intrusion sensor is triggered.

    6 – Prohibition of sending notification SMS from the intrusion sensor.

    ? – With this command, the module will send us an SMS containing general information about the device, such as the value from the temperature sensor, whether the load is on, the input status from the intrusion sensor and whether sending notification SMS from it is allowed. For example, this is what a message might look like: temperature +24, load off, motion sensor output 0, sending SMS if triggered is prohibited.

    Now how to configure the module to send SMS to your number. In the archive with the program we find the main file of the program, it is called “program” 🙂 and we find a constant in it:

    Const Phonenumber = “+7908390xxxx”

    We substitute your phone number here, compile the program and get a hex firmware file.

    The program, as always, is written in Bascom-AVR, so understanding the algorithm for working with the GSM module is quite simple. Good luck!

    And finally, a demonstration of how the module processes commands.

    Special thanks to long-time site friend Sergei RD3AVJ for participation and assistance in development!

    UPD: from 10/31/12

    I have slightly modified the firmware, now in order to set the number to which notification SMS will be sent, you do not need to recompile the program. It is enough to send an SMS with a message to the module "First number"(without quotes) and the number from which this command was sent is recorded in the non-volatile memory of the microcontroller.

    Can be used in devices where communication is required long distances. For example, a person controls a robot in Moscow while sitting in Krasnodar! Or a farmer turns on the water pump in a rice field from his home, located several kilometers from the field! There are several options for communicating with the device:

    Simple communication based on SMS messages:
    Turn on/off the device using simple SMS commands. You can use any mobile phone to control the device.
    Security/fire alarm system that informs the owner about emergency in the house via SMS.

    Call based communication:
    A smart burglar/fire alarm that calls the police or fire department and reports an emergency using pre-recorded voice messages.

    Communication using the Internet (GPRS):
    The user can control the device from any PC/tablet/mobile phone connected to the Internet. For example, information displays installed on highways are controlled from a central control room.
    Robot controlled via the Internet. Such a robot is accessible from any device connected to the Internet from anywhere in the world.
    Portable devices installed in vehicles that connect to the Internet using the SIM300 GPRS module and add the current position (using GPS (Global Position System, Global System Positioning)) to the server. This data is saved from a database on the server along with the vehicle ID. To view the vehicle route, you can connect to the server from your computer using World Wide Web (World Wide Web).

    Benefits of using SIM300 module

    The SIM300 Kit is completely independent module with SIM card connector, power supply, etc. This module can be easily interfaced with low cost AVR/PIC/8051 microcontrollers. Communication with the microcontroller is carried out through an asynchronous serial port. This is the basic type of serial communication that is supported in hardware by most microcontrollers. Data is transferred bit by bit and collected into bytes. On high level it looks like a simple text stream. There are two flows in total: one from the microcontroller to SIM300 and the other from SIM300 to the microcontroller. Commands are sent as plain text.

    If you have never used serial data transmission or heard of it, then it is advisable to understand how it works and practice with simpler examples.

    Communication with SIM300 module using AVR UART

    The microcontroller hardware used for serial communication is called UART and we use it to communicate with the SIM300 module (It can also be used to communicate with other devices such as RFID readers, GPS modules, fingerprint scanners, etc.). UART is a very common communication method in the electronics world, we wrote a clean and simple library for it that we use in all our UART projects.

    Since a byte from SIM300 can arrive at the microcontroller at any time, what happens if the microcontroller is busy with something else? To solve this problem, we made interrupt-based buffering of incoming data. The buffer is in RAM microcontroller. It has a function that allows you to determine the number of bytes in the queue.

    Below are the functions of the AVR USART library:

    void USARTInit(uint16_t ubrrvalue)

    Initializing the AVR USART hardware. Parameter value ubrrvalue the desired data transfer rate is set. Default data rate for SIM300: 9600 bps. For AVR microcontroller operating at 16 MHz value ubrrvalue for such a speed there should be 103 .

    char UReadData()

    Reading one character from the queue. If there is nothing in the queue, then the answer is 0.

    void UWriteData(char data)

    Writes one byte of data to the Tx line using the UWriteString() function.

    uint8_t UDataAvailable()

    Reports the amount of data in the FIFO queue.

    void UWriteString(char *str)

    Writes a null-terminated C-style string to the Tx line.
    Example 1: UWriteString("Hello World !");
    Example 2: char name="Avinash !"; UWriteString(name);

    void UReadBuffer(void *buff,uint16_t len)

    Copies the contents of the FIFO buffer into the memory specified by buff, the amount of data copied is determined by the len parameter. If less data than necessary (in accordance with the len parameter) was received via UART into the FIFO buffer, then the remaining space will be filled with zeros.

    char gsm_buffer;
    UReadBuffer(gsm_buffer,16);

    The above example will read 16 bytes of data (if any) from the FIFO buffer into a variable gsm_buffer. note that gsm_buffer a 128 byte array is allocated because we may need more than 16 bytes later. Thus, this buffer can be used to read up to 128 bytes in the future.

    The function shown above is usually used in conjunction with UDataAvailable().

    while(UDataAvailable()<16)
    {
    //Do nothing
    }

    char gsm_buffer;
    UReadBuffer(gsm_buffer,16);

    The code snippet shown above waits until there are 16 bytes of data in the buffer and then reads it.

    void UFlushBuffer()

    Cancels the FIFO buffer from waiting for data. Before sending a new command to the GSM module, first cancel the FIFO buffer waiting for data.

    The above functions are used to send and receive text commands from the SIM300 GSM module.

    AT command set for SIM300

    Now that you are familiar with the basics of the AVR USART library and how it is used to initialize the USART and send and receive data, it is time to learn the SIM300 module commands and how to send them and receive responses. SIM300 has several functions: sending text message, calling, etc. Each of these functions is executed after a specific command, and SIM300 has its own set of commands.

    All SIM300 commands begin with a prefix AT+ and end Carriage Return(abbreviated as carriage return). The ASCII code for CR is 0x0D (decimal 13). All commands you send to SIM300 will be returned on the SIM300 TX line. That is, if you send a command of 7 bytes (including the final CR), then you will immediately receive these 7 bytes into the buffer via UART. If you don't receive it, it means something is wrong!

    The first function we will study will be SIM300Cmd(const char *cmd), it does the following:

    • Writes commands specified by the parameter cmd.
    • Adds CR after the command.
    • Waits for the command to return, and if it arrives before the timeout, it responds SIM300_OK(constant defined in sim300.h). If you waited too long for a refund and it didn’t arrive, she responds SIM300_TIMEOUT.

    Note: All SIM300 dependent functions are stored in the file sim300.c. Patterns and constants are stored in sim300.h

    Working with SIM300Cmd()

    Int8_t SIM300Cmd(const char *cmd) ( UWriteString(cmd); //Send Command UWriteData(0x0D); //CR uint8_t len=strlen(cmd); len++; //Add 1 for trailing CR added to all commands uint16_t i= 0; //Wait for echo while(i< 10*len) { if(UDataAvailable() < len) { i++; _delay_ms(10); continue; } else { //We got an echo //Now check it UReadBuffer(sim300_buffer,len); //Read serial Data return SIM300_OK; } } return SIM300_TIMEOUT; }

    The command is usually followed by a response. The response form is:
    LF- Line Feed, its ASCII code is 0x0A (10 in decimal)

    So, while waiting for a response after sending a command, three things can happen:

    • There is no answer for a long time. A likely cause could be that the SIM300 is not connected to the microcontroller.
    • The answer was received, but not the one expected. The cause could be a faulty serial line, an incorrectly set baud rate, or a microcontroller operating at the wrong frequency.
    • Correct answer received.

    For example, the command Get Network Registration(Network registration) is performed as follows: Command String: " AT+CREG?"

    Response(Answer): +CREG: , OK

    You see the correct answer is 20 bytes. That is, after sending the command "AT + CREG?" you must wait until 20 bytes are received or until a certain time has elapsed. The second condition is met to avoid freezing if the SIM300 is faulty. That is, instead of waiting forever for a response, an error will be thrown if the SIM300 takes too long to respond (this is called a timeout)

    If the correct answer is received, then we analyze the variable to obtain information about registration in the network.

    Depending on the current state of registration in the network, the value may be: 0 - Not registered, SIM300 is not currently looking for a new operator to register. 1 - Registered in the home network. 2 - Not registered, SIM300 is currently looking for a new operator to register. 3 - Registration was denied. 4 - Unknown. 5 - Registered, roaming.

    Working with SIM300GetNetStat()

    Int8_t SIM300GetNetStat() ( //Send Command SIM300Cmd("AT+CREG?"); //Now wait for response uint16_t i=0; //correct response is 20 byte long //So wait until we have got 20 bytes // in buffer. while(i<10) { if(UDataAvailable()<20) { i++; _delay_ms(10); continue; } else { //We got a response that is 20 bytes long //Now check it UReadBuffer(sim300_buffer,20); //Read serial Data if(sim300_buffer=="1") return SIM300_NW_REGISTERED_HOME; else if(sim300_buffer=="2") return SIM300_NW_SEARCHING; else if(sim300_buffer=="5") return SIM300_NW_REGISTED_ROAMING; else return SIM300_NW_ERROR; } } //We waited so long but got no response //So tell caller that we timed out return SIM300_TIMEOUT; }

    The function is implemented in exactly the same way: int8_t SIM300IsSIMInserted()

    With another type of response, we do not know in advance the exact size of the response as in the above command. For example, this is the Get Service Provider Name command, where the length of the operator name is unknown in advance. This could be MTS, Beeline, etc. To solve this problem, we use what is located before and after the answer CR LF. So we simply buffer all characters until we encounter CR, which means the end of the answer.

    To simplify the processing of such commands, we created a function
    SIM300WaitForResponse (uint16_t timeout)

    This function waits for a response from SIM300 (the end of the response is indicated by CR) and reports the size of the response, while the response itself is copied to a global variable sim300_buffer.

    If the response is not received before the timeout, then the response is 0. The timeout time in milliseconds can be set with the parameter timeout. It does not count late LFs or last OKs, they remain in the UART FIFO buffer. So before returning we use the command UFlushBuffer() to remove them from the buffer.

    Working with SIM300WaitForResponse (uint16_t timeout)

    Int8_t SIM300WaitForResponse(uint16_t timeout) ( uint8_t i=0; uint16_t n=0; while(1) ( while (UDataAvailable()==0 && n

    Working with SIM300GetProviderName (char *name) The function does the following:

    1. Clears the USART buffer to remove any errors or responses.
    2. Sends the command "AT+CSPN?" using the SIM300Cmd function ("AT + CSPN?");
    3. It then waits for a response using the SIM300WaitForResponse() function
    4. If we get a non-zero response, it parses it to get the name of the operator.

    The following functions are implemented in a similar way:

    • uint8_t SIM300GetProviderName(char *name)
    • int8_t SIM300GetIMEI(char *emei)
    • int8_t SIM300GetManufacturer(char *man_id)
    • int8_t SIM300GetModel(char *model)
    uint8_t SIM300GetProviderName(char *name) ( UFlushBuffer(); //Send Command SIM300Cmd("AT+CSPN?"); uint8_t len=SIM300WaitForResponse(1000); if(len==0) return SIM300_TIMEOUT; char *start,*end ; start=strchr(sim300_buffer,"""); start++; end=strchr(start,"""); strcpy(name,start);

    SIM300 and ATmega32. Hardware

    To demonstrate communication with SIM300 using AVR ATmega32, we will need the following components:
    - ATmega32 with wiring – reset register, ISP pins, 16 MHz quartz.
    - +5V source for powering ATmega32 and LCD display.
    - 16x2 character LCD display to indicate results.
    - SIM300 module.

    We used the Xboard development board because it has an ATmega32 with harness, a +5V supply, and an LCD display.

    Demo source code for AVR and SIM300

    The demo source code is written in C and compiled using the free AVR-GCC compiler, using the latest . The project is divided into the following modules:

    • LCD Library
      - Files lcd.c, lcd.h, myutils.h, custom_char.h
      - Its job is to control a standard 16x2 LCD display.
      - More detailed information can be found at the link.
    • USART Library
      - Files usart.c, usart.h
      - Her job is to control the hardware USART microcontroller AVR. Includes USART initialization, character send/receive, and string send/receive functions.
    • SIM300 library
      - Files sim300.c, sim300.h

    Step-by-step setup of an AS6 project

    Create a new AS6 project called "Sim300Demo".
    Using solution explorer (project tree) create a folder named "lib" in the current folder.
    Inside the "lib" folder, create the folders "LCD", "USART" and "SIM300".
    Copy the files (using Windows Explorer) lcd.c, lcd.h, myutils.h, custom_char.h to the lcd folder.
    Copy the files (using Windows Explorer) usart.c, usart.h to the USART folder
    Copy the files (using Windows Explorer) sim300.c, sim300.h to the SIM300 folder.
    Add the files lcd.c, lcd.h, myutils.h, custom_char.h to the project using the solution explorer (project tree).
    Add filesusart.c, usart.h to the project using the solution explorer (project tree).
    Add files sim300.c, sim300.h to the project using the solution explorer (project tree).
    Define F_CPU = 16000000 AS6 usage.
    Copy and paste the main Sim300Demo.c file into the program.
    Compile the project to get a hex file.
    Flash Xboard using a USB programmer.
    If you are using a new ATmega32 microcontroller, set LOW FUSE to 0xFF and HIGH FUSE on 0xC9.

    What does the demo program do?

    Initializes the LCD display and SIM300 module.
    Verifies that the SIM300 module is connected to the USART and responds as expected.
    Displays the IMEI of the SIM300 module.
    Displays manufacturer ID
    Checks the presence of a SIM card.
    Searches for a GSM network and establishes a connection. To do this, you must have an active SIM card.
    Shows the name of the operator, such as MTS or Megafon.

    Possible problems

    No image on LCD

    Make sure your AVR Studio project is set to 16 MHz clock speed (16000000Hz)
    Adjust the contrast with the potentiometer.
    Press the reset button several times.
    Turn the device on/off several times.
    Connect the LCD only as shown in the diagram.

    "No Response" error appears during SIM300 initialization

    Check the integrity of the Rx, Tx and GND lines between SIM300 and Xboard.
    Make sure the microcontroller is running at 16 MHz.
    Set the fuses exactly as described above.

    Compiler errors

    Many people use programs that have already been written and compiled. They lack experience and are not familiar with the basics of programming and compilation. Getting familiar with compilers and how they work on different platforms (PC/MAC/Linux) is a great start. Embedded systems are not suitable for learning the basics. They are intended for those who have these skills and simply use them.
    Make sure all LCD library files are added to the project.
    Make sure AVR-GCC is installed. (Windows distribution is called WinAVR)
    Make sure your AVR Studio project is set to AVR GCC.

    General tips for beginners

    Use ready-made debug boards and programmers.
    Try to study based on articles and textbooks.

    List of radioelements

    Designation Type Denomination Quantity NoteShopMy notepad
    U1 MK AVR 8-bit

    ATmega32

    1 To notepad
    U2 Linear regulator

    LM7805

    1 To notepad
    D1 Rectifier diode

    1N4007

    1 To notepad
    D2 LED 1 To notepad
    C1, C2 Capacitor22 pF2 To notepad
    C3, C4, C6 Capacitor0.1 µF3

    The experience of using SIM900 described below will be more useful to those who have already worked a little with the module. For those readers who are just starting to study this microcircuit and plan to use it to exchange data via the Internet, we have prepared a series of lessons on this topic. Here .

    So, SIM900 is a GSM module from SIM COM, controlled by AT commands, able to send SMS, make calls, organize a direct CSD connection, and exchange information via GPRS.

    In my hands was a SIM900 GPRS shield debugging board ordered from China - compatible with the Arduino platform.

    The board contains the SIM900 chip itself, connectors for a microphone and headphones, a power supply switch (from an external connector or from Arduino), an antenna, several LEDs to indicate operating modes, a connector for a battery (if you need a real-time clock), and an on/off button. I found a good description on the manufacturer's wiki . There is also code for controlling the modem in various modes.

    As the manufacturer tells us, the board is perfectly compatible with Arduino Uno. Indeed, the SIM900 board simply plugs into the Uno and immediately starts working. However, as it turned out, the Arduino Uno may turn out to be “weak” for implementing some functions, but I’ll talk about this below.

    The board works with Arduino Mega with some restrictions. This is due to the fact that Mega, unlike Uno, has pins 7 and 8, which are not available for use as software serial (software USART). This can be solved by switching the USART interface to legs 0 and 1; for this purpose, jumpers are provided on the SIM900 board.

    In general, the board can be connected to any controller with a USART interface. For example, I tried to control the modem using the STM32F4 controller.

    SIM900: SMS messages and calls

    Testing of the module for exchanging SMS messages and calls was a great success! The module coped with these tasks without any problems, for this I simply copied c same site, compiled and flashed this code in Arduino Uno:

    //Serial Relay - Arduino will patch a //serial link between the computer and the GPRS Shield //at 19200 bps 8-N-1 //Computer is connected to Hardware UART //GPRS Shield is connected to the Software UART #include SoftwareSerial GPRS(7, 8); unsigned char buffer; // buffer array for data receive over serial port int count=0; // counter for buffer array void setup() ( GPRS.begin(19200); // the GPRS baud rate Serial.begin(19200); // the Serial port of Arduino baud rate. ) void loop() ( if (GPRS .available()) // if date is comming from softwareserial port ==> data is comming from gprs shield ( while(GPRS.available()) // reading data into char array ( buffer=GPRS.read(); // writing data into array if(count == 64)break; ) Serial.write(buffer,count); // if no data transmission ends, write buffer to hardware serial port clearBufferArray(); data from the array count = 0; // set counter of while loop to zero ) if (Serial.available()) // if data is available on hardwareserial port ==> data is comming from PC or notebook GPRS.write(Serial .read()); // write it to the GPRS shield ) void clearBufferArray() // function to clear buffer array ( for (int i=0; i

    In order to send commands to the module, it must be connected to a computer. This can be done using the Arduino USB port. On a computer, you need any COM port monitor for this. You can download it from here, or you can use the monitor built into the Arduino IDE.

    All the firmware Arduino program does is “catch” user commands and send them to the module, and then return responses to the SIM900 to the user. Thus, by manually transmitting AT commands to the module, I tested the reception and transmission of SMS messages, and by connecting a microphone and headphones to the appropriate connectors, I used the SIM900 module as a mobile phone.

    Data transfer via GPRS using SIM900

    I began my first experiments in data transfer via GPRS using the Arduino UNO platform to control the SIM900 (simply because it was at hand). To begin with, I bought hosting with a server running Apatche and deployed a simple application on it that could skillfully respond to GET requests. It worked! I still sent commands from the PC to the Arduino controller, which in turn sent them to the SIM900.

    Everything worked correctly as long as the GET requests were short enough (up to 100 characters). But as soon as the requests became longer, failures began: the requests were not transmitted completely. It has been noted that glitches can appear or disappear even when increasing/decreasing the Arduino control program by several lines. Subsequently, it turned out that the failures were related to the software USART, which the Arduino UNO uses to communicate with the SIM900, because such a USART is entirely dependent on the program cycle of the controller core. If the amount of data is small, it always has time to be transmitted, and if its amount increases, the result of the transmission depends on the duration of the program cycle.

    Conclusion from all of the above: it is IMPOSSIBLE to use software USART when communicating with SIM900, especially when it comes to a large amount of transmitted data.

    The Arduino Uno has only one “hardware” USART interface, which was used for exchange with a PC, so we had to abandon the UNO, replacing it with the Arduino Mega, which does not suffer from the lack of “hardware” USARTs. After such a “castling,” the operation of the device became stable and correct.

    SIM900: TCP-IP stack or HTTP? Which is better?

    While studying the modem management manual, I discovered that there are two groups of AT commands. The first group is used to transmit data via the built-in TCP-IP stack, and the second uses the HTTP protocol already implemented by the internal logic of SIM900. No matter how much I tormented Google and Yandex trying to find out how these methods differ, what the pros and cons of each of them are, I couldn’t find anything, so I tried both and am sharing my practical experience here.

    Both methods are working and have a right to exist.

    The TCP-IP stack is a little more difficult to initialize (more commands need to be passed to the module), and it is a little more difficult to manage. In order to send a request, you need to open a connection, wait for a response, and close it correctly.

    HTTP is, in simple terms, a browser built into the SIM900. It is easy to initialize; in order to start communicating with the server, you need to open a session. At the same time, opening and closing a connection with each request and solving other “organizational tasks” fall on the shoulders of SIM900. This is convenient, and data transfer in this way is somewhat faster, precisely because SIM900 can perform all “auxiliary operations” faster than the control controller can do.

    Thus, when choosing the exchange method, I still settled on the HTTP protocol.

    Incorrect GET request to the server

    At the very beginning of my work transmitting data via GPRS, I made a mistake that cost me more than one day of torment. Not having sufficient experience in interacting with the server via GET requests, I, having gained superficial knowledge on the Internet, compiled a request like:

    GET http://xxx.ru/d_command.php?UC=1111 HTTP/1.1
    HOST: xxx.ru

    This request is not correct, but it was perfectly “eaten” by the browser and the proxy server from which I sent requests for debugging - that’s why I considered the request correct.

    The most surprising thing is that SIM900 also coped well with a “bad” request (and I was sending requests through the TCP-IP stack back then). However, one fine day the server began to respond to such requests with error 404. This happened due to circumstances that have not yet been clarified, either the hosting provider changed the algorithms for processing the request (he denies this), or the mobile operator did it. But the fact remains a fact. Then I tried to send the same request via HTTP - everything worked. This is explained by the fact that the internal HTTP protocol of the SIM900 module (as I already said, essentially a built-in browser) is able to correctly “parse” incorrect requests and broadcast them to the network in the correct form. This is another advantage (dubious, of course) of using HTTP, since it allows the programmer some inaccuracies. In general, of course, the request must be written correctly and look like this:

    GET /d_command.php?UC=1111 HTTP/1.1
    HOST: xxx.ru

    With such a correct request, SIM900 successfully exchanges both via the TCP-IP stack and via HTTP.

    SIM900 freezes

    Sometimes, when exchanging via GPRS, situations arise after which the module may freeze. This could be due to incorrect data that arrived over the network and drove SIM900 into a stupor, or interference on the exchange line of the module and controller, in which SIM900 received “not what it expected,” or some other unknown problem. The chip manufacturer warns that this can happen and suggests that in such cases, reboot the module using a special sequence of pulses applied to the PWRKEY input.

    However, as it turned out, this does not always help - after such a reboot, the module may “wake up” still “glitchy”. And the manufacturer also warns us about this if we carefully read the DataSheet for the module. Here's what the documentation recommends:

    NOTE: It is recommended to cut off the VBAT power supply directly instead of using external reset pin when SIM900 can not respond to the AT command “AT+CPOWD=1” and PWRKEY pin.

    Therefore, the most correct way to reboot the module is to completely remove power from it (from the VBAT pin), wait for a pause (at least a second just in case) and reapply power. To reboot the module, it is better to provide a relay or transistor switch on the board, controlled by the controller.

    Conclusion

    In the future, I plan to release a series of article-lessons in which I will tell you how to organize an exchange between a server web application and SIM900, starting with purchasing hosting from a provider and ending with writing control program code.

    Goodbye! Stay tuned for updates on LAZY SMART .

    Finally, I managed to start studying perhaps the most popular GSM module in the DIY environment - GSM900. What is a GSM module? This is a device that implements the functions of a cell phone. In other words, GSM900 allows you to call other cellular network subscribers, receive calls, send and receive SMS messages. And, of course, transmit data using the GPRS protocol.

    I needed this module for a very specific purpose: I came up with a project for a lighting system controlled remotely. The easiest way to solve this problem is by SMS messages: send one SMS - the light turns on, send another - it turns off. You don’t need any remote controls, and everyone has a phone (even homeless people). Actually, in this article I will consider exactly this option for using the GSM900 module.

    1. Firmware

    As fate would have it, I ended up with the GSM900A module in my hands. After reading the first forum I came across about the revival of this thing, it turned out that the letter A in the name means that the module belongs to the Asian region. And therefore, he will not work with our operators. Despondency 🙁

    Fortunately, the following posts on the same forum contained reassuring information :) It turned out that not everything is so bad, and in order for the module to work in our region, it simply needs to be reflashed. This process is well described in the blog of our colleague Alex-EXE: “all in one” sim900 firmware
    I'll try to do the same thing, but in even more detail, and taking into account the features of my module.

    If you have the correct module and no firmware is required, you can immediately jump to section No. 2.

    Tools

    So, first, let's prepare all the necessary tools. Firstly, directly for the firmware you will need the SIM900 Series download Tools Develop application, which can be easily found on the Internet ().

    Secondly, the firmware file itself 1137B02SIM900M64_ST_ENHANCE will also be useful, which is also easy to obtain ().

    Finally, thirdly, we will need a good terminal to experiment with the module. I usually use TeraTerm, but this time its capabilities were not enough (or I didn’t understand it). I had to install a monster with a brilliant name.

    Connection to USB-UART bridge

    Now we connect the RX and TX lines to the bridge. For the latter I used CP2102. In my case, contrary to logic, the RX and TX of the bridge were connected to the RX and TX of the GSM module symmetrically (and not crosswise, as is customary).

    You should also power the module from a stable and powerful source, since the peak current on the module can reach 2A (supposedly). Suitable for 4 AA size batteries. The complete connection diagram looks like this:

    SIM900
    CP2102 Gnd Gnd
    CP2102 +5V VCC_MCU
    CP2102 RX SIMR
    CP2102TX SIMT
    External +5V source VCC5
    External source Gnd Gnd
    RST

    This model does not have a reset button, so to flash the firmware we will need to throw the RST pin to ground for a couple of seconds. To do this, we will leave it hanging in the air for now.

    Module pre-configuration

    Before we start flashing the firmware, we will connect to the module and change its UART speed. To do this, launch the Terminal terminal, select the correct port, and set the exchange rate to 9600. After that, click “Connect”.

    All communication with the module occurs via AT commands.

    The first thing we tell the module will be the most primitive AT command: “AT”. This is a kind of ping to which the module must respond with the word “OK”.

    If everything went well and the module really answered “OK” to us, we send the speed setting command:

    AT+IPR=115200

    At the end of the command there must be a carriage return character - CR. In the ASCII table it has code 13 (or 0x0D in hexadecimal). The symbol will be inserted automatically if you check the “+CR” checkbox next to the input line in our terminal. Other terminals also have similar settings.

    In response to the entered command we will again receive “OK”.

    We will need this setting to speed up the firmware procedure. Otherwise, as Alex-EXE pointed out in his blog, the firmware will take about an hour.

    Setting up the program

    After all the wires are plugged into the right places and the module is prepared for firmware, launch the SIM900 Series download Tools Develop application. Setting up the program consists of just a few points:

    • In the Target field we indicate the target chip. For some reason I couldn’t upload the firmware to SIM900A, so I chose “SIM900”;
    • select the correct port in the Port field;
    • Set the Baud Rate to 115200;
    • finally, specify the firmware file in the Core File field (file with the cla extension).

    That's it with the settings.

    Firmware

    Now we strictly and consistently carry out six important steps.

    • We connect power to the module (our 4 batteries). The red power light should turn on and the status light should start flashing.
    • We connect USB-UART to the computer.
    • We close the RST wire to ground (remember that all this time it was hanging in the air).
    • Click the Start Download button in the program.
    • We count to three in our heads and lift the RST off the ground.

    We wait 6 minutes until the firmware is completed.

    What do we have after the firmware?

    Firstly, the module can now work with our operators. Secondly, we installed advanced firmware, among the features of which, for example, is receiving module coordinates from cell towers, working with email and access to an additional 2.5 MB of memory.

    2. Experiments with GSM module

    Let's now try to perform various useful operations with the module. First, enter your PIN code (if you have one):

    AT+CPIN=8899

    The module's response will be:

    CPIN: READY.

    After this we will receive some information from the module.

    AT+GMR - firmware identifier. AT+GSN - IMEI. AT+CPAS - status (0 – ready for work, 2 – unknown, 3 – incoming call, 4 – voice connection). AT+COPS? - information about the operator.

    Phone calls

    Now let's dial some number. This is done using the command:

    ATD+790XXXXXXXX;

    The semicolon at the end of the command is very important, don't forget about it!

    If someone calls the device during a UART session, the following message will be returned:

    You can answer the call (pick up) with the command:

    If headphones and a microphone are connected to the module, you can communicate with a remote subscriber as if using a regular cell phone.

    The command ends the call:

    Sending SMS

    First, let's enable text message mode:

    AT+CMGF=1

    and set the encoding:

    AT+CSCS= "GSM"

    The module also supports other encodings that are more convenient for automatic systems. But for our experiments, it is most convenient to use the GSM mode, in which the phone is specified in numbers, and the text of messages is written in ASCII encoding. Now let's send someone a message:

    AT+CMGS="+79123456789"

    And at the end of the command you need to add two service characters at once: CR and LF. In Terminal, this can be done by checking CR=CR+LF, or manually adding at the end of the line: AT+CMGS=»+79123456789″&0D&0A

    After entering this command, the “>” symbol will be received in response, indicating the beginning of entering a message. We write some text:

    Hello World!

    At the end of the message we will need to pass one of two special characters. To send a message, enter a character from the ASCII table with number 26. To cancel sending, enter a character with number 27.

    In the terminal we use, to send a character by code, you can use one of two expressions: in hexadecimal: $1A, and in decimal: #026

    Receive SMS

    If an SMS is sent to the device during a session, a message in the following format will be returned:

    CMTI: "SM",4

    here 4 is the number of the incoming unread message.

    AT+CMGR=4

    In response we get:

    CMGR: "REC READ","+790XXXXXXXX","","13/09/21,11:57:46+24" Hello World! OK

    In general, everything is simple. This is quite enough for us to realize our plans. For a deeper study of the capabilities of the GFM900, I recommend reading another article by Alex-EXE: at-commands for the gsm modem sim900

    3. Interaction with microcontrollers

    In general, in order to control external devices it is not at all necessary to pair the GSM900 module with another microcontroller. You can embed your own program into this module, which will do whatever you want with free GPIO pins. However, in most ready-made boards the GPIOs are not routed, so to create a prototype of the intended device, we will use the simplest Arduino Uno/Nano.

    Arduino and GSM900 will communicate via the same UART interface. To do this, connect these two devices according to the following scheme:

    GSM900 GND VCC_MCU SIMT SIMR
    Arduino Uno GND +5V RX TX

    Now let’s create a program that will catch SMS messages and light up the LED on leg No. 13 for a couple of seconds. With this we simulate control of some external device.

    Const String spin = "1234"; const int rel_pin = 13; String ss = ""; // Send a PIN code void sendPin())( String cmd = "AT+CPIN="+spin+char(0x0D); Serial.print(cmd); ) // Turn on the LED for 2 seconds void receiveSMS(String s)( digitalWrite(rel_pin, HIGH); delay(2000); digitalWrite(rel_pin, LOW); // Parse the string that came from the module void parseString(String src)( bool collect = false; String s = ""; for(byte i =0;

    We load the program onto the Arduino and test the system. If everything is done correctly, sending an SMS message to the device will turn on the LED for 2 seconds. Of course, instead of an LED, you can turn on/off a powerful relay to which the heating boiler in a country house is connected.