#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <MD_MAX72xx.h>
#include <MD_Parola.h>
#include <SPI.h>
#include<EEPROM.h>
#define MAX_DEVICES 9
#define MAX_ZONES 4
Adafruit_MPU6050 mpu;
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define CLK_PIN 52 // CLK or SCK
#define DATA_PIN 51 // DATA or MOSI
#define CS_PIN 53 // CS or SS
#define PAUSE_TIME 0
#define FRAME_TIME 10
//MD_MAX72XX mx = MD_MAX72XX(MD_MAX72XX::PAROLA_HW, CS_PIN, MAX_DEVICES);
MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
//initialize global variables
int a_accelx = 0;
int a_accely = 0;
int a_accelz = 1;
int degreesF = 0;
String text;
int flag = 0;
int toggle1 = 0;
//int initial_flag = 0;
//int initital_flag_out = 0;
int eeprom_size = 1024;
const float BETA = 3950;
//for photoresistor
#define led1 13
#define led2 5
#define tempLED 11
const byte adcPin = 0;
volatile int adcReading;
volatile boolean adcDone;
boolean adcStarted;
boolean tempFlag = false;
boolean flag_fall = false;
typedef struct
{
uint8_t spacing; // character spacing
const char *msg; // message to display
} msgDef_t;
msgDef_t M[] =
{
{ 0, "" },
{ 0, "<==>" },
{ 0, "<=" },
{ 0, "=>" },
{ 0, "^^" },
{ 0, "VV" },
{ 0, ") (" },
{ 0, "( )" },
{ 1, "Fall" },
{ 1, "Enter Password" },
{ 1, "Select a option" },
};
void setup(void) {
Serial.begin(115200); //start serial
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(tempLED, OUTPUT);
//digitalWrite(tempLED, HIGH);
Serial.println("Enter Password:");
while (!mpu.begin()) { //MPU verfification
Serial.println("MPU6050 not connected!");
delay(1000);
}
//Serial.println("MPU6050 ready!");
P.begin(9);
P.setZone(0, 0, 1);
P.setZone(1, 2, 3);
P.setZone(2, 4, 5);
P.setZone(3, 6, 8);
P.setCharSpacing(MAX_ZONES, M[0].spacing);
P.displayZoneText (MAX_ZONES, M[0].msg, PA_LEFT, FRAME_TIME, PAUSE_TIME, PA_NO_EFFECT, PA_NO_EFFECT);
//https://majicdesigns.github.io/MD_Parola/class_m_d___parola.html
//for (int address = 0; address < eeprom_size; address ++)
//{
//EEPROM.write(address, " "); //EEPROM memory is Erased
//}
//writing password to eeprom using function (on every boot up gets set)
setPasswordInEEPROM(0, "EEE20003");
//***************************ADC INTERRUPT*******************************//
ADCSRA = bit (ADEN); // turn ADC on
ADCSRA |= bit (ADPS0) | bit (ADPS1) | bit (ADPS2); // Prescaler of 128
ADMUX = bit (REFS0) | (adcPin & 0x07); // AVcc and select input port
// initialize timer1
noInterrupts(); // disable all interrupts
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 3036; // preload timer 65536-16MHz/256/1Hz
TCCR1B |= (1 << CS12); // 256 prescaler
TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt
interrupts(); // enable all interrupts
//**************************ADC INTERRUPT***********************************//
//**************************MPU TIMER INTERRUPT***********************************//
//set timer1 interrupt at 1Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set compare match register for 1hz increments
OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12 and CS10 bits for 1024 prescaler
TCCR1B |= (1 << CS12) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
//**************************MPU TIMER INTERRUPT***********************************//
}
sensors_event_t event; //variable to store MPU event input
ISR(TIMER1_OVF_vect)
{
digitalWrite(led1, digitalRead(led1) ^ 1);
}
// ADC complete ISR
ISR (ADC_vect)
{
adcReading = ADC;
adcDone = true;
} // end of ADC_vect
//function to store the required password in eeprom
void setPasswordInEEPROM(int address, const String &str) {
//get length of string
byte strLen = str.length();
EEPROM.write(address, strLen); //store the length of the string in index 0
//for loop to write string
for (int i = 0; i < strLen; i++) {
EEPROM.write(address + 1 + i, str[i]);
}
}
ISR(TIMER1_COMPA_vect) { //timer1 interrupt 1Hz toggles pin 13 (LED)
//generates pulse wave of frequency 1Hz/2 = 0.5Hz (takes two cycles for full wave- toggle high then toggle low)
//count++;
toggle1 = 1; // flag for orange led event
//if (count==3) // flag for green led event
// toggle2=1;
}
void loop() {
password(); // password check
int initital_flag_out = 0;
initital_flag_out = EEPROM.read(800);
//Serial.println(initital_flag_out);
if ( initital_flag_out == 10)
{
EEPROM.get(100, a_accelx);
EEPROM.get(102, a_accely);
EEPROM.get(104, a_accelz);
mpu.getAccelerometerSensor()->getEvent(&event); //read using MPU function and pass to event variable
int accelx = event.acceleration.x; //store displacement in x into local variable
int accely = event.acceleration.y; //store displacement in y into local variable
int accelz = event.acceleration.z; //store displacement in z into local variable
delay(400);
if ( accelx < a_accelx)
{
display (0, 4, 1);
delay(10);
} else if ( accelx > a_accelx)
{
display (0, 5, 1);
delay(10);
}
else
{
display (0, 1, 1);
delay(10);
}
if ( accely < a_accely)
{
display (0, 2, 2);
delay(10);
} else if ( accely > a_accely)
{
display (0, 3, 2);
delay(10);
}
else
{
display (0, 1, 2);
delay(10);
}
if ( accelz < a_accelz)
{
display (0, 6, 3);
delay(10);
} else if ( accelz > a_accelz)
{
display (0, 7, 3);
delay(10);
}
else
{
display (0, 1, 3);
delay(10);
}
}
//*********************************ADC INTERRUPT************************************//
// if last reading finished, process it
if (adcDone)
{
adcStarted = false;
// do something with the reading, for example, print it
//Serial.println (adcReading);
degreesF = 1 / (log(1 / (1023. / adcReading - 1)) / BETA + 1.0 / 298.15) - 273.15; //convert to degrees
EEPROM.write(10, degreesF); //assing reading to variable to store
if (tempFlag == true) {
if (degreesF >= 40 || degreesF <= 5)
{
digitalWrite(tempLED, HIGH);
delay(500);
}
else {
digitalWrite(tempLED, LOW);
}
}
delay (500);
adcDone = false;
}
// if we aren't taking a reading, start a new one
if (!adcStarted)
{
adcStarted = true;
// start the conversion
ADCSRA |= bit (ADSC) | bit (ADIE);
}
//*********************************ADC INTERRUPT******************************//
//**************************MPU TIMER INTERRUPT***********************************//
if (toggle1 && flag_fall) {
int accelz_prev = 0;
EEPROM.get(104, accelz_prev);
mpu.getAccelerometerSensor()->getEvent(&event); //read using MPU function and pass to event variable
int accelz_current = event.acceleration.z;
if (accelz_current < accelz_prev)
{
display (0, 8, 4);
return;
}
toggle1 = 0;
}
//**************************MPU TIMER INTERRUPT***********************************//
}
//function to read from eeprom
String readPasswordEEPROM(int address) {
int strLen = EEPROM.read(0); //read the length of the string
char data[strLen + 1];//creating char array to store reading
//read from eeprom
for (int i = 0; i < strLen; i++) {
data[i] = EEPROM.read(address + 1 + i);
}
data[strLen] = "\0";
return String(data); //return string
}
void password()
{
if (Serial.available() > 0 && !flag) {
text = Serial.readString();
text.trim();
//read from eeprom using function
String passwordF = readPasswordEEPROM(0);
passwordF.trim();
if ( text == passwordF )
{
Serial.println("Welcome!");
menu();
tempFlag = true;
flag = true;
}
else
{
Serial.println("Wrong Password - Please re-enter:");
}
}
}
void menu()
{
Serial.println("*************************");
Serial.println("Option 1 - Save current position");
Serial.println("Option 2 - Save data from external sensor");
Serial.println("Option 3 - interrupt driven routine");
Serial.println("Please select an option number");
Serial.println("*************************");
//delay(5000);
while ( true)
{
if (Serial.available())
{
String option = Serial.readString();
option.trim();
Serial.println(option);
if ( option == "1")
{
Serial.println("O1 -Selected");
mau_initial();
} else if ( option == "2")
{
Serial.println("O2 -Selected");
addSensor();
} else if (option == "3")
{
Serial.println("O3 -Selected");
//fall_detection();
flag_fall = true;
} else
{
Serial.println("Wrong parameter - Please re-enter");
//flag2 = false;
}
return;
}
}
}
void display (int m, int n, int o)
{
if (P.displayAnimate())
{
boolean bAllDone = true;
switch (o)
{
case 1:
bAllDone = bAllDone && P.getZoneStatus(0);
if (bAllDone)
{
P.setTextBuffer(0, M[m, n].msg);
P.setCharSpacing(0, M[m, n].spacing);
P.displayReset(0);
//return;
}
break;
case 2:
bAllDone = bAllDone && P.getZoneStatus(1);
if (bAllDone)
{
P.setTextBuffer(1, M[m, n].msg);
P.setCharSpacing(1, M[m, n].spacing);
P.displayReset(1);
// return;
}
break;
case 3:
bAllDone = bAllDone && P.getZoneStatus(2);
if (bAllDone)
{
P.setTextBuffer(2, M[m, n].msg);
P.setCharSpacing(2, M[m, n].spacing);
P.displayReset(2);
//return;
}
break;
case 4:
bAllDone = bAllDone && P.getZoneStatus(3);
if (bAllDone)
{
P.setTextBuffer(3, M[m, n].msg);
P.setCharSpacing(3, M[m, n].spacing);
P.displayReset(3);
//return;
}
break;
}
}
}
void addSensor() {
//save temperature to eeprom
//read from eeprom
int light = EEPROM.read(10);
Serial.println("Temperature from EEPROM: ");
Serial.print(light);
Serial.print(" C");
}
void mau_initial()
{
mpu.getAccelerometerSensor()->getEvent(&event); //read using MPU function and pass to event variable
int accelx_ini = event.acceleration.x; //store displacement in x into local variable
int accely_ini = event.acceleration.y; //store displacement in y into local variable
int accelz_ini = event.acceleration.z;
EEPROM.put(100, accelx_ini);
EEPROM.put(102, accely_ini);
EEPROM.put(104, accelz_ini);
int initial_flag = 0;
Serial.println ("Initial values stored");
initial_flag = 10;
EEPROM.write ( 800, initial_flag);
//Serial.println(initial_flag );
return;
}