Connect to thinger.io via GPRS module (done)

Hello everyone!
Some time ago I liked thinger.io and libraries. It gives to link many devises via WiFi, Ethernet, etc.
But I need to link my board (Arduino UNO comp) with GSM/GPRS modem like A6 or M590. In standard thinger.io lib missing GPRS for non-LinkItOne boards (modules). GitHub provided by Volodymyr Shymanskyy lib TinyGSM for popular GSM modules and I do little changes in thinger.io lib files. Compile mofied ino-file and modified thinger.io lib (it just add new header for GPRS connection). And I got the result: successful connection (turn on/off led and got system millis). Link delay less than 1 sec. But it is only draft version for testing link. Need to be continue work libs.

ThingerLinkItOneGPRS.h now ThingerGPRSmy.h
make changes in constructor:

class ThingerMyGPRS : public ThingerClient {
public:
    	ThingerMyGPRS(const char* user, const char* device, const char* device_credential, TinyGsmClient *clnt):
    	ThingerClient(*clnt, user, device, device_credential), connected_(false),
                apn_(NULL), user_(NULL), password_(NULL), pin_(NULL)
    	{};

bool attachGPRS(){
		delay(2000);
            return true;
}

Call from main file looks like:

#include "GSM_GPRS.h"
#include "ThingerGPRSmy.h"

#define USERNAME "USER"
#define DEVICE_ID "GPRS"
#define DEVICE_CREDENTIAL "your_credential"

SoftwareSerial SerialAT(2, 3); // RX, TX for UNO

  TinyGsm modem(SerialAT);
  TinyGsmClient client(modem);
  
  ThingerMyGPRS thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, &client); 
void setup() {
  
  gsm_gprs_begin(modem, SerialAT);//modem setup (my choice M590)

  pinMode(4, OUTPUT);

  // pin control example (i.e. turning on/off a light, a relay, etc)
  thing["led"] << digitalPin(4);

  // resource output example (i.e. reading a sensor value, a variable, etc)
  thing["millis"] >> outputValue(millis());


  // more details at http://docs.thinger.io/arduino/
}
void loop() {
  thing.handle();
}

GSM_GPRS.h

#define TINY_GSM_MODEM_M590

#include "TinyGsmClient.h"
#include <SoftwareSerial.h>
#include "ThingerGPRSmy.h"

#define serial_bit_rate_modem 9600
#define serial_bit_rate_console 115200

//My own mobile net config
const char apn[]  = "ab.kyivstar.net";
const char user[] = "";
const char pass[] = "";

bool gsm_gprs_begin(TinyGsm &modem, SoftwareSerial &ser1);

bool gsm_gprs_begin(TinyGsm &modem, SoftwareSerial &ser1)
{
		
   	ser1.begin(serial_bit_rate_modem);
	Serial.begin(serial_bit_rate_console);

	Serial.println("Start modem");
	modem.restart();

	Serial.print("Waiting for network...");
	if (!modem.waitForNetwork()) {
			Serial.println(" fail");
			delay(10000);
    return true;
  }
	    Serial.println(" OK");
        Serial.print("Connecting to ");
        Serial.print(apn);
        if (!modem.gprsConnect(apn, user, pass)) {
    			Serial.println(" fail");
    			delay(10000);
    			return true;
    		}
    	Serial.println(" OK");
    	return true;
    }
1 Like

Nice!!! I didn’t know this library! But seems to be awesome for handling different GPRS devices! Will take a look to your code and the library. I have a SIM800L module around, so I can test it!

Thanks for sharing! I think that we can evolve this implementation and publish it to the Github for official support :slight_smile:

Thanks!
These codes do not look perfect, In published code I found a mistake

    Serial.print("Waiting for network...");
    	if (!modem.waitForNetwork()) {
    			Serial.println(" fail");
    			delay(10000);
    return false;// was true;
if (!modem.gprsConnect(apn, user, pass)) {
    			Serial.println(" fail");
    			delay(10000);
    			return false;// was true

Now after disconnecting (timeout occurred between user data activity) can’t connect again, but thingerClient level try to do it.

I have tested to integrate the TinyGSM with the Thinger.io library, and seems to have a working environment. I will keep you updated. I have to test reliability, as it is not quite stable. For my SIM800L i need a huge antenna in order to get it working!! And using software serial is little bit slow… but works!

How you did get it done?

I modified the “ThingerLinkItOneGPRS.h” by this way

#ifndef THINGER_LINKITONE_H
#define THINGER_LINKITONE_H

class ThingerMyGPRS : public ThingerClient {
public:
    	ThingerMyGPRS(const char* user, const char* device, const char* device_credential, TinyGsmClient *clnt):
    	ThingerClient(*clnt, user, device, device_credential), connected_(false),
                apn_(NULL), user_(NULL), password_(NULL), pin_(NULL)
    	{};

bool attachGPRS(){
		delay(2000);
            return true;
}

protected:

    virtual bool network_connected(){
        return connected_;
    }

    virtual bool connect_network(){
        long gprs_timeout = millis();
        THINGER_DEBUG("NETWORK", "Connecting to GPRS...");
        while(!attachGPRS())
        {
            if (millis() - gprs_timeout > 30000) return false;
            delay(500);
        }
        connected_ = true;
        THINGER_DEBUG("NETWORK", "Connected to GPRS!");
        return connected_;
    }

public:
    void set_apn(const char* apn, const char* user=NULL, const char* password=NULL){
        apn_ = apn;
        user_ = user;
        password_ = password;
    }

    void set_pin(const char* pin){
        pin_ = pin;
    }

private:
    bool connected_;
    LGPRSClient client_;
    const char* apn_;
    const char* user_;
    const char* password_;
    const char* pin_;

    bool attachGPRS(){
        if(apn_!=NULL){
            return LGPRS.attachGPRS(apn_, user_, password_) == 1;
        }
        else{
            return LGPRS.attachGPRS() == 1;
        }
    }
};

#endif

and after that, asked for a “lgprs.h” and “lgprsclient.h”, found it at techbang github, but it keeping asking for files…

I have 2 questions,

Is the modification of the file ok?

How can I resume the installation of those libraries?

Thanks in advance :wink:

Full mod of this file:

#ifndef THINGER_LINKITONE_H
#define THINGER_LINKITONE_H

#include "ThingerClient.h"

class ThingerMyGPRS : public ThingerClient {

public:
	ThingerMyGPRS(const char* user, const char* device, const char* device_credential, TinyGsmClient *clnt) :
            ThingerClient(*clnt, user, device, device_credential), connected_(false),
            apn_(NULL), user_(NULL), password_(NULL), pin_(NULL)
    {}

    ~ThingerMyGPRS(){
    }

protected:

    virtual bool network_connected(){
        return connected_;
    }

    virtual bool connect_network(){
        long gprs_timeout = millis();
        THINGER_DEBUG("NETWORK", "Connecting to GPRS...");
        while(!attachGPRS())
        {
            if (millis() - gprs_timeout > 30000) return false;
            delay(500);
        }
        connected_ = true;
        THINGER_DEBUG("NETWORK", "Connected to GPRS!");
        return connected_;
    }

public:
    void set_apn(const char* apn, const char* user=NULL, const char* password=NULL){
        apn_ = apn;
        user_ = user;
        password_ = password;
    }

    void set_pin(const char* pin){
        pin_ = pin;
    }

private:
    bool connected_;
    const char* apn_;
    const char* user_;
    const char* password_;
    const char* pin_;

    bool attachGPRS(){
		delay(2000);
            return true;
	}
};

#endif

At this moment I have tested something like:

ThingergGPRS.h:

#ifndef THINGER_GPRS_H
#define THINGER_GPRS_H

#include "ThingerClient.h"

class ThingerGPRS : public ThingerClient {

public:
    ThingerGPRS(const char* user, const char* device, const char* device_credential, Stream& serial) :
            apn_(NULL),
            user_(NULL),
            password_(NULL),
            pin_(NULL),
            modem_(serial),
            client_(modem_),
            lastModemCheck_(0),
            ThingerClient(client_, user, device, device_credential)
    {
    }

    ~ThingerGPRS(){

    }

protected:

    virtual bool network_connected(){
        return false;
    }

    virtual bool connect_network(){
        if(apn_==NULL) {
            THINGER_DEBUG("NETWORK", "Cannot connect without setting the APN!")
            return false;
        }

        RegStatus regStatus = modem_.getRegistrationStatus();
        THINGER_DEBUG_VALUE("NETWORK", "Network Status: ", regStatus)
        if(regStatus==REG_UNKNOWN || regStatus==REG_UNREGISTERED){
            THINGER_DEBUG("NETWORK", "Restarting Modem...")
            modem_.restart();
            THINGER_DEBUG("NETWORK", "Waiting for Network...")
            if(!modem_.waitForNetwork()) {
                THINGER_DEBUG("NETWORK", "Cannot connect network!")
                return false;
            }
            THINGER_DEBUG("NETWORK", "Network Connected!")
        }

        THINGER_DEBUG("NETWORK", "Connecting to APN...")
        if (!modem_.gprsConnect(apn_, user_, password_)) {
            THINGER_DEBUG("NETWORK", "Cannot connect to APN!")
            return false;
        }
    }


public:
    TinyGsm& getTinyGsm(){
        return modem_;
    }

    TinyGsmClient& getTinyGsmClient(){
        return client_;
    }

    void setAPN(const char* APN, const char* user=NULL, const char* password=NULL){
        apn_ = APN;
        user_ = user;
        password_ = password;
    }

    void setPIN(const char* PIN){

    }

private:
    const char* apn_;
    const char* user_;
    const char* password_;
    const char* pin_;
    TinyGsm modem_;
    TinyGsmClient client_;
    unsigned long lastModemCheck_;
    bool connected_ = false;
};

#endif

And the Sketch:

// Select your modem:
#define TINY_GSM_MODEM_SIM800
//#define TINY_GSM_MODEM_SIM900
//#define TINY_GSM_MODEM_A6
//#define TINY_GSM_MODEM_M590

#define _DEBUG_

#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
#include <ThingerGSM.h>

#define USERNAME ""
#define DEVICE_ID ""
#define DEVICE_CREDENTIAL ""

SoftwareSerial SerialAT(9, 8); // RX, TX

ThingerGPRS thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, SerialAT);

void setup() {
  // for logging
  Serial.begin(115200); 

   // SerialAT
  SerialAT.begin(38400);

  // set APN
  thing.setAPN("orangeworld", "orange", "orange");

  // set PIN (optional)
  // thing.setPin("1234");
  
  pinMode(13, OUTPUT);

}

void loop() {
  thing.handle();
}

And seems to work fine! I think something similar will be released soon!

Ups! This code will not work on the current client library. I have been working also in ThingerClient.h

// The MIT License (MIT)
//
// Copyright (c) 2017 THINK BIG LABS SL
// Author: alvarolb@gmail.com (Alvaro Luis Bustamante)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#ifndef THINGER_CLIENT_H
#define THINGER_CLIENT_H

#include "thinger/thinger.h"

using namespace protoson;

dynamic_memory_allocator alloc;
//circular_memory_allocator<512> alloc;
memory_allocator& protoson::pool = alloc;

#ifndef THINGER_SERVER
    #define THINGER_SERVER "iot.thinger.io"
#endif

#ifndef THINGER_PORT
    #define THINGER_PORT 25200
#endif

#ifndef THINGER_SSL_PORT
    #define THINGER_SSL_PORT 25202
#endif

#ifndef THINGER_TLS_FINGERPRINT
    #define THINGER_TLS_FINGERPRINT "C3 90 0E 8B CB 2D 7A 32 1B 55 5C 00 FA 7B 39 5E 53 BC D2 8F"
#endif

#ifndef THINGER_TLS_HOST
    #define THINGER_TLS_HOST "thinger.io"
#endif

#define RECONNECTION_TIMEOUT 5000   // milliseconds
#define DEFAULT_READ_TIMEOUT 30000  // milliseconds

#ifdef _DEBUG_
    #define THINGER_DEBUG(type, text) Serial.print("["); Serial.print(F(type)); Serial.print("] "); Serial.println(F(text));
    #define THINGER_DEBUG_VALUE(type, text, value) Serial.print("["); Serial.print(F(type)); Serial.print("] "); Serial.print(F(text)); Serial.println(value);
#else
    #define THINGER_DEBUG(type, text) void();
    #define THINGER_DEBUG_VALUE(type, text, value) void();
#endif

class ThingerClient : public thinger::thinger {

public:
    ThingerClient(Client& client, const char* user, const char* device, const char* device_credential) :
            client_(client), username_(user), device_id_(device), device_password_(device_credential),
            temp_data_(NULL), out_size_(0)
    {
    }

    ~ThingerClient()
    {

    }

protected:

    virtual bool read(char* buffer, size_t size)
    {
        long start = millis();
        size_t total_read = 0;
        //THINGER_DEBUG_VALUE("THINGER", "Reading bytes: ", size);
        while(total_read<size){
            // For solving this issue: https://github.com/ntruchsess/arduino_uip/issues/149
            #ifdef UIPETHERNET_H
            int read = client_.read((uint8_t*)(buffer+total_read), size-total_read);
            #else
            int read = client_.readBytes((char*)buffer+total_read, size-total_read);
            #endif
            total_read += read;
            if(read<=0 && (!client_.connected() || abs(millis()-start)>=DEFAULT_READ_TIMEOUT)){
                #ifdef _DEBUG_
                THINGER_DEBUG("_SOCKET", "Cannot read from socket!");
                #endif
                return false;
            }
        }
        return total_read == size;
    }

    // TODO Allow removing this Nagle's algorithm implementation if the underlying device already implements it
    virtual bool write(const char* buffer, size_t size, bool flush=false){
        if(size>0){
            temp_data_ = (uint8_t*) realloc(temp_data_, out_size_ + size);
            memcpy(&temp_data_[out_size_], buffer, size);
            out_size_ += size;
        }
        if(flush && out_size_>0){
            #ifdef _DEBUG_
            Serial.print(F("[THINGER] Writing bytes: "));
            Serial.print(out_size_);
            #endif

            size_t written = client_.write(temp_data_, out_size_);
            bool success = written == out_size_;
            free(temp_data_);
            temp_data_ = NULL;
            out_size_ = 0;

            #ifdef _DEBUG_
            Serial.print(F(" ["));
            Serial.print(success ? F("OK") : F("FAIL"));
            Serial.println(F("]"));
            #endif

            //FIXME Without this small delay or activating the debug (which takes time), the CC3200 does not work well. Why?
            #ifdef __CC3200R1M1RGC__
            delay(1);
            #endif

            return success;
        }
        return true;
    }

    virtual void disconnected(){
        thinger_state_listener(SOCKET_TIMEOUT);
        client_.stop();
        thinger_state_listener(SOCKET_DISCONNECTED);
        thinger::thinger::disconnected();
    }

    virtual bool connect_network(){
        return true;
    }

    virtual bool network_connected(){
        return true;
    }

    virtual bool connect_socket(){
        return client_.connect(THINGER_SERVER, THINGER_PORT);
    }

    virtual bool secure_connection(){
        return false;
    }

    enum THINGER_STATE{
        NETWORK_CONNECTING,
        NETWORK_CONNECTED,
        NETWORK_CONNECT_ERROR,
        SOCKET_CONNECTING,
        SOCKET_CONNECTED,
        SOCKET_CONNECTION_ERROR,
        SOCKET_DISCONNECTED,
        SOCKET_TIMEOUT,
        SOCKET_ERROR,
        THINGER_AUTHENTICATING,
        THINGER_AUTHENTICATED,
        THINGER_AUTH_FAILED
    };

    virtual void thinger_state_listener(THINGER_STATE state){
        #ifdef _DEBUG_
        switch(state){
            case NETWORK_CONNECTING:
                THINGER_DEBUG("NETWORK", "Starting connection...");
                break;
            case NETWORK_CONNECTED:
                THINGER_DEBUG("NETWORK", "Connected!");
                break;
            case NETWORK_CONNECT_ERROR:
                THINGER_DEBUG("NETWORK", "Cannot connect!");
                break;
            case SOCKET_CONNECTING:
                Serial.print(F("[_SOCKET] Connecting to "));
                Serial.print(THINGER_SERVER);
                Serial.print(F(":"));
                Serial.print(secure_connection() ? THINGER_SSL_PORT : THINGER_PORT);
                Serial.println(F("..."));
                Serial.print(F("[_SOCKET] Using secure TLS/SSL connection: "));
                Serial.println(secure_connection() ? F("yes") : F("no"));
                break;
            case SOCKET_CONNECTED:
                THINGER_DEBUG("_SOCKET", "Connected!");
                break;
            case SOCKET_CONNECTION_ERROR:
                THINGER_DEBUG("_SOCKET", "Error while connecting!");
                break;
            case SOCKET_DISCONNECTED:
                THINGER_DEBUG("_SOCKET", "Is now closed!");
                break;
            case SOCKET_TIMEOUT:
                THINGER_DEBUG("_SOCKET", "Timeout!");
                break;
            case THINGER_AUTHENTICATING:
                Serial.print(F("[THINGER] Authenticating. User: "));
                Serial.print(username_);
                Serial.print(F(" Device: "));
                Serial.println(device_id_);
                break;
            case THINGER_AUTHENTICATED:
                THINGER_DEBUG("THINGER", "Authenticated");
                break;
            case THINGER_AUTH_FAILED:
                THINGER_DEBUG("THINGER", "Auth Failed! Check username, device id, or device credentials.");
                break;
        }
        #endif
    }

    bool handle_connection()
    {
        // check if client is connected
        bool client = client_.connected();
        if(client) return true;

        // client is not connected, so check underlying network
        if(!network_connected()){
            thinger_state_listener(NETWORK_CONNECTING);
            if(!connect_network()){
                thinger_state_listener(NETWORK_CONNECT_ERROR);
                return false;
            }
            thinger_state_listener(NETWORK_CONNECTED);
        }

        // network is connected, so connect the client
        return connect_client();
    }

    bool connect_client(){
        bool connected = false;
        client_.stop(); // cleanup previous socket
        thinger_state_listener(SOCKET_CONNECTING);
        if (connect_socket()) {
            thinger_state_listener(SOCKET_CONNECTED);
            thinger_state_listener(THINGER_AUTHENTICATING);
            connected = thinger::thinger::connect(username_, device_id_, device_password_);
            if(!connected){
                thinger_state_listener(THINGER_AUTH_FAILED);
                client_.stop();
                thinger_state_listener(SOCKET_DISCONNECTED);
            }
            else{
                thinger_state_listener(THINGER_AUTHENTICATED);
            }
        }
        else{
            thinger_state_listener(SOCKET_CONNECTION_ERROR);
        }
        return connected;
    }

public:

    void handle(){
        if(handle_connection()){
            size_t available = client_.available();
            #ifdef _DEBUG_
            if(available>0){
                THINGER_DEBUG_VALUE("THINGER", "Available bytes: ", available);
            }
            #endif
            thinger::thinger::handle(millis(), available>0);
        }else{
            delay(RECONNECTION_TIMEOUT); // get some delay for a connection retry
        }
    }

private:

    Client& client_;
    const char* username_;
    const char* device_id_;
    const char* device_password_;
    uint8_t * temp_data_;
    size_t out_size_;
};

/**
 * Some syntactic sugar for defining input/output resources easily
 */

#if defined(__AVR__) || defined(ESP8266)

void digital_pin(protoson::pson& in, int pin){
    if(in.is_empty()){
        in = (bool) digitalRead(pin);
    }
    else{
        digitalWrite(pin, in ? HIGH : LOW);
    }
}

void inverted_digital_pin(protoson::pson& in, int pin){
    if(in.is_empty()){
        in = !(bool) digitalRead(pin);
    }
    else{
        digitalWrite(pin, in ? LOW : HIGH);
    }
}

#else

bool digital_pin(protoson::pson& in, int pin, bool& current_state){
    if(in.is_empty()) {
        in = current_state;
    }
    else{
        current_state = in;
        digitalWrite(pin, current_state ? HIGH : LOW);
    }
}

bool inverted_digital_pin(protoson::pson& in, int pin, bool& current_state){
    if(in.is_empty()) {
        in = !current_state;
    }
    else{
        current_state = in;
        digitalWrite(pin, current_state ? LOW : HIGH);
    }
}
#endif

/*
 * TODO ESP32 library does not implement analogWrite yet
 */

#ifndef ESP32
void analog_pin(protoson::pson& in, int pin){
    static int current = in;
    if(in.is_empty()){
        in = current;
    }
    else{
        current = in;
        analogWrite(pin, current);
    }
}
#endif

/**
 * AVR and ESP8266 supports reading the PIN state event if they are of output type. So they
 * can rely on reading the current pin state directly using the digitalRead function. However,
 * other devices cannot read the pin state while they are in output mode, so it is necessary to
 * keep a variable to keep the track of the current value.
 */
#if defined(__AVR__) || defined(ESP8266)
#define digitalPin(PIN) [](pson& in){ digital_pin(in, PIN); }
#define invertedDigitalPin(PIN) [](pson& in){ inverted_digital_pin(in, PIN); }
#else
#define digitalPin(PIN) [](pson& in){               \
    static bool state = LOW;                        \
    digital_pin(in, PIN, state);                    \
}
#define inverted_digital_pin(PIN) [](pson& in){     \
    static bool state = LOW;                        \
    inverted_digital_pin(in, PIN, state);           \
}
#endif

template <typename T>
inline bool inputResource(pson& in, T& value){
    if(in.is_empty()){
        in = value;
    } else{
        value = in;
        return true;
    }
    return false;
}

template<>
inline bool inputResource<String>(pson& in, String& value){
    if(in.is_empty()){
        in = value;
    } else{
        value = (const char*)in;
        return true;
    }
    return false;
}

#define analogPin(PIN) [](pson& in){ analog_pin(in, PIN);}
#define outputValue(value) [](pson& out){ out = value; }
#define outputString(value) [](pson& out){ out = value; }
#define servo(servo) [](pson& in){ if(in.is_empty()) in = (int)servo.read(); else servo.write((int)in); }
#define inputValue_1(value) [](pson& in){ inputResource(in, value); }
#define inputValue_2(value, callback) [](pson& in){ if(inputResource(in, value)){callback;}}
#define inputValue_X(x, value, callback, FUNC, ...)  FUNC
#define inputValue(...) inputValue_X(,##__VA_ARGS__,\
                                          inputValue_2(__VA_ARGS__),\
                                          inputValue_1(__VA_ARGS__)\
                                    )
#endif

It optimizes some connection checkings, that are “expensive” for AT command based communication. is probably better to wait for the full package…

I have published a new library version (2.6.0), but not pushed as a new release (it will not update with library manager) that should provide support (finally!) to GPRS modules by using AT commands. It relies on the commented TinyGSM library that can be installed with the library manager. There is an example called ArduinoTinyGSM.

Can you please manually install the library and test that? I have done some test with success!! It is not quite optimized yet, but it should work fine.

Bests!

You’re looking for AT+CIPSTATUS - it “Query Current Connection Status”.

Library updated: ok

Example compiled: ok

Instaled on an arduino uno, with sim800l gsm modem, and working: ok

You rock dude!

Im gonna develop my project and test on a production enviroment, I think that it must work without issues.

Keep you updated in this post about the results!

Thanks again.

Great work has been done you all!
I tested my device (arduino uno and GSM/GPRS M590). And it work ok, At all, thinger.io library now is more universal. Please, test these libs and if you find errors, please reply.

I also tried to connect my SIM900A GSM module to thinger.io platform.i tried in several ways.
But it did not success. I am just want to connect my SIM900A to thinger.io platform using Arduino UNO. please help me.

thank you.

first of all you must install library TinyGSM lib from GitHub.

my really work, but old and simple project with m590 GSM device

#define TINY_GSM_MODEM_M590
#define _DEBUG_

#include <TinyGsmClient.h>
#include <SoftwareSerial.h>
#include <ThingerGPRS.h>
//********************************
#include <OneWire.h>
OneWire  ds(7);  // on pin 10 (a 4.7K resistor is necessary)
//********************************

double dig =0;

#define USERNAME "GPRS"
#define DEVICE_ID "GPRS_CONTROL"
#define DEVICE_CREDENTIAL "KeyfhLmYug1i"
#define LED 6
SoftwareSerial SerialAT(2, 3); // RX, TX

ThingerGPRS thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, SerialAT);

void setup() {
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);

  Serial.begin(115200); 

   // SerialAT
  SerialAT.begin(9600);

  // set APN
  thing.setAPN( "ab.kyivstar.net", "", "");

  // set PIN (optional)
  // thing.setPin("1234");
  
  pinMode(4, OUTPUT);
  // pin control example (i.e. turning on/off a light, a relay, etc)
  thing["led"] << digitalPin(4);
  
  pinMode (LED,OUTPUT);

  thing["LED"] << analogPin(LED);

  // resource output example (i.e. reading a sensor value, a variable, etc)
  
  thing["T0"] >> outputValue((double)(analogRead(A0)-260)/10);

  thing["T_ds18"] >>outputValue(Sensor());
}

void loop() {
  thing.handle();
  }

Try it for your SIMCOM

1 Like

Thanks for working on this! It seems like this allows many more devices to connect. But a year after the latest update to this thread, which was a year after the initial conversation, it seems the method is still somewhat custom?

  • The updated [Thinger.io] library that alvarold mentioned in post #9 has now been included in new releases and requires no special action.
  • TinyGSM library from the library manager requires no special action.
  • ThingerGPRS.h is a new library that is the first code block in post #7 in this thread. To use it, copy that code into a new file named ThingerGPRS.h, zip it, and then import it into the Arduino IDE.

For the sketch, the ArduinoTinyGSM example in the Thinger.io library or the two in this thread are places to start. But both the examples in this thread use
ThingerGPRS thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, Serial1);
while the ArduinoTinyGSM example uses:
ThingerTinyGSM thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, Serial1);

In my case, that doesn’t make any difference because I seem to be having a problem before getting to Thinger.io. What’s confusing is that the debug information coming through the serial monitor (below) looks like there is no connection, but the LED blink pattern of my SIM800H indicate it is “registered to the network” but not that “GPRS communication is established.” (Before following this thread I was not able to use anything Thinger related and get the modem lights to do anything at the same time.) The serial monitor:

[NETWORK] Waiting for Network...
[NETWORK] Cannot connect network!
[NETWORK] Cannot connect!
[NETWORK] Starting connection...
[NETWORK] Network Status: 4
[NETWORK] Restarting Modem...

Is there other customization I missed? Have things changed in the last year?
Here’s the simple sketch I am trying:

 #include <TinyGsmClient.h>
    #include <SoftwareSerial.h>
    #include <ThingerGPRS.h>

    #define TINY_GSM_MODEM_SIM800

    #define _DEBUG_

    // Emulate Serial1 on pins 10/11 if HW is not present (use interrupt pin in RX for better performance)
    #ifndef HAVE_HWSERIAL1
    #include "SoftwareSerial.h"
    SoftwareSerial Serial1(10, 11); // RX, TX
    #endif

    #define USERNAME "XXXXX"
    #define DEVICE_ID "YYYYYYYYYY"
    #define DEVICE_CREDENTIAL "ZZZZZZZ"

    // use your own APN config
    #define APN_NAME "h2g2"
   //this is a data only plan that I have successfully tested over HTTP

    ThingerGPRS thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, Serial1);
    //same results whether this says ThingerGPRS or ThingerTinyGSM

    void setup() {
      // uncomment line for debug
      Serial.begin(115200);

      // Serial for AT commands (can be higher with HW Serial, or even lower in SW Serial)
      Serial1.begin(9600); //9600 from Seeeduino? 57600 from ArduinoTinyGSM?

      // set APN (you can remove user and password from call if your apn does not require them)
      thing.setAPN(APN_NAME);

      // resource input example (i.e, controlling a digitalPin);
      pinMode(LED_BUILTIN, OUTPUT);
      thing["led"] << digitalPin(LED_BUILTIN);

      // resource output example (i.e. reading a sensor value)
      thing["millis"] >> outputValue(millis());

      // more details at http://docs.thinger.io/arduino/
    }

    void loop() {
      thing.handle();
    }

it is giving me the error for compiling with arduino nano

 
#include <SoftwareSerial.h>
#define TINY_GSM_MODEM_SIM800

#include <TinyGsmClient.h>
#include <ThingerTinyGSM.h>

SoftwareSerial gsm(2, 3); // RX, TX

#define USERNAME "your_user_name"
#define DEVICE_ID "your_device_id"
#define DEVICE_CREDENTIAL "your_device_credential"

#define APN_NAME "your_apn_name"
#define APN_USER "your_apn_user"
#define APN_PSWD "your_apn_password"

// set your cad pin (optional)
#define CARD_PIN ""

ThingerTinyGSM thing(USERNAME, DEVICE_ID, DEVICE_CREDENTIAL, gsm);

void setup() 
{
  gsm.begin(57600);
  thing.setAPN(APN_NAME, APN_USER, APN_PSWD);

  // set PIN (optional)
  // thing.setPIN(CARD_PIN);

  // resource input example (i.e, controlling a digitalPin);
  pinMode(LED_BUILTIN, OUTPUT);
  thing["led"] << digitalPin(LED_BUILTIN);

  // resource output example (i.e. reading a sensor value)
  thing["millis"] >> outputValue(millis());

  // more details at http://docs.thinger.io/arduino/
}

void loop() {
  thing.handle();
}

And the error is…?

I´ve just opened the example sketch and compiled ok, what means that the issue is in your side, I have Arduino IDE v1.8.9 and Thinger.io Library v.2.13.0.

I´m curious, how do you expect that we help you, posting the skecth included in the library that all of us have?

Think twice about the info that are you posting (and before doing it) asking for help, help us to help you.

I am using Arduino Uno R3 and SIM900A. I get this error message. I have installed all the libraries. Please help!

Hi

I am deeply sorry but I cannot read anything on that image, please paste it in the correct way as code.

Hope this helps

1 Like

It did not allow me. In any case, since the post I have managed to figure out that as long as I use Thinger.io 2.16.0 no errors show. Then again I had to order a new module to test it, because the one I’ve got, the SIM900A is restricted to Asia only. It can be flashed with the firmware for SIM900, but I don’t have the tool yet.

In any case, I can’t figure out why with the Uno board nothing above Thinger 2.16.0 seems to work. There a few posts on the forum about that, but no answer.