/*
BME280 Barometric pressure-Humidity-Temperature
https://iotprojectsideas.com/interfacing-bme280-sensor-with-arduino/
LM393 Hall effect Magnetic field Sensor
https://circuitdigest.com/microcontroller-projects/interfacing-hall-effect-sensor-module-with-arduino
HLK-LD2410 24GHz Presence Sensing Radar
https://wiki.dfrobot.com/SKU_SEN0557_24GHz_Human_Presence_Sensing_Module
4 Wire Flame Detection Sensor Module
https://microcontrollerslab.com/flame-sensor-arduino-fire-detection/
GY-SGP30 CO2 , Total Volatile Organic Compounds (TVOC) in ppb. Raw measurement values of Ethanol and Hydrogen(H2).
https://how2electronics.com/interfacing-sgp30-co2-tvoc-sensor-with-arduino/
https://learn.adafruit.com/adafruit-sgp30-gas-tvoc-eco2-mox-sensor/arduino-code
address 0x58
For normal Operation exposing the sensor to outside air for 10min cumulative time should be sufficient.
VEML6075 advanced CMOS ultraviolet (UV) sensor UVA and UVB
https://learn.adafruit.com/adafruit-veml6075-uva-uvb-uv-index-sensor/arduino-test
address of 0x10 (cannot change)
(5V)
-tft------ArduMega------
LCD_D2 -> D2
LCD_D3 -> D3
LCD_D4 -> D4
LCD_D5 -> D5
LCD_D6 -> D6
LCD_D7 -> D7
LCD_D0 -> D8
LCD_D1 -> D9
SD_SS -> D53 TFT SD works on MEGA with cables
SD_D0 -> D50
SD_DI -> D51
SCK -> D52
LCD_RST -> A4
LCD_CS -> A3
LCD_RS -> A2 -or CD
LCD_WR -> A1
LCD_RD -> A0
---------------
(5V)
24GhzRadar--ArduMega
UartTx --> D10
UartRx --> D11
on Mega 2560 only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).
flame
infrared ArduMega
D0 -- D25
SGP30-gas --- ArduMega -----
SDA -> SDA D20
SCL -> SLC D21
address 0x58
-------- Buttons -------
*/
//---------TFT-----------
#include <SPI.h> // f.k. for Arduino-1.5.2
#include <SD.h> // Use the official SD library on hardware pins
#include <Adafruit_GFX.h> // without this SD card is not working
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
#define SD_CS 53
#define NAMEMATCH "" // "" matches any name
#define PALETTEDEPTH 0 // do not support Palette modes
char namebuf[32] = "/"; //BMP files in root directory
File root;
int pathlen;
#define TFT_WIDTH 320
#define TFT_HEIGHT 480
//-----TFT colors
#define BLACK 0x0000
#define GREY 0x8410
#define BLUE 0x001F
#define BLUE2 0x051F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define Navy 0x000F /* 0, 0, 128 */
#define DarkGreen 0x03E0 /* 0, 128, 0 */
#define DarkCyan 0x03EF /* 0, 128, 128 */
#define Maroon 0x7800 /* 128, 0, 0 */
#define Purple 0x780F /* 128, 0, 128 */
#define Olive 0x7BE0 /* 128, 128, 0 */
#define LightGrey 0xC618 /* 192, 192, 192 */
#define DarkGrey 0x7BEF /* 128, 128, 128 */
#define Orange 0xFD20 /* 255, 165, 0 */
#define GreenYellow 0xAFE5 /* 173, 255, 47 */
#define Pink 0xF81F
#include <Fonts/FreeSans9pt7b.h>
// SGP30 gas sensor
#include "SparkFun_SGP30_Arduino_Library.h" // Click here to get the library: http://librarymanager/All#SparkFun_SGP30
#include <Wire.h> // also UV sensor and SGP30, and BME280 uses this library
SGP30 mySensor; //create an object of the SGP30 class
long t1, t2;
// BME280
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#define SEALEVELPRESSURE_HPA (1013.25)
Adafruit_BME280 bme; // For I2C interface
float currentTemperature;
float previousTemperature = -999; // Initial value to ensure any temperature value is considered as maximum
float maxTemperature = -999; // Maximum temperature recorded
int changeCountT = 0; // Counter for significant temperature changes
float currentPressure;
float previousPressure = -999;
float maxPressure = -999;
int changeCountP = 0;
float currentHumidity;
float previousHumidity = -999;
float maxHumidity = -999;
int changeCountH = 0;
//----------------------------------------
// Hall sensor
int Hallpin = 24;
int HallSensorStatus;
// 24GHz presence
#include <SoftwareSerial.h>
//Tx, Rx
SoftwareSerial mySerial(10, 11); //Define soft serial port, define port 3 as TX and port 2 as RX,
size_t readN(uint8_t *buf, size_t len);
bool recdData(uint8_t *buf);
uint8_t Cache[23] = {0}; //Cache
// flame 4 wire light source detector of a wavelength in the range of 760nm-1100 nm.
int flame_sensor_pin = 25;
int flame_pin; // state of sensor
// UV sensor
#include "Adafruit_VEML6075.h"
Adafruit_VEML6075 uv = Adafruit_VEML6075();
//------------------------------- SETUP -------------------------
void setup() {
Serial.begin(9600);
//-----------TFT-------------
uint16_t ID;
ID = tft.readID();
if (ID == 0x0D3D3) ID = 0x9481;
tft.begin(ID);
tft.fillScreen(BLACK);
tft.setTextColor(WHITE, BLACK); // textcolor / background color
tft.setRotation(1); // 1=LANDSCAPE(pins top) , 2=PORTRAIT(pins left) , 3=LANDSCAPE(pins bottom)
tft.setCursor(0, 0);
tft.setTextSize(2);
tft.print("initializing Detector...");
tft.setCursor(0, 30); // left-right / up-down
tft.setTextColor(BLACK, GREEN);
tft.print("TFT ID:0x"); tft.println(ID, HEX); Serial.print("TFT ID:0x"); Serial.println(ID, HEX);
// TFT SD
bool good = SD.begin(SD_CS);
if (!good) {
tft.setCursor(0, 50); // left-right / up-down
tft.setTextSize(2);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.println("cannot start SD"); Serial.println(F("cannot start SD"));
delay(100);
//while (1); // to halt
} else if (good)
{ tft.setCursor(0, 50); // left-right / up-down
tft.setTextColor(BLACK, GREEN); // textcolor / background color
tft.print("SD : Found"); Serial.print("SD : found");
}
root = SD.open(namebuf);
pathlen = strlen(namebuf);
//--------------------------
// BME280
Serial.println(F("BME280 Sensor event test"));
if (!bme.begin()) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
tft.setCursor(0, 70); // left-right / up-down
tft.setTextSize(2);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.println("cannot start BME280 module"); Serial.println(F("cannot start SD"));
delay(100);
} else if (!bme.begin())
{ tft.setCursor(0, 70); // left-right / up-down
tft.setTextColor(BLACK, GREEN); // textcolor / background color
tft.print("BME280 module: Found"); Serial.print("BME280 module: Found");
}
//------------------------------------------------
//Hall sensor
pinMode(Hallpin, INPUT);
//24GHz presence
mySerial.begin(57600); //Soft serial port
//flame
pinMode(flame_sensor_pin , INPUT);
//--------- SGP30 ----------
Wire.begin();
//Sensor supports I2C speeds up to 400kHz
Wire.setClock(400000);
//Initialize sensor
if (mySensor.begin() == false) {
Serial.println("cannot start SGP30 module.");
tft.setCursor(0, 90); // left-right / up-down
tft.setTextSize(2);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.println("cannot start SGP30 module");
//while (1);
} else if (mySensor.begin() == true)
{ tft.setCursor(0, 90); // left-right / up-down
tft.setTextColor(BLACK, GREEN); // textcolor / background color
tft.print("SGP30 module: Found"); Serial.print("BME280 module: Found");
}
//Initializes sensor for air quality readings
//measureAirQuality should be called in one second increments after a call to initAirQuality
mySensor.initAirQuality();
t1 = millis();
//--------------------------
/*
// UV sensor ----------------------------
Serial.println("VEML6075 Full Test");
if (! uv.begin()) {
Serial.println("Failed to communicate with VEML6075 sensor, check wiring?");
}
Serial.println("Found VEML6075 sensor");
// Set the integration constant
uv.setIntegrationTime(VEML6075_100MS);
// Get the integration constant and print it!
Serial.print("Integration time set to ");
switch (uv.getIntegrationTime()) {
case VEML6075_50MS: Serial.print("50"); break;
case VEML6075_100MS: Serial.print("100"); break;
case VEML6075_200MS: Serial.print("200"); break;
case VEML6075_400MS: Serial.print("400"); break;
case VEML6075_800MS: Serial.print("800"); break;
}
Serial.println("ms");
// Set the high dynamic mode
uv.setHighDynamic(true);
// Get the mode
if (uv.getHighDynamic()) {
Serial.println("High dynamic reading mode");
} else {
Serial.println("Normal dynamic reading mode");
}
// Set the mode
uv.setForcedMode(false);
// Get the mode
if (uv.getForcedMode()) {
Serial.println("Forced reading mode");
} else {
Serial.println("Continuous reading mode");
}
// Set the calibration coefficients
uv.setCoefficients(2.22, 1.33, // UVA_A and UVA_B coefficients
2.95, 1.74, // UVB_C and UVB_D coefficients
0.001461, 0.002591); // UVA and UVB responses
*/
//----------------------------------------------------------------------
// switches
//pinMode(ELECTRICAL_PIN, INPUT_PULLUP);
//Buttons
//pinMode(Button1,INPUT_PULLUP);
//pinMode(buzzer, OUTPUT);
// print basics on SCREEN------------------------FRAMEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
tft.fillScreen(BLACK);
// draw rectangular frame
tft.drawRect(0, 0, 480, 320, GREEN);
// left-right/up-down textcolor / background color
showmsgXY(3, 15, 1, &FreeSans9pt7b, "Temp(c)");
showmsgXY(210, 15, 1, &FreeSans9pt7b, "| Max");
showmsgXY(377, 3, 1, NULL, "Possible Strange");
showmsgXY(377, 11, 1, NULL, "difference ! ");
showmsgXY(3, 38, 1, &FreeSans9pt7b, "Pressure(hPa)");
showmsgXY(210, 38, 1, &FreeSans9pt7b, "| Max");
showmsgXY(3, 61, 1, &FreeSans9pt7b, "Humidity%");
showmsgXY(210, 61, 1, &FreeSans9pt7b, "| Max");
// left-right/up-down
showmsgXY(3, 87, 1, &FreeSans9pt7b, "Magnetic");
showmsgXY(50, 91, 1, NULL, "Field");
showmsgXY(210, 87, 1, &FreeSans9pt7b, "| Max");
showmsgXY(3, 123, 1, &FreeSans9pt7b, "Radar(24GHz)");
showmsgXY(210, 123, 1, &FreeSans9pt7b, "| Max");
}
void loop()
{
BME280();
recdData(Cache); // 24GHz presence radar function call
delay(1000);
}
void BME280() {
currentTemperature = bme.readTemperature();
tft.setCursor(140, 15); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(currentTemperature);
if (currentTemperature != previousTemperature) {
if (abs(currentTemperature - previousTemperature) >= 2) { // if temperature is greater than 2 degrees in 10 measurements print "strange"
changeCountT++;
if (changeCountT >= 10) {
tft.setCursor(377, 26); // left-right / up-down
tft.setTextSize(1);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.print("Strange!");
changeCountT = 0;
}
} else {
changeCountT = 0;
}
}
if (currentTemperature > maxTemperature) {
maxTemperature = currentTemperature;
tft.setCursor(270, 15); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(maxTemperature);
}
previousTemperature = currentTemperature;
currentPressure = bme.readPressure() / 100.0; // Convert Pa to hPa
tft.setCursor(140, 38); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(currentPressure);
if (currentPressure != previousPressure) {
if (abs(currentPressure - previousPressure) >= 2) { // if Pressure change by 1 degree in 10 measurements print "strange"
changeCountP++;
if (changeCountP >= 10) {
tft.setCursor(377, 26); // left-right / up-down
tft.setTextSize(1);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.print("Strange!");
changeCountP = 0;
}
} else {
changeCountP = 0;
}
}
if (currentPressure > maxPressure) {
maxPressure = currentPressure;
tft.setCursor(270, 38); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(maxPressure);
}
previousPressure = currentPressure;
currentHumidity = bme.readHumidity();
tft.setCursor(140, 61); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(currentHumidity);
if (currentHumidity != previousHumidity) {
if (abs(currentHumidity - previousHumidity) >= 2) { // if Humidity change by 2 degrees in 10 measurements print "strange"
changeCountH++;
if (changeCountH >= 10) {
tft.setCursor(377, 49); // left-right / up-down
tft.setTextSize(1);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.print("Strange condition Detected");
changeCountH = 0;
}
} else {
changeCountH = 0;
}
}
if (currentHumidity > maxHumidity) {
maxHumidity = currentHumidity;
tft.setCursor(270, 61); // left-right / up-down
tft.setFont(&FreeSans9pt7b);
tft.print(maxHumidity);
}
previousHumidity = currentHumidity;
}
void HallSensor()
{
HallSensorStatus = digitalRead(Hallpin); // Check the sensor status
if (HallSensorStatus == 1) // if magnetic field near
{
tft.setCursor(60, 73); // left-right / up-down
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.setTextSize(2);tft.print("YES");
tft.setCursor(275, 73); // left-right / up-down
tft.setTextSize(1);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.print("Possible");
tft.setCursor(275, 81); // left-right / up-down
tft.setTextSize(1);
tft.setTextColor(WHITE, RED); // textcolor / background color
tft.print("Strange!");
}
else {
tft.setCursor(40, 73); // left-right / up-down
tft.setTextSize(2);
tft.setTextColor(WHITE, BLACK); // textcolor / background color
tft.print("NO ");
}
}
//24GHz presence radar
size_t readN(uint8_t *buf, size_t len)
{
size_t offset = 0, left = len;
int16_t Tineout = 1500;
uint8_t *buffer = buf;
long curr = millis();
while (left) {
if (Serial1.available()) {
// buffer[offset] = Serial1.read();
buffer[offset] = Serial.read();
offset++;
left--;
}
if (millis() - curr > Tineout) {
break;
}
}
return offset;
}
bool recdData(uint8_t *buf)
{
int16_t Tineout = 50000;
long curr = millis();
uint8_t ch;
bool ret = false;
const char *P;
while (!ret) {
if (millis() - curr > Tineout) {
break;
}
if (readN(&ch, 1) == 1) {
if (ch == 0xF4) {
buf[0] = ch;
if (readN(&ch, 1) == 1) {
if (ch == 0xF3) {
buf[1] = ch;
if (readN(&ch, 1) == 1) {
if (ch == 0xF2) {
buf[2] = ch;
if (readN(&ch, 1) == 1) {
if (ch == 0xF1) {
buf[3] = ch;
if (readN(&buf[4], 19) == 19) {
// printdf(buf, 23); //Print raw data
uint16_t Adistance = buf[10] << 8 | buf[9];
uint16_t Sdistance = buf[13] << 8 | buf[12];
uint16_t Distance = buf[16] << 8 | buf[15];
switch (buf[8]) {
case 0x00 : Serial.println("Detected status: nobody"); break;
case 0x01 : Serial.println("Detected status: moving"); break;
case 0x02 : Serial.println("Detected status: stationary"); break;
case 0x03 : Serial.println("Detected status: moving & stationary object"); break;
}
// Serial.print("Energy value of moving object:");
// Serial.println(buf[11]);
// Serial.print("Energy value of stationary object:");
// Serial.println(buf[14]);
// Serial.print("Distance to the moving object in CM:");
// Serial.println(Adistance);
// Serial.print("Distance to the stationary object in CM:");
// Serial.println(Sdistance);
tft.setCursor(60, 106); tft.setTextSize(2);tft.setTextColor(WHITE, BLACK);
tft.print(Distance);
Serial.print("Detection distance CM:");Serial.println(Distance);
break;
}
}
}
}
}
}
}
}
}
}
return ret;
}
void printdf(uint8_t *buf, int len)
{
for (int i = 0; i < len; i++) {
if (buf[i] < 0x10) {
Serial.print("0");
}
Serial.print(buf[i], HEX);
Serial.print(" ");
}
Serial.println();
}
//----------------------end of 24GHz radar presence ---------------------------------------
//----------------------------infrared detector
void infrared(){
flame_pin = digitalRead(flame_sensor_pin); // reading from the sensor
if (flame_pin == HIGH) // applying condition
{
Serial.println("Infrared DETECTED!");
}
else
{
Serial.println("No Detection");
}
delay(1000);
}
void sgp30gas()
{
//First fifteen readings will be
//CO2: 400 ppm TVOC: 0 ppb
t2 = millis();
if ( t2 >= t1 + 1000) //only will occur if 1 second has passed
{
t1 = t2;
//measure CO2 and TVOC levels
mySensor.measureAirQuality();
Serial.print("CO2: ");
Serial.print(mySensor.CO2);
Serial.print(" ppm\tTVOC: ");
Serial.print(mySensor.TVOC);
Serial.println(" ppb");
//get raw values for H2 and Ethanol
mySensor.measureRawSignals();
Serial.print("Raw H2: ");
Serial.print(mySensor.H2);
Serial.print(" \tRaw Ethanol: ");
Serial.println(mySensor.ethanol);
}
}
void UV()
{
Serial.print("Raw UVA reading: "); Serial.println(uv.readUVA());
Serial.print("Raw UVB reading: "); Serial.println(uv.readUVB());
Serial.print("UV Index reading: "); Serial.println(uv.readUVI());
}
void showmsgXY(int x, int y, int sz, const GFXfont *f, const char *msg)
{
int16_t x1, y1;
uint16_t wid, ht;
//tft.drawFastHLine(0, y, tft.width(), WHITE);
tft.setFont(f);
tft.setCursor(x, y);
tft.setTextColor(WHITE);
tft.setTextSize(sz);
tft.print(msg);
delay(1000);
}