pleasedontcode

# Gas Monitor rev_02

Jan 25th, 2026
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 15.23 KB | None | 0 0
  1. /********* Pleasedontcode.com **********
  2.  
  3.     Pleasedontcode thanks you for automatic code generation! Enjoy your code!
  4.  
  5.     - Terms and Conditions:
  6.     You have a non-exclusive, revocable, worldwide, royalty-free license
  7.     for personal and commercial use. Attribution is optional; modifications
  8.     are allowed, but you're responsible for code maintenance. We're not
  9.     liable for any loss or damage. For full terms,
  10.     please visit pleasedontcode.com/termsandconditions.
  11.  
  12.     - Project: # Gas Monitor
  13.     - Source Code NOT compiled for: Arduino Uno
  14.     - Source Code created on: 2026-01-25 18:35:10
  15.  
  16. ********* Pleasedontcode.com **********/
  17.  
  18. /****** SYSTEM REQUIREMENTS *****/
  19. /****** SYSTEM REQUIREMENT 1 *****/
  20.     /* when gas sms is sent to sim 900a it should send */
  21.     /* the gas level to phone */
  22. /****** END SYSTEM REQUIREMENTS *****/
  23.  
  24.  
  25. /* START CODE */
  26.  
  27. /****** SYSTEM REQUIREMENTS *****/
  28. /* System Requirement 1: "when gas sms is sent to sim 900a it should send the gas level to phone" */
  29.  
  30. /****** DEFINITION OF LIBRARIES *****/
  31. #include <MQUnifiedsensor.h>    //https://github.com/miguel5612/MQSensorsLib
  32. #include <SoftwareSerial.h>     //Software Serial for SIM900A communication
  33.  
  34. /****** FUNCTION PROTOTYPES *****/
  35. void setup(void);
  36. void loop(void);
  37. void initMQ5Sensor(void);
  38. void initSIM900A(void);
  39. void readGasLevel(void);
  40. void checkIncomingSMS(void);
  41. void enableSMSReception(void);
  42. void processSMSMessage(String messageIndex);
  43. void extractSenderPhoneNumber(String messageIndex);
  44. void sendGasLevelResponse(String phoneNumber);
  45. void sendATCommand(String command, unsigned long timeout);
  46. String waitForResponseWithData(String expectedResponse, unsigned long timeout);
  47. void waitForResponse(String expectedResponse, unsigned long timeout);
  48. void displayDebugInfo(void);
  49. void handleATError(String command);
  50.  
  51. /***** DEFINITION OF DIGITAL INPUT PINS *****/
  52. const uint8_t MQ5_MQ5_DOUT_PIN_D2               = 2;
  53.  
  54. /***** DEFINITION OF ANALOG INPUT PINS *****/
  55. const uint8_t MQ5_MQ5_AOUT_PIN_A0               = A0;
  56.  
  57. /***** DEFINITION OF SIM900A COMMUNICATION PINS *****/
  58. // SoftwareSerial(RX, TX)
  59. const uint8_t SIM900A_RX_PIN                    = 10;   // RX pin for SIM900A
  60. const uint8_t SIM900A_TX_PIN                    = 11;   // TX pin for SIM900A
  61.  
  62. /***** DEFINITION OF SENSOR CALIBRATION PARAMETERS *****/
  63. // MQ-5 sensor configuration for LPG detection
  64. const float MQ5_RATIO_CLEAN_AIR                 = 6.5;  // RS/R0 ratio in clean air
  65. const float MQ5_RL_VALUE                        = 10.0; // Load resistance in KOhms
  66. const float MQ5_VOLTAGE_RESOLUTION              = 5.0;  // Arduino Uno voltage reference
  67. const int MQ5_ADC_BIT_RESOLUTION                = 10;   // Arduino Uno ADC resolution
  68.  
  69. /***** DEFINITION OF GSM MODULE CONFIGURATION *****/
  70. const unsigned long SIM900A_BAUD_RATE           = 9600;     // SIM900A communication speed
  71. const unsigned long AT_COMMAND_TIMEOUT          = 1000;     // Timeout for AT commands (ms)
  72. const unsigned long SMS_DELAY                   = 5000;     // Delay between SMS messages (ms)
  73. const unsigned long SMS_RECEPTION_TIMEOUT       = 2000;     // Timeout for SMS reception check (ms)
  74.  
  75. /***** DEFINITION OF MEASUREMENT PARAMETERS *****/
  76. const unsigned long GAS_READING_INTERVAL        = 10000;    // Interval for gas readings (ms)
  77.  
  78. /***** SMS RECEPTION CONSTANTS *****/
  79. const String SMS_KEYWORD                        = "gas";    // Keyword to detect in incoming SMS
  80. const String SMS_INDICATOR                      = "+CMT:";  // SMS indicator string
  81.  
  82. /****** DEFINITION OF LIBRARIES CLASS INSTANCES *****/
  83. // Create SoftwareSerial instance for SIM900A communication
  84. SoftwareSerial SIM900A_Serial(SIM900A_RX_PIN, SIM900A_TX_PIN);
  85.  
  86. // Create MQ5 sensor instance
  87. // MQUnifiedsensor(Board, Voltage_Resolution, ADC_Bit_Resolution, Pin, Type)
  88. MQUnifiedsensor MQ5("Arduino UNO", MQ5_VOLTAGE_RESOLUTION, MQ5_ADC_BIT_RESOLUTION, MQ5_MQ5_AOUT_PIN_A0, "MQ-5");
  89.  
  90. /***** GLOBAL VARIABLES *****/
  91. float currentGasLevel = 0.0;                        // Current gas level reading in PPM
  92. unsigned long lastGasReadTime = 0;                  // Timestamp of last gas reading
  93. bool SIM900AInitialized = false;                    // Flag for SIM900A initialization status
  94. String serialBuffer = "";                           // Buffer for serial communication
  95. String smsReceptionBuffer = "";                     // Buffer for SMS reception data
  96. bool smsReceptionEnabled = false;                   // Flag for SMS reception mode
  97. String incomingSMSPhoneNumber = "";                 // Phone number of incoming SMS sender
  98. bool incomingSMSReceived = false;                   // Flag indicating incoming SMS detected
  99. String incomingSMSContent = "";                     // Content of incoming SMS message
  100.  
  101. /****** SETUP FUNCTION *****/
  102. void setup(void)
  103. {
  104.     // Initialize Serial for debugging
  105.     Serial.begin(9600);
  106.    
  107.     // Wait for Serial to initialize
  108.     delay(100);
  109.    
  110.     Serial.println(F("\n\n=== Gas SMS Alert System Started ==="));
  111.     Serial.println(F("REQUEST-BASED SMS MODE: System will respond to incoming 'gas' SMS requests"));
  112.     Serial.println(F("Initializing MQ5 Sensor..."));
  113.    
  114.     // Configure GPIO pins
  115.     pinMode(MQ5_MQ5_DOUT_PIN_D2, INPUT_PULLUP);
  116.     pinMode(MQ5_MQ5_AOUT_PIN_A0, INPUT);
  117.    
  118.     // Initialize MQ5 sensor
  119.     initMQ5Sensor();
  120.    
  121.     // Initialize SIM900A GSM module
  122.     Serial.println(F("Initializing SIM900A GSM Module..."));
  123.     initSIM900A();
  124.    
  125.     Serial.println(F("=== System Initialization Complete ===\n"));
  126.    
  127.     // Initialize timestamps
  128.     lastGasReadTime = millis();
  129. }
  130.  
  131. /****** MAIN LOOP *****/
  132. void loop(void)
  133. {
  134.     // Read incoming data from SIM900A module
  135.     while (SIM900A_Serial.available())
  136.     {
  137.         char inChar = (char)SIM900A_Serial.read();
  138.         smsReceptionBuffer += inChar;
  139.        
  140.         // Process complete lines
  141.         if (inChar == '\n')
  142.         {
  143.             // Check if this line contains an SMS indicator
  144.             if (smsReceptionBuffer.indexOf(SMS_INDICATOR) != -1)
  145.             {
  146.                 Serial.println(F("\n=== INCOMING SMS DETECTED ==="));
  147.                 Serial.print(F("SMS Header: "));
  148.                 Serial.print(smsReceptionBuffer);
  149.                
  150.                 // Extract phone number and mark SMS received
  151.                 incomingSMSReceived = true;
  152.                
  153.                 // Parse the phone number from the +CMT line
  154.                 // Format: +CMT: "+1234567890",,"2024/01/15,10:30:45+00"
  155.                 int startQuote = smsReceptionBuffer.indexOf('"');
  156.                 int endQuote = smsReceptionBuffer.indexOf('"', startQuote + 1);
  157.                
  158.                 if (startQuote != -1 && endQuote != -1 && endQuote > startQuote)
  159.                 {
  160.                     incomingSMSPhoneNumber = smsReceptionBuffer.substring(startQuote + 1, endQuote);
  161.                     Serial.print(F("Sender: "));
  162.                     Serial.println(incomingSMSPhoneNumber);
  163.                 }
  164.             }
  165.             // If SMS was received, next line should be the message content
  166.             else if (incomingSMSReceived && smsReceptionBuffer.length() > 0)
  167.             {
  168.                 incomingSMSContent = smsReceptionBuffer;
  169.                 Serial.print(F("SMS Content: "));
  170.                 Serial.print(incomingSMSContent);
  171.                
  172.                 // Check if message contains the "gas" keyword
  173.                 if (incomingSMSContent.indexOf(SMS_KEYWORD) != -1 || incomingSMSContent.toLowerCase().indexOf("gas") != -1)
  174.                 {
  175.                     Serial.println(F("Keyword 'gas' detected in message"));
  176.                     Serial.println(F("Processing request..."));
  177.                    
  178.                     // Read current gas level
  179.                     readGasLevel();
  180.                    
  181.                     // Send response with gas level
  182.                     if (incomingSMSPhoneNumber.length() > 0)
  183.                     {
  184.                         sendGasLevelResponse(incomingSMSPhoneNumber);
  185.                     }
  186.                     else
  187.                     {
  188.                         Serial.println(F("Error: Invalid phone number, cannot send response"));
  189.                     }
  190.                 }
  191.                 else
  192.                 {
  193.                     Serial.println(F("Keyword 'gas' not found in message, ignoring SMS"));
  194.                 }
  195.                
  196.                 // Reset SMS reception flags
  197.                 incomingSMSReceived = false;
  198.                 incomingSMSPhoneNumber = "";
  199.                 incomingSMSContent = "";
  200.             }
  201.            
  202.             // Print raw buffer for debugging (excluding empty lines)
  203.             if (smsReceptionBuffer.length() > 1)
  204.             {
  205.                 Serial.print(F("SIM900A: "));
  206.                 Serial.print(smsReceptionBuffer);
  207.             }
  208.            
  209.             smsReceptionBuffer = "";
  210.         }
  211.     }
  212.    
  213.     // Perform gas level reading at specified interval
  214.     if (millis() - lastGasReadTime >= GAS_READING_INTERVAL)
  215.     {
  216.         lastGasReadTime = millis();
  217.         readGasLevel();
  218.         displayDebugInfo();
  219.     }
  220. }
  221.  
  222. /****** FUNCTION IMPLEMENTATIONS *****/
  223.  
  224. // Initialize MQ5 sensor with calibration parameters
  225. void initMQ5Sensor(void)
  226. {
  227.     // Set regression method for PPM calculation
  228.     MQ5.setRegressionMethod(1);  // 1 = Exponential equation
  229.    
  230.     // Configure sensor parameters for LPG detection
  231.     // These values are based on MQ-5 datasheet calibration curve
  232.     // For LPG: PPM = a * (RS/R0)^b
  233.     MQ5.setA(1163.8);           // Coefficient 'a' for LPG
  234.     MQ5.setB(-3.207);           // Coefficient 'b' for LPG
  235.    
  236.     // Set the RL value (load resistance on the sensor module)
  237.     MQ5.setRL(MQ5_RL_VALUE);
  238.    
  239.     // Perform calibration - R0 value obtained from clean air calibration
  240.     // For a properly calibrated sensor in clean air
  241.     float R0 = MQ5.calibrate(MQ5_RATIO_CLEAN_AIR);
  242.    
  243.     Serial.print(F("MQ5 Calibration - R0: "));
  244.     Serial.println(R0);
  245.    
  246.     // Initialize sensor
  247.     MQ5.init();
  248.    
  249.     Serial.println(F("MQ5 Sensor initialized successfully"));
  250. }
  251.  
  252. // Initialize SIM900A GSM module
  253. void initSIM900A(void)
  254. {
  255.     // Initialize software serial for SIM900A
  256.     SIM900A_Serial.begin(SIM900A_BAUD_RATE);
  257.    
  258.     // Give SIM900A time to boot
  259.     delay(2000);
  260.    
  261.     // Test communication with AT command
  262.     Serial.println(F("Testing SIM900A communication..."));
  263.     sendATCommand("AT", AT_COMMAND_TIMEOUT);
  264.     delay(500);
  265.    
  266.     // Disable echo for cleaner responses
  267.     Serial.println(F("Disabling echo..."));
  268.     sendATCommand("ATE0", AT_COMMAND_TIMEOUT);
  269.     delay(500);
  270.    
  271.     // Set SMS text mode (required for text-based SMS)
  272.     Serial.println(F("Setting SMS text mode..."));
  273.     sendATCommand("AT+CMGF=1", AT_COMMAND_TIMEOUT);
  274.     delay(500);
  275.    
  276.     // Set SMS character set
  277.     Serial.println(F("Setting SMS character set..."));
  278.     sendATCommand("AT+CSCS=\"GSM\"", AT_COMMAND_TIMEOUT);
  279.     delay(500);
  280.    
  281.     // Enable SMS reception with unsolicited result codes
  282.     Serial.println(F("Enabling SMS reception mode..."));
  283.     enableSMSReception();
  284.     delay(500);
  285.    
  286.     // Check signal quality
  287.     Serial.println(F("Checking signal quality..."));
  288.     sendATCommand("AT+CSQ", AT_COMMAND_TIMEOUT);
  289.     delay(500);
  290.    
  291.     SIM900AInitialized = true;
  292.     smsReceptionEnabled = true;
  293.     Serial.println(F("SIM900A initialized successfully in REQUEST-BASED SMS mode"));
  294. }
  295.  
  296. // Enable SMS reception on SIM900A
  297. void enableSMSReception(void)
  298. {
  299.     // Set AT+CNMI to enable unsolicited SMS reception notifications
  300.     // Format: AT+CNMI=<mode>,<mt>,<bm>,<ds>,<bfr>
  301.     // <mode>=2: Enable unsolicited result codes
  302.     // <mt>=2: SMS received on message type 2 (mobile terminated)
  303.     // <bm>=0: No buffering
  304.     // <ds>=0: No save in memory
  305.     // <bfr>=0: No flushing
  306.     sendATCommand("AT+CNMI=2,2,0,0", AT_COMMAND_TIMEOUT);
  307. }
  308.  
  309. // Read gas level from MQ5 sensor
  310. void readGasLevel(void)
  311. {
  312.     // Update sensor readings
  313.     MQ5.update();
  314.    
  315.     // Read PPM value for LPG
  316.     currentGasLevel = MQ5.readSensor();
  317.    
  318.     // Ensure reading is non-negative
  319.     if (currentGasLevel < 0)
  320.     {
  321.         currentGasLevel = 0;
  322.     }
  323.    
  324.     Serial.print(F("Gas Level Read: "));
  325.     Serial.print(currentGasLevel);
  326.     Serial.println(F(" PPM"));
  327. }
  328.  
  329. // Send SMS response with gas level to the sender
  330. void sendGasLevelResponse(String phoneNumber)
  331. {
  332.     if (!SIM900AInitialized)
  333.     {
  334.         Serial.println(F("Error: SIM900A not initialized, cannot send response"));
  335.         return;
  336.     }
  337.    
  338.     Serial.println(F("\n=== Sending Gas Level Response SMS ==="));
  339.    
  340.     // Prepare SMS recipient number with AT+CMGS command
  341.     String smsCommand = "AT+CMGS=\"" + phoneNumber + "\"";
  342.    
  343.     // Send SMS command to put SIM900A in SMS input mode
  344.     SIM900A_Serial.println(smsCommand);
  345.     Serial.print(F(">> "));
  346.     Serial.println(smsCommand);
  347.    
  348.     // Wait for '>' prompt indicating ready to input message
  349.     unsigned long startTime = millis();
  350.     bool promptReceived = false;
  351.     String response = "";
  352.    
  353.     while (millis() - startTime < AT_COMMAND_TIMEOUT)
  354.     {
  355.         if (SIM900A_Serial.available())
  356.         {
  357.             char inChar = (char)SIM900A_Serial.read();
  358.             response += inChar;
  359.             Serial.write(inChar);
  360.            
  361.             // Check for '>' prompt
  362.             if (inChar == '>')
  363.             {
  364.                 promptReceived = true;
  365.                 break;
  366.             }
  367.         }
  368.     }
  369.    
  370.     if (!promptReceived)
  371.     {
  372.         Serial.println(F("\nError: Did not receive SMS prompt from SIM900A"));
  373.         handleATError("AT+CMGS");
  374.         return;
  375.     }
  376.    
  377.     // Prepare response message with gas level
  378.     String message = "Gas Level: ";
  379.     message += String(currentGasLevel, 2);
  380.     message += " PPM";
  381.    
  382.     // Send message content
  383.     SIM900A_Serial.print(message);
  384.     Serial.print(F("\nMessage: "));
  385.     Serial.println(message);
  386.    
  387.     // Send Ctrl+Z (ASCII 26) to confirm and send SMS
  388.     SIM900A_Serial.write(26);
  389.     Serial.println(F("Ctrl+Z sent"));
  390.    
  391.     // Wait for confirmation
  392.     delay(SMS_DELAY);
  393.    
  394.     // Read any remaining response
  395.     String finalResponse = "";
  396.     unsigned long readStartTime = millis();
  397.     while (millis() - readStartTime < 1000)
  398.     {
  399.         if (SIM900A_Serial.available())
  400.         {
  401.             char inChar = (char)SIM900A_Serial.read();
  402.             finalResponse += inChar;
  403.         }
  404.     }
  405.    
  406.     // Check for success or failure indicators
  407.     if (finalResponse.indexOf("+CMGS") != -1)
  408.     {
  409.         Serial.println(F("SMS sent successfully to "));
  410.         Serial.println(phoneNumber);
  411.         Serial.println(F("=== Response Complete ===\n"));
  412.     }
  413.     else if (finalResponse.indexOf("OK") != -1)
  414.     {
  415.         Serial.println(F("SMS response sent successfully\n"));
  416.     }
  417.     else
  418.     {
  419.         Serial.println(F("Warning: Could not confirm SMS delivery"));
  420.         Serial.print(F("Response: "));
  421.         Serial.println(finalResponse);
  422.     }
  423. }
  424.  
  425. // Send AT command to SIM900A
  426. void sendATCommand(String command, unsigned long timeout)
  427. {
  428.     // Clear any existing data in buffer
  429.     while (SIM900A_Serial.available())
  430.     {
  431.         SIM900A_Serial.read();
  432.     }
  433.    
  434.     // Send command
  435.     SIM900A_Serial.println(command);
  436.    
  437.     Serial.print(F(">> "));
  438.     Serial.println(command);
  439.    
  440.     // Wait for response
  441.     waitForResponse("OK", timeout);
  442. }
  443.  
  444. // Wait for response from SIM900A with data return
  445. String waitForResponseWithData(String expectedResponse, unsigned long timeout)
  446. {
  447.     unsigned long startTime = millis();
  448.     String response = "";
  449.    
  450.     while (millis() - startTime < timeout)
  451.     {
  452.         if (SIM900A_Serial.available())
  453.         {
  454.             char inChar = (char)SIM900A_Serial.read();
  455.             response += inChar;
  456.            
  457.             // Check if we received the expected response
  458.             if (response.indexOf(expectedResponse) != -1)
  459.             {
  460.                 Serial.print(F("<< "));
  461.                 Serial.println(response);
  462.                 return response;
  463.             }
  464.         }
  465.     }
  466.    
  467.     // Timeout occurred
  468.     Serial.println(F("No response from SIM900A (timeout)"));
  469.     if (response.length() > 0)
  470.     {
  471.         Serial.print(F("Partial response: "));
  472.         Serial.println(response);
  473.     }
  474.    
  475.     return response;
  476. }
  477.  
  478. // Wait for response from SIM900A
  479. void waitForResponse(String expectedResponse, unsigned long timeout)
  480. {
  481.     unsigned long startTime = millis();
  482.     String response = "";
  483.    
  484.     while (millis() - startTime < timeout)
  485.     {
  486.         if (SIM900A_Serial.available())
  487.         {
  488.             char inChar = (char)SIM900A_Serial.read();
  489.             response += inChar;
  490.            
  491.             // Check if we received the expected response
  492.             if (response.indexOf(expectedResponse) != -1)
  493.             {
  494.                 Serial.print(F("<< "));
  495.                 Serial.println(response);
  496.                 return;
  497.             }
  498.         }
  499.     }
  500.    
  501.     // Timeout occurred
  502.     Serial.println(F("No response from SIM900A (timeout)"));
  503.     if (response.length() > 0)
  504.     {
  505.         Serial.print(F("Partial response: "));
  506.         Serial.println(response);
  507.     }
  508. }
  509.  
  510. // Handle AT command errors
  511. void handleATError(String command)
  512. {
  513.     Serial.print(F("Error executing command: "));
  514.     Serial.println(command);
  515.     Serial.println(F("Attempting to recover by clearing buffers..."));
  516.    
  517.     // Clear SIM900A buffer
  518.     while (SIM900A_Serial.available())
  519.     {
  520.         SIM900A_Serial.read();
  521.     }
  522.    
  523.     // Send escape sequence to exit any active mode
  524.     SIM900A_Serial.write(27);  // ESC character
  525.     delay(100);
  526.    
  527.     Serial.println(F("Recovery attempted"));
  528. }
  529.  
  530. // Display debug information
  531. void displayDebugInfo(void)
  532. {
  533.     Serial.print(F("System Time: "));
  534.     Serial.print(millis() / 1000);
  535.     Serial.print(F("s | Gas: "));
  536.     Serial.print(currentGasLevel);
  537.     Serial.print(F(" PPM | SIM900A: "));
  538.     Serial.print(SIM900AInitialized ? F("Ready") : F("Not Ready"));
  539.     Serial.print(F(" | SMS Reception: "));
  540.     Serial.println(smsReceptionEnabled ? F("Enabled") : F("Disabled"));
  541. }
  542.  
  543. /* END CODE */
  544.  
Advertisement
Add Comment
Please, Sign In to add comment