Skip to content

7. Input & Output device

Research

My final project will include a Dot Matrix display that uses a Max7219 chip, and my preferred input is a rotary dial input. I found these excellent tutorials and reused code from them.

Rotary Encoder

https://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/

MAX7219

https://how2electronics.com/8x32-max7219-dot-matrix-led-display-with-arduino/

Parts

1 x Arduino Nano

1 x Dot Matrix (4 in series) + MAX7219 Chip

1 x Rotary Encoder

Problems faced

1- The upload failed often, I figured out that the serial monitor has to be manually closed to free up the com port and upload the updated sketch 2- At one point when I coded in the button, it was clicking randomly, so I immediately figured that I forgot to pullup the input 3- For now, the code uses delay, which locks up the MCU board. This is fine for this example.

Code and Results

Here is the final code with the in-line comments

/* Original code for rotary encoder by Dejan Nedelkovski howtomechatronics.com
 * MAX7219 Code from how2electronics.com
 * Modified by Ahmed AlKooheji to act as a countdown timer
 */

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::GENERIC_HW

#define MAX_DEVICES 4
#define CS_PIN 10
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

#define outputA 2
#define outputB 3
#define SW 4

int counter = 0; //Counter for the timer
int aState; //Current Rotation State
int aLastState; //Last Rotation Ttate

unsigned long lastButtonPress = 0; //to save the time when the button was clicked

 void setup() { 
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
  pinMode(SW, INPUT_PULLUP);

   Serial.begin (9600);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);   

  myDisplay.begin();
  myDisplay.setIntensity(4);
  myDisplay.displayClear();
  myDisplay.setTextAlignment(PA_CENTER);
 } 

 void loop() { 

    // Read the button state
    int btnState = digitalRead(SW);

    //If we detect LOW signal, button is pressed
    if (btnState == LOW) {
        //if 50ms have passed since last LOW pulse, it means that the
        //button has been pressed, released and pressed again
        if (millis() - lastButtonPress > 50) {
            Serial.println("Button pressed!");
      for (int x=counter; x>=0; x--) //Start a loop from the Counter, and increment one down to reach 0
        {Serial.println(x);
        myDisplay.print(x); //display on screen
        delay(1000); //delay by 1 second
        }
        }
        // Remember last button press event
        lastButtonPress = millis();
    }

   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if (aState != aLastState){     
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) { 
       counter ++;
     } else {
       if (counter>0)
        counter --;
     }
     Serial.print("Position: ");
     Serial.println(counter);
   } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
    myDisplay.print(counter);

  // Put in a slight delay to help debounce the readings
    delay(1);
 }

Here is the result of the project (additional components in the video are there for testing)


Last update: June 28, 2024