Max-485 and Rotary Encoder does not work

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);
  }
}

Yes! But we need the following:

  • Annotated Schematic: Clearly show all connections, including power, ground, and power sources. This will help us understand your circuit setup and identify potential issues.
  • Technical Information Links: Provide links to technical documentation for each hardware component in your setup. Avoid links to sales sites like Amazon, as they often lack the detailed specifications we need to assist you effectively.

Why Do We Want This:

We can’t accurately assist without knowing the specifics of your setup. Clear, detailed descriptions will allow us to offer the best help possible. Without this information, diagnosing and solving your issues will be much harder.

What does the compiler show for available memory?

The sketch uses 2958 bytes (9%)
The global variables use 603 bytes (29%)

1 Like

From the DMX library file...

#define DMXMODEPIN 2     ///< Arduino pin 2 for controlling the data direction is the default value.

Hardware interrupts on the Nano are pins 2 and 3. Maybe free those pins and assign clock and data to 5 and 6?

1 Like

This should be the schematic.

I tried that and it did kind of work. The i tried pins around and found that CLK = 4; DT = 3; SW = 1 works perfect. So thanks for the help, Pin 2 was blocked by the library.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.