Working with T-SIM7600 which has a ESP32 Rover onboard.
Want to publish to Hive and have it working but have some random characters appearing?
#define TINY_GSM_MODEM_SIM7600
// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
#define SerialAT Serial1
// See all AT commands, if wanted
#define DUMP_AT_COMMANDS
// Define the serial console for debug prints, if needed
#define TINY_GSM_DEBUG SerialMon
// set GSM PIN, if any
#define GSM_PIN ""
// Set phone numbers, if you want to test SMS and Calls
//#define SMS_TARGET "+xxxxxx"
//#define CALL_TARGET "+xxxxxx"
// Your GPRS credentials, if any
//const char apn[] = "internet.xxx.xx";
const char apn[] = "";
const char gprsUser[] = "";
const char gprsPass[] = "";
//Your WiFi connection credentials, if applicable
const char wifiSSID[] = "xxxx";
const char wifiPass[] = "xxxx";
// MQTT details Private 8883
//const char* broker = "xxxxx";
//const char* mqttUsername = "xxxxx"; // MQTT username
//const char* mqttPassword = "xxxxx"; // MQTT password
// MQTT details Public 1883
const char* broker = "broker.xxx.com"; x
const char* mqttUsername = "xxxx"; // MQTT username
const char* mqttPassword = "xxxx"; // MQTT password
const char* topicOutput1 = "Protect/output1";
const char* topicOutput2 = "Protect/output2";
//const char* topicTemperature = "Protect/temperature";
const char* topicTemperature = "Protect/temperature";
const char* topicHumidity = "Protect/humidity";
//Trigger
unsigned long TriggerTimes[3];
unsigned TriggerCount = 0;
//All Functions libraries
#include <SPI.h>
#include <SD.h>
#include <Ticker.h>
#include <TinyGsmClient.h>
#include "utilities.h"
#include <WiFi.h>
//PIR HCSR501
int ledPin = 12; // LED
int pirPin = 19; // PIR Out pin
int pirStat = 0; // PIR status
// Sensor state
boolean pirState, lastPirState;
//Interger countPIR
int countPIR = 0;
//Interger count Down
int countDown = 0;
//Interger timeInterval
int timeinterval = 51000; //51000 is 51secs allows it to count => than 50 remove equals
//Interger CPUTemp
//int temp = 0;
float temp = 0;
//Interger MQTTcount
int MQTTcount = 0;
//Debug
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
//MQTT
#include <PubSubClient.h>
TinyGsmClient client(modem);
PubSubClient mqtt(client);
#define OUTPUT_1 2
#define OUTPUT_2 15
uint32_t lastReconnectAttempt = 0;
// Static Wireless IP address
IPAddress local_IP(192, 168, x, x);
IPAddress gateway(192, 168, x, x);
IPAddress subnet(255, 255, 255, 255);
IPAddress primaryDNS(192, 168, x, x); //optional
IPAddress secondaryDNS(1, 1, 1, 1); //optional
//Libraries for OLED Display
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Graphics File
#include "graphics.h"
//OLED Display pins
#define OLED_SDA 21 //4
#define OLED_SCL 22 //15
#define OLED_RST 16
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
//OLED
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RST);
RTC_DATA_ATTR int counter = 0;
#define Logo_BMPWIDTH 128
#define Logo_BMPHEIGHT 64
#define Logo2_BMPWIDTH 128
#define Logo2_BMPHEIGHT 64
#define Sleeping_BMPWIDTH 128
#define Sleeping_BMPHEIGHT 64
#define Sleeping2_BMPWIDTH 128
#define Sleeping2_BMPHEIGHT 64
//MQTT Setup
void mqttCallback(char* topic, byte* message, unsigned int len) {
Serial.print("Message arrived on topic: ");
Serial.print(topic);
Serial.print(". Message: ");
String messageTemp;
for (int i = 0; i < len; i++) {
Serial.print((char)message[i]);
messageTemp += (char)message[i];
}
Serial.println();
// Feel free to add more if statements to control more GPIOs with MQTT
// If a message is received on the topic Protect/output1, you check if the message is either "true" or "false".
// Changes the output state according to the message
if (String(topic) == "Protect/output1") {
Serial.print("Changing output to ");
if (messageTemp == "true") {
Serial.println("true");
digitalWrite(OUTPUT_1, HIGH);
}
else if (messageTemp == "false") {
Serial.println("false");
digitalWrite(OUTPUT_1, LOW);
}
}
else if (String(topic) == "Protect/output2") {
Serial.print("Changing output to ");
if (messageTemp == "true") {
Serial.println("true");
digitalWrite(OUTPUT_2, HIGH);
}
else if (messageTemp == "false") {
Serial.println("false");
digitalWrite(OUTPUT_2, LOW);
}
}
}
boolean mqttConnect() {
SerialMon.print("Connecting to ");
// Connect to MQTT Broker without username and password
boolean status = mqtt.connect("Protect");
// Or, if you want to authenticate MQTT:
//boolean status = mqtt.connect("Protect", mqttUsername, mqttPassword);
//SerialMon.print(status);
/*
if (status == false) {
SerialMon.println(" fail");
//ESP.restart();
return false;
}
SerialMon.println(" success");
mqtt.subscribe(topicOutput1);
mqtt.subscribe(topicOutput2);
*/
return mqtt.connected();
SerialMon.print("MQTT Connected ");
}
void setup()
{
//PIR
pinMode(ledPin, OUTPUT);
pinMode(pirPin, INPUT);
SerialMon.begin(115200);
delay(10);
//Reset OLED display via software
pinMode(OLED_RST, OUTPUT);
digitalWrite(OLED_RST, LOW);
delay(20);
digitalWrite(OLED_RST, HIGH);
//initialize OLED
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3c, false, false)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
//Draw BitMap Logo
display.clearDisplay();
display.drawBitmap(0, 0, Logo, 128, 64, WHITE);
display.display();
delay(1000);
display.clearDisplay();
display.drawBitmap(0, 0, Logo2, 128, 64, WHITE);
display.display();
delay(1000);
display.clearDisplay();
display.drawBitmap(0, 0, Logo, 128, 64, WHITE);
display.display();
delay(1000);
display.clearDisplay();
display.drawBitmap(0, 0, Logo2, 128, 64, WHITE);
display.display();
delay(1000);
Serial.println("Booting");
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // draw box
display.setCursor(2, 2);
display.print("Booting...");
display.display();
delay(1000);
//The indicator light of the board can be controlled
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
//MODEM_PWRKEY IO:4 The power-on signal of the modulator must be given to it,
//otherwise the modulator will not reply when the command is sent
pinMode(MODEM_PWRKEY, OUTPUT);
digitalWrite(MODEM_PWRKEY, HIGH);
delay(300); //Need delay
digitalWrite(MODEM_PWRKEY, LOW);
//MQTT
pinMode(OUTPUT_1, OUTPUT);
pinMode(OUTPUT_2, OUTPUT);
//MODEM_FLIGHT IO:25 Modulator flight mode control,
//need to enable modulator, this pin must be set to high
pinMode(MODEM_FLIGHT, OUTPUT);
digitalWrite(MODEM_FLIGHT, HIGH);
SerialMon.println("Wait...");
//Set GSM module baud rate
SerialAT.begin(UART_BAUD, SERIAL_8N1, MODEM_RX, MODEM_TX);
//delay(6000);
//Connect to a WiFi network
WiFi.begin(wifiSSID, wifiPass);
// Configures static IP address
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS)) {
Serial.println("STA Failed to configure");
}
// Connect to Wi-Fi network with SSID and password
Serial.print("Connecting to ");
Serial.println(wifiSSID);
WiFi.begin(wifiSSID, wifiPass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
// Print local IP address
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
bool res ;
DBG("Initializing modem...");
Serial.println("Initializing modem..");
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // draw box
display.setCursor(3, 3);
display.print("Initializing modem..");
display.display();
delay(1000);
if (!modem.init()) {
DBG("Failed to restart modem, delaying 10s and retrying");
return;
}
//Print Wireless IP address and if connected
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // draw box
display.setCursor(3, 3);
display.print("Connecting ");
display.println(wifiSSID);
display.setCursor(3, 12);
display.print(WiFi.localIP());
display.display();
delay(2000);
/*
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
ESP.restart();
}
else {
SerialMon.println(" OK");
}
if (modem.isGprsConnected()) {
SerialMon.println("GPRS connected");
}
*/
// MQTT Broker setup
mqtt.setServer(broker, 1883); //use TLS 8883 not Web Sockets not supported 8884
//mqtt.setCallback(mqttCallback);
DBG("Connecting to APN");
Serial.println("Connecting to APN");
delay(1000);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
light_sleep(10);
return;
}
res = modem.isGprsConnected();
DBG("GPRS status: ", res ? "connected" : "not connected");
String ccid = modem.getSimCCID();
DBG("CCID: ", ccid);
Serial.println(ccid);
String imei = modem.getIMEI();
DBG("IMEI: ", imei);
Serial.println(imei);
String imsi = modem.getIMSI();
DBG("IMSI: ", imsi);
Serial.println(imsi);
String cop = modem.getOperator();
DBG("Operator: ", cop);
Serial.println(cop);
IPAddress local = modem.localIP();
DBG("Local IP: ", local);
Serial.println(local);
int csq = modem.getSignalQuality();
DBG("Signal quality: ", csq);
Serial.println(csq);
//Write to the display
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.drawRect(0, 0, 128, 64, SSD1306_WHITE); // draw box
// drawFastVLine(x, y, length, color)
// Draw a verticle line starting at x,y for the length of pixels
// L/R vPos, vLength
display.drawFastVLine(30, 3, 58, WHITE);
//display.setCursor(3, 3);
//display.print("NTWK: ");
display.drawBitmap(1, 1, Connected, 24, 16, SSD1306_WHITE);
//left/right then down/up (l/r, u/d)
display.setCursor(34, 3);
display.print(cop);
//display.setCursor(3, 15);
//display.print("IP: ");
display.drawBitmap(1, 14, IPAddressID, 24, 12, SSD1306_WHITE);
display.setCursor(34, 17);
display.print(local);
//display.setCursor(3, 30);
//display.print("SIG: ");
display.drawBitmap(3, 28, Signalcellular, 24, 12, SSD1306_WHITE);
display.setCursor(34, 31);
display.print(csq);
display.drawBitmap(3, 40, statusconnection, 24, 24, SSD1306_WHITE);
//display.setCursor(3, 45);
//display.print("Status: ");
display.setCursor(34, 46);
display.print(res ? + "Connected" : "Not connected");
display.display();
delay(5000);
display.clearDisplay();
/*
mqttConnect();
//mqtt.connect("Protect", mqttUsername, mqttPassword);
mqtt.connect("Protect");
SerialMon.print("MQTT Connected ");
//mqtt.publish("Protect/temperature", "1332");
temp = modem.getTemperature(); //get CPUtem
// Convert the value to a char array
char tempString[2];
dtostrf(temp, 1, 1, tempString);
mqtt.publish(topicTemperature, tempString);
SerialMon.println("MQTT publish Protect/temperature value ");
//Serial.println(topicTemperature, tempString);
delay(2000); //wait to see on the serial monitor
*/
//mqttConnect();
//mqtt.connect("Protect");
//SerialMon.print("MQTT Connected ");
//mqtt.publish("Protect/temperature", "1332"); //manually enter the topic
Serial.print("Status: ");
Serial.println("Armed");
}
//Sleep Timer
void light_sleep(uint32_t sec )
{
esp_sleep_enable_timer_wakeup(sec * 1000000ULL);
esp_light_sleep_start();
}
void loop() {
/*
// Make sure we're still registered on the network
if (!modem.isNetworkConnected()) {
SerialMon.println("Network disconnected");
if (!modem.waitForNetwork(180000L, true)) {
SerialMon.println(" fail");
delay(10000);
return;
}
if (modem.isNetworkConnected()) {
SerialMon.println("Network re-connected");
}
}
//MQTT Check and reconnect
if (!mqtt.connected()) {
SerialMon.println("=== MQTT NOT CONNECTED ===");
// Reconnect every 10 seconds
uint32_t t = millis();
if (t - lastReconnectAttempt > 60000L) {
lastReconnectAttempt = t;
if (mqttConnect()) { lastReconnectAttempt = 0; }
}
delay(100);
return;
}
mqtt.loop();
*/
/*
https://components101.com/sensors/hc-sr501-pir-sensor
HC-SR501 sensors is to turn the 'time' pot fully anticlockwise for the shortest 'on' time (~3sec).
Then the Arduino can take care of timing.
Leave the 'sens' pot in the middle. It does NOT control distance.
The sketch is better written as a state machine. Do something if the PIR output CHANGES.
Wrote a quick example (untested).
Be patient, and sit very still. These sensors are very sensitive. And not only to human heat sources
Range it's 5-7metres with that Fresnel lens.
You can only influence the 'ignore' time with the sensitivity pot, to reduce false triggers
Two LiPo batteries in series (~7.4volt) can be connected to the DC socket.
The Uno draws about 50mA, so theoretically about 20 hours on two 1000mAh cells.
Can ignore the PIR sensor in the calculations. It draws less than 0.1mA
*/
display.clearDisplay();
display.drawBitmap(0, 0, NoMovement, 128, 64, WHITE);
display.setCursor(29, 57);
display.print(" A R M E D ");
display.display();
display.display();
// PIR Detector
Check_PIR();
//MQTTcount int MQTTcount = 0;
//MQTTcount++; // increment x by one and returns the old value of x
Serial.print("MQTT#: ");
Serial.println(MQTTcount);
MQTT_temp(); //call the function
//currentTime int countDown = 0;
countDown++; // increment x by one and returns the old value of x
if (countDown >= 50) {
countDown = 0; //reset countDown to 0 // x is greater than or equal to y
TriggerCount = 0;
Serial.print("Threshold hit, 50s timeout: ");
Serial.println(countDown);
Serial.print("Threshold hit, 5x trigger reset: ");
Serial.println(TriggerCount);
}
else { // Display counter
Serial.print("Timer: ");
Serial.println(countDown);
digitalWrite(ledPin, HIGH); // enable LED
display.setCursor(2, 2);
display.print("CNTR:");
display.print(countDown); // display counter
display.setCursor(97, 2);
display.print("TRG:");
display.print(TriggerCount); // display counter
display.setCursor(2, 14);
display.print(temp); // display CPUTemp
display.print((char)247);// print char 1 (which is the degree)
display.print("C");
display.display();
delay(1000);
}
//If the first (oldest) time in the list is more than 50 seconds ago, remove that time and move the other times (if any) up the list
if (TriggerCount > 0 &&
millis() - TriggerTimes[0] >= timeinterval) //51 seconds counts to 50 resets on 51
{
for (unsigned tt = 1; tt < TriggerCount; tt++)
{
TriggerTimes[tt - 1] = TriggerTimes[tt];
}
TriggerCount--;
}
}
void Check_PIR()
{
// PIR Detector
int pirState = digitalRead(pirPin);
if (pirState) // if LOW to HIGH
{ // The opening bracket goes HERE...
Short_Flash_LED();
temp = modem.getTemperature(); //get CPUtem
Serial.print("Status: ");
Serial.println("Motion Detected!");
Serial.print("Trigger Count: ");
Serial.println(TriggerCount);
// ... not HERE
PIR_Triggered(); //Call Trigger Function
}
}
// PIR triggers, add the time (millis()) to the bottom of the list.
// If the length of the list has reached 3, sound the alarm and clear the list.
void PIR_Triggered()
{
TriggerTimes[TriggerCount++] = millis();
if (TriggerCount >= 5)
{
// SOUND THE ALARM HERE
TriggerCount = 0;
countDown = 0;
Serial.print("Status: ");
Serial.println("Alarm triggered, alert sent!");
Serial.print("Trigger, 5x threshold met, reset trigger to: ");
Serial.println(TriggerCount);
Serial.print("Trigger, 50s threshold met, reset counter to: ");
Serial.println(countDown);
Movement_NoMovement(); //display alarms
Long_Flash_LED ();
}
}
void MQTT_temp() // publish MQTT temp every 30 counts approx 30secs
{
MQTTcount++; // increment x by one and returns the old value of x
if (MQTTcount >= 30) {
MQTTcount = 0; //reset MQTTcountn to 0 // x is greater than or equal to y
temp = modem.getTemperature(); //get CPUtem
// Convert the value to a char array
char tempString[8];
dtostrf(temp, 1, 1, tempString);
Serial.print("MQTT#2: ");
Serial.println(MQTTcount);
mqttConnect();
mqtt.connect("Protect");
SerialMon.print("MQTT Connected ");
//mqtt.publish(topicTemperature, tempString); //publish temp // has addtional characters
mqtt.publish("Protect/temperature", tempString); //publish temp // has addtional characters
}
}
void Long_Flash_LED() // Long Flash the LED
{
digitalWrite(ledPin, HIGH);
delay (800);
digitalWrite(ledPin, LOW);
delay (800);
digitalWrite(ledPin, HIGH);
delay (800);
digitalWrite(ledPin, LOW);
}
void Short_Flash_LED() //Short Flash the LED
{
digitalWrite(ledPin, HIGH);
delay (100);
digitalWrite(ledPin, LOW);
delay (100);
digitalWrite(ledPin, HIGH);
delay (100);
digitalWrite(ledPin, LOW);
delay (100);
digitalWrite(ledPin, HIGH);
delay (100);
digitalWrite(ledPin, LOW);
delay (100);
}
void Movement_NoMovement() //animate the alarm symbol
{
display.clearDisplay();
display.drawBitmap(0, 0, Movement, 128, 64, WHITE);
display.setCursor(29, 57);
display.print(" A L E R T ");
display.display();
display.clearDisplay();
delay(600);
display.drawBitmap(0, 0, NoMovement, 128, 64, WHITE);
display.setCursor(27, 57);
display.print("S M S - S e n t");
display.display();
display.clearDisplay();
delay(600);
display.drawBitmap(0, 0, Movement, 128, 64, WHITE);
display.setCursor(27, 57);
display.print("P X T - S e n t");
display.display();
display.clearDisplay();
delay(600);
}
![]()
O and two boxes? Thoughts?
Connects and publishes ok but some time comes up with non numerical number.
