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)