Code Review Asked by marcellothearcane on January 12, 2021
I have created a darkroom timer, which is used for enlarging and developing film.
It has four separate timers, and can toggle mains via a relay to turn on the enlarger for a specified amount of time. Something like a mix between a triple timer for development and an enlarger timer.
For this project, I used an Arduino Uno, with the following hardware configuration:
#include <SevSeg.h>
#include <EEPROM.h>
const byte SAFELIGHT_PIN = 1;
const byte BUTTON_ARRAY_PIN = A0;
const byte ENCODER_A_PIN = A1;
const byte ENCODER_B_PIN = A2;
const byte RELAY_PIN = A3;
const byte SAFELIGHT_BUTTON_PIN = A4;
const byte BUZZER_PIN = A5;
// Changable if EEPROM ever wears out at these addresses
const int EEPROM_ADDRESSES[] = { 0, 1, 2, 3 };
const byte NUM_DIGITS = 4;
const byte DIGIT_PINS[] = { 5, 4, 3, 2 };
const byte SEGMENT_PINS[] = { 11, 13, 9, 7, 6, 12, 10, 8 };
SevSeg screen;
int buttonArrayValue;
unsigned long lastButtonArrayTime;
unsigned long lastTimerUpdate;
unsigned long timerUpdate;
boolean lastEncoderAValue;
boolean encoderAValue;
boolean encoderBValue;
byte activeTimer = 0;
int timers[] = {
EEPROM.read(EEPROM_ADDRESSES[0]),
EEPROM.read(EEPROM_ADDRESSES[1]),
EEPROM.read(EEPROM_ADDRESSES[2]),
EEPROM.read(EEPROM_ADDRESSES[3])
};
boolean timerRunning = false;
boolean safelightOn = false;
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(ENCODER_A_PIN, INPUT);
pinMode(ENCODER_B_PIN, INPUT);
pinMode(SAFELIGHT_BUTTON_PIN, INPUT);
// Type, digits, segments, digit pins, segment pins, resistors on pins, update with delay, leading zeroes.
screen.begin(COMMON_CATHODE, NUM_DIGITS, DIGIT_PINS, SEGMENT_PINS, true, false, true);
screen.setBrightness(10);
lastEncoderAValue = digitalRead(ENCODER_A_PIN);
}
void loop() {
// Read rotary encoder
encoderAValue = digitalRead(ENCODER_A_PIN);
encoderBValue = digitalRead(ENCODER_B_PIN);
if (encoderAValue != lastEncoderAValue && encoderAValue == true && timerRunning == false) {
if (encoderBValue != encoderAValue) {
timers[activeTimer]++;
} else {
timers[activeTimer]--;
}
// Minimum timer is 0, maximum timer is 99 minutes, 99 seconds = 6039 seconds
timers[activeTimer] = min(max(0, timers[activeTimer]), 6039);
}
lastEncoderAValue = encoderAValue;
// Button array
buttonArrayValue = analogRead(BUTTON_ARRAY_PIN);
if (millis() - lastButtonArrayTime > 100 && timerRunning == false) {
if (buttonPressed(buttonArrayValue, 516)) {
startTimer();
} else if (buttonPressed(buttonArrayValue, 344)) {
startTimer();
digitalWrite(RELAY_PIN, HIGH);
} else if (buttonPressed(buttonArrayValue, 257)) {
activeTimer = 0;
} else if (buttonPressed(buttonArrayValue, 205)) {
activeTimer = 1;
} else if (buttonPressed(buttonArrayValue, 171)) {
activeTimer = 2;
} else if (buttonPressed(buttonArrayValue, 146)) {
activeTimer = 3;
}
lastButtonArrayTime = millis();
}
timerUpdate = millis() - lastTimerUpdate;
// Clear timer
if (timerUpdate > 1000 && timerRunning == true && timers[activeTimer] <= 0) {
timers[activeTimer] = EEPROM.read(EEPROM_ADDRESSES[activeTimer]);
tone(BUZZER_PIN, 880, 1000);
timerRunning = false;
digitalWrite(RELAY_PIN, LOW);
}
// Update timer every second
if (timerUpdate > 1000 && timerRunning == true) {
timers[activeTimer]--;
// Beep every second, with a higher beep every 30 seconds.
if (timers[activeTimer] % 30 == 0) {
tone(BUZZER_PIN, 880, 250);
} else {
tone(BUZZER_PIN, 440, 50);
}
lastTimerUpdate += timerUpdate; // Use the timerUpdate so average time is correct
}
// Update displays (safelight and screen).
safelightOn = digitalRead(SAFELIGHT_BUTTON_PIN);
if (safelightOn == true) {
digitalWrite(SAFELIGHT_PIN, HIGH);
screen.setNumber(secondsToMinutes(timers[activeTimer]), 3 - activeTimer);
} else {
digitalWrite(SAFELIGHT_PIN, LOW);
screen.blank();
}
screen.refreshDisplay();
}
// Calculates if a number is within a margin of +/- 15. If so, it returns true.
// This is used for the analogue buttons to see if they were pressed.
boolean buttonPressed (int buttonArrayValue, int target) {
if (abs(buttonArrayValue - target) < 15) {
return true;
} else {
return false;
}
}
// Returns a seconds value in MMSS format.
int secondsToMinutes (int seconds) {
if (seconds < 60) {
return seconds;
} else {
return (floor(seconds / 60) * 100) + (seconds % 60);
}
}
// Stores the current time if it is new, and starts the timer.
void startTimer () {
EEPROM.update(EEPROM_ADDRESSES[activeTimer], timers[activeTimer]);
timerRunning = true;
}
const
variables, however should I use #define
? I didn’t run into memory allocation problems.loop()
function. I tried splitting some parts off (such as reading the rotary encoder), but it didn’t work – the encoder ‘read’ massively large numbers instead for some reason.if (someVariable == true) {
rather than if (someVariable) {
– I thought it was more readable with other Boolean operators such as &&
.Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP