Docs

Micro-controllers, wireless transmission and database

Head

Post data to http server using STM32 & SIM7600

SIM7600 comes in different version. The one I am using is SIM7600G (Global) that can work with many bands. I checked here in Australia with two different providers (Telstra and Vodafone). Both sim cards worked fine.

The pin outs are quite simple. Connect four pins VCC,GND,UART(RX) and UART(TX), it will just work. This module includes proper power regulator, so we can connect 5V to the V pin. Also the TX/RX serial communication already includes necessary 3.3V level shifter. So we can connect to 3.3V ESP or STM microcontroller directly.

AT command manual, Schematic and Datasheet can be found in the following links. https://www.adrive.com/public/bPqyGe/BK-SIM7600E-H.zip

Items can be purchased from https://www.aliexpress.com/store/605000. I bought my items from https://www.aliexpress.com/item/4000224044192.html

This project assumes you have already installed STM32CubeIDE. You need to have previously done a basic program using STM32CubeIDE. I have made a complete video from installing STM32CubeIDE to LED blink program. You can watch it by clicking this link. https://www.youtube.com/watch?v=kXg467nVd_A

There are few steps in this project. So I have listed them below

1. Create a free web server account from https://www.awardspace.com/ and create three PHP files.

2. Do the wiring connection for STM32

3. Upload the code from CubeIDE

4. Using web browser to visualise data and graph

5. Downloading Microsoft Excel file

1. Create a free web server account from https://www.awardspace.com/ and create three PHP files.

Go to https://www.awardspace.com/ and click Free Signup button

Fill in Your name, Email address and create a password.

Click Register Now Button

Check your email and click the activation link.

Go again to https://www.awardspace.com/ and click Login button

Click Hosting Tools → Domain Manager then click Create a Free Subdomain and type a name you like. If it is already taken by someone, you will get "This subdomain name already exists in our system" message. Try again with different one. When it is successful, please note this domain name ******.atwebpages.com

This will be your domain name. You can access it from anywhere in the world. You will need to include it in the CubeIDE code for posting of the sensor data to your free server.

Now Click Hosting Tools → File Manager then double click ******.atwebpages.com CREATE 3 (THREE) FILES

For the first file, click Create button and select create file option type insert.php then Create button

Double click insert.php file and paste the following code there

<!--  insert.php file start here  -->
<?php
    $key = "";
    $distance = "0";
    if (isset($_POST['key'])) $key = $_POST['key'];
    if (isset($_POST['distance'])) $distance = $_POST['distance'];
    if ($key == "a@4K3") {
      $date = time();
      $intdistance = intval($distance);
      $db = new PDO('sqlite:readingsDB.sqlite');
      $db->exec("CREATE TABLE IF NOT EXISTS readings(date INTEGER, distance INTEGER)");
      $db->exec("INSERT INTO readings(date, distance) VALUES('$date','$intdistance');");
      echo "ok";
    }
?>
<!--  End of insert.php file  -->

Cilck save button then Cilck close button

For the second file, click Create button again and select create file option type index.php then Create button

Double click index.php file and paste the following code there

<!--  index.php file start here  -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        table {
        font-family: arial, sans-serif;
        border-collapse: collapse;
        }
        td, th {
        border: 1px solid #dddddd;
        text-align: left;
        padding: 8px;
        }
        tr:nth-child(even) {
        background-color: #dddddd;
        }
        </style>
    <title>Sensor Readings</title>
</head>
<body>
    <h1>Sensor Readings</h1>
    <form action="/excel.php">
        <label for="selectDay1">Date:</label>
        <input type="date" id="selectDay1" name="selectDay1">
        <input type="submit" value="Download">
    </form>
    <form action="/index.php">
        <label for="selectDay2">Date:</label>
        <input type="date" id="selectDay2" name="selectDay2">
        <input type="submit" value="Refresh">
    </form>
    <div id="chart_div"></div>
    <p></p>
    <table>
        <tr>
            <th>Date (GMT or Iceland Time)</th>
            <th>Reading</th>
        </tr>
        <?php
            $selectDay = 0;
            if (isset($_GET['selectDay2']) && $_GET['selectDay2']!="") {
                $selectDay=strtotime($_GET['selectDay2']);
            } else {
                $selectDay=time()-43200;
            }
            $nextDay = $selectDay+86400;
            $db = new PDO('sqlite:readingsDB.sqlite');
            $query = "SELECT * FROM readings Where date  BETWEEN " .$selectDay." AND ".$nextDay." ORDER BY date DESC";
            $result = $db->query($query);
            foreach($result as $row) {
                print "<tr><td>".date('d/m/Y H:i:s', $row['date'])."</td>";
                print "<td>".$row['distance']."</td></tr>";
            }
        ?>
    </table>
    <?php
        $query = "SELECT * FROM readings Where date  BETWEEN " .$selectDay." AND ".$nextDay." ORDER BY date ASC";
        $result = $db->query($query);
        $rows[][] = array();        
        $rows[0][0] = "Date";
        $rows[0][1] = "Sensor Readings";
        $count=1;
        foreach($result as $row) {
            $rows[$count][0] = date('H:i', $row['date']);
            $rows[$count][1] = intval($row["distance"]);
            $count++;
        }
        $jsonTable = json_encode($rows);
    ?>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript">
        google.charts.load("current", {packages:["imagelinechart"]});
        google.charts.setOnLoadCallback(drawChart);
        function drawChart() {
            let data = google.visualization.arrayToDataTable(<?php echo  $jsonTable; ?>);
            let chart = new google.visualization.ImageLineChart(document.getElementById('chart_div'));
            let options = {'title':'Sensor Readings', 'showCategoryLabels':false, 'min':0};
            chart.draw(data, options);
        }
    </script>
</body>
</html>
<!--  End of index.php file  -->

Cilck save button then Cilck close button

For the third file, click Create button again and select create file option type excel.php then Create button

Double click excel.php file and paste the following code there

<!--  excel.php file start here  -->

<?php
    header('Content-Type: application/xls');
    header('Content-Disposition: attachment; filename=Readings.xls');
?>
<table>
    <tr>
        <th>Date (GMT or Iceland Time)</th>
        <th>Readings</th>
    </tr>
    <?php
        $selectDay = 0;
        if (isset($_GET['selectDay1']) && $_GET['selectDay1']!="") {
            $selectDay = strtotime($_GET['selectDay1']);
        } else {
            $selectDay = time()-43200;
        }
        $nextDay = $selectDay+86400;
        $db = new PDO('sqlite:readingsDB.sqlite');
        $query = "SELECT * FROM readings Where date  BETWEEN " .$selectDay." AND ".$nextDay." ORDER BY date DESC";
        $result = $db->query($query);
        foreach($result as $row) {
            print "<tr><td>".date('d/m/Y H:i:s', $row['date'])."</td>";
            print "<td>".$row['distance']."</td></tr>";
        }
    ?>
</table>
<!--  End of excel.php file  -->

Cilck save button then Cilck close button

2. Do the wiring connection for STM32

Diagram

Image1

Image2

3. Upload the code from CubeIDE

STM32CubeIDE Settings

ADC1 - IN9 (tick)

Parameter Settings --> ADC Settings --> Continuous Conversion Mode (Enabled)

Enable USART1 asynchronous

Configuration → Parameter Settings → Basic Parameters → Baud rate 115200

Additional code on top of STM32CubeIDE generated code

/* USER CODE BEGIN Includes */
#include <string.h>
#include <stdio.h>
/* USER CODE END Includes */

/* USER CODE BEGIN 0 */
const char apn[]  = "live.vodafone.com"; // Change this to your Provider details
const char server[] = "nizarmohideen.atwebpages.com"; // Change this to your domain
const int  port = 80;
const char resource[] = "/insert.php";
const uint32_t timeOut =10000;
char content[80];
char ATcommand[80];
uint8_t buffer[100] = {0};
uint8_t ATisOK = 0;
uint8_t CGREGisOK = 0;
uint8_t CIPOPENisOK = 0;
uint8_t NETOPENisOK = 0;
uint32_t previousTick;
uint16_t distance;

void SIMTransmit(char *cmd)
{
  memset(buffer,0,sizeof(buffer));
  HAL_UART_Transmit(&huart1,(uint8_t *)cmd,strlen(cmd),1000);
  HAL_UART_Receive (&huart1, buffer, 100, 1000);
}

void httpPost(void)
{
  ATisOK = 0;
  CGREGisOK = 0;
  NETOPENisOK = 0;
  CIPOPENisOK = 0;
  // Check for OK response for AT 
  previousTick =  HAL_GetTick();
  while(!ATisOK && previousTick  + timeOut >  HAL_GetTick())
  {
    SIMTransmit("AT\r\n");
    HAL_Delay(1000);
    if(strstr((char *)buffer,"OK"))
    {
      ATisOK = 1;
    }
  }

  // Check for network registration. 
  if(ATisOK)
  {
    previousTick =  HAL_GetTick();
    while(!CGREGisOK  && previousTick  + timeOut >  HAL_GetTick())
    {
      SIMTransmit("AT+CGREG?\r\n");
      if(strstr((char *)buffer,"+CGREG: 0,1"))
      {
        CGREGisOK = 1;
      }
    }
  }

  // Check for Internet IP Connection
  if(ATisOK && CGREGisOK)
  {
    previousTick =  HAL_GetTick();
    while(!NETOPENisOK  && previousTick  + timeOut >  HAL_GetTick())
    {
      SIMTransmit("AT+NETCLOSE\r\n");
      sprintf(ATcommand,"AT+CGDCONT=1,\"IP\",\"%s\",\"0.0.0.0\",0,0\r\n",apn);
      SIMTransmit(ATcommand);
      SIMTransmit("AT+CIPMODE=0\r\n");
      SIMTransmit("AT+CIPSENDMODE=0\r\n");
      SIMTransmit("AT+CIPCCFG=10,0,0,0,1,0,75000\r\n");
      SIMTransmit("AT+CIPTIMEOUT=75000,15000,15000\r\n");
      SIMTransmit("AT+NETOPEN\r\n");
      SIMTransmit("AT+NETOPEN?\r\n");
      if(strstr((char *)buffer,"+NETOPEN: 1"))
      {
        NETOPENisOK = 1;
      }
    }
  }

  // Check for TCP connection
  if(ATisOK && CGREGisOK && NETOPENisOK)
  {
    SIMTransmit("AT+IPADDR\r\n");
    previousTick =  HAL_GetTick();
    while(!CIPOPENisOK  && previousTick  + timeOut >  HAL_GetTick())
    {
      SIMTransmit("AT+CIPCLOSE=0\r\n");
      sprintf(ATcommand,"AT+CIPOPEN=0,\"TCP\",\"%s\",%d\r\n",server,port);
      SIMTransmit(ATcommand);
      HAL_Delay(1000);
      if(strstr((char *)buffer,"+CIPOPEN: 0,0"))
      {
        CIPOPENisOK = 1;
      }
    }
  }

  // If all Connection success (Wiring, Registration and TCP/IP)
  if(ATisOK && CGREGisOK && CIPOPENisOK && NETOPENisOK)
  {
    // Perform http request
    sprintf(ATcommand,"AT+CIPSEND=0,%d\r\n",strlen(resource)+16);
    SIMTransmit(ATcommand);
    if(strstr((char *)buffer,">"))
    {
      sprintf(ATcommand,"POST %s HTTP/1.1\r\n",resource);
      SIMTransmit(ATcommand);
    }

    sprintf(ATcommand,"AT+CIPSEND=0,%d\r\n",strlen(server)+8);
    SIMTransmit(ATcommand);
    if(strstr((char *)buffer,">"))
    {
      sprintf(ATcommand,"Host: %s\r\n",server);
      SIMTransmit(ATcommand);
    }

    SIMTransmit("AT+CIPSEND=0,19\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("Connection: close\r\n");
    }

    SIMTransmit("AT+CIPSEND=0,49\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("Content-Type: application/x-www-form-urlencoded\r\n");
    }

    SIMTransmit("AT+CIPSEND=0,16\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("Content-Length: ");
    }

    char sLength[5];
    snprintf(sLength, 5,"%d",strlen(content));
    sprintf(ATcommand,"AT+CIPSEND=0,%d\r\n",strlen(sLength));
    SIMTransmit(ATcommand);
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit(sLength);
    }

    SIMTransmit("AT+CIPSEND=0,2\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("\r\n");
    }

    SIMTransmit("AT+CIPSEND=0,2\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("\r\n");
    }

    sprintf(ATcommand,"AT+CIPSEND=0,%d\r\n",strlen(content));
    SIMTransmit(ATcommand);
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit(content);
    }

    SIMTransmit("AT+CIPSEND=0,2\r\n");
    if(strstr((char *)buffer,">"))
    {
      SIMTransmit("\r\n");
    }
    HAL_Delay(2000);
    // Close connections
    SIMTransmit("AT+CIPCLOSE=0\r\n");
    SIMTransmit("AT++NETCLOSE\r\n");
  }
}
/* USER CODE END 0 */

  /* USER CODE BEGIN 2 */
  HAL_ADC_Start(&hadc1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_ADC_PollForConversion(&hadc1,1000);
    distance = HAL_ADC_GetValue(&hadc1);
    sprintf(content,"key=a@4K3&distance=%d",distance);
    httpPost();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

NEED TO DO TWO CHANGES TO ABOVE CubeIDE CODE

1. Find out your SIM card providers APN. You can google search or use https://wiki.apnchanger.org/ Replace

const char apn[]  = "live.vodafone.com";

In the place of "live.vodafone.com", put your providers APN

2. Change the subdomain name you created

const char server[] = "nizarmohideen.atwebpages.com"; 

In the place of nizarmohideen, put your domain address you created.

4. Using web browser to visualise data and graph

In your web browser type ******.atwebpages.com

Here remember to use your domain address instead of ******

5. Downloading Microsoft Excel file

Click the Download button. It will save Excel file Readings.xls into your download folder. When you open the file, you may get a warning message that file format does not match. It is because I have kept the web server code to minimal for simplicity. So you can ignore the warning.