M5Stick->SIM7080-> MQTT->Thingspeak-->Sample code



  • Dear all,
    Please let me share with you my sample code. Needs cleaning up, but it could be a good example for those that are interested in using the SIM7080 module.

    #include <M5StickC.h>
    #include "AXP192.h"
    #include "DHT12.h"
    #include <Wire.h>
    #include "Adafruit_Sensor.h"
    #include <Adafruit_BMP280.h> // Dit is de pressure sensor. https://cdn-shop.adafruit.com/datasheets/BST-BMP280-DS001-11.pdf
    //#include "bmm150.h"
    //#include "bmm150_defs.h"
    //#include "M5_SIM7080G.h"

    DHT12 dht12;
    //BMM150 bmm = BMM150();
    //bmm150_mag_data value_offset;
    Adafruit_BMP280 bme;

    float tmp = 0.0;
    float hum = 0.0;
    float pressure = 0.0;
    float BatVoltage;

    String ClientId="";
    String Username="
    ";
    String Password="";
    String ChannelId="
    *";

    const int buffer_size=5000;
    char Receive_buffer[buffer_size];
    long time_taken;

    char date_time_char_array[50];
    char date_time_char_array_processed[50];
    const char allowed_char[]="0123456789/,:+-";

    typedef struct {
    int Second;
    int Minute;
    int Hour;
    int Day;
    int Month;
    int Year; // offset from 1970;
    int Timezone;
    } Date_time_struct;

    Date_time_struct Thisday;
    bool DateTime_Error=false;
    char buf[10];

    uint8_t setup_flag = 1;

    const long SIMWaitTime=10000;
    const long Delay_between_commands=300;

    int RSSI;

    char* Pntr;
    char* Pntr_1;
    char* Pntr_2;

    char IP_buffer[20]; // hier komt het toegewezen IP adress in

    char itoa_buffer[10];
    #define max_float_digits 20 //7 // including NULL let op, in retrieve data gebruik ik precision 4 ipv 2
    #define dtostrf_precision 4
    #define dtostrf_leader 15

    String Date_payload; //="&created_at=2023-05-11 09:20:59";

    #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */

    bool Wakeup_Other_Cause;
    bool Wakeup_Through_Button;
    bool Wakeup_Through_Time;
    int Sleep_Period=10;

    int Sleep_Period_After_Error=10;

    int Error_Code;

    //#define BMM150_CHIP_ID_ADDR 0x76

    void setup() {
    // put your setup code here, to run once:
    M5.begin(false,true,true);
    Serial.begin(115200);
    delay(300);

    M5.Axp.SetLDO2(false);
    M5.Axp.SetLDO3(false);

    Wire.end();
    //delay(300);
    Wire.begin(0,26);
    Serial.println();
    Serial.println();
    Serial.println();
    Serial.println();

    print_wakeup_reason();

    esp_sleep_wakeup_cause_t wakeup_reason;
    wakeup_reason = esp_sleep_get_wakeup_cause();
    Wakeup_Other_Cause=false;
    Wakeup_Through_Button=false;
    Wakeup_Through_Time=false;

     switch(wakeup_reason)
       {
         case ESP_SLEEP_WAKEUP_EXT0 :  Wakeup_Through_Button=true;break;
         case ESP_SLEEP_WAKEUP_EXT1 :  break;  // nu toch de server
         case ESP_SLEEP_WAKEUP_TIMER : Wakeup_Through_Time=true;break;
         case ESP_SLEEP_WAKEUP_TOUCHPAD : break;
         case ESP_SLEEP_WAKEUP_ULP :break;
         default : Wakeup_Other_Cause=true; break;
    

    }

    //M5.Lcd.setRotation(3);
    //M5.Lcd.fillScreen(BLACK);
    //M5.Lcd.setCursor(0, 0, 2);
    //M5.Lcd.println("ENV TEST");
    //pinMode(M5_BUTTON_HOME, INPUT);

    Serial.println("Init doing");
    /*
    if(bmm.initialize() == BMM150_E_ID_NOT_CONFORM) {
    Serial.println("Chip ID can not read!");
    while(1);
    } else {
    Serial.println("Initialize done!");
    }
    */

    if (!bme.begin(0x76)){
    Serial.println("Could not find a valid BMP280 sensor, check wiring!");
    while (1);
    }

    tmp = dht12.readTemperature();
    hum = dht12.readHumidity();
    pressure = bme.readPressure();
    BatVoltage=M5.Axp.GetBatVoltage();

    Serial.println(tmp);
    Serial.println(hum);
    Serial.println(pressure);
    Serial.println(BatVoltage);

    //while (1) {delay(300);}

    Serial2.begin(115200, SERIAL_8N1,33,32); // M5 Stick Port B

    Serial2.print("AT+IPR=115200\r"); //
    Read_Response_WaitFor("OK",SIMWaitTime);
    delay(Delay_between_commands);

    Serial2.print("AT+CREBOOT\r"); //
    Read_Response_WaitFor("OK",30000);
    delay(Delay_between_commands);
    //Read_Response_OK(3000);
    Serial.println(Receive_buffer);

    Serial2.print("ATZ\r"); // Request TA Serial Number Identification(IMEI)
    Read_Response_WaitFor("OK",SIMWaitTime);
    delay(Delay_between_commands);
    //Read_Response_OK(3000);
    Serial.println(Receive_buffer);

    Serial2.print("AT+GSN\r"); // Request TA Serial Number Identification(IMEI)
    Read_Response_WaitFor("OK",SIMWaitTime);
    delay(Delay_between_commands);
    //Read_Response_OK(3000);
    Serial.println(Receive_buffer);

    int max_trials=5;
    Error_Code=0;

    while (1) {

    //Serial.print("********************************* Trail : ");
    //Serial.println(max_trials);

    //************************************************** READ SMS

    /*
    Signal Strength General Results
    -50 to -79 dBm Considered great signal (4 to 5 bars)
    -80 to -89 dBm Considered good signal (3 to 4 bars)
    -90 to -99 dBm Considered average signal (2 to 3 bars)
    -100 to -109 dBm Considered poor signal (1 to 2 bars)
    -110 to -120 dBm Considered very poor signal (0 to 1 bar)

    */

    Serial2.print("AT+CSQ\r"); // Clock returns *PSUTTZ: 23/04/14,11:56:48","+08",1 time zone in quarters of an hour
    Read_Response(2000); //Read_Response_WaitFor("OK",SIMWaitTime);
    //Read_Response_OK(2000);
    Serial.println(Receive_buffer);

    RSSI=0;
    Pntr=strstr(Receive_buffer,"+CSQ:");
    if (Pntr!=NULL)
    {
    Pntr_1=strtok(Pntr,":,");
    if (Pntr_1!=NULL);
    {
    Pntr_1=strtok(NULL,":,");
    if (Pntr_1!=NULL)
    {
    //Serial.println(Pntr_1);
    RSSI=atoi(Pntr_1);
    switch (RSSI) {
    case 0: RSSI=-115;break;
    case 1: RSSI=-111;break;
    case 99 : RSSI=99;break;
    default : RSSI=-112+RSSI;break;

                 }
    
              }
        }
    
    }
    

    Serial.print("Rssi : ");
    Serial.println(RSSI);

    if (RSSI==0 or RSSI==99)
    {
    Serial.println();
    Serial.println();
    Serial.println("********************************************* NO SIGNAL");
    Serial.println("********************************************* Going to sleep");
    Serial.println();
    Serial.println();
    Error_Code=1;
    break;

       //esp_sleep_enable_timer_wakeup(60 * uS_TO_S_FACTOR);
       //esp_deep_sleep_start();
    }
    

    Serial2.print("AT+CLTS=1\r"); // Get local timestamp
    Read_Response_WaitFor("OK",SIMWaitTime);
    //Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+CCLK?\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    //Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    if (Process_DateandTime(false)) {Error_Code=4;}

    //AT+CSSLCFG="SSLVERSIO N",<ctxindex>,<sslversion>

    Serial2.print("AT+CSSLCFG="SSLVERSION",0,3\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+CNACT=0,1\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+CNACT?\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    if (!GET_IP_Address ()) 
       {
          Serial.println("No IP address");
          Serial.println("Program stalled");
          Error_Code=2;
          break;
          //while (1) {delay(300);}
      }
    

    Serial2.print("AT+SMCONF="URL","mqtt3.thingspeak.com","1883"\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="KEEPTIME",60\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="CLEANSS",1\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="QOS",0\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="TOPIC","My Topic"\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="MESSAGE","My Message"\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="RETAIN",0\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONF="SUBHEX",0\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial.println("AT+SMCONF="CLIENTID",""+ClientId+""\r");
    Serial2.print("AT+SMCONF="CLIENTID",""+ClientId+""\r");

    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial.println("AT+SMCONF="USERNAME",""+Username+""\r");
    Serial2.print("AT+SMCONF="USERNAME",""+Username+""\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial.println("AT+SMCONF="PASSWORD",""+ Password+ ""\r");
    Serial2.print("AT+SMCONF="PASSWORD",""+ Password+ ""\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    Serial2.print("AT+SMCONN\r");
    Read_Response_WaitFor("OK",SIMWaitTime);
    Serial.println(Receive_buffer);
    delay(Delay_between_commands);

    if(strstr(Receive_buffer,"ERROR") != NULL)
    {
    Serial.println("SMCONN ERROR " );
    Error_Code=3;
    break;
    }
    else
    {
    Serial.println("We have a MQTT connection");
    // Format
    // https://nl.mathworks.com/help/thingspeak/publishtoachannelfeed.html
    // created_at=2014-12-31 23:59:59

    /*
    In the Payload pane, use the following settings:

    Topic: channels/33301/publish
    Payload: field1=45&field2=60&status=MQTTPUBLISH
    This PUBLISH message publishes a value of 45 to field1 and 60 to field2 of channel 33301, along with a status message MQTTPUBLISH.

    lengte van de payload nog
    */
    //String Date_payload="&created_at=2023-05-11 09:20:59";
    String payload;

            payload="field1="+String(int(pressure))+"&field2="+String(int(tmp))+"&field3="+String(int(hum))+"&field4="+String(int(BatVoltage*100))+Date_payload;
            String Mqtt_Message;
    
            int Payload_Length;
            Payload_Length=payload.length();
            Serial.print(payload);
            Serial.print ("   ");
            Serial.println(Payload_Length);
            //Mqtt_Message="AT+SMPUB=\"channels/888617/publish\","+String(Payload_Length)+",1,1\r";
    
            Mqtt_Message="AT+SMPUB=\"channels/"+ ChannelId+"/publish\","+String(Payload_Length)+",1,1\r";
            Serial.println(Mqtt_Message);
            Serial2.print(Mqtt_Message);
            //Serial2.print("AT+SMPUB=\"channels/888617/publish/fields/field1\",1,1,1\r");   // lengte moet goed zijn      
            Read_Response_WaitFor("OK",SIMWaitTime);
            Serial.println(Receive_buffer);
            delay(Delay_between_commands); 
            String Str;
            //pressure=12;
            Serial.println(pressure);
            Str=String(int(pressure/100))+"\r";
            Serial.println(Str);
            //Serial2.print("9\r");
            Serial2.print(payload);
            //Serial2.print(Str);        
            Read_Response_WaitFor("OK",SIMWaitTime);
            Serial.println(Receive_buffer);
            delay(Delay_between_commands); 
            break;
        }
    

    } //end while

    Serial.print("Done with error code : ");
    Serial.println(Error_Code);

    if (Error_Code==0)
    {
    esp_sleep_enable_timer_wakeup(Sleep_Period * uS_TO_S_FACTOR);
    esp_deep_sleep_start();
    }
    else
    {
    esp_sleep_enable_timer_wakeup(Sleep_Period_After_Error * uS_TO_S_FACTOR);
    esp_deep_sleep_start();
    }

    while (1) {delay(300);}

    } // end of setup

    void loop()
    {

    }

    bool Read_Response(long time_out) {
    int k=0;
    long wait_until;
    char ccc;
    //while (!Serial2.available() and millis()<wait_until) {delay(10);}
    wait_until=millis()+time_out;
    while (millis()<wait_until)
    {
    while (Serial2.available())
    {
    ccc=Serial2.read();
    //Serial.print(ccc);
    if (k<buffer_size-1)
    {
    Receive_buffer[k]=ccc;
    k++;
    }
    }
    Receive_buffer[k]=NULL;
    //if (strstr(Receive_buffer,"OK")!=NULL)
    // {
    //Serial.println("OK found");
    // SIM7600_Error=0;
    //break;
    //}
    }
    //if (k>=buffer_size-1) {SIM7600_Error=1; strcpy(Receive_buffer,SIM7600_Error_list[SIM7600_Error].c_str());return;}
    //if (millis()>=wait_until) {SIM7600_Error=2; strcpy(Receive_buffer,SIM7600_Error_list[SIM7600_Error].c_str()); return;}
    Receive_buffer[k]=NULL;
    if (strstr(Receive_buffer,"ERROR")!=NULL) {return true;} else {return false;}
    }

    bool Read_Response_WaitFor(char* StopCharArray,long time_out) { // false als niet gevonden
    int k=0;
    long wait_until;
    char ccc;
    //while (!Serial2.available() and millis()<wait_until) {delay(10);}
    time_taken=millis();
    wait_until=time_taken+time_out;
    while (millis()<wait_until)
    {
    while (Serial2.available())
    {
    ccc=Serial2.read();
    //Serial.print(ccc);
    if (k<buffer_size-1)
    {
    Receive_buffer[k]=ccc;
    k++;
    }
    }
    Receive_buffer[k]=NULL;
    if (strstr(Receive_buffer,StopCharArray)!=NULL)
    {
    //Serial.println("OK found");
    // SIM7600_Error=0;
    Receive_buffer[k]=NULL;
    return false;
    }
    }
    //if (k>=buffer_size-1) {SIM7600_Error=1; strcpy(Receive_buffer,SIM7600_Error_list[SIM7600_Error].c_str());return;}
    //if (millis()>=wait_until) {SIM7600_Error=2; strcpy(Receive_buffer,SIM7600_Error_list[SIM7600_Error].c_str()); return;}
    Receive_buffer[k]=NULL;
    time_taken=millis()-time_taken;
    Serial.println();
    Serial.print("1] This operation took ");
    Serial.print(time_taken);
    Serial.println(" millisec");
    return true; //if (strstr(Receive_buffer,"ERROR")!=NULL) {return true;} else {return false;}
    }

    void clear_Receive_buffer(){
    for (int i=0;i<buffer_size;i++) {Receive_buffer[i]=NULL;}
    }

    bool Process_DateandTime(bool PSUTZ) {
    char *Process_ptr;
    bool Date_Error;
    Date_Error=false;

    //Process_ptr=strstr(Receive_buffer,"CCLK:");
    if (PSUTZ) {Process_ptr=strstr(Receive_buffer,"PSUTTZ:");}
    else {Process_ptr=strstr(Receive_buffer,"CCLK:");}

    if (Process_ptr!=NULL)
    {

       //strcpy(date_time_char_array,"PSUTTZ: 23/04/14,11:56:48\",\"+08\",1");
       //strcat(date_time_char_array,"\0");
      //Serial.println(date_time_char_array);
       Serial.println(Process_ptr);
       strcpy(date_time_char_array,Process_ptr);
    
      Serial.println(date_time_char_array);
    
     int k=0;
     for (int i=0; i<strlen(date_time_char_array); i++)
       {
          if (strchr(allowed_char,date_time_char_array[i])!=NULL)
           {
             date_time_char_array_processed[k]=date_time_char_array[i];
             k++;
           }
       }
    
    
    
      Serial.println(date_time_char_array_processed); 
    
    
    
      Process_ptr=date_time_char_array_processed+1;
      Serial.println(Process_ptr);
       while (1)
         {
           Process_ptr=strtok(Process_ptr,"/,:");     // 23/04/14,11:56:48,+08,1
           if (Process_ptr==NULL) {DateTime_Error=true;break;}
           Thisday.Year=atoi(Process_ptr);
    
            Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
            if (Process_ptr==NULL) {DateTime_Error=true;break;}
            Thisday.Month=atoi(Process_ptr);
    
            Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
             if (Process_ptr==NULL) {DateTime_Error=true;break;}
              Thisday.Day=atoi(Process_ptr);
    
    
            Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
             if (Process_ptr==NULL) {DateTime_Error=true;break;}
             Thisday.Hour=atoi(Process_ptr);
    
             Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
             if (Process_ptr==NULL) {DateTime_Error=true;break;}
             Thisday.Minute=atoi(Process_ptr);
    
             Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
            if (Process_ptr==NULL) {DateTime_Error=true;break;}
            Thisday.Second=atoi(Process_ptr);
    
             Process_ptr=strtok(NULL,"/,:");     // 23/04/14,11:56:48,+08,1
              if (Process_ptr==NULL) {DateTime_Error=true;break;}
              Thisday.Timezone=atoi(Process_ptr);
              Thisday.Hour=Thisday.Hour+(Thisday.Timezone/4);
    
    
             break;
    
           }
    
    
     
           //Append_this_Struct.Photo_Taken=SetDateTime(Thisday.Hour,Thisday.Minute,Thisday.Second, Thisday.Day,Thisday.Month,(Thisday.Year+30));    // CurrentYear (2023-1970) == 55 yea 23 plus 32 dus
           //print_time_t(Append_this_Struct.Photo_Taken);
           Serial.println();
           Serial.print(Thisday.Year);
           Serial.print("/");
           Serial.print( Thisday.Month);
           Serial.print("/");
           Serial.print( Thisday.Day);
           Serial.print(",");
           Serial.print(Thisday.Hour);
           Serial.print(":");
           Serial.print( Thisday.Minute);
           Serial.print(":");
           Serial.print( Thisday.Second);
           Serial.print(",");
           Serial.println( Thisday.Timezone);
    
           
    
           Date_payload="&created_at=20"+String(Thisday.Year)+"-"+Int_to_2_Digits(Thisday.Month)+"-"+Int_to_2_Digits(Thisday.Day)+" "+Int_to_2_Digits(Thisday.Hour)+":"+Int_to_2_Digits(Thisday.Minute)+":"+Int_to_2_Digits(Thisday.Second);
           Serial.println(Date_payload);
              //Serial.println("Done with it");
             //while (1) {delay(300);}
    
           if (Thisday.Year<23)   {Date_Error=true; }
           if (Thisday.Month<0 or Thisday.Month>12 )   {Date_Error=true; }
           if (Thisday.Day<0 or Thisday.Month>31 )   {Date_Error=true; }
           if (Thisday.Hour<0 or Thisday.Hour>12 )   {Date_Error=true; }
           if (Thisday.Minute<0 or Thisday.Minute>60 )   {Date_Error=true; }
           if (Thisday.Second<0 or Thisday.Second>60 )   {Date_Error=true; }
    }
    

    else
    {
    //strcpy(fnameJPG,"AA00000001012011.JPG");
    Date_Error=true;
    }

    return Date_Error;
    }

    String Int_to_2_Digits(int this_int){

    if (this_int<10)
    {return("0"+String(this_int));}
    else
    {return(String(this_int));}

    }

    bool GET_IP_Address () {

    char *p0;
    char *p1;
    int span;
    //Serial.println("GET_IP_Address");

        //strcpy(Receive_buffer,"CHOPEN: 0,\"aap.noot.mies\"");
        //strcpy(Receive_buffer,"CHOPEN: 0,\"\"");
         p0=strstr(Receive_buffer,"CNACT: ");
         if (p0!=NULL)
           {
             p0=p0+strlen("CNACT: ");
             p1=strstr(p0,"\n");
             if (p1!=NULL)
               {
                 span=min(19,p1-p0);
                 strncpy(IP_buffer, p0, span);
                 IP_buffer[span]='\0';
                 Serial.print("IP_buffer : ");
                 Serial.println(IP_buffer);
                 Serial.print(" : ");
                 Serial.println(strlen(IP_buffer));
                 if (strlen(IP_buffer) >8) {return true;} else {return false;}
               }
             else
              { 
                return (false);
                Serial.println("No IP address");
              }
           }
         else
           {
             return (false);
             //$Serial.println("No IP address");
           }
    

    }

    void print_wakeup_reason(){
    esp_sleep_wakeup_cause_t wakeup_reason;

    wakeup_reason = esp_sleep_get_wakeup_cause();

    switch(wakeup_reason)
    {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
    }
    }