/*****************************************************************************************
This project was developed and produced by Steve Barth(2021).
This is the main controller for the dosimetric access gate.
The system has an esp32-based microcontroller that displays instructions on a 320x240-pixel color tft display.
The controller has a measurement time display and a corresponding light and sound signal.
The measurement is started by an ultrasonic sensor, after measuring for 5 seconds, the number of pulses received
from the Geiger counters connected to it is displayed.
(Version 4.02 with NTI logo, non-digital number, ultrasonic sensor)
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [ ] 4.2% (used 13728 bytes from 327680 bytes)
Flash: [=== ] 32.4% (used 424258 bytes from 1310720 bytes)
******************************************************************************************/
/********* DECLARATIONS & CONSTANS & PIN CONNECTING *************/
#include "nti_inv.h" // NTI logo file
#include <Arduino.h> // only for VS Code
#include <SPI.h> // Serial Peripheral Interface (SPI) library
#include <TFT_eSPI.h> // tft display library v.2.3.87
#include <Tone32.h> // sound library
#include <Wire.h> // TWI/I2C library
#include <pitches.h> // sounds definition
// connections
#define BUZZER_CHANNEL 0 // use 0 PWM channel GPIO36
#define ONBOARD_LED 2 // onboard (BLUE)led pin GPIO2
#define Light_Green 12 // connect green led (meas: OK) GPIO12
#define BUZZER_PIN 13 // buzzer connect GPIO13
#define Light_Red 14 // connect red led (meas: ERROR) GPIO14
#define UH_start 15 // connect UH sensor start input GPIO15
#define TFT_LED 22 // tft display backlite pin GPIO22
#define Light_Yellow 26 // connect yellow led (UH sensor: normal) GPIO26
#define Light_Blue 27 // connect blue led (UH sensor: sensing person) GPIO27
#define trig 32 // UH sensor trigger signal GPIO32
#define echo 33 // UH sensor echo signal GPIO33
// Connections for the TFT display
#define _rst 5 // goes to TFT RESET GPIO5
#define _dc 16 // goes to TFT DC GPIO16
#define _cs 17 // goes to TFT CS GPIO17
#define _sclk 18 // goes to TFT SCK/CLK GPIO18
#define _mosi 23 // goes to TFT MOSI GPIO23
TFT_eSPI tft = TFT_eSPI(); // Use hardware SPI
// start settings
const int pulse_input = 21; // This is all counting pulse input pin
const int intruderDistance = 45; // the minimum distance cm upto which the sensor is able to sense any object (GM gate 45cm)
unsigned short int duration; // time taken by the pulse to return back orig float
unsigned short int distance; // oneway distance travelled by the pulse orig float
bool Error; // data type for error state
long startTime; // data type for starting time
int pulse; // variable pulse count
int timerMode = 0; // data type for timer mode
int count_mode = 0; // set start counting mode
/*
LCD color def. RGB 5:6:5 bit Converter
http://greekgeeks.net/#maker-tools_convertColor exp: Black= 5:6:5(0x0000), 8:8:8(0x000000), {HTML ccs(#000000)}
http://www.barth-dev.de/online/rgb565-color-pic
*/
/**********************************************/
/**************** SETUP ***************/
/**********************************************/
void setup()
{
// blue led program start indicating
pinMode(ONBOARD_LED, OUTPUT); // Program start indication
digitalWrite(ONBOARD_LED, LOW); // turn the Blue LED off (LOW is the voltage level)
digitalWrite(ONBOARD_LED, HIGH); // turn the Blue LED on (HIGH is the voltage level)
delay(50); // wait for a milisecond
digitalWrite(ONBOARD_LED, LOW); // turn the Blue LED off (LOW is the voltage level)
delay(100); // wait for a milisecond
digitalWrite(ONBOARD_LED, HIGH); // turn the Blue LED on (HIGH is the voltage level)
delay(50); // wait for a milisecond
digitalWrite(ONBOARD_LED, LOW); // turn the Blue LED off (LOW is the voltage level)
// tft display start
pinMode(TFT_LED, OUTPUT); // LCD backlite
digitalWrite(TFT_LED, LOW); // turn the LED off (LOW is the voltage level)
tft.begin(); // tft display initialising
tft.setRotation(3); // LCD view direction ( 0 & 2 Portrait. 1 & 3 landscape)
tft.fillScreen(ILI9341_BLACK); // full screen set background black (reset screen)
// Starting picture
tft.setSwapBytes(true); // set swap byte
tft.pushImage(1, 0, 319, 240, logo_inv); // display nti logo
delay(200); // pause
digitalWrite(TFT_LED, HIGH); // turn the backlite on (HIGH is the voltage level)
delay(1500); // pause
tft.drawRoundRect(0, 0, 320, 240, 5, ILI9341_ORANGE); // white frame 1
delay(150); // pause
tft.drawRoundRect(1, 1, 318, 238, 4, ILI9341_ORANGE); // white frame 2
delay(150); // pause
tft.fillRoundRect(2, 2, 316, 234, 3, ILI9341_NAVY); // set background color
delay(150); // pause
tft.setFreeFont(&Orbitron_Light_24); // font type
tft.setCursor(80, 76); // set cursor
tft.setTextSize(1); // font size
tft.setTextColor(ILI9341_WHITE); // font color (white)
tft.print("Created by:"); // subtitle
delay(1000); // pause
tft.setCursor(35, 133); // set cursor
tft.print("Steve Barth 2021"); // subtitle
delay(1200); // pause
tft.setFreeFont(&FreeSans12pt7b); // font type
tft.setTextColor(ILI9341_ORANGE); // font color (yellow)
tft.setCursor(93, 194); // set cursor
tft.print("version 4.02"); // subtitle
delay(1400); // pause
tft.fillScreen(ILI9341_BLACK); // full screen set background black (reset screen)
delay(100); // pause
// settings measure proced start & state light & pulse input, output
pinMode(pulse_input, INPUT_PULLUP); // set input pin
pinMode(UH_start, INPUT_PULLUP); // setting pinmode with pullup resistor
pinMode(trig, OUTPUT); // set trigger pin output
pinMode(echo, INPUT); // set echo pin input
pinMode(Light_Green, OUTPUT); // setting pinmode output for green led
pinMode(Light_Red, OUTPUT); // setting pinmode output for red led
pinMode(Light_Yellow, OUTPUT); // setting pinmode output for yellow led
pinMode(Light_Blue, OUTPUT); // setting pinmode output for blue led
digitalWrite(Light_Green, LOW); // green led off
digitalWrite(Light_Red, LOW); // red led off
digitalWrite(Light_Yellow, LOW); // yellow led off
digitalWrite(Light_Blue, LOW); // blue led off
// display white frames
tft.drawRoundRect(2, 2, 316, 236, 3, ILI9341_WHITE); // white frame 3
delay(150); // pause
tft.drawRoundRect(3, 3, 314, 234, 2, ILI9341_WHITE); // white frame 4
delay(150); // pause
tft.drawRoundRect(4, 4, 312, 232, 1, ILI9341_WHITE); // white frame 5
delay(150); // pause
}
/*********************************************/
/**************** LOOP ***************/
/*********************************************/
void loop()
{
// COUNTING OF DETECTING PULSES
if (digitalRead(pulse_input) != count_mode) // when a pulse is received
{
count_mode = 1; // start counting
pulse++; // increase the number
}
if (digitalRead(pulse_input) == 0) // if no pulse input
{
count_mode = 0; // stop counting
}
delay(1); // Delay for stability.
// STAND BY STATUS
Error = 0; // errormode status 0
if (timerMode == 0) // if timermode "0" status
{
pulse = 0; // all detected pulse reset
tft.setFreeFont(&tahomabd29pt7b); // font type
tft.setCursor(50, 100); // cursor moving
tft.setTextSize(1); // set font size
tft.setTextColor(ILI9341_CYAN); // font colortft.setTextColor(ILI9341_INVON);
tft.print("PLEASE"); // subtitle 32mm x 6mm
delay(200); // pause
tft.setCursor(84, 179); // cursor moving
tft.print("NEXT"); // subtitle 23mm x 6mmtft.setTextColor(ILI9341_INVOFF);
}
// WHEN A START SIGNAL RECEIVED
if (digitalRead(UH_start) == LOW) // if IR sensor add start impuls (high-low-high)
{
delay(300); // delay for no bounce
startTime = millis(); // starttime settings
tft.fillRect(7, 7, 306, 226, ILI9341_BLACK); // clears the full screen (reset screen)
tft.drawRoundRect(10, 10, 300, 90, 18, ILI9341_WHITE); // white long frame 1
tft.drawRoundRect(11, 11, 298, 88, 17, ILI9341_WHITE); // white long frame 2
tft.fillRoundRect(13, 13, 294, 84, 15, ILI9341_RED); // fill white frame
tft.setFreeFont(&tahomabd29pt7b); // font type
tft.setCursor(58, 75); // cursor moving
tft.setTextSize(1); // font size
tft.setTextColor(ILI9341_WHITE); // font color (white)
tft.print("S T O P"); // subtitle
timerMode++; // increase the timermode status
}
// START TIME OF THE MEASUREMENT
if (timerMode == 1) // if timermode status 1
{
tft.setFreeFont(&FreeSans12pt7b);
tft.setCursor(13, 142); // cursor position
tft.setTextSize(1); // setting text size
tft.setTextColor(ILI9341_YELLOW); // text color
tft.print("Measurements, please wait!"); // text on the display
tft.setTextFont(6); // set font see User_Setup.h
tft.setCursor(74, 174); // cursor position
tft.setTextSize(1); // set font size
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // text color
tft.print((millis() - startTime) / 1000.0); // print start time
tft.setFreeFont(&FreeSans18pt7b); // set font
tft.setTextSize(1); // set font size
tft.setCursor(192, 210); // cursor position
tft.setTextColor(ILI9341_WHITE); // text color
tft.print("sec."); // text on the display
if ((millis() - startTime) >= 5000.0) // stoptime max.: 5 sec
{
timerMode++; // increase the timermode status
}
}
// IF NOT ENOUGH TIME FOR MEASUREMENT
else if ((20 <= (millis() - startTime)) && ((millis() - startTime) <= 4980) && timerMode >= 1) // if time between 0,02s-4,98s
{
digitalWrite(Light_Red, HIGH); // red led on
Error = 1; // errormode status 1
}
// WHEN THE MEASUREMENT TIME EXPIRES
if (timerMode > 1) // if timermode status bigger 1
{
if (Error == 0) // if errormode status 0
{
tft.fillRect(7, 103, 306, 130, ILI9341_BLACK); // clears the bottom of the screen
tft.setFreeFont(&FreeSerifBold24pt7b); // font type
tft.setCursor(98, 180); // cursor moving
tft.setTextSize(1); // font size
tft.setTextColor(ILI9341_GREEN); // font color
tft.print("Done!"); // subtitle
delay(500); // pause
tft.fillRect(7, 103, 306, 130, ILI9341_BLACK); // clears the bottom of the screen (set background black)
tft.setFreeFont(&FreeSansBold12pt7b); // font type
tft.setCursor(44, 155); // counts cursor position
// tft.setCursor(65, 155); // CPM cursor position
tft.setTextSize(1); // setting text size
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // text color
tft.print("all detected counts:"); // counts on the display
// tft.print("calculated CPM:"); // CPM on the display
delay(100); // pause
tft.setTextColor(ILI9341_ORANGE, ILI9341_BLACK); // text color
tft.setTextFont(6); // font type
tft.setCursor(94, 174); // cursor moving (max 3 digit number OK.)
tft.setTextSize(1); // setting text size
char string[6]; // max 6 digit wide string
dtostrf(pulse / 2, 5, 0, string); // counts convering string (_//_ = 2 counts !!)
// dtostrf((pulse / 2) * 12, 5, 0, string); // CPM convering string (60sec => meas 5sec, pulse edge * 12)
tft.printf(string); // data string on the display
delay(400); // pause
tft.fillRect(7, 7, 306, 96, ILI9341_BLACK); // clears the top of the screen (set background black)
tft.drawRoundRect(10, 10, 300, 90, 18, ILI9341_WHITE); // white long frame 1
tft.drawRoundRect(11, 11, 298, 88, 17, ILI9341_WHITE); // white long frame 2
tft.fillRoundRect(13, 13, 294, 84, 15, ILI9341_GREEN); // fill white frame
digitalWrite(Light_Green, HIGH); // green led on
tft.setFreeFont(&FreeSerifBold24pt7b); // set font
tft.setCursor(36, 73); // cursor moving
tft.setTextSize(1); // font size
tft.setTextColor(ILI9341_BLACK); // font color
tft.print("You can GO"); // subtitle "YOU CAN GO"
delay(400); // pause
tone(13, NOTE_A5, 100, 0); // sound on (BUZZER_PIN, 800Hz, 80ms, BUZZER_CHANNEL)A5
tone(13, NOTE_CS6, 100, 0); // sound on (BUZZER_PIN, 1kHz, 80ms, BUZZER_CHANNEL)C6
tone(13, NOTE_FS6, 180, 0); // sound on (BUZZER_PIN, 1.2kHz, 100ms, BUZZER_CHANNEL)E6
noTone(13, 0); // sound off (BUZZER_PIN, BUZZER_CHANNEL)
}
// IF THEY DO NOT WAIT FOR THE MEASUTEMENT TIME
if (Error == 1) // if errormode status 1
{
tft.setFreeFont(&FreeSerifBold24pt7b);
tft.setCursor(73, 142); // cursor position
tft.setTextSize(1); // setting text size
tft.setTextColor(ILI9341_YELLOW); // text color
tft.print("FAULT!"); // text on the display red
tft.setCursor(64, 185); // cursor position
tft.print("PLEASE"); // text on the display
tft.setCursor(71, 226); // cursor position
tft.print("AGAIN!"); // text on the display
tone(13, NOTE_C3, 700, 0); // Plays 131Hz tone for 0.7 seconds
noTone(13, 0); // sound off
}
delay(700); // 0,7 seconds delay before clear
digitalWrite(Light_Red, LOW); // red led off
digitalWrite(Light_Green, LOW); // green led off
tft.fillRect(7, 7, 306, 226, ILI9341_BLACK); // clears the full screen (reset screen)
timerMode = 0; // set timermode status 0
}
}
//! Attention!! Don't forget to save the TFT_eSPI/User_Setup.h configuration file !!
//! If you install a font in the TFT_eSPI/Font/Custom folder, don't forget to register in the TFT_eSPI/User_Setups/User_Custom_Font.h file!
/***************** END of LOOP **********************/