UPDATE 1: Posting the rest of the code.
// Program header files
#include <Wire.h>
#include <WiFi.h>
#include <WebServer.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "FS.h"
#include "FirebaseESP32.h"
#include "memorysaver.h"
#include <Adafruit_MMA8451.h>
#include <Adafruit_Sensor.h>
//Time and Date NTP Server Header
#include <NTPClient.h>
#include <WiFiUdp.h>
//Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
//Variables to save date and time
String formattedDate = "";
String dayStamp = "";
String timeStamp = "";
String logPath = "/Log";
String tempPath = "/Log/Temperature";
String pirPath = "/Log/PIR_Sensor";
String accelPath = "/Log/Accelerometer";
String pirDatePath = "/Log/pir_Date";
String pirTimePath = "/Log/pir_Time";
String accelDatePath = "/Log/accel_Date";
String accelTimePath = "/Log/accel_Time";
// Database/Wi-Fi configuration
#define FIREBASE_HOST "host"
#define FIREBASE_AUTH "auth"
#define AP_SSID "apssid"
#define AP_PASSWORD "password"
#define WIFI_SSID "ssid"
#define WIFI_PASSWORD "passsword"
// Variables to keep track of previous and current time to create a delay
unsigned long currentTime = 0;
unsigned long prevTime = 0;
unsigned long bool_waitForAccel = 0; // Used to flag the accelerometer
unsigned long bool_waitForPIR = 0; // Used to flag the PIR
unsigned long num_timeAtPIR = 0; // Used to keep track of the time the PIR sensor detected motion
unsigned long num_timeAtAccel = 0; // Used to keep track of the time the accelerometer detected a fall
unsigned long period = 20000; // Amount of time given to check after motion is detected
int statusLED = 26; // Choose the pin for status LED
int buzzer = 12; // Choose the pin for Piezzo Buzzer. Connected from MOSFET gate.
int tempSensor = 2; // Choose pin for Temperature Sensor
int pirSensor = 27; // Choose pin for controller PIR Sensor
int PIR_Power = 25; // Controls Power gate for PIR Sensor
int ArduCAM_Power = 32; // Controls Power gate for ArduCAM
const int CS = 5; // GPIO5 as Slave Select for ArduCAM
int wifiType = 0; // 0: Station 1: AP (Access Point)
// Set up requests to send captured image to external server
bool onlineMode = true;
String start_request = "";
String boundary = "_cam_";
String end_request = "\n--" + boundary + "--\n";
// Set buffer size for camera data
static const size_t bufferSize = 2048;
static uint8_t buffer[bufferSize] = {0xFF};
byte buf[256];
static int iPic = 0;
static int kPic = 0;
uint8_t temp = 0, temp_last = 0;
uint32_t len = 0;
bool is_header = false;
// Threshhold for declaring a fall on the accelerometer
float sensitivity = 11.0;
float magnitude = 0.0; // Stores the calculated magnitude
// Accelerometer, Semaphore, and Firebase instances
Adafruit_MMA8451 mma = Adafruit_MMA8451();
FirebaseData firebaseData;
#if defined (OV2640_MINI_2MP) || defined (OV2640_CAM)
ArduCAM myCAM(OV2640, CS);
#endif
WiFiClient client;
void start_capture()
{
myCAM.clear_fifo_flag();
myCAM.start_capture();
}
void camCapture()
{
digitalWrite(ArduCAM_Power, HIGH);
// Flush the FIFO
myCAM.flush_fifo();
// Clear capture done flag
myCAM.clear_fifo_flag();
// Start capture
myCAM.start_capture();
Serial.println("Start capture!");
while(!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));
len = myCAM.read_fifo_length();
Serial.print("The FIFO length is: ");
Serial.println(len);
if(len >= MAX_FIFO_SIZE) // 8M
{
Serial.println("Over size!");
}
if(len == 0) // 0KB
{
Serial.println("Size is 0KB");
return;
}
long full_length;
if(client.connect("xx.xx.xx.xx", 80) || onlineMode)
{
if(onlineMode)
{
while(client.available())
{
String line = client.readStringUntil('\r');
}
}
start_request = start_request +
"\n--" + boundary + "\n" +
"Content-Disposition: form-data; name=\"data\"; filename=\"CAM.jpg\"\n" +
"Content-Transfer-Encoding: binary\n\n";
full_length = start_request.length() + len + end_request.length();
client.println("POST /uploads.php HTTP/1.1");
client.println("Host: xx.xx.xx.x");
client.println("Content-Type: multipart/form-data; boundary =" + boundary);
client.print("Content-Length: "); client.println(full_length);
client.println();
client.print(start_request);
iPic = 0;
static uint8_t buffer[bufferSize] = {0xFF};
while (len--)
{
temp_last = temp;
temp = SPI.transfer(0x00);
//Read JPEG data from FIFO
if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
{
buf[iPic++] = temp; //save the last 0XD9
//Write the remain bytes in the buffer
myCAM.CS_HIGH();
client.write(buf, iPic);
//Close the file
//file.close();
Serial.println(F("Image save OK."));
is_header = false;
iPic = 0;
}
if (is_header == true)
{
//Write image data to buffer if not full
if (iPic < 256)
buf[iPic++] = temp;
else
{
//Write 256 bytes image data to file
myCAM.CS_HIGH();
client.write(buf, 256);
iPic = 0;
buf[iPic++] = temp;
myCAM.CS_LOW();
myCAM.set_fifo_burst();
}
}
else if ((temp == 0xD8) & (temp_last == 0xFF))
{
is_header = true;
buf[iPic++] = temp_last;
buf[iPic++] = temp;
}
}
// End the POST request to the server
client.println(end_request);
myCAM.CS_HIGH();
// Stop the client
client.stop();
digitalWrite(ArduCAM_Power, LOW);
}
else // No connection to the server.
{
Serial.println("Could not connect to external server!");
Serial.println("Please check the IP address or Port");
return;
}
}
// Calculate the magnitude with the x, y, and z axis of the accelerometer.
// Gives an overall value that is better than just using the z-axis
float calculateMagnitude(float x, float y, float z)
{
float magnitude = sqrt(sq(x) + sq(y) + sq(z));
return magnitude;
}
void setup()
{
Wire.begin();
Serial.begin(115200);
SPI.begin();
SPI.setFrequency(4000000);
pinMode(CS, OUTPUT);
pinMode(PIR_Power, OUTPUT); // Set mosfet gate to output for PIR Sensor
pinMode(ArduCAM_Power, OUTPUT); // Set mosfet gate to output for ArduCAM
pinMode(statusLED, OUTPUT); // Declare LED as output
pinMode(buzzer, OUTPUT); // Declare Piezo Buzzer as output
pinMode(pirSensor, INPUT); // Declare PIR Sensor as input
Serial.println();
// Check if accelerometer is properly connected/found
if(!mma.begin())
{
Serial.println("Couldn't start MMA8451 Accelerometer.");
Serial.println("Check your connections.");
while(1);
}
Serial.println("MMA8451 Accelerometer found!");
// Set the g-range for the accelerometer. Can be adjusted to 2g, 4g, or 8g.
mma.setRange(MMA8451_RANGE_2_G);
// Check if camera is found
digitalWrite(ArduCAM_Power, HIGH);
uint8_t vid, pid;
uint8_t temp;
while(1)
{
//Check if the ArduCAM SPI bus is OK
myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
temp = myCAM.read_reg(ARDUCHIP_TEST1);
if (temp != 0x55) {
Serial.println(F("SPI interface Error!"));
delay(2);
continue;
}
else
break;
}
#if defined (OV2640_MINI_2MP) || defined (OV2640_CAM)
//Check if the camera module type is OV2640
myCAM.wrSensorReg8_8(0xff, 0x01);
myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 )))
Serial.println(F("Can't find OV2640 module!"));
else
Serial.println(F("OV2640 detected."));
#endif
//Change to JPEG capture mode and initialize the OV2640 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
myCAM.OV2640_set_JPEG_size(OV2640_640x480);
myCAM.clear_fifo_flag();
// Turn off Camera
digitalWrite(ArduCAM_Power, LOW);
// Connect to WiFi
if (wifiType == 0)
{
if(!strcmp(WIFI_SSID,"SSID"))
{
Serial.println(F("Please set your SSID"));
while(1);
}
if(!strcmp(WIFI_PASSWORD,"PASSWORD"))
{
Serial.println(F("Please set your PASSWORD"));
while(1);
}
// Connect to WiFi network
Serial.println();
Serial.print(F("Connecting to: "));
Serial.println(WIFI_SSID);
WiFi.mode(WIFI_STA);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(F("."));
}
Serial.println();
Serial.println(F("WiFi connected"));
Serial.println();
Serial.println(WiFi.localIP());
}
else if (wifiType == 1)
{
Serial.println();
Serial.println();
Serial.print(F("Shared AP: "));
Serial.println(AP_SSID);
Serial.print(F("The password is: "));
Serial.println(AP_PASSWORD);
WiFi.mode(WIFI_AP);
WiFi.softAP(AP_SSID, AP_PASSWORD);
Serial.println();
Serial.print("AP IP Address is: ");
Serial.println(WiFi.softAPIP());
}
// Initialize a NTPClient to get time
timeClient.begin();
timeClient.setTimeOffset(-14400);
//If Firebase is connected, turn on the LED
Firebase.begin(FIREBASE_HOST, FIREBASE_AUTH);
Firebase.reconnectWiFi(true);
digitalWrite(statusLED,HIGH);
Serial.println("------------------------------------");
Serial.println("Path exist test...");
if (Firebase.pathExist(firebaseData, logPath))
{
Serial.println("Path " + logPath + " exists");
}
else
{
Serial.println("Path " + logPath + " does not exist");
Serial.println("Adding all necessary paths to /Log");
Serial.println("Will have to reinitialize later once everything is set up.");
// Initialize All variables to 0;
Firebase.setFloat(firebaseData, tempPath, 0.0);
Firebase.setInt(firebaseData, pirPath, 0);
Firebase.setInt(firebaseData, accelPath, 0);
//Firebase.setString(firebaseData, pirDatePath, ???);
//Firebase.setString(firebaseData, pirTimePath, ???);
//Firebase.setString(firebaseData, accelDatePath, ???);
//Firebase.setString(firebaseData, accelTimePath, ???);
}
Serial.println("------------------------------------");
Serial.println();
digitalWrite(PIR_Power, HIGH);
digitalWrite(pirSensor, LOW);
digitalWrite(statusLED, LOW);
Serial.println("Sensors booting up...");
delay(10000); // Let sensors boot up, 10s
Serial.println("Sensors ready!");
}