Search This Blog

Sunday, 15 June 2025

tes call dan sms sim800L dan oled 128x64 sukses

 #include <HardwareSerial.h>

#include <Wire.h> // For I2C OLED communication

#include <Adafruit_GFX.h>

#include <Adafruit_SSD1306.h>


// Define RX and TX pins for serial communication between ESP32 and SIM800L

#define SIM800L_RX_PIN 16 // ESP32 RX pin connected to SIM800L TX

#define SIM800L_TX_PIN 17 // ESP32 TX pin connected to SIM800L RX


// Define pin for the LED indicator

#define LED_PIN 2 // Example GPIO2 pin for LED, can be changed as needed


// Define pin for the push button

#define BUTTON_PIN 4 // Example GPIO4 pin for button, can be changed as needed

                     // Connect one side of the button to this pin, and the other side to GND.

                     // Internal pull-up resistor will be enabled.


// OLED screen dimensions (128x64)

#define SCREEN_WIDTH 128 // OLED width in pixels

#define SCREEN_HEIGHT 64 // OLED height in pixels


// Declare SSD1306 object (OLED I2C address 0x3C or 0x3D)

// Change 0x3C if your OLED uses address 0x3D

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);


// Create HardwareSerial object for SIM800L

HardwareSerial sim800lSerial(1); // Use UART1 on ESP32 (UART0 is used for Serial debugging)


// --- Function Prototype Declarations ---

// Function to send AT command and read its response

String sendATCommand(String command);

// Function to get and display signal strength on OLED

void getAndDisplaySignalStrength();

// Function to send SMS

void sendSMS(String phoneNumber, String message);

// Function to control LED status based on "ping" result

void setLedStatus(bool pingSuccess);

// Function to make a phone call

void makeCall(String phoneNumber, int callDurationSeconds);


// Variables for button debouncing

long lastButtonPressTime = 0; // Last time the button was pressed

const long debounceDelay = 50; // Debounce time in milliseconds


void setup() {

  // Initialize serial communication for debugging (serial monitor)

  Serial.begin(115200);

  Serial.println("Starting ESP32, SIM800L, OLED, LED, and Button connection test...");


  // Initialize LED pin as output

  pinMode(LED_PIN, OUTPUT);

  digitalWrite(LED_PIN, LOW); // Ensure LED is off at initialization


  // Initialize button pin as input with internal pull-up resistor

  // The button should be wired to connect this pin to GND when pressed.

  pinMode(BUTTON_PIN, INPUT_PULLUP);

  Serial.println("Button pin initialized with INPUT_PULLUP.");


  // Initialize OLED

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Common I2C address for OLED

    Serial.println(F("SSD1306 allocation failed"));

    for (;;) ; // Don't proceed if failed, stop here

  }

  display.display(); // Show Adafruit boot-up logo

  delay(2000);

  display.clearDisplay(); // Clear display

  display.setTextSize(1); // Text size 1

  display.setTextColor(SSD1306_WHITE); // White text color


  // Display initialization message on OLED

  display.setCursor(0, 0);

  display.println("ESP32 + SIM800L");

  display.println("Initializing...");

  display.display();

  delay(2000);


  // Initialize serial communication for SIM800L

  // Baud rate 9600, 8 data bits, no parity, 1 stop bit

  sim800lSerial.begin(9600, SERIAL_8N1, SIM800L_RX_PIN, SIM800L_TX_PIN);

  delay(1000); // Give module time to stabilize


  // --- SIM800L Module and LED Indicator Test ---


  Serial.println("Sending AT command to check connection...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Checking GSM Conn...");

  display.display();

  // Send AT command and update LED status

  String atResponse = sendATCommand("AT");

  // Update LED status: ON if "OK", blink if not

  setLedStatus(atResponse.indexOf("OK") != -1);

  delay(1000);


  Serial.println("Sending AT+CSQ to check signal quality...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Checking Signal...");

  display.display();

  // Call function to get and display signal (this function also calls sendATCommand)

  getAndDisplaySignalStrength();

  delay(2000);


  Serial.println("Sending AT+CREG? to check network registration...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Registering Net...");

  display.display();

  // Send AT+CREG? command and update LED status

  String cregResponse = sendATCommand("AT+CREG?");

  setLedStatus(cregResponse.indexOf("OK") != -1); // Update LED based on CREG response

  delay(2000); // Give more time for network registration if needed


  Serial.println("Attempting to send SMS...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Sending SMS...");

  display.display();

  // Send SMS (this function also calls sendATCommand and updates LED)

  sendSMS("+628112508805", "Halo dari ESP32 dan SIM800L!");

  delay(3000); // Give time after SMS sending


  // --- Initial Phone Call Test (for verification during setup) ---

  Serial.println("Attempting to make a phone call (initial test)...");

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Initial Call Test...");

  display.display();

  // Make a call to the same number, duration 10 seconds

  makeCall("+628112508805", 10);

  delay(3000); // Give time after call


  // Final test message on OLED

  display.clearDisplay();

  display.setCursor(0, 0);

  display.println("Test Complete!");

  display.println("Press Button for Call.");

  display.display();

}


void loop() {

  // In the loop, we can update signal strength and "ping" periodically

  // to keep the LED indicator relevant.

  static unsigned long lastPingTime = 0;

  static unsigned long pingInterval = 10000; // Ping every 10 seconds


  if (millis() - lastPingTime >= pingInterval) {

    lastPingTime = millis();

    Serial.println("Performing ping (AT command) for LED indicator...");

    String atResponseLoop = sendATCommand("AT");

    setLedStatus(atResponseLoop.indexOf("OK") != -1); // Update LED status

    getAndDisplaySignalStrength(); // Update signal strength on OLED and LED

  }


  // --- Button Check Logic ---

  // Read the state of the button. Since INPUT_PULLUP is used, it's LOW when pressed.

  int buttonState = digitalRead(BUTTON_PIN);


  // Check if the button is pressed (LOW) and if enough time has passed since the last press

  if (buttonState == LOW && (millis() - lastButtonPressTime) > debounceDelay) {

    // Check if the button was just pressed (not held down from previous loop)

    if (lastButtonPressTime != 0) { // Only trigger if it's a new press

      Serial.println("Button Pressed! Initiating call...");

      display.clearDisplay();

      display.setCursor(0,0);

      display.println("Button Pressed!");

      display.println("Calling...");

      display.display();

      delay(500); // Brief delay for display update


      // Trigger the makeCall function

      makeCall("+628112508805", 15); // Call duration of 15 seconds when button is pressed

      

      display.clearDisplay();

      display.setCursor(0,0);

      display.println("Call Initiated.");

      display.println("Ready for next press.");

      display.display();

    }

    lastButtonPressTime = millis(); // Record the time of this press

  } else if (buttonState == HIGH) {

      lastButtonPressTime = 0; // Reset debounce timer if button is released

  }

}


// Function to send AT command to SIM800L and read its response

String sendATCommand(String command) {

  Serial.print("Sending: ");

  Serial.println(command);

  sim800lSerial.println(command); // Send command to SIM800L


  String response = "";

  long timeout = millis();

  // Wait for response for 2 seconds

  while (millis() - timeout < 2000) {

    if (sim800lSerial.available()) {

      char c = sim800lSerial.read(); // Read character from SIM800L

      Serial.write(c); // Write character to Serial Monitor for debugging

      response += c; // Add character to response string

    }

  }

  Serial.println(); // New line for clarity in Serial Monitor

  return response; // Return the complete response string

}


// Function to control LED status based on "ping" result

// If pingSuccess TRUE (module responds with "OK"), LED stays on.

// If pingSuccess FALSE (module does not respond with "OK" or timeout), LED blinks fast.

void setLedStatus(bool pingSuccess) {

  if (pingSuccess) {

    digitalWrite(LED_PIN, HIGH); // LED ON (stable light)

    Serial.println("LED ON: Module responded with OK.");

  } else {

    Serial.println("LED BLINK: Module did not respond OK (timeout or error).");

    for (int i = 0; i < 5; i++) { // Blink fast 5 times

      digitalWrite(LED_PIN, HIGH); // LED on

      delay(100); // Short delay

      digitalWrite(LED_PIN, LOW); // LED off

      delay(100); // Short delay

    }

    digitalWrite(LED_PIN, LOW); // Ensure LED is off after blinking

  }

}


// Function to get and display signal strength (RSSI) on OLED

void getAndDisplaySignalStrength() {

  String response = sendATCommand("AT+CSQ"); // Send AT+CSQ and get response

  // Update LED status based on AT+CSQ response as well

  setLedStatus(response.indexOf("OK") != -1);


  int rssi = -1; // Default value if not found

  int commaIndex = response.indexOf(','); // Find the first comma

  // Check if response contains "+CSQ:" and a comma

  if (response.indexOf("+CSQ:") != -1 && commaIndex != -1) {

    // Extract RSSI string

    String rssiStr = response.substring(response.indexOf(":") + 1, commaIndex);

    rssi = rssiStr.toInt(); // Convert to integer

  }


  // Display signal information on OLED

  display.clearDisplay();

  display.setCursor(0, 0);

  display.setTextSize(1);

  display.println("Signal Strength:");

  display.setTextSize(2); // Larger text size for RSSI value


  if (rssi >= 0 && rssi <= 31) { // Check if RSSI is valid

    display.print("RSSI: ");

    display.print(rssi);

    display.print(" (");

    display.print(-113 + rssi * 2); // Rough conversion to dBm (for reference)

    display.println(" dBm)");


    display.setTextSize(1);

    display.print("Status: ");

    if (rssi >= 20) {

      display.println("Very Good");

    } else if (rssi >= 10) {

      display.println("Good");

    } else if (rssi >= 2) {

      display.println("Fair");

    } else {

      display.println("Weak/None");

    }

  } else {

    display.println("Unknown"); // If RSSI is invalid

  }

  display.display(); // Display on OLED screen

}


// Function to send SMS to a specific phone number with a specific message

void sendSMS(String phoneNumber, String message) {

  Serial.println("Setting SMS mode to Text Mode...");

  // Set module to SMS Text Mode and update LED status

  String modeResponse = sendATCommand("AT+CMGF=1");

  setLedStatus(modeResponse.indexOf("OK") != -1);

  delay(1000); // Give module time to respond


  Serial.print("Sending SMS to: ");

  Serial.println(phoneNumber);

  sim800lSerial.print("AT+CMGS=\""); // Command to send SMS

  sim800lSerial.print(phoneNumber); // Destination number

  sim800lSerial.println("\""); // End command with quote and new line

  delay(100); // Give a little time


  sim800lSerial.print(message); // Send message content

  sim800lSerial.write(0x1A); // Ctrl+Z character to end message and trigger sending

  Serial.println("Message sent. Waiting for confirmation...");


  String smsConfirmation = "";

  long timeout = millis();

  // Wait for SMS sending confirmation response for 10 seconds

  while (millis() - timeout < 10000) {

    if (sim800lSerial.available()) {

      char c = sim800lSerial.read();

      Serial.write(c);

      smsConfirmation += c;

    }

  }

  Serial.println();

  // Update LED status: ON if SMS confirmed OK or +CMGS:, BLINK if error/timeout

  setLedStatus(smsConfirmation.indexOf("OK") != -1 || smsConfirmation.indexOf("+CMGS:") != -1);

}


// Function to make a phone call to the specified number

// The call will automatically hang up after callDurationSeconds

void makeCall(String phoneNumber, int callDurationSeconds) {

  Serial.print("Making call to: ");

  Serial.println(phoneNumber);

  display.clearDisplay();

  display.setCursor(0,0);

  display.println("Calling:");

  display.println(phoneNumber);

  display.display();


  String callResponse = sendATCommand("ATD" + phoneNumber + ";"); // Dial command, ';' is important

  // Update LED status: ON if module accepts dial command ("OK"), BLINK if not

  setLedStatus(callResponse.indexOf("OK") != -1);


  if (callResponse.indexOf("OK") != -1) {

    Serial.println("Call started. Waiting for connection or timeout...");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Call In Progress...");

    display.println(phoneNumber);

    display.display();


    // Wait for the specified call duration

    delay(callDurationSeconds * 1000);


    Serial.println("Ending call...");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Ending Call...");

    display.display();

    String hangupResponse = sendATCommand("ATH"); // Command to hang up the call

    // Update LED based on ATH response

    setLedStatus(hangupResponse.indexOf("OK") != -1);

    delay(1000); // Give module time to hang up


    Serial.println("Call ended.");

  } else {

    Serial.println("Failed to start call or invalid number.");

    display.clearDisplay();

    display.setCursor(0,0);

    display.println("Call Failed!");

    display.println("Check Signal/Number.");

    display.display();

    // LED is already set to BLINK by sendATCommand if failed

  }

}


No comments:

Post a Comment

CARGER AKI CONTROLER INA226-LIBARY WE ROTARI SW+OLED 0.96 SUKSES TAMPILAN LEBIH BAIK

 #include <Wire.h>  #include <Adafruit_GFX.h>    // Library grafis Adafruit #include <Adafruit_SSD1306.h> // Library untuk...