Its a little long and alot of doesnt affect this particular code module.
But here it is.
//TASK LIST
//1. Resource Manager Finite State Machine (FSM)
//2. A multi-functional traffic lights controllerK
//3. Barrier crossing controller [DONE]
//4. Motor racing lights controller [DONE]
//5. A 3-colour LED controller [DONE]
//6. Two switch-debounce modules [DONE]
//7. A heartbeat module [DONE]
//8. A Tilt-Sensor and Thermometer based on the MPU6050
//9. A simple Command Interpreter[DONE]
//10. Scheduler(s)
#include <Wire.h>
const byte Characters[] = {
0b01100000, //1 0
0b11011010, //2 1
0b00111110, //B 2
0b10011110, //E 3
0b10001110, //F 4
0b00000001, //DP 5
0b00011110, //t 6
0b01111100, //U 7
0b00011100, //L 8
0b10000100, //I 9
0b00000110, //R 10
0b00000000 //OFF 11
};
unsigned long currentTime;
byte SegDSPL;
//==============================RGB FADE LEDS=====================================
#define RED 9
#define BLUE 10
#define GREEN 11
int color = 8;
int i = 0;
bool fade = false;
//================================================================================================//
//====================================SW1 MODULE (MODE SELECT)====================================//
//================================================================================================//
unsigned long SW1_LastDT = 0;
int SW1, SW1_State, SW1_lastState = 1, SW1flickState = 0;
bool Switch_1;
int Module = 0;
int Mode = 0;
int Trains = 0;
#define button1 A0
void switchTwo() {
SW1 = digitalRead(A0);
//unsigned long currentTime = millis();
if (SW1 == LOW) {
SW1_State = 0; // Replicating digitalRead() function.
}
else {
SW1_State = 1;
}
if (SW1_State != SW1flickState) {
// reset the debouncing timer
SW1_LastDT = millis();
// save the the last flickerable state
SW1flickState = SW1_State;
}
// Checks that the apporriate time has passed, basically a delay();
if (((long)(currentTime - SW1_LastDT) >= 300)) {
if (SW1_lastState == 1 && SW1_State == 0) {
Switch_1 = true;
Mode = Mode + 1;
//Trains = Trains + 1;
}
else {
Switch_1 = false;
}
SW1_lastState = SW1_State;
}
}
//================================================================================================//
//====================================SW2 MODULE (MODULE SELECT)==================================//
//================================================================================================//
unsigned long SW2_LastDT = 0;
int SW2, SW2_State, SW2_lastState = 1, SW2flickState = 0;
bool Switch_2;
#define button2 A1
void switchOne() {
SW2 = digitalRead(A1);
//unsigned long currentTime = millis();
if (SW2 == LOW) {
SW2_State = 0; // Replicating digitalRead() function.
}
else {
SW2_State = 1;
}
if (SW2_State != SW2flickState) {
// reset the debouncing timer
SW2_LastDT = millis();
// save the the last flickerable state
SW2flickState = SW2_State;
}
// Checks that the apporriate time has passed, basically a delay();
if (((long)(currentTime - SW2_LastDT) >= 300)) {
if (SW2_lastState == 1 && SW2_State == 0) {
Switch_2 = true;
Module = Module + 1;
// Trains = Trains - 1;
}
else {
Switch_2 = false;
}
SW2_lastState = SW2_State;
}
}
//================================================================================================//
//===================================FSM MODULE===================================================//
//================================================================================================//
#define GRANTED A2
#define GRANTED_H pinMode(GRANTED,INPUT_PULLUP);
#define GRANTED_L digitalWrite(GRANTED,LOW); pinMode(GRANTED,OUTPUT);
// State definitions
#define NoTriggerNoDemand 0 // idle state
#define TriggerIamMaster 1 // we are master after a successful claim
#define IamSlave 2 // we are slave after other device has made a successful claim
bool ACCEL = false;
bool TRIGGER;
int STATE;
int timingState, Counter;
char data, response;
unsigned long lastTime, lastTime_1 = 0;
//unsigned long currentTime;
//=================================================================================
void leaveHigh(unsigned char pin) {
pinMode(pin, INPUT_PULLUP);
}
//=================================================================================
void pullLow(unsigned char pin) {
digitalWrite(pin, LOW);
pinMode(pin, OUTPUT);
}
//=================================================================================
bool demandREQ() {
return (!(analogRead(A6) >> 8));
}
//=================================================================================
// function that executes whenever data is requested from master
void requestEvent() {
Wire.write("ACK"); /*send string on request */
}
//=================================================================================
void receiveEvent(int howMany) {
while (0 < Wire.available()) {
data = Wire.read(); /* receive byte as a character */
//Serial.print(data); /* print the character */
}
//Serial.println(); /* to newline */
}
//=================================================================================
void FSM() {
switch (STATE) {
case NoTriggerNoDemand: //No trigger, No demand
GRANTED_H;
if (TRIGGER == true) {
STATE = 1;
}
else if (!TRIGGER && demandREQ()) {
STATE = 2;
}
break;
case TriggerIamMaster: // I am master
GRANTED_H;
if (TRIGGER == false) {
STATE = 0;
}
break;
case IamSlave: // I am Slave
GRANTED_L;
if (!demandREQ()) {
STATE = 0;
}
break;
}
if (((long)(currentTime - lastTime_1)) >= 1) {
TimerModule();
lastTime_1 = currentTime;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
void TimerModule() {
switch (timingState) {
case 0:
timingState = 1;
lastTime = millis();
break;
case 1:
{
currentTime = millis();
if (((long)(currentTime - lastTime)) > 17) {
TRIGGER = true;
lastTime = millis();
timingState = 2;
}
else {
timingState = 1;
}
}
break;
case 2:
if (STATE == TriggerIamMaster) { //State 1 is MASTER state
timingState = 3;
}
else {
timingState = 2;
}
break;
case 3:
receiveEvent(1);
TRIGGER = false;
timingState = 0;
break;
}
}
//================================================================================================//
//===================================HEARTBEAT MODULE=============================================//
//================================================================================================//
unsigned long HB_LastTime = 0;
byte DP_ON_OFF;
void HeartBeatMod() {
if (((long)(currentTime - HB_LastTime)) >= 500) {
DP_ON_OFF = Characters[5];
}
if (((long)(currentTime - HB_LastTime)) >= 1000) {
DP_ON_OFF = Characters[11];
HB_LastTime = millis();
}
}
//================================================================================================//
//===================================BIT BANGING MODULE===========================================//
//================================================================================================//
#define LATCH 13
#define CLOCK 12
#define DATA 8
void bitBang(unsigned char b) {
for (int a = 0; a < 8; a++) {
if ((b >> a) & (0x01)) {
digitalWrite(DATA, HIGH);
}
else {
digitalWrite(DATA, LOW);
}
digitalWrite(CLOCK, HIGH);
digitalWrite(CLOCK, LOW);
}
digitalWrite(LATCH, HIGH);
digitalWrite(LATCH, LOW);
}
//================================================================================================//
//==================================RGB LIGHTS====================================================//
//================================================================================================//
int RGBLastTime;
void RGB(int R, int G, int B) {
analogWrite(RED, R);
analogWrite(GREEN, G);
analogWrite(BLUE, B);
}
void ColorFade() {
Serial.println(i);
if (!fade) {
if (((long)(currentTime - RGBLastTime)) > 4) {
i++;
if (i == 255) {
fade = true;
}
RGBLastTime = millis();
}
}
if (fade) {
if (((long)(currentTime - RGBLastTime)) > 4) {
i--;
if (i == 0) {
fade = false;
}
RGBLastTime = millis();
}
}
}
//================================================================================================//
//===================================ACCELERMOTERE MODULE=========================================//
//================================================================================================//
#define MPU_ADDRESS 0x68
int aX, aY, aZ;
int tempL, tempH, tempOut;
float mpuTemp;
void AccelerometerModule() {
//READING THE ACCELEROMETER DATA
Wire.beginTransmission(0x68);
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission();
Wire.requestFrom(MPU_ADDRESS, 6, true); // request a total of 6 registers
aX = Wire.read() << 8 | Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
aY = Wire.read() << 8 | Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
aZ = Wire.read() << 8 | Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Wire.beginTransmission(MPU_ADDRESS); //Start communication with the MPU-6050.
Wire.write(0x6B); //We want to write to the PWR_MGMT_1 register (6B hex).
Wire.write(0x00); //enable temp sensor
Wire.endTransmission();
Wire.beginTransmission(MPU_ADDRESS);
Wire.write(0x41);
Wire.endTransmission();
//Wire.beginTransmission(MPU_ADDRESS);
Wire.requestFrom(MPU_ADDRESS, 2, true);
tempH = Wire.read() << 8 | Wire.read();
tempL = Wire.read() << 8 | Wire.read();
tempOut = (tempH | tempL);
mpuTemp = (tempOut / 340.00) + 36.53;
// if (aX > 15000) {
// data = 'U'; // LANDSCAPE
// }
// if (aX < -13000) {
// data = 'L'; // UPSIDEDOWN
// }
// if (aY > 14000) {
// data = 'l'; // ROTATED RIGHT
// }
// if (aY < -14000) {
// data = 'R'; // ROTATED LEFT
// }
// if (aZ > 11000) {
// data = 'F'; // FLAT
// }
// if (aZ < -18000) {
// data = 'B'; // BASE
// }
}
//================================================================================================//
//===================================ON OFF MODULE SORTING=========================================//
//================================================================================================//
bool Equal = false, Set1 = false, Set2 = false, Maintenance = false, Crossing = false, Racing = false,
ledOFF = false, Amber = false, Blue = false, Green = false, Red = false;
void sortingModule() {
//----------------------------------- Traffic Lights ------------------------
if (data == 0x61) {
TrafficPriority(true);
Equal = true;
Set1 = Set2 = Maintenance = Crossing = Racing = false;
}
if (data == 0x62) {
TrafficPriority(true);
Set1 = true;
Equal = Set2 = Maintenance = Crossing = Racing = false;
}
if (data == 0x63) {
TrafficPriority(true);
Set2 = true;
Set1 = Equal = Maintenance = Crossing = Racing = false;
}
if (data == 0x64) {
TrafficPriority(false);
Crossing = true;
Set1 = Set2 = Maintenance = Equal = Racing = false;
}
if (data == 0x65) {
TrafficPriority(false);
Maintenance = true;
Set1 = Set2 = Equal = Crossing = Racing = false;
}
if (data == 0x66) {
TrafficPriority(false);
Racing = true;
Set1 = Set2 = Maintenance = Crossing = Equal = false;
}
//----------------------------------- RGB Lights ------------------------
if (data == 0x67) {
RGB(0, 0, 0);
Blue = Green = Red = Amber = false;
}
if (data == 0x68) {
Amber = true;
Blue = Green = Red = false;
}
if (data == 0x69) {
Blue = true;
Amber = Green = Red = false;
}
if (data == 0x6A) {
Green = true;
Blue = Amber = Red = false;
}
if (data == 0x6B) {
Red = true;
Blue = Green = Amber = false;
}
}
//================================================================================================//
//====================================MULTIFUNCTIONAL TRAFFIC LIGHTS MODULES======================//
//================================================================================================//
#define LEDS_OFF B00000000
#define LR B10000000//PIN7 R
#define LY B01000000//PIN6 Y
#define LG B00100000//PIN5 G
#define RG B00010000//PIN4 GG
#define RY B00001000//PIN3 YY
#define RR B00000100//PIN2 RR
//==============================BARRIER CROSSING=====================================
int T_barrierCrossing[] = { 5000, 500, 500, 500 };
const byte L_barrierCrossing[] = { LY | RY, LR | RR, LR, RR };
unsigned long mlastTime, clastTime, cArrayCounter;
//===============================================================================================//
int arrayCounter = 0, arrayCounter1 = 0;
unsigned long LS1, LS2, LS3;
const byte LightsSet1[] = { LY, LR, LR | LY, LG, LY, LR, LR, LR, LR };
const byte LightsSet2[] = { RY, RR, RR, RR, RR, RR, RR | RY, RG, RY };
int T_SET1[] = { 0, 2, 1, 1, 5, 1, 1, 1, 3, 1 };
int T_SET2[] = { 0, 2, 1, 1, 5, 1, 1, 1, 3, 1 };
void TrafficPriority(bool tfLights) {
if (tfLights) {
if (((long)(currentTime - LS1) > T_SET1[arrayCounter] * 1000)) {
PORTD = LightsSet1[arrayCounter] | LightsSet2[arrayCounter1];
LS1 = millis();
arrayCounter = (arrayCounter + 1);
if (arrayCounter >= 8) {
arrayCounter = 0;
}
}
if (((long)(currentTime - LS2) > T_SET2[arrayCounter1] * 1000)) {
PORTD = LightsSet2[arrayCounter1] | LightsSet1[arrayCounter];
LS2 = millis();
arrayCounter1 = (arrayCounter1 + 1);
if (arrayCounter1 == 8) {
arrayCounter1 = 0;
}
}
}
}
//--------------------------------------------------Racing Lights-------------------------------//
#define r_idle 0
#define r_racing 1
#define r_finished 2
#define r_aborted 3
#define r_redflagged 4
int racing_aCounter, racingState;
unsigned long r_lastTime;
int r_Random = random(2, 6);
bool racingCount = false;
int r_Timing[] = {0, 1000, 1000, 1000, 1000, (r_Random * 1000) , 2000 , 500 , 500 };
const byte r_lightSet[] = {LR , LR | LY , LR | LY | LG , LR | LY | LG | RR ,
LR | LY | LG | RR | RY , LEDS_OFF , LG | RG
};
void racingLights() {
//Display the letter F at all times whiles racing module is active.
bitBang(Characters[4] | DP_ON_OFF);
switch (racingState) {
case r_idle:
//Whilst in idle state all leds off;
PORTD = LEDS_OFF;
//A press of switch 1 will jump to racing state;
if (Switch_1) {
racing_aCounter = 0;
racingState = r_racing;
}
break;
case r_racing:
//The code for lights turning on in sequence
if (((long)(currentTime - r_lastTime) > r_Timing[racing_aCounter])) {
r_Random = random(2, 6);
PORTD = r_lightSet[racing_aCounter];
r_lastTime = millis();
racing_aCounter = racing_aCounter + 1;
if (racing_aCounter == 8) {
//When lights are finished set them to green and jump to finished state;
PORTD = LG | RG;
racingState = r_finished;
}
}
//If switch 1 is pressed and the lights arent upto green yet jump to aborted state;
if (Switch_1 && racing_aCounter <= 5) {
racingState = r_aborted;
}
break;
case r_finished:
//Both green LEDS always on whilst in the finished state
PORTD = LG | RG;
//When switch 1 is pressed, jump to redflagged state;
if (Switch_1) {
racingState = r_redflagged;
}
//When switch 2 is pressed jump to idle state;
else if (Switch_2) {
racingState = r_idle;
}
break;
case r_aborted:
//Whilst in aborted state, turn both yellow leds of and on for 0.5s;
if (((long)(currentTime - mlastTime) >= 500)) {
PORTD = LY | RY;
}
if (((long)(currentTime - mlastTime) >= 1000)) {
PORTD = LEDS_OFF;
mlastTime = millis();
}
//When switch 2 is presesd jump to idle state;
if (Switch_2) {
racingState = r_idle;
}
break;
case r_redflagged:
//Whilst in the redflagged state both red leds on, a press of switch 2 will jump to idle state;
PORTD = RR | LR;
if (Switch_2) {
racingState = r_idle;
}
break;
}
}
//--------------------------------------------------Barrier Crossing-------------------------------//
#define b_idle 0
#define b_trainsPassing 1
int barrierState;
void barrierCrossing() {
//Whilst this module is active, display b on the 7seg dsp;
bitBang(Characters[2] | DP_ON_OFF);
switch (barrierState) {
case b_idle:
//Whilst in this state, all leds off, a press of switch 1 will jump to trainsPassing state;
PORTD = LEDS_OFF;
if (Switch_1) {
barrierState = b_trainsPassing;
Trains = Trains + 1;
}
break;
case b_trainsPassing:
PORTD = L_barrierCrossing[cArrayCounter];
if ((long)(currentTime - clastTime) >= T_barrierCrossing[cArrayCounter]) {
cArrayCounter = cArrayCounter + 1;
clastTime = millis();
if (cArrayCounter == 4) {
cArrayCounter = 2;
}
}
if (Switch_1) {
Trains = Trains + 1;
}
if (Switch_2 && cArrayCounter >= 1) {
Trains = Trains - 1;
}
else if (Trains == 0) {
cArrayCounter = 0;
barrierState = b_idle;
}
break;
}
}
void setup() { //-----------------------------------SETUP----------------------------------------//
////////////////////////////////////////////////////////////////////
leaveHigh(GRANTED);
TRIGGER = false;
STATE = 0;
timingState = 0;
Wire.begin(8); /* join i2c bus with address 8 */
Wire.onReceive(receiveEvent); /* register receive event */
Wire.onRequest(requestEvent); /* register request event */
/////////////////////////////////////////////////////////////////////
pinMode(DATA, OUTPUT);
pinMode(LATCH, OUTPUT);
pinMode(CLOCK, OUTPUT);
DDRD |= B11111100;
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
Serial.begin(9600);
pinMode(RED, OUTPUT);
pinMode(BLUE, OUTPUT);
pinMode(GREEN, OUTPUT);
}
void loop() { //-----------------------------------LOOP----------------------------------------//
currentTime = millis(); // Main track of time used in all modules
FSM();
switchOne();
switchTwo();
HeartBeatMod();
bitBang(DP_ON_OFF);
sortingModule();
if (Equal) { // Equal Priority
bitBang(Characters[3] | DP_ON_OFF);
T_SET1[4] = 5;
T_SET1[8] = 3;
T_SET2[4] = 5;
T_SET2[8] = 3;
}
if (Set1) { // Set 1 Priority
bitBang(Characters[0] | DP_ON_OFF);
T_SET1[4] = 7;
T_SET1[8] = 7;
T_SET2[4] = 5;
T_SET2[8] = 3;
}
if (Set2) { // Set 2 Priority
bitBang(Characters[1] | DP_ON_OFF);
T_SET1[4] = 5;
T_SET1[8] = 3;
T_SET2[4] = 3;
T_SET2[8] = 5;
}
if (Maintenance) { // Maintenance Mode
bitBang(Characters[6] | DP_ON_OFF); // If maintenance mode 7SEG = t.
if (((long)(currentTime - mlastTime) >= 500)) {
PORTD = LY | RY;
}
if (((long)(currentTime - mlastTime) >= 1000)) {
PORTD = LEDS_OFF;
mlastTime = millis();
}
}
if (Crossing) { // Barrier Crossing
barrierCrossing();
}
if (Racing) {
racingLights();
}
//----------------------------------- RGB Lights ------------------------
if (Amber) {
ColorFade();
RGB(i, i / 10, 0);
}
if (Blue) {
ColorFade();
RGB(0, 0, i);
}
if (Green) {
ColorFade();
RGB(0, i, 0);
}
if (Red) {
ColorFade();
RGB(i, 0, 0);
}
//AccelerometerModule();
//Serial.println(mpuTemp);
Wire.beginTransmission(0x69); //Start communication with the MPU-6050.
Wire.write(0x6B); //We want to write to the PWR_MGMT_1 register (6B hex).
Wire.write(0x00); //enable temp sensor
Wire.endTransmission();
//----pointing temp sensor-----------------
Wire.beginTransmission(0x69);
Wire.write(0x41); //pointing Temp_Out_High Reg
Wire.endTransmission();
Wire.requestFrom(0x69, 2); //two-byte temp data from Temp_H and Temp_L
byte x1 = Wire.read();
byte x2 = Wire.read();
int x = (int)(x1<<8)|(int)x2;
//------compute temp from x-----
float mpuTemp = (float)(x/340.0 + 36.53); //formula from data sheets
Serial.print("Temp = ");
Serial.print(mpuTemp, 2); //2-digit after decimal point
Serial.println(" degC");
delay(1000);
}