Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /********* Pleasedontcode.com **********
- Pleasedontcode thanks you for automatic code generation! Enjoy your code!
- - Terms and Conditions:
- You have a non-exclusive, revocable, worldwide, royalty-free license
- for personal and commercial use. Attribution is optional; modifications
- are allowed, but you're responsible for code maintenance. We're not
- liable for any loss or damage. For full terms,
- please visit pleasedontcode.com/termsandconditions.
- - Project: # Gas Monitor
- - Source Code NOT compiled for: Arduino Uno
- - Source Code created on: 2026-01-25 18:35:10
- ********* Pleasedontcode.com **********/
- /****** SYSTEM REQUIREMENTS *****/
- /****** SYSTEM REQUIREMENT 1 *****/
- /* when gas sms is sent to sim 900a it should send */
- /* the gas level to phone */
- /****** END SYSTEM REQUIREMENTS *****/
- /* START CODE */
- /****** SYSTEM REQUIREMENTS *****/
- /* System Requirement 1: "when gas sms is sent to sim 900a it should send the gas level to phone" */
- /****** DEFINITION OF LIBRARIES *****/
- #include <MQUnifiedsensor.h> //https://github.com/miguel5612/MQSensorsLib
- #include <SoftwareSerial.h> //Software Serial for SIM900A communication
- /****** FUNCTION PROTOTYPES *****/
- void setup(void);
- void loop(void);
- void initMQ5Sensor(void);
- void initSIM900A(void);
- void readGasLevel(void);
- void checkIncomingSMS(void);
- void enableSMSReception(void);
- void processSMSMessage(String messageIndex);
- void extractSenderPhoneNumber(String messageIndex);
- void sendGasLevelResponse(String phoneNumber);
- void sendATCommand(String command, unsigned long timeout);
- String waitForResponseWithData(String expectedResponse, unsigned long timeout);
- void waitForResponse(String expectedResponse, unsigned long timeout);
- void displayDebugInfo(void);
- void handleATError(String command);
- /***** DEFINITION OF DIGITAL INPUT PINS *****/
- const uint8_t MQ5_MQ5_DOUT_PIN_D2 = 2;
- /***** DEFINITION OF ANALOG INPUT PINS *****/
- const uint8_t MQ5_MQ5_AOUT_PIN_A0 = A0;
- /***** DEFINITION OF SIM900A COMMUNICATION PINS *****/
- // SoftwareSerial(RX, TX)
- const uint8_t SIM900A_RX_PIN = 10; // RX pin for SIM900A
- const uint8_t SIM900A_TX_PIN = 11; // TX pin for SIM900A
- /***** DEFINITION OF SENSOR CALIBRATION PARAMETERS *****/
- // MQ-5 sensor configuration for LPG detection
- const float MQ5_RATIO_CLEAN_AIR = 6.5; // RS/R0 ratio in clean air
- const float MQ5_RL_VALUE = 10.0; // Load resistance in KOhms
- const float MQ5_VOLTAGE_RESOLUTION = 5.0; // Arduino Uno voltage reference
- const int MQ5_ADC_BIT_RESOLUTION = 10; // Arduino Uno ADC resolution
- /***** DEFINITION OF GSM MODULE CONFIGURATION *****/
- const unsigned long SIM900A_BAUD_RATE = 9600; // SIM900A communication speed
- const unsigned long AT_COMMAND_TIMEOUT = 1000; // Timeout for AT commands (ms)
- const unsigned long SMS_DELAY = 5000; // Delay between SMS messages (ms)
- const unsigned long SMS_RECEPTION_TIMEOUT = 2000; // Timeout for SMS reception check (ms)
- /***** DEFINITION OF MEASUREMENT PARAMETERS *****/
- const unsigned long GAS_READING_INTERVAL = 10000; // Interval for gas readings (ms)
- /***** SMS RECEPTION CONSTANTS *****/
- const String SMS_KEYWORD = "gas"; // Keyword to detect in incoming SMS
- const String SMS_INDICATOR = "+CMT:"; // SMS indicator string
- /****** DEFINITION OF LIBRARIES CLASS INSTANCES *****/
- // Create SoftwareSerial instance for SIM900A communication
- SoftwareSerial SIM900A_Serial(SIM900A_RX_PIN, SIM900A_TX_PIN);
- // Create MQ5 sensor instance
- // MQUnifiedsensor(Board, Voltage_Resolution, ADC_Bit_Resolution, Pin, Type)
- MQUnifiedsensor MQ5("Arduino UNO", MQ5_VOLTAGE_RESOLUTION, MQ5_ADC_BIT_RESOLUTION, MQ5_MQ5_AOUT_PIN_A0, "MQ-5");
- /***** GLOBAL VARIABLES *****/
- float currentGasLevel = 0.0; // Current gas level reading in PPM
- unsigned long lastGasReadTime = 0; // Timestamp of last gas reading
- bool SIM900AInitialized = false; // Flag for SIM900A initialization status
- String serialBuffer = ""; // Buffer for serial communication
- String smsReceptionBuffer = ""; // Buffer for SMS reception data
- bool smsReceptionEnabled = false; // Flag for SMS reception mode
- String incomingSMSPhoneNumber = ""; // Phone number of incoming SMS sender
- bool incomingSMSReceived = false; // Flag indicating incoming SMS detected
- String incomingSMSContent = ""; // Content of incoming SMS message
- /****** SETUP FUNCTION *****/
- void setup(void)
- {
- // Initialize Serial for debugging
- Serial.begin(9600);
- // Wait for Serial to initialize
- delay(100);
- Serial.println(F("\n\n=== Gas SMS Alert System Started ==="));
- Serial.println(F("REQUEST-BASED SMS MODE: System will respond to incoming 'gas' SMS requests"));
- Serial.println(F("Initializing MQ5 Sensor..."));
- // Configure GPIO pins
- pinMode(MQ5_MQ5_DOUT_PIN_D2, INPUT_PULLUP);
- pinMode(MQ5_MQ5_AOUT_PIN_A0, INPUT);
- // Initialize MQ5 sensor
- initMQ5Sensor();
- // Initialize SIM900A GSM module
- Serial.println(F("Initializing SIM900A GSM Module..."));
- initSIM900A();
- Serial.println(F("=== System Initialization Complete ===\n"));
- // Initialize timestamps
- lastGasReadTime = millis();
- }
- /****** MAIN LOOP *****/
- void loop(void)
- {
- // Read incoming data from SIM900A module
- while (SIM900A_Serial.available())
- {
- char inChar = (char)SIM900A_Serial.read();
- smsReceptionBuffer += inChar;
- // Process complete lines
- if (inChar == '\n')
- {
- // Check if this line contains an SMS indicator
- if (smsReceptionBuffer.indexOf(SMS_INDICATOR) != -1)
- {
- Serial.println(F("\n=== INCOMING SMS DETECTED ==="));
- Serial.print(F("SMS Header: "));
- Serial.print(smsReceptionBuffer);
- // Extract phone number and mark SMS received
- incomingSMSReceived = true;
- // Parse the phone number from the +CMT line
- // Format: +CMT: "+1234567890",,"2024/01/15,10:30:45+00"
- int startQuote = smsReceptionBuffer.indexOf('"');
- int endQuote = smsReceptionBuffer.indexOf('"', startQuote + 1);
- if (startQuote != -1 && endQuote != -1 && endQuote > startQuote)
- {
- incomingSMSPhoneNumber = smsReceptionBuffer.substring(startQuote + 1, endQuote);
- Serial.print(F("Sender: "));
- Serial.println(incomingSMSPhoneNumber);
- }
- }
- // If SMS was received, next line should be the message content
- else if (incomingSMSReceived && smsReceptionBuffer.length() > 0)
- {
- incomingSMSContent = smsReceptionBuffer;
- Serial.print(F("SMS Content: "));
- Serial.print(incomingSMSContent);
- // Check if message contains the "gas" keyword
- if (incomingSMSContent.indexOf(SMS_KEYWORD) != -1 || incomingSMSContent.toLowerCase().indexOf("gas") != -1)
- {
- Serial.println(F("Keyword 'gas' detected in message"));
- Serial.println(F("Processing request..."));
- // Read current gas level
- readGasLevel();
- // Send response with gas level
- if (incomingSMSPhoneNumber.length() > 0)
- {
- sendGasLevelResponse(incomingSMSPhoneNumber);
- }
- else
- {
- Serial.println(F("Error: Invalid phone number, cannot send response"));
- }
- }
- else
- {
- Serial.println(F("Keyword 'gas' not found in message, ignoring SMS"));
- }
- // Reset SMS reception flags
- incomingSMSReceived = false;
- incomingSMSPhoneNumber = "";
- incomingSMSContent = "";
- }
- // Print raw buffer for debugging (excluding empty lines)
- if (smsReceptionBuffer.length() > 1)
- {
- Serial.print(F("SIM900A: "));
- Serial.print(smsReceptionBuffer);
- }
- smsReceptionBuffer = "";
- }
- }
- // Perform gas level reading at specified interval
- if (millis() - lastGasReadTime >= GAS_READING_INTERVAL)
- {
- lastGasReadTime = millis();
- readGasLevel();
- displayDebugInfo();
- }
- }
- /****** FUNCTION IMPLEMENTATIONS *****/
- // Initialize MQ5 sensor with calibration parameters
- void initMQ5Sensor(void)
- {
- // Set regression method for PPM calculation
- MQ5.setRegressionMethod(1); // 1 = Exponential equation
- // Configure sensor parameters for LPG detection
- // These values are based on MQ-5 datasheet calibration curve
- // For LPG: PPM = a * (RS/R0)^b
- MQ5.setA(1163.8); // Coefficient 'a' for LPG
- MQ5.setB(-3.207); // Coefficient 'b' for LPG
- // Set the RL value (load resistance on the sensor module)
- MQ5.setRL(MQ5_RL_VALUE);
- // Perform calibration - R0 value obtained from clean air calibration
- // For a properly calibrated sensor in clean air
- float R0 = MQ5.calibrate(MQ5_RATIO_CLEAN_AIR);
- Serial.print(F("MQ5 Calibration - R0: "));
- Serial.println(R0);
- // Initialize sensor
- MQ5.init();
- Serial.println(F("MQ5 Sensor initialized successfully"));
- }
- // Initialize SIM900A GSM module
- void initSIM900A(void)
- {
- // Initialize software serial for SIM900A
- SIM900A_Serial.begin(SIM900A_BAUD_RATE);
- // Give SIM900A time to boot
- delay(2000);
- // Test communication with AT command
- Serial.println(F("Testing SIM900A communication..."));
- sendATCommand("AT", AT_COMMAND_TIMEOUT);
- delay(500);
- // Disable echo for cleaner responses
- Serial.println(F("Disabling echo..."));
- sendATCommand("ATE0", AT_COMMAND_TIMEOUT);
- delay(500);
- // Set SMS text mode (required for text-based SMS)
- Serial.println(F("Setting SMS text mode..."));
- sendATCommand("AT+CMGF=1", AT_COMMAND_TIMEOUT);
- delay(500);
- // Set SMS character set
- Serial.println(F("Setting SMS character set..."));
- sendATCommand("AT+CSCS=\"GSM\"", AT_COMMAND_TIMEOUT);
- delay(500);
- // Enable SMS reception with unsolicited result codes
- Serial.println(F("Enabling SMS reception mode..."));
- enableSMSReception();
- delay(500);
- // Check signal quality
- Serial.println(F("Checking signal quality..."));
- sendATCommand("AT+CSQ", AT_COMMAND_TIMEOUT);
- delay(500);
- SIM900AInitialized = true;
- smsReceptionEnabled = true;
- Serial.println(F("SIM900A initialized successfully in REQUEST-BASED SMS mode"));
- }
- // Enable SMS reception on SIM900A
- void enableSMSReception(void)
- {
- // Set AT+CNMI to enable unsolicited SMS reception notifications
- // Format: AT+CNMI=<mode>,<mt>,<bm>,<ds>,<bfr>
- // <mode>=2: Enable unsolicited result codes
- // <mt>=2: SMS received on message type 2 (mobile terminated)
- // <bm>=0: No buffering
- // <ds>=0: No save in memory
- // <bfr>=0: No flushing
- sendATCommand("AT+CNMI=2,2,0,0", AT_COMMAND_TIMEOUT);
- }
- // Read gas level from MQ5 sensor
- void readGasLevel(void)
- {
- // Update sensor readings
- MQ5.update();
- // Read PPM value for LPG
- currentGasLevel = MQ5.readSensor();
- // Ensure reading is non-negative
- if (currentGasLevel < 0)
- {
- currentGasLevel = 0;
- }
- Serial.print(F("Gas Level Read: "));
- Serial.print(currentGasLevel);
- Serial.println(F(" PPM"));
- }
- // Send SMS response with gas level to the sender
- void sendGasLevelResponse(String phoneNumber)
- {
- if (!SIM900AInitialized)
- {
- Serial.println(F("Error: SIM900A not initialized, cannot send response"));
- return;
- }
- Serial.println(F("\n=== Sending Gas Level Response SMS ==="));
- // Prepare SMS recipient number with AT+CMGS command
- String smsCommand = "AT+CMGS=\"" + phoneNumber + "\"";
- // Send SMS command to put SIM900A in SMS input mode
- SIM900A_Serial.println(smsCommand);
- Serial.print(F(">> "));
- Serial.println(smsCommand);
- // Wait for '>' prompt indicating ready to input message
- unsigned long startTime = millis();
- bool promptReceived = false;
- String response = "";
- while (millis() - startTime < AT_COMMAND_TIMEOUT)
- {
- if (SIM900A_Serial.available())
- {
- char inChar = (char)SIM900A_Serial.read();
- response += inChar;
- Serial.write(inChar);
- // Check for '>' prompt
- if (inChar == '>')
- {
- promptReceived = true;
- break;
- }
- }
- }
- if (!promptReceived)
- {
- Serial.println(F("\nError: Did not receive SMS prompt from SIM900A"));
- handleATError("AT+CMGS");
- return;
- }
- // Prepare response message with gas level
- String message = "Gas Level: ";
- message += String(currentGasLevel, 2);
- message += " PPM";
- // Send message content
- SIM900A_Serial.print(message);
- Serial.print(F("\nMessage: "));
- Serial.println(message);
- // Send Ctrl+Z (ASCII 26) to confirm and send SMS
- SIM900A_Serial.write(26);
- Serial.println(F("Ctrl+Z sent"));
- // Wait for confirmation
- delay(SMS_DELAY);
- // Read any remaining response
- String finalResponse = "";
- unsigned long readStartTime = millis();
- while (millis() - readStartTime < 1000)
- {
- if (SIM900A_Serial.available())
- {
- char inChar = (char)SIM900A_Serial.read();
- finalResponse += inChar;
- }
- }
- // Check for success or failure indicators
- if (finalResponse.indexOf("+CMGS") != -1)
- {
- Serial.println(F("SMS sent successfully to "));
- Serial.println(phoneNumber);
- Serial.println(F("=== Response Complete ===\n"));
- }
- else if (finalResponse.indexOf("OK") != -1)
- {
- Serial.println(F("SMS response sent successfully\n"));
- }
- else
- {
- Serial.println(F("Warning: Could not confirm SMS delivery"));
- Serial.print(F("Response: "));
- Serial.println(finalResponse);
- }
- }
- // Send AT command to SIM900A
- void sendATCommand(String command, unsigned long timeout)
- {
- // Clear any existing data in buffer
- while (SIM900A_Serial.available())
- {
- SIM900A_Serial.read();
- }
- // Send command
- SIM900A_Serial.println(command);
- Serial.print(F(">> "));
- Serial.println(command);
- // Wait for response
- waitForResponse("OK", timeout);
- }
- // Wait for response from SIM900A with data return
- String waitForResponseWithData(String expectedResponse, unsigned long timeout)
- {
- unsigned long startTime = millis();
- String response = "";
- while (millis() - startTime < timeout)
- {
- if (SIM900A_Serial.available())
- {
- char inChar = (char)SIM900A_Serial.read();
- response += inChar;
- // Check if we received the expected response
- if (response.indexOf(expectedResponse) != -1)
- {
- Serial.print(F("<< "));
- Serial.println(response);
- return response;
- }
- }
- }
- // Timeout occurred
- Serial.println(F("No response from SIM900A (timeout)"));
- if (response.length() > 0)
- {
- Serial.print(F("Partial response: "));
- Serial.println(response);
- }
- return response;
- }
- // Wait for response from SIM900A
- void waitForResponse(String expectedResponse, unsigned long timeout)
- {
- unsigned long startTime = millis();
- String response = "";
- while (millis() - startTime < timeout)
- {
- if (SIM900A_Serial.available())
- {
- char inChar = (char)SIM900A_Serial.read();
- response += inChar;
- // Check if we received the expected response
- if (response.indexOf(expectedResponse) != -1)
- {
- Serial.print(F("<< "));
- Serial.println(response);
- return;
- }
- }
- }
- // Timeout occurred
- Serial.println(F("No response from SIM900A (timeout)"));
- if (response.length() > 0)
- {
- Serial.print(F("Partial response: "));
- Serial.println(response);
- }
- }
- // Handle AT command errors
- void handleATError(String command)
- {
- Serial.print(F("Error executing command: "));
- Serial.println(command);
- Serial.println(F("Attempting to recover by clearing buffers..."));
- // Clear SIM900A buffer
- while (SIM900A_Serial.available())
- {
- SIM900A_Serial.read();
- }
- // Send escape sequence to exit any active mode
- SIM900A_Serial.write(27); // ESC character
- delay(100);
- Serial.println(F("Recovery attempted"));
- }
- // Display debug information
- void displayDebugInfo(void)
- {
- Serial.print(F("System Time: "));
- Serial.print(millis() / 1000);
- Serial.print(F("s | Gas: "));
- Serial.print(currentGasLevel);
- Serial.print(F(" PPM | SIM900A: "));
- Serial.print(SIM900AInitialized ? F("Ready") : F("Not Ready"));
- Serial.print(F(" | SMS Reception: "));
- Serial.println(smsReceptionEnabled ? F("Enabled") : F("Disabled"));
- }
- /* END CODE */
Advertisement
Add Comment
Please, Sign In to add comment