commit 39821eeed5dbf26d9e469d9833f6ca538bdd74d7 Author: kicap Date: Fri Feb 21 12:26:42 2025 +0800 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/include/README b/include/README new file mode 100644 index 0000000..49819c0 --- /dev/null +++ b/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..9379397 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..159230b --- /dev/null +++ b/platformio.ini @@ -0,0 +1,20 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp12e] +platform = espressif8266 +board = esp12e +framework = arduino +lib_deps = + ostaquet/SIM800L HTTP connector@^1.14.0 + adafruit/Adafruit SSD1306@^2.5.13 + adafruit/Adafruit GFX Library@^1.11.11 + +monitor_speed = 115200 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..fc289fd --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,319 @@ +#include + +int led = LED_BUILTIN; // ESP8266 built-in LED pin +int sensor = 12; // The pin that the sensor is attached to +int state = LOW; // By default, no motion detected +int val = 0; // Variable to store the sensor status (value) +unsigned long motionStart = 0; // Time when motion is first detected +bool motionDetected = false; + +// this is for sim800l +#include +#include "SIM800L.h" + +#define SIM800_RX_PIN 12 +#define SIM800_TX_PIN 13 +#define SIM800_RST_PIN 14 +// end of sim800l + +// this is for oled +#include +#include +#include + +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define SCREEN_ADDRESS 0x3C +// Declaration for an I2C OLED display +Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); +// end of oled + +const char APN[] = "internet"; +const char URL[] = "http://cekont.mywork-kk.online/data1"; + +// Replace these with your network credentials +// const char* ssid = "hu"; +// const char* password = "12345679"; + +SIM800L *sim800l; + +// void IRAM_ATTR stateChange() +// { // Interrupt function +// motionDetected = 1; +// } + +void displayText(const char *text) +{ + display.clearDisplay(); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0, 30); + display.println(text); + display.display(); +} +void displayText2(const String &text, const String &text2) +{ + display.clearDisplay(); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0, 20); + display.println(text); + display.setCursor(0, 40); + display.println(text2); + display.display(); +} + +void setupModule() +{ + // Wait until the module is ready to accept AT commands + while (!sim800l->isReady()) + { + Serial.println(F("Problem to initialize AT command, retry in 1 sec")); + displayText2("Problem to initialize AT command,", " retry in 1 sec"); + delay(1000); + } + + // Active echo mode (for some module, it is required) + sim800l->enableEchoMode(); + + Serial.println("Module ready"); + displayText("Module ready"); + delay(1000); + + // Print version + Serial.print("Module "); + Serial.println(sim800l->getVersion()); + Serial.print("Firmware "); + Serial.println(sim800l->getFirmware()); + displayText2("Module : " + String(sim800l->getVersion()), "Firmware : " + String(sim800l->getFirmware())); + delay(1000); + + // Print SIM card status + Serial.print(F("SIM status ")); + Serial.println(sim800l->getSimStatus()); + displayText2("SIM status : ", String(sim800l->getSimStatus())); + delay(1000); + + // Print SIM card number + Serial.print("SIM card number "); + Serial.println(sim800l->getSimCardNumber()); + displayText2("SIM card number : ", String(sim800l->getSimCardNumber())); + delay(1000); + + // Wait for the GSM signal + uint8_t signal = sim800l->getSignal(); + while (signal <= 0) + { + delay(1000); + signal = sim800l->getSignal(); + } + + if (signal > 5) + { + Serial.print(F("Signal OK (strenght: ")); + displayText2(("Signal OK "), ("(strenght: " + String(signal) + ")").c_str()); + delay(1000); + } + else + { + Serial.print(F("Signal low (strenght: ")); + displayText2(("Signal low "), (" (strenght: " + String(signal) + ")").c_str()); + delay(1000); + } + Serial.print(signal); + Serial.println(F(")")); + delay(1000); + + // Wait for operator network registration (national or roaming network) + NetworkRegistration network = sim800l->getRegistrationStatus(); + while (network != REGISTERED_HOME && network != REGISTERED_ROAMING) + { + delay(1000); + network = sim800l->getRegistrationStatus(); + } + Serial.println(F("Network registration OK")); + displayText("Network registration OK"); + delay(1000); + + Serial.println("End of test protocol"); + displayText("End of test protocol"); + delay(1000); + + // Setup APN for GPRS configuration + bool success = sim800l->setupGPRS(APN); + while (!success) + { + success = sim800l->setupGPRS(APN); + delay(5000); + } + Serial.println(F("GPRS config OK")); + displayText("GPRS config OK"); + delay(1000); +} + +void getHttpData(const String ¶ms) +{ + Serial.println(F("Start HTTP GET...")); + displayText("Start HTTP GET..."); + delay(1000); + + String url = URL + params; + + // Do HTTP GET communication with 10s for the timeout (read) + uint16_t rc = sim800l->doGet(url.c_str(), 20000); + if (rc == 200) + { + // Success, output the data received on the serial + Serial.print(F("HTTP GET successful (")); + Serial.print(sim800l->getDataSizeReceived()); + Serial.println(F(" bytes)")); + Serial.print(F("Received : ")); + Serial.println(sim800l->getDataReceived()); + displayText2("HTTP GET successful ", String(sim800l->getDataSizeReceived()) + " bytes)"); + delay(1000); + displayText2("Received : ", String(sim800l->getDataReceived())); + delay(3000); + } + else + { + // Failed... + Serial.print(F("HTTP GET error ")); + Serial.println(rc); + displayText2("HTTP GET error ", String(rc)); + delay(1000); + } + + delay(1000); +} +void setup() +{ + pinMode(led, OUTPUT); // Initialize LED as an output + pinMode(sensor, INPUT); // Initialize sensor as an input + // attachInterrupt(digitalPinToInterrupt(sensor), stateChange, RISING); // Attach interrupt + // Initialize Serial Monitor for debugging + Serial.begin(115200); + while (!Serial) + ; + + if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) + { + Serial.println(F("SSD1306 allocation failed")); + for (;;) + ; // Don't proceed, loop forever + } + + displayText("Starting..."); + delay(1000); + + // Initialize a SoftwareSerial + SoftwareSerial *serial = new SoftwareSerial(SIM800_RX_PIN, SIM800_TX_PIN); + serial->begin(9600); + delay(1000); + + // Initialize SIM800L driver with an internal buffer of 200 bytes and a reception buffer of 512 bytes, debug disabled + sim800l = new SIM800L((Stream *)serial, SIM800_RST_PIN, 200, 512); + + // Equivalent line with the debug enabled on the Serial + // sim800l = new SIM800L((Stream *)serial, SIM800_RST_PIN, 200, 512, (Stream *)&Serial); + + Serial.println("Start of test protocol"); + displayText2("Start of ", "test protocol"); + delay(1000); + + setupModule(); +} +void loop() +{ + // Establish GPRS connectivity (5 trials) + bool connected = false; + for (uint8_t i = 0; i < 5 && !connected; i++) + { + delay(1000); + connected = sim800l->connectGPRS(); + } + + // Check if connected, if not reset the module and setup the config again + if (connected) + { + Serial.print(F("GPRS connected with IP ")); + Serial.println(sim800l->getIP()); + displayText2("GPRS connected with IP ", String(sim800l->getIP())); + delay(2000); + } + else + { + Serial.println(F("GPRS not connected !")); + Serial.println(F("Reset the module.")); + displayText2("GPRS not connected !", "Reset the module."); + delay(1000); + sim800l->reset(); + setupModule(); + return; + } + + // getHttpData(""); + val = digitalRead(sensor); // Read sensor value + + if (val == HIGH) + { + if (!motionDetected) + { + motionStart = millis(); // Start counting when motion is detected + motionDetected = true; + } + if (millis() - motionStart > 2000) + { // Check if motion lasts more than 2 sec + Serial.println("Motion detected"); + displayText2("Motion detected !", "Sending data..."); + delay(1000); + getHttpData(""); + digitalWrite(led, LOW); // Turn LED on + } + } + else + { + Serial.println("No motion"); + motionDetected = false; + digitalWrite(led, HIGH); // Turn LED off + } + + delay(100); // Small delay to prevent serial spamming + + // Close GPRS connectivity (5 trials) + bool disconnected = sim800l->disconnectGPRS(); + for (uint8_t i = 0; i < 5 && !connected; i++) + { + delay(1000); + disconnected = sim800l->disconnectGPRS(); + } + + if (disconnected) + { + Serial.println(F("GPRS disconnected !")); + displayText("GPRS disconnected !"); + delay(1000); + } + else + { + Serial.println(F("GPRS still connected !")); + displayText2("GPRS disconnected !", "GPRS still connected !"); + delay(1000); + } + + // // Go into low power mode + // bool lowPowerMode = sim800l->setPowerMode(MINIMUM); + // if(lowPowerMode) { + // Serial.println(F("Module in low power mode")); + // displayText("Module in low power mode"); + // delay(1000); + // } else { + // Serial.println(F("Failed to switch module to low power mode")); + // displayText2("Failed to switch module to low power mode", ""); + // delay(1000); + // } + + // End of program... wait... + // while(1); + delay(500); +} + diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html