Making the ESP32 Computer [SOLVED]

Hi everyone!

I'm new to the forum and excited to be here. I've been working on an ambitious project to create a multi-functional computer using Arduino. It's been quite a journey, and the project is still a work in progress.

I've recently decided to transition the project to use an ESP32 because of its Bluetooth capabilities, which opens up a lot of possibilities for control and connectivity.

Below is my old program code. It's not perfect, but I gave it my all. Since it's quite long, remember that it's designed for a multi-functional computer. I would love to hear your thoughts on it and any advice you might have!

/*
 * Project: Arduino Computer 
 * Author: Logan.W. (LoganTheEngineer)
 * Description: This code is part of an Arduino-based computer system using the ATmega2560 microcontroller.
 *              It includes functionalities for environmental sensing, motion detection, distance measurement,
 *              remote control handling, display management, and more.
 * 
 * computer: "LoganMultiFunctionComputer"
 *
 * version: 0.0.1.
 *
 * processor: ATMEGA2560/ATMEGA1280. it doesn't matter, as long as they have lots of pins and storage.
 *
 * development board: Arduino MEGA2560/Arduino MEGA. it doesn't matter, as long as they have lots of pins and storage.
 *
 * UART_processor: MEGA16U2.
 *
 * clockSpeed: 16MHz.
 *
 * MAX_overClockSpeed: 24MHz.
 *
 * COM_address: 4.
 *
 * cores: 4.
 *
 * pins: 70. (no shift regiaters are included in this calculation, this calculation includes ALL Arduino pins.)
 *
 * max pin current draw: 40mA.
 *
 * max voltage: 12V though power adapter, this is not recommended. 5V though vin/USB, however is recommended.
 *
 * max current: 500mA though power adapter, which can cause significant heat, this is not recommended. 1.5A though vin/USB, however is recommended.
 *
 * CPU board max current to CPU: 200mA.
 *
 * Disclaimer: This code, part of the "LoganMultiFunctionComputer" project, is created by Logan W. (LoganTheEngineer)
 * for educational and personal use only. It is not affiliated with any commercial company or official entity. 
 * Any resemblance to actual company names, logos, or trademarks is purely coincidental and unintentional. 
 * Components and parts used in this system may be derived from various official manufacturers; however, 
 * their inclusion does not imply any endorsement or association with LoganTheEngineer. LoganTheEngineer 
 * assumes no responsibility for any misuse of logos or other intellectual property.
 */

#if defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__)
// Code specific to the Arduino MEGA2560/MEGA
#pragma message("Correct microcontroller. Arduino MEGA/MEGA2560 is reqiured for direct port manipulation, storage, and computing speeds.")
#warning The computer code is currently under development, if any issues happen to occur, please contact Logan.
#warning WARNING: All of this new stuff is all experimental so it might have some issues.
#warning Please adjust the interrupt and ISR if it does not work, the interrupt and ISR may vary from microcontroller to microcontroller.
// now run rest of code since there's no error.
#else
#error "This code is intended for the Arduino MEGA2560/MEGA with ATmega2560/ATmega1280 microcontroller. Please select the correct board in your IDE."
#endif
#include <EEPROM.h> // the required libries.
#include <Wire.h>
#include <dht_nonblocking.h>
#include <IRremote.hpp>
#include "MPU6050.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OUTPUT_PULLHIGH 0x3



enum ColorFadeConstants{FADE, CYCLE};                                       
enum SSD1306_constants{SCREEN_WIDTH = 128, SCREEN_HEIGHT = 64, OLED_RESET = -1, SCREEN_ADDRESS = 0x3C};
enum pedometer_distanceTypes{MILES_PER_HOUR, METERS_PER_SECOND, KILOMETERS_PER_HOUR, FEET_PER_SECOND};
enum pedometer_energyTypes{CALORIES, KILOCALORIES, JOULES, KILOJOULES};
enum ColorList{COLOR_BY_BLACK, COLOR_BY_LIGHT_RED, COLOR_BY_RED, COLOR_BY_DARK_RED, COLOR_BY_LIGHT_GREEN,COLOR_BY_GREEN, COLOR_BY_DARK_GREEN,
COLOR_BY_LIGHT_BLUE, COLOR_BY_BLUE, COLOR_BY_DARK_BLUE, COLOR_BY_YELLOW, COLOR_BY_CYAN, COLOR_BY_MAGENTA, COLOR_BY_ORANGE, COLOR_BY_DARK_ORANGE, 
COLOR_BY_GOLD, COLOR_BY_LIME, COLOR_BY_PURPLE, COLOR_BY_PINK, COLOR_BY_DEEP_PINK, COLOR_BY_INDIGO, COLOR_BY_VIOLET, COLOR_BY_DARK_VIOLET,
COLOR_BY_WHITE};
enum UsbSlowCharger{USB_SLOW_CHARGER_PIN = 4};
enum recorder{RECORD, PLAY, MAX_REC_ADDRESS = 2008, USED_LOWER_NUMBER_ADDRESSES = 8};
enum MPU6050_compass{NORTH, NORTH_WEST, WEST, SOUTH_WEST, SOUTH, SOUTH_EAST, EAST, NORTH_EAST};
enum rebootPin{resetTrigPin = 5};
enum months{Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec};
enum tempTypes{CELSIUS, FAHRENHEIT, KELVIN};
enum clockTypes{AM, PM};
enum DHT_info{DHT_PIN = A0, DHT_TYPE = DHT_TYPE_11};
enum ultrasonicDistanceSensorPins{ECHO_PIN = 8, TRIG_PIN = 2};
enum distanceTypes{MM, CM, IN, FT, YD, M};
enum mainShiftRegisterInPins{MAIN_DATA_PIN = 10, MAIN_CLOCK_PIN = 12, MAIN_LATCH_PIN = 11};
enum DisableByResetingValueBackToZero{DISABLE};
//daisy-chain shift registers together to get a higher-bit shift register.
enum mainShiftRegisterBits{MAIN_SHIFT_REGISTER_8_BIT = 8, MAIN_SHIFT_REGISTER_16_BIT = 16, MAIN_SHIFT_REGISTER_24_BIT = 24,
MAIN_SHIFT_REGISTER_32_BIT = 32, MAIN_SHIFT_REGISTER_40_BIT = 40, MAIN_SHIFT_REGISTER_48_BIT = 48, MAIN_SHIFT_REGISTER_56_BIT = 56,
MAIN_SHIFT_REGISTER_64_BIT = 64, MAIN_SHIFT_REGISTER_72_BIT = 72, MAIN_SHIFT_REGISTER_80_BIT = 80, MAIN_SHIFT_REGISTER_88_BIT = 88};
enum IR_remoteButtonMap{POWER = 0xBA45FF00, FUNC_OR_STOP = 0xB847FF00, INCREMENT_VOL = 0xB946FF00, FAST_BACK = 0xBB44FF00,
PAUSE_OR_PLAY = 0xBF40FF00, FAST_FORWARD = 0xBC43FF00, DOWN = 0xF807FF00, DECREMENT_VOL = 0xEA15FF00, UP = 0xF609FF00,
EQ = 0xE619FF00, ST_OR_REPT = 0xF20DFF00, ZERO = 0xE916FF00, ONE = 0xF30CFF00, TWO = 0xE718FF00, THREE = 0xA15EFF00,
FOUR = 0xF708FF00, FIVE = 0xE31CFF00, SIX = 0xA55AFF00, SEVEN = 0xBD42FF00, EIGHT = 0xAD52FF00, NINE = 0xB54AFF00};
enum currentMainShiftRegisterSize{MAIN_SHIFT_REGISTER_SIZE = MAIN_SHIFT_REGISTER_8_BIT};//i'm using an 8-bit shift register. how about you?
enum calculatorSettings{MULTIPLICATION, DIVISION, ADDITION, SUBTRACTION, SQUARED, CUBED, ABSOLUTE_VALUE, TO_THE_POWER_OF, REMAINDER, LOG, SIN, COS,
PERCENT, PERCENTAGE_VALUE, NUM_TO_BOOL, PERCENTAGE_TO_FBOOL};
enum IR_receiver{receiverPin = 9};
uint8_t ShiftPWMArray[8];
uint16_t ShiftToneArray[8];

MPU6050 mpu;
DHT_nonblocking DHT(DHT_PIN, DHT_TYPE);
IRrecv IR_Receiver(receiverPin);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const uint8_t degree_bitmap[] PROGMEM = {
0b00111100,
0b01000010,
0b01000010,
0b00111100,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};

const uint8_t cloud_bitmap[] PROGMEM = {
0b00011110,
0b01111110,
0b11111111,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};

const uint8_t rainy_bitmap[] PROGMEM = {
0b00011110,
0b01111110,
0b11111111,
0b00000000,
0b10001000,
0b10001000,
0b00100010,
0b00100010
};

const uint8_t snowy_bitmap[] PROGMEM = {
0b00011110,
0b01111110,
0b11111111,
0b01000000,
0b11100100,
0b01001110,
0b00000100,
0b00000000
};

const uint8_t lightning_cloud_bitmap[] PROGMEM = {
0b00111000,
0b01111100,
0b11111111,
0b11111111,
0b00010000,
0b00111100,
0b00001000,
0b00010000
};

const uint8_t sunny_bitmap[] PROGMEM = {
0b00000000,
0b10011001,
0b01011010,
0b00111100,
0b00111100,
0b01011010,
0b10011001,
0b00000000
};

const uint8_t lightbulb_bitmap[] PROGMEM = {
0b00111100,
0b11111111,
0b11111111,
0b11111111,
0b01111110,
0b00111100,
0b00111100,
0b00011000
};

const uint8_t halfBright_lightbulb_bitmap[] PROGMEM = {
0b00111100,
0b11101011,
0b10101011,
0b11010101,
0b01010110,
0b00111100,
0b00111100,
0b00011000
};

const uint8_t dark_lightbulb_bitmap[] PROGMEM = {
0b00111100,
0b11000011,
0b10000001,
0b10000001,
0b01000010,
0b00111100,
0b00111100,
0b00011000
};

const uint8_t LoganComputerBootupSymbol_bitmap[] PROGMEM = {
0b00000000,
0b10000000,
0b10011100,
0b10100000,
0b10100000,
0b10011100,
0b10000000,
0b11111000
};

const uint8_t up_arrow_bitmap[] PROGMEM = {
0b00011000,
0b00111100,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000
};

const uint8_t down_arrow_bitmap[] PROGMEM = {
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00011000,
0b00111100,
0b00011000
};

const uint8_t left_arrow_bitmap[] PROGMEM = {
0b00000000,
0b00000000,
0b01000000,
0b11111111,
0b11111111,
0b01000000,
0b00000000,
0b00000000
};

const uint8_t right_arrow_bitmap[] PROGMEM = {
0b00000000,
0b00000000,
0b00000010,
0b11111111,
0b11111111,
0b00000010,
0b00000000,
0b00000000
};

const uint8_t top_left_arrow_bitmap[] PROGMEM = {
0b11100000,
0b11000000,
0b10100000,
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001
};

const uint8_t top_right_arrow_bitmap[] PROGMEM = {
0b00000111,
0b00000011,
0b00000101,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000
};

const uint8_t bottom_left_arrow_bitmap[] PROGMEM = {
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b10100000,
0b11000000,
0b11100000
};

const uint8_t bottom_right_arrow_bitmap[] PROGMEM = {
0b10000000,
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000101,
0b00000011,
0b00000111,
};

const uint8_t white_square_bitmap[] PROGMEM = {
0b00000000,
0b01111110,
0b01111110,
0b01111110,
0b01111110,
0b01111110,
0b01111110, 
0b00000000
};

const uint8_t black_square_bitmap[] PROGMEM = {
0b11111111,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b10000001,
0b11111111
};

const uint8_t waterdrop_bitmap[] PROGMEM = {
0b00000000,
0b00001000,
0b00001000,
0b00011100,
0b00011100,
0b00111110,
0b00111110,
0b00011100
};

const uint8_t snowflake_bitmap[] PROGMEM = {
0b00000000,
0b01001001,
0b00101010,
0b00011100,
0b01110111,
0b00011100,
0b00101010,
0b01001001
};

const uint8_t flame_bitmap[] PROGMEM = {
0b00000000,
0b00000000,
0b00000000,
0b00001000,
0b00011100,
0b00111110,
0b00111110,
0b00011100
};

const uint8_t warning_bitmap[] PROGMEM = {
0b00000000,
0b00001000,
0b00010100,
0b00101010,
0b00101010,
0b01000001,
0b01001001,
0b01111111
};

const uint8_t hot_surface_bitmap[] PROGMEM = {
0b01010001,
0b10001010,
0b01010001,
0b10001010,
0b01010001,
0b10001010,
0b00000000,
0b11111111
};

const uint8_t crossed_square_bitmap[] PROGMEM = {
0b11111111,
0b11000011,
0b10100101,
0b10011001,
0b10011001,
0b10100101,
0b11000011,
0b11111111
};

const uint8_t circled_square_bitmap[] PROGMEM = {
0b11111111,
0b10000001,
0b10111101,
0b10100101,
0b10100101,
0b10111101,
0b10000001,
0b11111111
};

const uint8_t hourglass_bitmap[] PROGMEM = {
0b11111111,
0b10000001,
0b10000001,
0b01111110,
0b00111100,
0b01011010,
0b10111101,
0b11111111,
};



void setup() {
setupRebootPin(resetTrigPin);
fastPinSetup(MAIN_DATA_PIN, OUTPUT);
fastPinSetup(MAIN_CLOCK_PIN, OUTPUT);
fastPinSetup(MAIN_LATCH_PIN, OUTPUT);
// Set up Timer1
TCCR1A = _BV(WGM11); // Configure for Fast PWM mode using ICR1 as top
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // Set mode, fast PWM, and no prescaling
ICR1 = 100; // Set the top value for Timer1 (defines PWM frequency)
OCR1A = 0; // Set the compare match value for OCR1A

// Enable Timer1 compare interrupt
TIMSK1 = _BV(OCIE1A); // Enable interrupt on compare match with OCR1A
}
ISR(TIMER1_COMPA_vect) {
volatile uint8_t *MAIN_dataPinPort = portOutputRegister(digitalPinToPort(MAIN_DATA_PIN));
volatile uint8_t *MAIN_clockPinPort = portOutputRegister(digitalPinToPort(MAIN_CLOCK_PIN));
volatile uint8_t *MAIN_latchPinPort = portOutputRegister(digitalPinToPort(MAIN_LATCH_PIN));
volatile uint8_t *READ_MAIN_latchPinPort = portInputRegister(digitalPinToPort(MAIN_LATCH_PIN));
uint8_t MAIN_dataPinBit = digitalPinToBitMask(MAIN_DATA_PIN);
uint8_t MAIN_clockPinBit = digitalPinToBitMask(MAIN_CLOCK_PIN);
uint8_t MAIN_latchPinBit = digitalPinToBitMask(MAIN_LATCH_PIN);
static bool ToneprevState[MAIN_SHIFT_REGISTER_SIZE];
static bool PWM_prevState[MAIN_SHIFT_REGISTER_SIZE];
static uint8_t pwmTimer = 0;
static uint16_t toneTimer = 0;
bool pwmToggle = 0;
uint16_t period = 0;
bool toneToggle = 0;
if((*READ_MAIN_latchPinPort & MAIN_latchPinBit) != 0){
toneTimer = (toneTimer < period) ? toneTimer+1:0;
pwmTimer = (pwmTimer < 255)?pwmTimer+5:0;
*MAIN_latchPinPort &= ~MAIN_latchPinBit;
for (int i = 0; i < MAIN_SHIFT_REGISTER_SIZE; i++) {
period = (ShiftToneArray[i] == 0)?0:30000/ShiftToneArray[i];
toneToggle = (toneTimer < period / 2);
if (toneToggle != ToneprevState[i]) {
(toneToggle)?*MAIN_dataPinPort |= MAIN_dataPinBit:*MAIN_dataPinPort &= ~MAIN_dataPinBit;
*MAIN_clockPinPort |= MAIN_clockPinBit;
*MAIN_clockPinPort &= ~MAIN_clockPinBit;
ToneprevState[i] = toneToggle; // Update the previous state
}
}
*MAIN_latchPinPort |= MAIN_latchPinBit;



*MAIN_latchPinPort &= ~MAIN_latchPinBit;
for (int i = 0; i < MAIN_SHIFT_REGISTER_SIZE; i++) {
if(ShiftPWMArray[i] > 0 && ShiftPWMArray[i] < 255){
pwmToggle = (pwmTimer < ShiftPWMArray[i]);
}else{
pwmToggle = true;
}

if (pwmToggle != PWM_prevState[i]) {
(pwmToggle)?*MAIN_dataPinPort |= MAIN_dataPinBit:*MAIN_dataPinPort &= ~MAIN_dataPinBit;
*MAIN_clockPinPort |= MAIN_clockPinBit;
*MAIN_clockPinPort &= ~MAIN_clockPinBit;
PWM_prevState[i] = pwmToggle; // Update the previous state
}
}
*MAIN_latchPinPort |= MAIN_latchPinBit;
}
}

void loop() {
//do nothing for now.

}

//currently set to 8 bits.
void MainShiftRegisterWrite(uint8_t portToWrite, bool val){
volatile uint8_t *MAIN_dataPinPort = portOutputRegister(digitalPinToPort(MAIN_DATA_PIN));
volatile uint8_t *MAIN_clockPinPort = portOutputRegister(digitalPinToPort(MAIN_CLOCK_PIN));
volatile uint8_t *MAIN_latchPinPort = portOutputRegister(digitalPinToPort(MAIN_LATCH_PIN));
uint8_t MAIN_dataPinBit = digitalPinToBitMask(MAIN_DATA_PIN);
uint8_t MAIN_clockPinBit = digitalPinToBitMask(MAIN_CLOCK_PIN);
uint8_t MAIN_latchPinBit = digitalPinToBitMask(MAIN_LATCH_PIN);
static bool state[MAIN_SHIFT_REGISTER_SIZE]; //Adjust the size of the state array based on the bit of the register or number of registers.
static bool prevState[MAIN_SHIFT_REGISTER_SIZE];
state[portToWrite] = val;

*MAIN_latchPinPort &= ~MAIN_latchPinBit;
for (int i = 0; i < MAIN_SHIFT_REGISTER_SIZE; i++) {
if (state[i] != prevState[i]) {
(state[i])?*MAIN_dataPinPort |= MAIN_dataPinBit:*MAIN_dataPinPort &= ~MAIN_dataPinBit;
*MAIN_clockPinPort |= MAIN_clockPinBit;
*MAIN_clockPinPort &= ~MAIN_clockPinBit;
prevState[i] = state[i]; // Update the previous state
}
}
*MAIN_latchPinPort |= MAIN_latchPinBit;
}
bool PIR_Read(uint8_t pin, uint32_t delay) {
// delay is how long to keep alarm triggered once triggered.
static bool motionDetected = false;
static uint32_t lastMotionTime = 0;
bool currentState = digitalRead(pin);  
if (currentState && !motionDetected) {
lastMotionTime = millis();
motionDetected = true;
}
if (millis() - lastMotionTime > delay) {
motionDetected = false;
}  
return motionDetected;
}

void DHT_Read(float *temperature, float *humidity, uint8_t tempType)
{
static uint32_t timeStart;
float temp;
float humid;
timeStart = millis();
if(millis()-timeStart > 250){
if(DHT.measure(&temp, &humid)){
switch(tempType){
case CELSIUS:
*temperature = temp;
break;
case FAHRENHEIT:
*temperature = (temp*1.8)+32;
break;
case KELVIN:
*temperature = temp+273.15;
break;
default:
*temperature = temp;
}
*humidity = humid;
}
}
}

double ReadDistance(uint8_t OutputPin, uint8_t InputPin, bool state, uint8_t convertTo, uint32_t pulse_us){
volatile uint8_t *pulseOutPort = portOutputRegister(digitalPinToPort(OutputPin));
volatile uint8_t *pulseInPort = portInputRegister(digitalPinToPort(InputPin));
uint8_t PulseInBit = digitalPinToBitMask(InputPin);
uint8_t PulseOutBit = digitalPinToBitMask(OutputPin);
uint32_t timeout = 40000;
uint32_t pulseStart = micros();
uint32_t startMicros = micros();
uint32_t pulseStartMicros;
uint32_t pulseEndMicros;
uint32_t pulsePeriod;
const double speedOfSoundCmPerSec = 34350.0; // Speed of sound in cm/s
const double CF = speedOfSoundCmPerSec / 1000000.0 / 2.0;
double distance;
while(micros()-pulseStart < pulse_us){
*pulseOutPort |= PulseOutBit;
*pulseOutPort &= ~PulseOutBit;
}
while (((*pulseInPort & PulseInBit) != 0) != state && micros() - startMicros <= timeout);
pulseStartMicros = micros();
while (((*pulseInPort & PulseInBit) != 0) == state && micros() - pulseStartMicros <= timeout);
pulseEndMicros = micros();
if(pulseEndMicros - pulseStartMicros <= timeout){
pulsePeriod = pulseEndMicros - pulseStartMicros;
distance = pulsePeriod*CF; // Calculate distance in cm
switch(convertTo){
case MM:
distance *= 10.0; // Convert cm to mm
break;
case IN:
distance /= 2.54; // Convert cm to inches
break;
case FT:
distance /= 30.48; // Convert cm to feet
break;
case YD:
distance /= 91.44; // Convert cm to yards
break;
case M:
distance /= 100.0; // Convert cm to meters
break;
}
return distance;
}else{
return(NAN);
}
}

uint8_t ReadLight(uint8_t pin){
uint8_t output;
output = 100*(analogRead(pin)/1023.0);
return(output);
}
uint8_t ReadNCVNS(uint8_t pin){ //Non-Contact Volage / Noise sensor, thus the name NCVNS.
static uint8_t output;
uint16_t input;
input = analogRead(pin);
output = 0.01*input+(1.0-0.01)*output;
return(100*(output/1023));
}
void IR_Remote(bool *powerButtonIsPressed, bool *funcOrStopButtonIsPressed, bool *incrementVolButtonIsPressed, bool *fastBackButtonIsPressed, 
bool *pauseOrPlayButtonIsPressed, bool *fastForwardButtonIsPressed, bool *downButtonIsPressed, bool *decrementVolButtonIsPressed,
bool *upButtonIsPressed, bool *EQ_buttonIspressed, bool *stOrReptButtonIspressed, bool *zeroButtonIspressed, bool *oneButtonIspressed,
bool *twoButtonIspressed, bool *threeButtonIspressed, bool *fourButtonIspressed, bool *fiveButtonIspressed, bool *sixButtonIspressed,
bool *sevenButtonIspressed, bool *eightButtonIspressed, bool *nineButtonIspressed){

//assign all variables to zero before we begin.
*powerButtonIsPressed = 0;
*funcOrStopButtonIsPressed = 0;
*incrementVolButtonIsPressed = 0;
*fastBackButtonIsPressed = 0;
*pauseOrPlayButtonIsPressed = 0;
*fastForwardButtonIsPressed = 0;
*downButtonIsPressed = 0;
*decrementVolButtonIsPressed = 0;
*upButtonIsPressed = 0;
*EQ_buttonIspressed = 0;
*stOrReptButtonIspressed = 0;
*zeroButtonIspressed = 0;
*oneButtonIspressed = 0;
*twoButtonIspressed = 0;
*threeButtonIspressed = 0;
*fourButtonIspressed = 0;
*fiveButtonIspressed = 0;
*sixButtonIspressed = 0;
*sevenButtonIspressed = 0;
*eightButtonIspressed = 0;
*nineButtonIspressed = 0;

if(IR_Receiver.available()){
switch (IR_Receiver.decodedIRData.decodedRawData){
case POWER: *powerButtonIsPressed = 1; break;
case FUNC_OR_STOP:*funcOrStopButtonIsPressed = 1; break;
case INCREMENT_VOL: *incrementVolButtonIsPressed = 1; break;
case FAST_BACK: *fastBackButtonIsPressed = 1; break;
case PAUSE_OR_PLAY: *pauseOrPlayButtonIsPressed = 1; break;
case FAST_FORWARD: *fastForwardButtonIsPressed = 1; break;
case DOWN: *downButtonIsPressed = 1; break;
case DECREMENT_VOL: *decrementVolButtonIsPressed = 1; break;
case UP: *upButtonIsPressed = 1; break;
case EQ: *EQ_buttonIspressed = 1; break;
case ST_OR_REPT: *stOrReptButtonIspressed = 1; break;
case ZERO: *zeroButtonIspressed = 1; break;
case ONE: *oneButtonIspressed = 1; break;
case TWO: *twoButtonIspressed = 1; break;
case THREE: *threeButtonIspressed = 1; break;
case FOUR: *fourButtonIspressed = 1; break;
case FIVE: *fiveButtonIspressed = 1; break;
case SIX: *sixButtonIspressed = 1; break;
case SEVEN: *sevenButtonIspressed = 1; break;
case EIGHT: *eightButtonIspressed = 1; break;
case NINE: *nineButtonIspressed = 1; break;
default:
return; //we can't use an error. can we? break is not required in this default case as return ends the function.
}
}
IR_Receiver.resume();
}
void MainShiftRegisterAnalogWrite(uint8_t pin, uint8_t val){
ShiftPWMArray[pin] = val;
}
void MainShiftRegisterTone(uint8_t pin, uint16_t frequency){
ShiftToneArray[pin] = frequency;
}
void NoMainShiftRegisterAnalogWrite(uint8_t pin, uint8_t val){
ShiftPWMArray[pin] = DISABLE;
}
void NoMainShiftRegisterTone(uint8_t pin, uint16_t frequency){
ShiftToneArray[pin] = DISABLE;
}
bool isLeapYear(uint16_t year) {
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
void CLOCK(uint8_t setTimeSeconds, uint8_t setTimeMinutes, uint8_t setTimeHours, uint8_t setDay, uint8_t setMonth, uint16_t setYear, 
uint8_t CLOCK_TYPE, uint8_t *GetSeconds, uint8_t *GetMinutes,uint8_t *GetHours, uint8_t *GetDay, uint8_t *GetMonth, uint16_t *GetYear,
uint8_t *return_type){
static uint32_t timeStart;
static uint8_t sec;
static uint8_t min;
static uint8_t hour;
static uint8_t day;
static uint8_t month;
static uint16_t year;
static bool DST;
static bool runClock;
static uint8_t clock_type;
uint8_t daysInMonth[] = {31, uint8_t((isLeapYear(year))?29:28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if(hour > 0 && day > 0 && year > 0 && runClock){
if(millis()-timeStart >= 1000){
timeStart = millis();
if(sec < 60){
sec++;
}else{
min++;
sec = 0;
}
if(min == 60){
hour++;
min = 0;
}
if(hour > 12){
clock_type = !clock_type;
hour = 1;
}
*GetSeconds = sec;
*GetMinutes = min;
*GetHours = hour;
*return_type = clock_type;
}
if(hour == 12 && clock_type == 0){
day++;
}
if(day < daysInMonth[month]){
month++;
day = 1;
}
if(month == 3 && !DST && day == 10){
hour++;
DST = !DST;
}else if(month == 10 && DST && day == 3){
hour--;
DST = !DST;
}
if(month > Dec){
month = Jan;
year++;
}
}
if(setTimeHours > 0 && setTimeHours <= 12 && setTimeMinutes < 60 && setTimeSeconds < 60 && CLOCK_TYPE < 2 && setDay > 0 && setMonth >= Jan
&& setMonth <= Dec && setYear > 0){
if(setDay <= daysInMonth[setMonth]){
day = setDay;
}else{
return;
}
month = setMonth;
year = setYear;
sec = setTimeSeconds;
min = setTimeMinutes;
hour = setTimeHours;
clock_type = CLOCK_TYPE;
if(!runClock){
timeStart = millis();
runClock = true;
}
}
}
void LCD_Refresh(uint16_t refreshRateHz, bool *timeToWriteOLED, bool holdPreviousImage){
static uint32_t timeStamp = micros();
*timeToWriteOLED = 0;
if(refreshRateHz > 0){
uint32_t delay = 1000000/refreshRateHz;
if(micros()-timeStamp >= delay){
if(!holdPreviousImage){
display.fillScreen(BLACK);
display.display();
}
timeStamp = micros();
*timeToWriteOLED = true;
}
}else{
*timeToWriteOLED = false; /* If you set refreshRateHz to 0, your screen will freeze up, so uh, don't do that. However, I can't stop you.
If you freeze your screen, a reboot/reset is necessary. There is a built-in RST button, press that,
since you can't software-wise with a frozen screen. */
}

}

float calculator(float X, float Y, int mode){ //i know, i'm working on this and everything else.
float result;
switch(mode){
case MULTIPLICATION:
result = X*Y;
break;
case DIVISION:
result = (Y >= 0.01 || Y <= -0.01)?X/Y:NAN;
break;
case ADDITION:
result = X+Y;
break;
case SUBTRACTION:
result = X-Y;
break;
case SQUARED:
result = pow(X, 2.0);
break;
case CUBED:
result = pow(X, 3.0);
break;
case ABSOLUTE_VALUE:
result = (X < 0)?-X:X;
break;
case TO_THE_POWER_OF:
result = pow(X, Y);
break;
case REMAINDER:
result = (Y >= 0.01 || Y <= -0.01)?fmod(X, Y):NAN;
break;
case LOG:
result = log(X);
break;
case SIN:
result = sin(X);
break;
case COS:
result = cos(X);
break;
case PERCENT:
result = X*0.01;
break;
case PERCENTAGE_VALUE:
result = X*100.0;
break;
case NUM_TO_BOOL:
result = (X < 0.5)?0:1;
break;
case PERCENTAGE_TO_FBOOL:
result = (X >= 0 && X <= 100)?X*0.01:NAN;
break;
default:
return(NAN);
}
return(result);
}
void fastPinSetup(uint8_t pin, uint8_t mode){
uint8_t pinBit = digitalPinToBitMask(pin);
volatile uint8_t *setMode = portModeRegister(digitalPinToPort(pin));
volatile uint8_t *pinState = portOutputRegister(digitalPinToPort(pin));
switch(mode){
case INPUT:
*setMode &= ~pinBit;
*pinState &= ~pinBit;
break;
case OUTPUT:
*setMode |= pinBit;
*pinState &= ~pinBit;
break;
case INPUT_PULLUP:
*setMode &= ~pinBit;
*pinState |= pinBit;
break;
case OUTPUT_PULLHIGH: //#define OUTPUT_PULLHIGH 0x3
*setMode |= pinBit;
*pinState |= pinBit;
break;
default:
// "INPUT".
*setMode &= ~pinBit;
*pinState &= ~pinBit;
}
}
bool isNAN(float val){
return(val != val);
}
bool isPOS_INFINITY(float val){
return(val == INFINITY);
}
bool isNEG_INFINITY(float val){
return(val == -INFINITY);
}
bool isOVF(float val, float limit){
return(val > limit); //float doesn't have an OVF (overflow) value, so this is for displays & stuff.
}
bool isUNF(float val, float limit){
return(val < limit); //float doesn't have an UNF (underflow) value, so this is for displays & stuff.
}
void setupRebootPin(uint8_t pin){
uint8_t pinBit = digitalPinToBitMask(pin);
volatile uint8_t *setMode = portModeRegister(digitalPinToPort(pin));
volatile uint8_t *pinState = portOutputRegister(digitalPinToPort(pin));
*pinState |= pinBit;
*setMode |= pinBit;
}
//just handling fatal errors, or just fresh restarts.
void rebootAVR_Microcontroller(uint8_t pin){
volatile uint8_t *PinPort = portOutputRegister(digitalPinToPort(pin));
uint8_t PinBit = digitalPinToBitMask(pin);
*PinPort &= ~PinBit;
}
void digital_MPU6050_compass(uint8_t *direction, uint16_t *degrees, uint8_t offset, bool changeOffset){
const uint8_t defaultFactor = 211;
const float scalingFactor = 0.0008;
static float totalYaw;
float yawChange;
int16_t gx, gy, gz;
if(changeOffset){
switch(offset){
case NORTH:
totalYaw = 22.5;
break;
case NORTH_WEST:
totalYaw = 67.5;
break;
case WEST:
totalYaw = 112.5;
break;
case SOUTH_WEST:
totalYaw = 157.5;
break;
case SOUTH:
totalYaw = 202.5;
break;
case SOUTH_EAST:
totalYaw = 247.5;
break;
case EAST:
totalYaw = 292.5;
break;
case NORTH_EAST:
totalYaw = 337.5;
break;
default: //NORTH.
totalYaw = 22.5;
}
}
mpu.getRotation(&gx, &gy, &gz);
// Calculate change in yaw angle (angular velocity) around Z-axis
yawChange = (gz+defaultFactor)*scalingFactor;
// Update total yaw angle
totalYaw += yawChange;
// Keep yaw angle within [0, 360] range
if(totalYaw < 0){
totalYaw += 360;
}else if(totalYaw >= 360) {
totalYaw -= 360;
}
*degrees = totalYaw;
// Determine compass direction (approximate)
if(totalYaw > 0 && totalYaw < 45){
*direction = NORTH;
}else if(totalYaw > 45 && totalYaw < 90){
*direction = NORTH_WEST;
}else if(totalYaw > 90 && totalYaw < 135) {
*direction = WEST;
}else if(totalYaw > 135 && totalYaw < 180) {
*direction = SOUTH_WEST;
}else if(totalYaw > 180 && totalYaw < 225) {
*direction = SOUTH;
}else if(totalYaw > 225 && totalYaw < 270) {
*direction = SOUTH_EAST;
}else if(totalYaw > 270 && totalYaw < 315) {
*direction = EAST;
}else{
*direction = NORTH_EAST;
}
}
void digital_MPU6050_speedometer(float *speedX, float *speedY, float *speedZ, bool include_gravity){
const float G_To_M_PER_SECOND_Factor = 9.806;
const float AxisTo_G_Factor = 0.00006103515625;
const int RemoveGravityFactor = 17950;
int ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
switch(include_gravity){
case true:
*speedY = (az*AxisTo_G_Factor)*G_To_M_PER_SECOND_Factor;
break;
case false:
*speedY = ((az-RemoveGravityFactor)*AxisTo_G_Factor)*G_To_M_PER_SECOND_Factor;
break;
}
*speedZ = ((ax-1100)*AxisTo_G_Factor)*G_To_M_PER_SECOND_Factor;
*speedX = ((ay-90)*AxisTo_G_Factor)*G_To_M_PER_SECOND_Factor;
}
void digital_MPU6050_force_meter(float *forceX, float *forceY, float *forceZ, bool include_gravity){
const float AxisTo_G_Factor = 0.00006103515625;
const int RemoveGravityFactor = 17950;
int ax, ay, az;
mpu.getAcceleration(&ax, &ay, &az);
switch(include_gravity){
case true:
*forceY = az*AxisTo_G_Factor;
break;
case false:
*forceY = (az-RemoveGravityFactor)*AxisTo_G_Factor;
break;
}
*forceZ = ((ax*-1)-1000)*AxisTo_G_Factor;
*forceX = ((ay*-1)-150)*AxisTo_G_Factor;
}
void setAlarm1(uint8_t hour, uint8_t min, uint8_t sec, bool clockMode){
if(hour > 0){
EEPROM.write(0, hour);
delay(10); //writing EEPROM takes time, so be patient. GREG!
EEPROM.write(1, min);
delay(10);
EEPROM.write(2, sec);
delay(10);
EEPROM.write(3, clockMode); //0 = AM, 1 = PM.
delay(10);
}else{ //erase EEPROM
EEPROM.write(0, 0x00);
delay(10); //writing EEPROM takes time, so be patient. GREG!
EEPROM.write(1, 0x00);
delay(10);
EEPROM.write(2, 0x00);
delay(10);
EEPROM.write(3, 0x00);
delay(10);
}
}
void setAlarm2(uint8_t hour, uint8_t min, uint8_t sec, bool clockMode){
if(hour > 0){
EEPROM.write(4, hour);
delay(10); //writing EEPROM takes time, so be patient. GREG!
EEPROM.write(5, min);
delay(10);
EEPROM.write(6, sec);
delay(10);
EEPROM.write(7, clockMode); //0 = AM, 1 = PM.
delay(10);
}else{ //erase EEPROM
EEPROM.write(4, 0x00);
delay(10); //writing EEPROM takes time, so be patient. GREG!
EEPROM.write(5, 0x00);
delay(10);
EEPROM.write(6, 0x00);
delay(10);
EEPROM.write(7, 0x00);
delay(10);
}
}
bool alarmIsTriggered(){ // no need to tell me what alarm, I check both.
uint8_t hours = 0;
uint8_t minutes = 0;
uint8_t seconds = 0;
uint8_t clockMode = 0;
uint8_t setHours1 = EEPROM.read(0);
uint8_t setMinutes1 = EEPROM.read(1);
uint8_t setSeconds1 = EEPROM.read(2);
bool setClockMode1 = EEPROM.read(3);
uint8_t setHours2 = EEPROM.read(4);
uint8_t setMinutes2 = EEPROM.read(5);
uint8_t setSeconds2 = EEPROM.read(6);
bool setClockMode2 = EEPROM.read(7);
static uint32_t millisStart = 0;
static bool alarmTriggered = 0;

CLOCK(0, 0, 0, 0, 0, 0, 0, &seconds, &minutes, &hours, NULL, NULL, NULL, &clockMode);
if((setHours1 == hours && setMinutes1 == minutes && setSeconds1 == seconds && setClockMode1 == clockMode)
|| (setHours2 == hours && setMinutes2 == minutes && setSeconds2 == seconds && setClockMode2 == clockMode)){
alarmTriggered = 1;
millisStart = millis();
}
if(millis()-millisStart > 600000 && alarmTriggered == 1){
alarmTriggered = 0;
}
return(alarmTriggered);
}
void manageSound(uint8_t shiftPin, uint8_t micPin, uint8_t mode, uint8_t RecAddress){
volatile uint8_t *micPort = portInputRegister(digitalPinToPort(micPin));
uint8_t micBit = digitalPinToBitMask(micPin);
uint8_t soundData[MAX_REC_ADDRESS] = {0};
if(mode == PLAY){
for(int address = USED_LOWER_NUMBER_ADDRESSES; address < MAX_REC_ADDRESS; address++){
soundData[address] = EEPROM.read(address); // write soundData[] before replaying to provent bugs and stressing the micro-controller.
}
for(int VarAddress = USED_LOWER_NUMBER_ADDRESSES; VarAddress < MAX_REC_ADDRESS; VarAddress++){
for(int bitPos = 0; bitPos < 8; bitPos++) {
bool sampleBit = (soundData[VarAddress] >> bitPos) & 1;
MainShiftRegisterWrite(shiftPin, sampleBit);
delayMicroseconds(50);
}
}
}else if(mode == RECORD){
for(int VarAddress = USED_LOWER_NUMBER_ADDRESSES; VarAddress < MAX_REC_ADDRESS; VarAddress++){
for(int bitPos = 0; bitPos < 8; bitPos++) {
bool sampleBit = (*micPort & micBit) != 0;
soundData[VarAddress] |= (sampleBit << bitPos);
delayMicroseconds(50);
}
}
for(int address = USED_LOWER_NUMBER_ADDRESSES; address < MAX_REC_ADDRESS; address++){
EEPROM.write(address, soundData[address]);
delay(25); //writing an EEPROM takes time as it takes time for it to register data. so be patient, Greg!!
}
}
}

void detectSoilMoisture(uint8_t pin, uint8_t *val, bool *isDry, bool *isWet){ //use a soil moisture sensor.
uint8_t moisturePercentage = analogRead(pin) / 10.23;
*isWet = (moisturePercentage > 75);
*isDry = (moisturePercentage < 25);
*val = moisturePercentage;
}
void detectSensorWetness(uint8_t pin, uint8_t *val){ /*use a "raindrop" sensor, though i'll use it for other things becuase leaving a computer
in the rain is illogical.*/
uint8_t sensorWetness = analogRead(pin) / 10.23;
*val = sensorWetness;
}
void extractFloatBits(float val, bool *sign, uint8_t *exponent, uint32_t *mantissa){
uint32_t Bits = 0;
memcpy(&Bits, &val, sizeof(val));
*sign = (Bits >> 31) & 0x1;
*exponent = (Bits >> 23) & 0xFF;
*mantissa = Bits & 0x7FFFFF;
}
void createFloatBits(bool sign, uint8_t exponent, uint32_t mantissa, float *val) {
uint32_t Bits = (uint32_t(sign) << 31) | (uint32_t(exponent) << 23) | (mantissa & 0x7FFFFF);
memcpy(val, &Bits, sizeof(Bits));
}
void enableUsbSlowCharger(uint8_t UsbSlowChargerPowerTransistorPin, bool enableSlowCharging){
volatile uint8_t *UsbSlowChargerPort = portOutputRegister(digitalPinToPort(UsbSlowChargerPowerTransistorPin));
uint8_t UsbSlowChargerBit = digitalPinToBitMask(UsbSlowChargerPowerTransistorPin);
if(enableSlowCharging){
*UsbSlowChargerPort |= UsbSlowChargerBit;
}else{
*UsbSlowChargerPort &= ~UsbSlowChargerBit;
}
}
void timer(uint8_t hours, uint8_t minutes, uint8_t seconds, bool reset,
uint8_t *hoursLeft, uint8_t *minutesLeft, uint8_t *secondsLeft, bool *timerDoneAlarm) {
static uint32_t timeStamp = 0;
static uint8_t Hours = 0;
static uint8_t Minutes = 0;
static uint8_t Seconds = 0;
static bool timerBegan = false;

if(reset){
Hours = hours;
Minutes = minutes;
Seconds = seconds;
timeStamp = millis();
timerBegan = true;
*timerDoneAlarm = false;
}
if (timerBegan){
if (millis() - timeStamp >= 1000) {
timeStamp += 1000;
if(Seconds > 0){
Seconds--;
}else{
if(Minutes > 0){
Minutes--;
Seconds = 59;
}else if(Hours > 0){
Hours--;
Minutes = 59;
Seconds = 59;
}
}
}
*hoursLeft = Hours;
*minutesLeft = Minutes;
*secondsLeft = Seconds;
if(Hours == 0 && Minutes == 0 && Seconds == 0){
timerBegan = false;
*timerDoneAlarm = true;
}else{
*timerDoneAlarm = false;
}
}
}
uint16_t systemRandomizer(uint16_t min_val, uint16_t max_val){
static uint16_t lfsr = 1;
uint16_t bit;
uint16_t result;

bit  = ((lfsr >> 0)^(lfsr >> 2)^(lfsr >> 3)^(lfsr >> 5)+1); //taps at 0, 2, 3, and 5.
lfsr =  (lfsr >> 1)|(bit << 15);
result = min_val + (lfsr % (max_val - min_val + 1)); //calculate a result in between min_val and max_val.
return(result); //give the result.
}

void colorBy(uint8_t R_pin, uint8_t G_pin, uint8_t B_pin, uint8_t colorMapNum, uint8_t Brightness, uint8_t Saturation){
uint8_t R = 0;
uint8_t G = 0;
uint8_t B = 0;
switch(colorMapNum){
case COLOR_BY_BLACK:
R = 0;
G = 0;
B = 0;
break;
case COLOR_BY_LIGHT_RED:
R = 255;
G = 51;
B = 51;
break;
case COLOR_BY_RED:
R = 255;
G = 0;
B = 0;
break;
case COLOR_BY_DARK_RED:
R = 255;
G = 0;
B = 0;
break;
case COLOR_BY_LIGHT_GREEN:
R = 0;
G = 204;
B = 0;
break;
case COLOR_BY_GREEN:
R = 0;
G = 153;
B = 0;
break;
case COLOR_BY_DARK_GREEN:
R = 0;
G = 102;
B = 0;
break;
case COLOR_BY_LIGHT_BLUE:
R = 51;
G = 51;
B = 255;
break;
case COLOR_BY_BLUE:
R = 0;
G = 0;
B = 255;
break;
case COLOR_BY_DARK_BLUE:
R = 0;
G = 0;
B = 139;
break;
case COLOR_BY_YELLOW:
R = 255;
G = 255;
B = 0;
break;
case COLOR_BY_CYAN:
R = 0;
G = 255;
B = 255;
break;
case COLOR_BY_MAGENTA:
R = 255;
G = 0;
B = 255;
break;
case COLOR_BY_ORANGE:
R = 255;
G = 165;
B = 0;
break;
case COLOR_BY_DARK_ORANGE:
R = 255;
G = 140;
B = 0;
break;
case COLOR_BY_GOLD:
R = 255;
G = 215;
B = 0;
break;
case COLOR_BY_LIME:
R = 0;
G = 255;
B = 0;
break;
case COLOR_BY_PURPLE:
R = 128;
G = 0;
B = 128;
break;
case COLOR_BY_PINK:
R = 255;
G = 64;
B = 64;
break;
case COLOR_BY_DEEP_PINK:
R = 255;
G = 16;
B = 16;
break;
case COLOR_BY_INDIGO:
R = 75;
G = 0;
B = 130;
break;
case COLOR_BY_VIOLET:
R = 127;
G = 32;
B = 255;
break;
case COLOR_BY_DARK_VIOLET:
R = 127;
G = 0;
B = 255;
break;
case COLOR_BY_WHITE:
R = 255;
G = 255;
B = 255;
break;
default:
R = 0;
G = 0;
B = 0;
break;
}
color(R_pin, G_pin, B_pin, R, G, B, Brightness, Saturation);
}
void RGB_CCT_ColorLighting(uint8_t R_pin, uint8_t G_pin, uint8_t B_pin, uint32_t CCT, uint8_t Brightness, uint8_t Saturation) {
uint8_t R = 0;
uint8_t G = 0;
uint8_t B = 0;
uint32_t val = CCT / 100;

if (val <= 66) {
R = 255;
G = (99.4708025861 * log(val)) - 161.1195681661;
G = constrain(G, 0, 255);
if (val <= 20) {
B = 0;
}else{
B = (138.5177312231 * log(val - 10)) - 305.0447927307;
B = constrain(B, 0, 255);
}
}else{
R = 329.698727466 * pow(val - 60, -0.1332047592);
R = constrain(R, 0, 255);
G = 288.1221695283 * pow(val - 60, -0.0755148492);
G = constrain(G, 0, 255);
B = 255;
}
color(R_pin, G_pin, B_pin, R, G, B, Brightness, Saturation);
}

void ColorFade(uint8_t R_pin, uint8_t G_pin, uint8_t B_pin, uint8_t fadeSpeed, uint8_t Brightness, uint8_t Saturation, uint8_t mode, bool reset){
static uint32_t RGB_Timestamp = 0;
static uint8_t ColorFadeRegister = 0;
static uint8_t ColorCycleRegister = 0;
static uint8_t Red = 255;
static uint8_t Green = 0;
static uint8_t Blue = 0;
if(reset){
ColorFadeRegister = 0;
ColorCycleRegister = 0;
Red = 255;
Green = 0;
Blue = 0;
}
if(millis()-RGB_Timestamp >= fadeSpeed){ //millis timer.
RGB_Timestamp = millis();
switch(mode){
case FADE:
if(ColorFadeRegister == 0 && Red < 255){
Red++; //brighten red.
}else if(ColorFadeRegister == 0 && Red == 255){
ColorFadeRegister = 1; //next stage.
}if(ColorFadeRegister == 1 && Blue > 0){ 
Blue--; //dim blue.
}else if(ColorFadeRegister == 1 && Blue == 0){
ColorFadeRegister = 2; //next stage.
}if(ColorFadeRegister == 2 && Green < 255){
Green++; //brighten green.
}else if(ColorFadeRegister == 2 && Green == 255){
ColorFadeRegister = 3; //next stage.
}if(ColorFadeRegister == 3 && Red > 0){
Red--; //dim red.
}else if(ColorFadeRegister == 3 && Red == 0){
ColorFadeRegister = 4; //next stage.
}if(ColorFadeRegister == 4 && Blue < 255){
Blue++; //brighten blue.
}else if(ColorFadeRegister == 4 && Blue == 255){
ColorFadeRegister = 5; //next stage.
}if(ColorFadeRegister == 5 && Green > 0){
Green--; //dim green.
}else if(ColorFadeRegister == 5 && Green == 0){
ColorFadeRegister = 0; //back to first stage.
}
break;
case CYCLE:
if(ColorCycleRegister == 0 && Red < 255){
Red++; //brighten red.
}else if(ColorCycleRegister == 0 && Red == 255){
ColorCycleRegister = 1; //next stage.
}if(ColorCycleRegister == 1 && Red > 0){ 
Red--; //dim red.
}else if(ColorCycleRegister == 1 && Red == 0){
ColorCycleRegister = 2; //next stage.
}if(ColorCycleRegister == 2 && Green < 255){
Green++; //brighten green.
}else if(ColorCycleRegister == 2 && Green == 255){
ColorCycleRegister = 3; //next stage.
}if(ColorCycleRegister == 3 && Green > 0){
Green--; //dim green.
}else if(ColorCycleRegister == 3 && Green == 0){
ColorCycleRegister = 4; //next stage.
}if(ColorCycleRegister == 4 && Blue < 255){
Blue++; //brighten blue.
}else if(ColorCycleRegister == 4 && Blue == 255){
ColorCycleRegister = 5; //next stage.
}if(ColorCycleRegister == 5 && Blue > 0){
Blue--; //dim blue.
}else if(ColorCycleRegister == 5 && Blue == 0){
ColorCycleRegister = 6; //next stage.
}if(ColorCycleRegister == 6 && Red < 255 && Green < 255){
Red++; //brighten red.
Green++; //brighten green.
}else if(ColorCycleRegister == 6 && Red == 255 && Green == 255){
ColorCycleRegister = 7; //next stage.
}if(ColorCycleRegister == 7 && Red > 0 && Green > 0){
Red--; //dim red.
Green--; //dim green.
}else if(ColorCycleRegister == 7 && Red == 0 && Green == 0){
ColorCycleRegister = 8; //next stage.
}if(ColorCycleRegister == 8 && Red < 255 && Blue < 255){
Red++; //brighten red.
Blue++; //brighten blue.
}else if(ColorCycleRegister == 8 && Red == 255 && Blue == 255){
ColorCycleRegister = 9; //next stage.
}if(ColorCycleRegister == 9 && Red > 0 && Blue > 0){
Red--; //dim red.
Blue--; //dim blue.
}else if(ColorCycleRegister == 9 && Red == 0 && Blue == 0){
ColorCycleRegister = 10; //next stage.
}if(ColorCycleRegister == 10 && Green < 255 && Blue < 255){
Green++; //brighten green.
Blue++; //brighten blue.
}else if(ColorCycleRegister == 10 && Green == 255 && Blue == 255){
ColorCycleRegister = 11; //next stage.
}if(ColorCycleRegister == 11 && Green > 0 && Blue > 0){
Green--; //dim green.
Blue--; //dim blue.
}else if(ColorCycleRegister == 11 && Green == 0 && Blue == 0){
ColorCycleRegister = 0; //back to first stage.
}
break;
}
color(R_pin, G_pin, B_pin, Red, Green, Blue, Brightness, Saturation);
}
}

void color(uint8_t R_pin, uint8_t G_pin, uint8_t B_pin, uint8_t R, uint8_t G, uint8_t B, uint8_t Brightness, uint8_t Saturation){
//set up color function, for an easy and more professional way to change led colors.
uint8_t outputRedValue, outputGreenValue, outputBlueValue;
uint8_t saturator = (R+G+B)/3;
outputRedValue = ((R*Saturation)/255)+(saturator*(255-Saturation)/255);
outputGreenValue = ((G*Saturation)/255)+(saturator*(255-Saturation)/255);
outputBlueValue = ((B*Saturation)/255)+(saturator*(255-Saturation)/255);
outputRedValue = outputRedValue/(256-Brightness);
outputGreenValue = outputGreenValue/(256-Brightness);
outputBlueValue = outputBlueValue/(256-Brightness);
ShiftPWMArray[R_pin] = outputRedValue;
ShiftPWMArray[G_pin] = outputGreenValue;
ShiftPWMArray[B_pin] = outputBlueValue;
}

bool isDark(uint8_t photoResistorPin){
uint8_t output = 100*(analogRead(photoResistorPin)/1023.0);
return(output < 30);
}
bool isBright(uint8_t photoResistorPin){
uint8_t output = 100*(analogRead(photoResistorPin)/1023.0);
return(output > 60);
}

void pedometer(float *distance, float *energyUsed, uint8_t distanceType, uint8_t energyType, float weightIn, bool reset){
const float G_To_MILES_PER_HOUR_Factor = 21.93736;
const float AxisTo_G_Factor = 0.00006103515625;
static uint32_t millisStart = 0;
static bool millisStarted = 0;
static uint32_t minsWhileWalking = 0;
static float weight = 0;
float caloriesBurnedPerMin = 0.0;
float totalCaloriesBurned = 0.0;
float energyOut = 0.0;
float speedZ = 0.0;
float speedX = 0.0;
float totalSpeed = 0.0;
float MET_calSpeed = 0.0;
float OutputSpeed = 0.0;
float METs = 0.0;
int ax, ay;
if(reset){
millisStart = 0;
millisStarted = 0;
minsWhileWalking = 0;
}
if(weightIn > 30 && weightIn < 150){
weight = weightIn;
}

if(weight < 30){
*distance = NAN;
*energyUsed = NAN;
return;
}

mpu.getAcceleration(&ax, &ay, NULL);
speedZ = ((ax-1100)*AxisTo_G_Factor)*G_To_MILES_PER_HOUR_Factor;
speedX = ((ay-90)*AxisTo_G_Factor)*G_To_MILES_PER_HOUR_Factor;
totalSpeed = abs(speedZ)+abs(speedX);
OutputSpeed = totalSpeed;
MET_calSpeed = totalSpeed/2.23693629*60;
METs = (0.1 * MET_calSpeed + 3.5)/3.5;
if(totalSpeed > 0){
if(!millisStarted){
millisStart = millis();
millisStarted = 1;
}else if(millis()-millisStart >= 60000){
minsWhileWalking++;
}
}else{
millisStarted = 0;
}
caloriesBurnedPerMin = (METs*3.5*(weight*2.20462)/200)*minsWhileWalking;
energyOut = caloriesBurnedPerMin;

switch(distanceType){
case METERS_PER_SECOND:
OutputSpeed /= 2.23693629;
break;
case KILOMETERS_PER_HOUR:
OutputSpeed *= 1.609344;
break;
case FEET_PER_SECOND:
OutputSpeed *= 1.46666667;
break;
}

switch(energyType){
case KILOCALORIES:
energyOut /= 1000.0;
break;
case JOULES:
energyOut *= 4.184;
break;
case KILOJOULES:
energyOut /= 239.005736;
break;
}
*distance = OutputSpeed;
*energyUsed = energyOut;
}
void SetFanSpeed(uint8_t pin, uint8_t speed){
ShiftPWMArray[pin] = speed;
}
void resetScreen(){
display.clearDisplay();
display.display();
}

Thank you all for your support!

Please dont post your question in code tags!

Question? I don't have any questions, those "?"s in the code are ternaries.

they work like:
num = (bool condition)?numIfStatementTrue:numIfStatmentFalse;
it's similar to:
if(bool condition){ num = numIfStatementTrue; }else{ num = numIfStatementFalse; }

I hope this helps you understand my uncompleted code better.

He meant you enclose the whole message inside "code" tags, and not only the sketch/code.
See how it currently shows up:

You can see everything has been formatted as a code (and a "code" tag appears around the real code lines). Just edit your first post, then remove the first code tag.

Have you read this?

@johnerrington
Thank you!

yea, fixed that... I think... :thinking:

should be fine, and remember, it's unfinished, so there's no main code.

I made mistakes... but everyone learns right?

It's ok now.

Well, the project is clearly ambitious, but if you want to make it published for others (there's no question, as you remarked, so it looks like just a project presentation) I think you need to better describe the project (I mean, not just inside the code...), its target and foreseen usage/purpose, together with some graphics (i.e. a connections diagram, some screen/output samples, etc).

Oh, yea, it's for security, distance measuring, temp & humidity sensing, making a virtual compass, (which'll need toning) recording sound data, playing sound data, making alarms, self cooling, RGB lighting for lighting up the room with cool colors, custom PWM and tone, since I need to use shift registers as outputs, speed sensing, calorie usage sensing, OLED screen, USB slow charging, (since I can't have it fast charge) remote control, motion detecting, light sensing, noise level sensing, and... there!

Sorry I didn't give you all, everyone here, all of that.

I will try to follow the rules from now on.
I love everyone here, I feel happy here!
I hope y'all like this!

Wow, I read most of that inside your code comments, but that's a pretty big project, isn't it? How long are you working on it, what is the airspeed velocity of an unladen... Uh, no that's another movie... I mean, what is the purpose of publishing a huge but unfinished project like this (aka what can we do with it)?

PS: btw, you forgot some very important things like making coffee, controlling the cleaning robot, automatic lwan mowing, washing the car, and maybe even ending wars all over the World. :sunglasses: :laughing:

yeah, but as I said, I'll continue the project, but this time, on the ESP32!
This is because I'd like my tablet to be a remote control, it uses CLI, most know CLI as Code Line Interface, but in this case it's a Command Line Interface.
I'll use "Bluetooth.h"

Hi, @LoganTheEngineer7
Welcome to the forum.

Can you please tell us your electronics, programming, arduino, hardware experience?

And where is the kitchen sink? :rofl:

What is the overall purpose of your project?
Home automation?

Tom.. :smiley: :+1: :coffee: :australia:

yeah, I missed out! :laughing:
though, really, my sensors are limited, but NOW I can make a distance heat sensor now that I have flame sensor, but it'll do no bueno (no good) around a burning food in the oven (more likely and safe). so we know soot and smoke block light, so if we sense that change, we can trigger the alarm. right? this should work.

@TomGeorge
oh, hello there! great to see you, I'm getting ready to make an ESP32 Computer!

oh wait! I'll add a flashlight and morse code function, you might wonder why, and it's simple. what if you have no service, and radio battery died? you might use morse code, issue is, I don't think people really use morse code anymore.

They do. Aslo semaphore.

@johnerrington
they do?!
cool! I guess it will be useful!
Thank you!

issue with:

oh wait! I'll add a flashlight and morse code function, you might wonder why, and it's simple. what if you have no service, and radio battery died? you might use morse code, issue is, I don't think people really use morse code anymore.

the problem is it's unlikely for someone to bring a bunch of electronics out on a trip called a "computer" if it doesn't even have a case, so it's best used indoors.