Micro-controllers, wireless transmission and database
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
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
ADC1 - IN9 (tick)
Parameter Settings --> ADC Settings --> Continuous Conversion Mode (Enabled)
Enable USART1 asynchronous
Configuration → Parameter Settings → Basic Parameters → Baud rate 115200
/* 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.
In your web browser type ******.atwebpages.com
Here remember to use your domain address instead of ******
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.