I'm working on a project to control relays using DMX and display the addresses on a 4-digit 7-segment display. The first digit indicates which relay address is currently selected, while the last four digits show the corresponding DMX address. I plan to use a rotary encoder to change the address, and pressing it will cycle to the next relay.
My setup includes an Arduino Nano, a MAX485 module for DMX, a SH5461AS display, and a SN74HC595N shift register as an I/O expander.
The DMX communication and display are functioning correctly, and the rotary encoder works well too—until I uncomment Line 57 DMXSerial.init(DMXReceiver);
. Once I do that, the rotary encoder fails to detect any rotation, although the button press still works fine.
I'm having trouble pinpointing the issue. Could this be related to hardware timers or interrupts? Any insights or suggestions would be greatly appreciated!
#include <Encoder.h>
#include <DMXSerial.h>
// Pin definitions for the display
const int latchPin = 14;
const int clockPin = 15;
const int dataPin = 13;
// Pins for the 7-segment digits
const int zifferPins[] = {16, 17, 18, 19};
// Pins for the rotary encoder
const int CLK = 2;
const int DT = 3;
const int SW = 4;
// Pins for the relay outputs
const int relayPins[] = {12, 11, 10, 9, 8, 7};
// Constants for configuration
const int MAX_DMX_ADDRESS = 512; // Maximum DMX address
const int NUM_RELAYS = 6; // Number of relays
const int DISPLAY_DELAY = 6; // Delay for display persistence
// Setup variables
long altePosition = 1; // Previous encoder position
int altButton = 0; // Previous button state
int dmxAdresse[NUM_RELAYS] = {1, 2, 3, 4, 5, 6}; // DMX addresses for relays
int displayNumber = 1001; // Current number to display
int relay = 0; // Current relay index
// Initialize the rotary encoder
Encoder rotaryEncoder(DT, CLK);
// Binary values for digits 0-9 for the 7-segment display
const byte digitValues[10] = {252, 96, 218, 242, 102, 182, 190, 224, 254, 246};
void setup() {
// Set up pin modes
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// Set digit pins as outputs
for (int i = 0; i < 4; i++) {
pinMode(zifferPins[i], OUTPUT);
}
// Set relay pins as outputs
for (int i = 0; i < NUM_RELAYS; i++) {
pinMode(relayPins[i], OUTPUT);
}
// Set the switch pin as input
pinMode(SW, INPUT);
// Initialize DMX if needed
// DMXSerial.init(DMXReceiver); // Uncomment if using DMX
}
void loop() {
// Handle button presses
buttonPress();
// Read the rotary encoder position
readEncoderPosition();
// Construct the number to display based on current relay and DMX address
displayNumber = (relay + 1) * 1000 + dmxAdresse[relay];
// Update the display with the constructed number
display(displayNumber);
// Uncomment to update DMX outputs if needed
// dmx();
}
void buttonPress() {
// Read the current state of the button
int neuButton = digitalRead(SW);
// Check for state change
if (neuButton != altButton) {
altButton = neuButton;
// If button is pressed
if (neuButton == 0) {
// Increment the relay index and wrap around if necessary
relay = (relay + 1) % NUM_RELAYS;
delay(10); // Simple debounce delay
}
}
}
void readEncoderPosition() {
// Read the current position of the rotary encoder
long neuePosition = rotaryEncoder.read() / 4;
// Check if the position has changed
if (neuePosition != altePosition) {
// Adjust DMX address based on encoder movement
if (neuePosition < altePosition) {
dmxAdresse[relay] = (dmxAdresse[relay] == 1) ? MAX_DMX_ADDRESS : dmxAdresse[relay] - 1;
} else {
dmxAdresse[relay] = (dmxAdresse[relay] == MAX_DMX_ADDRESS) ? 1 : dmxAdresse[relay] + 1;
}
altePosition = neuePosition; // Update the previous position
}
}
void dmx() {
// Read DMX values and control relay outputs accordingly
for (int i = 0; i < NUM_RELAYS; i++) {
digitalWrite(relayPins[i], DMXSerial.read(dmxAdresse[i]) >= 128 ? HIGH : LOW);
}
}
void display(int num) {
// Display the number on the 7-segment display
for (int pos = 3; pos >= 0; pos--) {
int digit = num % 10; // Get the current digit
num /= 10; // Remove the current digit from the number
// Turn off all digit pins
for (int i = 0; i < 4; i++) {
digitalWrite(zifferPins[i], HIGH);
}
// Activate the current digit pin
digitalWrite(zifferPins[pos], LOW);
// Send the digit value to the display
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, LSBFIRST, digitValues[digit] + (pos == 0 ? 1 : 0));
digitalWrite(latchPin, HIGH);
// Delay for display persistence
delay(DISPLAY_DELAY);
}
}