Blog

Envoi de sms depuis un module de developpement A9G pudding

Et oui! encore un article sur l’envoi de SMS! Cette fois nous allons le faire depuis un module A9G pudding. J’espère que ce sera le deuxième dans une série sur ce module. Mon projet est de faire un système de suivi GPS avec enregistrement du tracé sur une carte SD et envoi à la demande de la position par sms.

Je reprend là où j’ai laissé l’article précédent (
https://www.twiggotronix.com/fr/a9g-pudding-module-de-developpement/ ) qui explique comment mettre en place le sdk et uploader notre premier programme.

J’ai créé un repo sur github où vous pourrez trouver le code relatif à cet article :
https://github.com/twiggotronix/a9g-pudding-sms

J’avoue que je me suis grandement inspiré des exemples de démo qui sont plutôt bien faits. Ce code va envoyer un sms au démarrage du module pour signaler qu’il est en route et puis renvoyer le contenu des messages qu’il reçoit.

Configuration

La seule configuration est celle du numéro de téléphone qui va recevoir les messages. Il suffit de dupliquer le fichier include/app_main_example.h, le renommer en include/app_main.h et renseigner le numéro de téléphone (j’ai pas essayé d’autres formats mais ça marche bien avec le format “+336XXXXXXXX”). Cette manipulation permet d’ignorer le fichier dans git.

vous pouvez compiler et uploader le code comme ça et vous devriez recevoir un message contenant ” Ready and able! “.

Evénements

Nous pouvons savoir quand le module est enregistré sur le réseau et pret à communiquer (ou non en cas d’erreur) grâce aux événements. A chaque événement, la fonction EventDispatch est appelé avec un objet contenant des informations décrivant ce qu’il c’est passé (dans la boucle while de la tâche principale ). Par exemple, lorsque l’id de l’événement correspond à la constante API_EVENT_ID_NETWORK_REGISTER_SEARCHING , cela signifie que le module est en train de chercher le réseau. Vous pouvz trouver la liste des événements possibles dans /include/api_inc/api_event.h. l’événement

void EventDispatch(API_Event_t* pEvent)
{
    
    switch(pEvent->id)
    {
        case API_EVENT_ID_NO_SIMCARD:
            Trace(10,"!!NO SIM CARD%d!!!!",pEvent->param1);
            break;
       ....
    }
}

Note: Au moment où je pensais avoir quelque chose de stable, le module a arrêté de communiquer correctement… En ajoutant un cas dans le switch, j’ai pu voir que j’avais une erreur d’enregistrement sur le réseau ( API_EVENT_ID_NETWORK_REGISTER_DENIED ). Je ne suis pas sûr mais j’ai l’impression que cette erreur est venue du fait que mon antenne c’est détachée du module qui s’est mis à remarcher depuis…

Envoi de messages

Pour envoyer un message j’ai créé la fonction SendSMS (j’ai juste extrait la partie du code qui gère l’envoi dans la demo sms) qui prend en paramètre uint8_t message[] et l’envoi au numéro paramétré.

void SendSMS(uint8_t message[])
{
    uint8_t* unicode = NULL;
    uint32_t unicodeLen;
 
    Trace(1,"sms start send UTF-8 message");
 
    if(!SMS_LocalLanguage2Unicode(message,strlen(message),CHARSET_UTF_8,&unicode,&unicodeLen))
    {
        Trace(1,"local to unicode fail!");
        return;
    }
    if(!SMS_SendMessage(PHONE_NUMBER,unicode,unicodeLen,SIM0))
    {
        Trace(1,"sms send message fail");
    }
    OS_Free(unicode);
}
 
SendSMS("Ready and able!");

Réception des messages

Lors de la réception de l’événement API_EVENT_ID_SMS_RECEIVED on peut récupérer le contenu du message dans l’attribut pParam2 (pEvent->pParam2). Dans mon code, la fonction messageRecieved récupère le contenu et le renvoi par sms. Vous pouvez aussi récupéré le numéro qui a envoyé le sms reçu dans l’attribut pParam1 (qui contient les entêtes du message) mais ça demande un peu plus de travail pour l’extraire de la chaîne de caractères. N’hesitez pas à nous dire comment vous vous y prendrez!

void messageRecieved(uint8_t* content)
{
    char buffer[200];
    snprintf(buffer, sizeof(buffer), "Message received : %s", content);
    Trace(1, buffer);
    SendSMS(buffer);
}

void EventDispatch(API_Event_t* pEvent)
{
    switch(pEvent->id)
    {
        case API_EVENT_ID_SMS_RECEIVED:
            Trace(2,"received message");
            uint8_t* content = pEvent->pParam2;

            Trace(2,"message header:%s",header);
            Trace(2,"message content length:%d",contentLength);
            messageRecieved(content);            
            break;
    }
}

Send sms from an A9G pudding dev board

Yet another article on sending sms!! This time with a A9G pudding dev board. I hope this will be the second in a series of articles on this module. My project is to make a GPS tracking system that can save the coordinates to an SD card and send them by SMS when requested.

This article starts where the previous one left off (
https://www.twiggotronix.com/en/a9g-pudding-grps-gps-and-microcontroller-all-in-one/) which explains how get set up and upload your first program.

I created a git repo with all the code for this article :
https://github.com/twiggotronix/a9g-pudding-sms

I admit having shamelessly copied the sms example and adapted it to my needs! This code will send an sms on startup to tell us that the module is ready, and then relay all messages recieved to a configured phone number.

Configuration

The only configuration needed is the phone number to send messages to. We simply need to copy and rename include/app_main_example.h to
include/app_main.h and edit the phone number (I haven’t tried other formats but it works well for me with the “+336xxxxx” format with the country code, 33 being France).

You should be able to compile and upload the code and get a message containing “Ready and able!”

.\build.bat app

Events

We can know what state the module is currently in by observing events. This way we can know when the module is registered on the network and ready to comunicate or when an error occures. For each event, the
EventDispatch function is called with an object that contains more information. For example, when the event’s id corresponds to the
API_EVENT_ID_NETWORK_REGISTER_SEARCHING constant, we know that the board is searching for a network. You can find the list of available event constants in /include/api_inc/api_event.h

void EventDispatch(API_Event_t* pEvent)
{
    
    switch(pEvent->id)
    {
        case API_EVENT_ID_NO_SIMCARD:
            Trace(10,"!!NO SIM CARD%d!!!!",pEvent->param1);
            break;
       ....
    }
}

Note: Just when I thought I had something stable and working, the module stoped comunicating… By adding a case uin the switch, I was able to determine that I was getting an error while registering on the network (
API_EVENT_ID_NETWORK_REGISTER_DENIED ). I’m not 100% sure why but I think it was to do with the antena thatgot disconnected, it started working again later, probably because I fiddled about with it in frustration!

Sending messages

I made the SendSMS function (I actually just extracted what I needed from the sms demo and adapted it) that takes a uint8_t message[] parameter and sends the content.

void SendSMS(uint8_t message[])
{
    uint8_t* unicode = NULL;
    uint32_t unicodeLen;
 
    Trace(1,"sms start send UTF-8 message");
 
    if(!SMS_LocalLanguage2Unicode(message,strlen(message),CHARSET_UTF_8,&unicode,&unicodeLen))
    {
        Trace(1,"local to unicode fail!");
        return;
    }
    if(!SMS_SendMessage(PHONE_NUMBER,unicode,unicodeLen,SIM0))
    {
        Trace(1,"sms send message fail");
    }
    OS_Free(unicode);
}

SendSMS("Ready and able!");

Receiving messages

When we receive a message, the API_EVENT_ID_SMS_RECEIVED event is fired, we can get the contents of the message in the pParam2
(pEvent->pParam2). In my code, the function messageRecieved extracts the content of the message and relays it to my phone by sms. You could get the phone number of the person that sent the message in the pParam1 attribute that contains the message headers, but I didn’t need to. I would love to know how you go about it though!

void messageRecieved(uint8_t* content)
{
    char buffer[200];
    snprintf(buffer, sizeof(buffer), "Message received : %s", content);
    Trace(1, buffer);
    SendSMS(buffer);
}

void EventDispatch(API_Event_t* pEvent)
{
    switch(pEvent->id)
    {
        case API_EVENT_ID_SMS_RECEIVED:
            Trace(2,"received message");
            uint8_t* content = pEvent->pParam2;

            Trace(2,"message header:%s",header);
            Trace(2,"message content length:%d",contentLength);
            messageRecieved(content);            
            break;
    }
}

A9G pudding – GRPS, GPS and microcontroller all in one!

Not only does it have a cool name, this little dev board has a ton of functions :

GPS, SMS, Calls, Internet, Flash card reader, loads of I/Os, and much more…

The module responds to AT commands just like the A6 and A7 chips but I focused on using the build-in micro controller in C!!! No need for a seperate arduino, lowering cost, size and power requirements.

Getting set up and running under windows takes a bit of work but once it’s done, it works great!

Wiring:

setup your FTDI programmer module like this:

FTDIA9G
RX HST_TX
TX HST_RX
GNDGND
VCCDon’t connect

The board will be powered by an external phone charger pluged into the micro usb port.

Toolchain

The toolchain contains all the tools you’ll need to compile and run your code on the chip. You can download it here :
 http://test.ai-thinker.com/csdk/CSDTK42.7z (the documentation is here : https://ai-thinker-open.github.io/GPRS_C_SDK_DOC/en/c-sdk/installation.html)

Open PowerShell in admin mode and go to the CSDTK directory (or CSDTK42 in my case), and execute the config_env_admin.bat script. It will add all the environment variables you’ll need:

./config_env_admin.bat 

SDK:

Download the SDK :https://github.com/Ai-Thinker-Open/GPRS_C_SDK/releases/tag/V2.112 (the file GPRS_C_SDK_V2112.7z)

Open PowerShell again in admin mode and cd to the
GPRS_C_SDK directory. You will find a demo directory containg loads of examples!

To test our setup, we’re going to compile the “first” example :

./build.bat demo first

If all goes well, you should see the compiled version in the hex/first directory.

Getting our code on to the chip :

In the CSDTK42\cooltools directory, the coolwatcher.exe tool will allow us to send code to our dev board. When coolwatcher starts up, select profil 8955 and specify the lastcomport field (my FTDI is on port COM4) :

The first thing to do is select the programmer in the
« Flash > Choose Flash Programmer… » menu and choose the
CSDTK42\cooltools\chipgen\Modem2G\toolpool\plugins\fastpf\flash_programmershost_8955_flsh_spi32m_ramrun.lod file

Then we need to choose the compiled project in
« Flash > Choose LOD file… » and select the largest if the files we generated earlier : GPRS_C_SDK\hex\trackerfirst_B2112_debug.lod

To start uploading the code to the module, go to
« Flash > Launch fastpf with current LOD file and flash programmer ».

If all goes well you should have something like this :

This step didn’t work on the first go for me, check the connections and especially that the GND pins are connected. If that doesn’t work, click on the
« Restart Chip » button in coolwatcher and try again…

Once the upload has completed, go to the « Plugins > Activate Tracer » menu to see the debug info. You should see the « Hello GRPS » trace :

Voilà! We have programmed our module! now all we need to do is dig deeper into the examples to start having fun! 🙂

A9G pudding – GRPS, GPS et microcontrôleur tout en un

Ce petit module à tout faire est doté, en plus d’un nom qui donne faim, de fonctionnalités incroyables :

GPS, SMS, Appels, Internet, Emplacement carte flash, Entrées/Sorties à foison, et plein d’autres encore …

Ce module répond aux commandes AT comme pour les modules A6 et A7, mais je ne me suis pas trop intéressé à cet aspect car il est aussi programmable directement en C++!!! Du coup, pas besoin d’un autre microcontrôleur à côté!! On réduit donc les coûts, l’encombrement et la puissance nécessaire.

L’installation des dépendances sous Windows est un peu laborieux et n’est pas hyper intuitif, mais une fois que tout est en place c’est assez simple!

Branchement :

Branchez votre module de programmation FTDI au module comme ceci :

Programmateur FTDIModule A9G
RXHST_TX
TXHST_RX
GNDGND
VCCNE PAS BRANCHER!

Puis branchez une alimentation USB (5V – 2A) au module A9

Toolchain :

La toolchain contient tous les outils nécessaires à la compilation et au déploiement du code vers notre module. Téléchargez la ici : http://test.ai-thinker.com/csdk/CSDTK42.7z (la doc est ici : https://ai-thinker-open.github.io/GPRS_C_SDK_DOC/en/c-sdk/installation.html)

http://test.ai-thinker.com/csdk/CSDTK42.7z (la doc est ici : https://ai-thinker-open.github.io/GPRS_C_SDK_DOC/en/c-sdk/installation.html)

Ouvrez PowerShell en mode administrateur et placez vous dans le répertoire CSDTK (ou CSDTK42 dans mon cas), exécutez alors le script config_env_admin.bat qui va ajouter les variables d’environnement nécessaires :

./config_env_admin.bat 

SDK :

Téléchargez la SDK :https://github.com/Ai-Thinker-Open/GPRS_C_SDK/releases/tag/V2.112 (le fichier GPRS_C_SDK_V2112.7z)

Ouvrez de nouveau PowerShell en mode administrateur et placez vous dans le répertoire GPRS_C_SDK. Vous trouverez un répertoire demo contenant des exemple pour toutes les fonctionnalités!

Pour tester, nous allons compiler l’exemple first :

./build.bat demo first

Si tout se passe bien, vous verrez alors la version compilé dans le répertoire hex/first

Programmer le module :

Dans le répertoire CSDTK42\cooltools, l’utilitaire coolwatcher.exe permet de téléverser le code sur le module. Au lancement, sélectionnez le profil 8955 et précisez le port COM dans le champs lastcomport :

La première chose à faire est de sélectionner le programmateur dans le menu “Flash > Choose Flash Programmer…” et choisissez le fichier CSDTK42\cooltools\chipgen\Modem2G\toolpool\plugins\fastpf\flash_programmershost_8955_flsh_spi32m_ramrun.lod

Ensuite il faut choisir le projet compilé à téléverser en allant dans le menu “Flash > Choose LOD file…” et choisissez le fichier généré précédemment : GPRS_C_SDK\hex\trackerfirst_B2112_debug.lod (choisissez le fichier le plus lourd)

Pour lancer le téléversement, allez dans le menu “Flash > Launch fastpf with current LOD file and flash programmer”.

Si tout fonctionne bien vous devriez avoir ceci :

Cette étape n’a pas marché du premier coup pour moi, vérifiez l’ordre des branchements et surtout que les GND sont bien en commun. Si ça ne fonctionne toujours pas, cliquez sur le bouton “Restart Chip” dans coolwatcher.

Une fois l’upload terminé, allez dans le menu “Plugins > Activate Tracer” pour avoir accès à l’écran de debug. Vous devriez vois apparaître “Hello GRPS” :

Voilà! Nous avons programmé notre module! Il ne nous reste plus qu’à étudier les exemples et essayer de faire quelque chose de fun! 🙂

Librairie A6Smslib pour simplifier l’envoi d’un sms

Pour simplifier un peu le code de mon article “Envoyer des SMS avec un ESP8266 et un module A6” j’ai créé une librairie qui permet d’envoyer un sms et de voir l’état de l’envoi.

Vous pouvez le trouver sur github : https://github.com/davidtw/a6SmsLib

Exemple de code :

#include "A6SmsLib.h"

const String NUMBER = "00336XXXXXXXX";
const String MESSAGE = "whoop whoop!";

const int rx = D1;
const int tx = D2;
const int resetPin = D0;

A6SmsLib a6Sms(rx, tx, resetPin);

void statusUpdate(String state, String message)
{
  Serial.println("[statusUpdate] " + state + " : " + message);
}

void smsUpdate(String state, String message)
{
    Serial.println("[smsUpdate] " + state + " : " + message);
}

void setup()
{
    Serial.begin(9600);
    a6Sms.debug();
    a6Sms.begin();
    a6Sms.setStatusCallback(statusUpdate);
    a6Sms.setSmsCallback(smsUpdate);
    a6Sms.waitUntilReady();

    a6Sms.sms(NUMBER, MESSAGE);
}

void loop()
{
    a6Sms.loop();
}

Initialisation

Dans l’exemple j’ai configuré les entrées de la même manière que pour mon montage (D1 pour RX, D2 pour TX et D0 pour le redémarrer le module)

const int rx = D1;
const int tx = D2;
const int resetPin = D0;

A6SmsLib a6Sms(rx, tx, resetPin);

Activer le mode Debug

Active la sortie sur le port série de messages provenant de l’A6

a6Sms.debug();

Fonctions de rappel

a6Sms.setStatusCallback(statusUpdate);
a6Sms.setSmsCallback(smsUpdate);
  • setStatusCallback permet de spécifier la fonction a appeler à la mise à jour de l’état du module.
  • setSmsCallback spécifie la fonction a appeler après l’envoi d’un sms

La boucle

La fonction loop permet à la librairie de mettre à jour les états en fonction des retours du module. Il faut l’appeler à chaque itération.

L’envoi

L’envoi se fait avec la fonction SMS en précisant le numéro de téléphone du destinataire et le message.

Simple A6Smslib Librairy for sending sms with an A6 module

To simplify the code from my previous post “Send SMS with an ESP8266 and an A6 GSM module“, I created a small library to send SMS and get feedback on the state.

You can find it on github : https://github.com/davidtw/a6SmsLib

An example of code :

#include "A6SmsLib.h"

const String NUMBER = "00336XXXXXXXX";
const String MESSAGE = "whoop whoop!";

const int rx = D1;
const int tx = D2;
const int resetPin = D0;

A6SmsLib a6Sms(rx, tx, resetPin);

void statusUpdate(String state, String message)
{
  Serial.println("[statusUpdate] " + state + " : " + message);
}

void smsUpdate(String state, String message)
{
    Serial.println("[smsUpdate] " + state + " : " + message);
}

void setup()
{
    Serial.begin(9600);
    a6Sms.debug();
    a6Sms.begin();
    a6Sms.setStatusCallback(statusUpdate);
    a6Sms.setSmsCallback(smsUpdate);
    a6Sms.waitUntilReady();

    a6Sms.sms(NUMBER, MESSAGE);
}

void loop()
{
    a6Sms.loop();
}

Setup

In this example, i configured the pins according to my protoboard circuit (D1 pour RX, D2 pour TX et D0 pour le redémarrer le module)

const int rx = D1;
const int tx = D2;
const int resetPin = D0;

A6SmsLib a6Sms(rx, tx, resetPin);

Activate Debug mode

Call the debug method to allow debug messages to the serial output :

a6Sms.debug();

Callbacks

  • setStatusCallback specifies the function to be called when the module’s state updates
  • setSmsCallback specifies the function to be called when an sms has been sent, or attempted.

The loop

the loop function allows the library to update it’s internal states, it should be called on each loop.

Sending

Sending an sms is done with the sms function, you just need to give a number and a message to be sent.

Le tout assemblé et branché

Send SMS with an ESP8266 and an A6 GSM module

This article takes off from where I left off in the previous one (http://www.twiggotronix.com/en/send-sms-with-an-a6-gsm-module/), I recommend you read that one first.

In the previous article, we managed to send SMSs with an FTDI programmer board. This time we’re going to replace it with a microcontroller (ESP8266 in this case but it should work with just about any arduino).

What you’ll need:

More or less the same as for the previous article, plus a microcontroller. I used a WEMOS D1 mini :

Wemos D1 mini
Wemos D1 mini

I buy them straight from WEMOS Electronics, Delivery tends to be a bit long, but they’re cheap and really reliable.

Wiring

I made a bit of an effort this time 😉 and did the diagram out in fritzing :

Wiring diagram
Wiring diagram

I added a wire between D0 on the D1 and the RST pin on the A6 that will allow us to restart the module when we’re ready. Then I just added power and hooked up D1 and D2 respectiverly to UTX and URX on the GSM module.

At this point, I thought it would be a good idea to make things a bit more permanent and broke out a perfboard. This will make sure I don’t get errors due to wiring… You can however just leave everything on the breadboard.

Perfboard from above
Perfboard from above

Perfboard from bellow
Perfboard from bellow (sorry if my soldering job makes you nauseous…)

The assembled kit
The assembled kit

To the code!

Initialisation

Communication between our GSM module and our microcontroller is done using the standard softwareSerial librairy:

#include <SoftwareSerial.h>

#define RX_PIN D1 // Green wire
#define TX_PIN D2 // Orange wire
#define RESET_PIN D0 // Yellow wire

SoftwareSerial a6Serial(RX_PIN, TX_PIN);

void setup() {
    Serial.begin(9600);
    a6Serial.begin(115200); //The A6's defaul baudrate is 115200
    delay(500);
}
void loop() {}

Then we can restart our A6 module. This step is probably not necessary but allows us to keep track of the GSM module’s state.

void resetModule() {
    digitalWrite(RESET_PIN, HIGH);
    delay(200);
    digitalWrite(RESET_PIN, LOW); 
}

void setup() {
    Serial.begin(9600);
    a6Serial.begin(115200); //The A6's defaul baudrate is 115200
    delay(500);

    pinMode(RESET_PIN, OUTPUT);
    resetModule(); //restart the GSM module
}

To finish setting everything up, we need to wait for the module to connect to the GSM network, and then set SMS mode :

void waitUntilReady()
{
  Serial.println("Waiting for network");
  while(state == "initing" || state == "sms_mode") {  
    if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println(recievedA6);
      if(state == "initing" && recievedA6.indexOf("+CREG: 5") >= 0) {
        Serial.println("Mode sms");
        state = "sms_mode";
        delay(2000);
        a6Serial.println("AT+CMGF=1");  
      } else if(state == "sms_mode" && recievedA6.indexOf("OK") >= 0) {
        state = "ready";
        Serial.println("Ready!");
      }
    }
    yield(); // hands controll back to the ESP8266 to avoid wifi connexion loss
  }
}

Send an SMS

As seen in the previous article, sending an SMS is done using AT commands:

followed by the the message and Ctrl-Z:

void sendSms(String number, String message) {
  if(state == "ready") {
    Serial.println("Sending \"" + message + "\" to " + number);
    a6Serial.print("AT+CMGS=\"");
    a6Serial.print(number);
    a6Serial.write(0x22);
    a6Serial.write(0x0D);  // Return carriage in hexadecimal
    a6Serial.write(0x0A);  // New line in hexadecimal
    delay(2000);
    a6Serial.print(message);
    delay(500);
    a6Serial.println(char(26));// Control-Z in hexadecimal
  }
}

Just for the example, I send an SMS using a custom sendSMS command to the ESP8266 over  Serial :

void loop() {
  if(Serial.available()) {
    String received = Serial.readString();
    received.trim();
    if(state == "ready") {
      if(received == "sendSms") {
        sendSms(PHONE_NUMBER, MESSAGE);
      }
    }
  }
  if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println("[A6] " + recievedA6);
  }
}

The result is :

Result of sending an SMS
Result of sending an SMS

The full code

#include <Arduino.h>
#include <SoftwareSerial.h>

#define RX_PIN D1 // Green wire
#define TX_PIN D2 // Orange wire
#define RESET_PIN D0 // Yellow wire

#define PHONE_NUMBER "+336XXXXXXXXX" // Replace with your country code (+33 is for France) and phone number
#define MESSAGE "Whoop whoop"

SoftwareSerial a6Serial(RX_PIN, TX_PIN);
String state = "initing";

void resetModule() {
    digitalWrite(RESET_PIN, HIGH);
    delay(200);
    digitalWrite(RESET_PIN, LOW); 
}

void waitUntilReady()
{
  Serial.println("Waiting for network");
  while(state == "initing" || state == "sms_mode") {  
    if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println(recievedA6);
      if(state == "initing" && recievedA6.indexOf("+CREG: 5") >= 0) {
        Serial.println("Sms mode");
        state = "sms_mode";
        delay(2000);
        a6Serial.println("AT+CMGF=1");  
      } else if(state == "sms_mode" && recievedA6.indexOf("OK") >= 0) {
        state = "ready";
        Serial.println("Ready!");
      }
    }
    yield(); // hands controll back to the ESP8266 to avoid wifi connexion loss
  }
}

void sendSms(String number, String message) {
  if(state == "ready") {
    Serial.println("Sending \"" + message + "\" to " + number);
    a6Serial.print("AT+CMGS=\"");
    a6Serial.print(number);
    a6Serial.write(0x22);
    a6Serial.write(0x0D);  // Return carriage in hexadecimal
    a6Serial.write(0x0A);  // New line in hexadecimal
    delay(2000);
    a6Serial.print(message);
    delay(500);
    a6Serial.println(char(26));// Control-Z in hexadecimal
  }
}

void setup() {
    Serial.begin(9600);
    a6Serial.begin(115200); //The A6's defaul baudrate is 115200
    delay(500);

    pinMode(RESET_PIN, OUTPUT);
    resetModule(); //restart the GSM module
    waitUntilReady(); //Wait for the GSM network
}

void loop() {
  if(Serial.available()) {
    String received = Serial.readString();
    received.trim();
    if(state == "ready") {
      if(received == "sendSms") {
        sendSms(PHONE_NUMBER, MESSAGE);
      }
    }
  }
  if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println("[A6] " + recievedA6);
  }
}

Conclusion

We now have a small module that allows us to send SMSs! Now all we need to do is to turn it into an even more connected thing!

Le tout assemblé et branché

Envoyer des SMS avec un ESP8266 et un module A6

Cet article se base sur l’article précédent (Envoyer des SMS avec un module GSM A6), je vous recommande de le lire avant afin de comprendre d’où on part ici.

Dans l’article précédent, nous avons réussi a envoyer des SMS à l’aide d’un module FTDI. Nous allons maintenant voir comment faire la même chose avec un microcontrôleur (ESP8266 dans mon cas mais ça devrait fonctionner avec n’importe quel Arduino).

Ce qu’il faut:

La même chose que pour l’article précédent, plus un microcontrôleur, moi j’ai utilisé un module Wemos D1 :

Wemos D1 mini

Je les achète directement chez le fabricant (https://wiki.wemos.cc/products:d1:d1_mini), le temps de livraison est assez long (plusieurs semaines, a un mois pour arriver en France…) mais au moins on l’a au moins chère et je n’ai jamais été déçu en terme de qualité. Pour ceux qui ne connaissent pas, ils sont top! Ils embarquent un microcontrôleur programmable, une antenne wifi, 9 entrèes numériques, une entrée analogique, un convertisseur 5V en 3,3V et 4M de mémoire. C’est largement suffisant pour faire des objets connectés, même relativement complexes.

Le câblage

J’ai fait un effort ce coup-ci 😉 et j’ai fait le schéma sous fritzing :

Schéma de câblage
Schéma de câblage

J’ai ajouté un fil entre la borne D0 du Wemos D1 mini et le RST du module qui nous permettra de le redémarrer quand on serra prêt a communiquer avec lui. Sinon il s’agit juste de l’alimenter, et de raccorder D1 et D2 respectivement aux bornes UTX et URX du module.

A cette étape, j’ai préféré faire un câblage un peu plus permanent, ça permet d’éviter les problèmes de fils cavaliers ect… Mais vous pouvez tout aussi bien tout faire sur votre breadbord. J’ai donc utilisé un perfboard et soudé le tout ensemble :

Perfboard - vue de dessus
Perfboard – vue de dessus

Perfboard - vue de dessous
Perfboard – vue de dessous (avec soudures déguelasses…)

Le tout assemblé et branché
Le tout assemblé et branché

Côté code:

Initialisation

Pour dialoguer avec notre module GSM, nous allons utiliser la communication série à travers la librairie standard SoftwareSerial:

Ensuite nous pouvons redémarrer notre module A6. Cette étape n’est probablement pas nécessaire mais permet de s’assurer de l’état du A6 au démarrage.

void resetModule() {
    digitalWrite(RESET_PIN, HIGH);
    delay(200);
    digitalWrite(RESET_PIN, LOW); 
}

void setup() {
    Serial.begin(9600);
    a6Serial.begin(115200); //le baudrate par défaut de l'A6 est 115200
    delay(500);

    pinMode(RESET_PIN, OUTPUT); //Pour redémarrer le A6, ça nous permettra de mieux controller l'état du module
    resetModule(); //On redemarre le module
}

Pour finir l’initialisation, il faut attendre que le module soit prêt et connecté au réseau, puis le passer en mode SMS :

void waitUntilReady()
{
  Serial.println("En attente du réseau");
  unsigned long startTime = millis();
  while(state == "initing" || state == "sms_mode") {  
    if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println(recievedA6);
      if(state == "initing" && recievedA6.indexOf("+CREG: 5") >= 0) {
        Serial.println("Mode sms");
        state = "sms_mode";
        delay(2000);
        a6Serial.println("AT+CMGF=1");  
      } else if(state == "sms_mode" && recievedA6.indexOf("OK") >= 0) {
        state = "ready";
        Serial.println("Tout est prêt!");
      }
    }
    yield(); // redonne la main à l'esp8266 temporairement pour qu'il maintienne la connetion au wifi
  }
}

Envoyer un sms

Comme vu dans l’article précédent, l’envoi d’un sms se fait en envoyant la commande AT

suivi du message, puis Ctrl-Z pour envoyer :

void sendSms(String number, String message) {
  if(state == "ready") {
    Serial.println("Sending \"" + message + "\" to " + number);
    a6Serial.print("AT+CMGS=\"");
    a6Serial.print(number);
    a6Serial.write(0x22);
    a6Serial.write(0x0D);  // Retour chariot en hexadecimal
    a6Serial.write(0x0A);  // Nouvelle ligne en hexadecimal
    delay(2000);
    a6Serial.print(message);
    delay(500);
    a6Serial.println(char(26));// Control-Z en hexadecimal
  }
}

Pour l’exemple j’envoi un SMS en envoyant la commande sendSms à l’Esp8266 par l’objet Serial :

#define PHONE_NUMBER "+336XXXXXXXX"
#define MESSAGE "Whoop whoop"

void loop() {
  if(Serial.available()) {
    String received = Serial.readString();
    received.trim();
    if(state == "ready") {
      if(received == "sendSms") {
        sendSms(PHONE_NUMBER , MESSAGE );
      }
    }
  }
}

Ce qui donne :

Résultat de l'envoi d'un SMS
Résultat de l’envoi d’un SMS

Le code complet :

#include <Arduino.h>
#include <SoftwareSerial.h>

#define RX_PIN D1 // Fil jaune
#define TX_PIN D2 // Fil orange
#define RESET_PIN D0 // Fil jaune

#define PHONE_NUMBER "+336XXXXXXXXX"
#define MESSAGE "Whoop whoop"

SoftwareSerial a6Serial(RX_PIN, TX_PIN);
String state = "initing";

void resetModule() {
    digitalWrite(RESET_PIN, HIGH);
    delay(200);
    digitalWrite(RESET_PIN, LOW); 
}

void waitUntilReady()
{
  Serial.println("En attente du réseau");
  while(state == "initing" || state == "sms_mode") {  
    if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println(recievedA6);
      if(state == "initing" && recievedA6.indexOf("+CREG: 5") >= 0) {
        Serial.println("Mode sms");
        state = "sms_mode";
        delay(2000);
        a6Serial.println("AT+CMGF=1");  
      } else if(state == "sms_mode" && recievedA6.indexOf("OK") >= 0) {
        state = "ready";
        Serial.println("Tout est prêt!");
      }
    }
    yield();
  }
}

void sendSms(String number, String message) {
  if(state == "ready") {
    Serial.println("Sending \"" + message + "\" to " + number);
    a6Serial.print("AT+CMGS=\"");
    a6Serial.print(number);
    a6Serial.write(0x22);
    a6Serial.write(0x0D);  // Retour chariot en hexadecimal
    a6Serial.write(0x0A);  // Nouvelle ligne en hexadecimal
    delay(2000);
    a6Serial.print(message);
    delay(500);
    a6Serial.println(char(26));// Control-Z en hexadecimal
  }
}

void setup() {
    Serial.begin(9600);
    a6Serial.begin(115200); //le baudrate par défaut de l'A6 est 115200
    delay(500);

    pinMode(RESET_PIN, OUTPUT); //Pour redémarrer le A6, ça nous permettra de mieux controller l'état du module
    resetModule(); //On redemarre le module
    waitUntilReady(); // On attend d'être connecté au réseau GSM
}

void loop() {
  if(Serial.available()) {
    String received = Serial.readString();
    received.trim();
    if(state == "ready") {
      if(received == "sendSms") {
        sendSms(PHONE_NUMBER, MESSAGE);
      }
    }
  }
  if (a6Serial.available()) {
      String recievedA6 = a6Serial.readString();
      Serial.println("[A6] " + recievedA6);
  }
}

Conclusion

Nous voila avec un petit module qui nous permet d’envoyer des sms, il ne reste plus qu’à en faire un objet connecté (enfin, encore plus connecté!)

Send SMS with an A6 GSM module

AI Thinker, the makers of my favorite micro controller, the ESP8266 have done it again with the A6 GSM module allowing us to connect to the GSM network and send sms, connect to the internet and even make phone calls!

What you’ll need:

  • A6 GSM moduleAn A6 module (This is an A6 mini bought you can find on ebay, aliexpress ect.. for 5 to 10€)
  • Sim card A Sim card with a valid subscription. Remember to remove the pin before starting by inserting it into a phone and deactivating the pin number.
  • Breadbord and jumper wires A breadboard and some jumper wires.
  • FDTI programer module An FTDI programer (2 to 5€ on Ebay ou aliexpress)
  • micro USB breakout board A micro usb breakout board get power to it all easily
  • Power supply A relatively powerful wall wart (here I recycled a 5V/2A power supply from a raspberry pi I had laying around ). Sending sms takes quite a lot of power for sending.
  • CoolTerm A computer with Windows and CoolTerm

Wiring

A6 wiring diagram
Wiring scematic of the A6 module with an FTDI

As you can see, I used my awesome artistic skills to come up with this horrible diagram!!

We need to power the module with our phone charger, join the FTDI and A6 module neutrals and then connect the TX of the of the RX pin, of the A6 and vice versa.

The finished setup
The finished setup

To the code!

Once you have pluged the FTDI in, CoolTerm should find the COM port on it’s own. You can also find it in windows device manager :

Peripherals

In CoolTerm, set the baudrate to 115200 and click on Connect. It takes a few seconds but it should come up with something like this (if not, try unpluging and pluging the A6 module power back in again) :

Connecting to the GSM network

+CREG: 5 means the module was able to conect to the network and is ready to go!

If nothing comes up, check all the connections again, especially that the RX/TX pins.

Snding an SMS

To send an SMS, go to Connection -> Send String ou Ctrl-T. The AT command (for attention) followed by a new line will return the current state :

send AT commandAT serial response

 The module should answer “ok”, however in some cases I got CME 58 errors. I think it means that it temporarily lost the signal, just sending AT again should work.

Next, we need to set the module to SMS mode :

AT+CMGF=1

followed with a new line:

Setting SMS mode

And finaly, to send the message :

AT+CMGS="003361234567"

(replacing the phone number with your’s) It will ask you to enter your message :

Sending SMS

Wait a few seconds and you should have youself a new message on your phone!

Traps

I had a few problems due the poor quality of my chinese jumper wires… I was also using a faulty usb extender cable.

Here is a document that helped me with certain errors and AT commands : GSM Developer Guide – GSM AT Commands – Rev A

Conclusion

Once all the wiring was in done and checked and the module answers, you only need 3 lines to send an sms! In the next article, I’ll try and send one from an arduino/ESP8266 instead of the computer.

Envoyer des SMS avec un module GSM A6

AI Thinker, les fabricants de mes MCU préférés, les ESP8266 ont sorti il y a quelques temps déjà le module GSM A6 permettant de se connecter au réseau GSM / GPRS et d’envoyer des SMS, se connecter à internet et même d’émettre des appels!

J’ai eu l’idée de me faire un petit appareil connecté qui recevra des ordres par MQTT et enverra des SMS, ce qui me permettra de recevoir un sms facilement à chaque fois qu’un de mes capteurs remontrons une info importante. Cet article est la première étape, je vais en écrire d’autres au fur et à mesure que le projet avance.

Ce qu’il faut:

  • Module GSM/GRPS A6 mini Un module A6 :  (ici il s’agit d’un modue A6 mini disponible sur ebay, aliexpress, ect.. pour 5 à 10€)
  • Carte SIM Une carte SIM, j’ai pris une carte free à 2€/mois (si votre box est chez free elle est même gratuite)
  • Breadboard et fils de cavalier Quelques fils de cavalier et un breadboard
  • module FTDI Un module FTDI ‘entre 2 et 5€ sur Ebay ou aliexpress
  • PCB micro USB Une PCB avec prise USB pour alimenter le tout et un chargeur de téléphone pour alimenter tout ça.
  • Alimentation Une alimention assez puissante (ici j’ai recyclé une alim qui me servait pour un raspberry de 5V/2A). L’envoi de SMS demande pas mal de courant au moment de l’envoi.
  • CoolTerm Un ordinateur sous Windows avec CoolTerm (ça se fait très bien sous Mac ou linux mais je n’en ai pas sous la main)

Le câblage

Schéma de câblage du module A6 avec un FTDI
Schéma de câblage du module A6 avec un FTDI

Comme vous pouvez le constater, j’ai réuni tous mes talents de graphiste pour pondre ce schéma très très moche!!

L’idée est d’alimenter le module avec notre chargeur de téléphone, de mettre les les neutres du module A6 et de l’FTDI en commun puis de brancher le TX du module A6 au RX de du FTDI et vice et versa.

le cablage fini
Le montage fini et branché

Côté PC

Normalement CoolTerm arrivera a trouver tout seul le port COM sur lequel est branché votre FTDI. Sinon vous pourvez le trouver dans le gestionnaire de périphériques :

Gestionnaires de périphériques
Gestionnaires de périphériques

Dans coolTerm, réglez le baudrate à 115200 et cliquez sur Connect. Ca prend quelques secondes mais vous devriez voir apparaître des les retours du A6 qui ressemblent à ça :

connexion au réseau GSM

+CREG: 5 signifie que le module est connecté au réseau et est prêt a recevoir et envoyer des sms!

Si vous n’avez aucun retour du module, vérifiez que le branchement est bon, surtout au niveau des rx/tx, je me suis fait avoir…

Envoi du SMS

Pour envoyer une commande au module, allez dans Connection -> Send String ou faites Ctrl-T sous windows. La commande AT (pour Attention) suivi d’un retour à la ligne vous renverra l’état du module :

Envoi de la commande ATRécupération de l'état

Normalement, le module devrait répondre “OK”, mais il m’est arrivé d’avoir des erreurs CME 58, je crois que ça veut dire qu’il a temporairement perdu le signal, en réessayant la commande AT, ça se mettait a fonctionner.

Ensuite pour passer le module en mode SMS, envoyez :

AT+CMGF=1

toujours suivi d’un retour à la ligne.

passage en mode sms

Et enfin pour envoyer le message :

AT+CMGS="003361234567"

(en remplaçant bien sur par le numéro auquel vous voulez envoyer). Il vous demandera ensuite d’entrer votre message, fermez la boite de dialogue et dans coolTerm faites Ctrl-z pour envoyer le message :

Retour série après envoi du sms

Attendez quelques secondes et consultez votre téléphone!

Pièges:

J’ai eu quelques problèmes au début pour communiquer avec le module, il faut bien vérifier tous les branchements (mes fils de cavaliers de chine ne sont pas d’une qualité extraordinaire…) et j’utilisais une rallonge USB qui ne marchait pas très bien non plus.

Voici un document qui m’a aidé de MultiTech Systems qui reprend les commandes AT de base et qui donne la signification d’erreurs : GSM Developer Guide – GSM AT Commands – Rev A

Conclusion

Une fois les branchements correctement faits et que le module répond, il suffit de 3 lignes pour envoyer un Sms! Dans un prochain article, je montrerais comment envoyer un message depuis un arduino ou encore mieux, un ESP8266!