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)
Learnings from Input Device (Rotary Encoder)¶
I learned that a rotary encoder is a great way to take user input, as it allows a user to change settings, and make a selection through one knob. You can also rotate it indefinitely meaning the user doesn’t need to stop at any point. The knob is also removable, which means I can 3D print a knob! Here is how rotary encoder works:
- There are two small contact points inside, and based on the rotation direction contact A will connect to ground, before contact B. The reverse is true if the direction of the rotation is alternated
- This Allows us to both know the direction (DT Pin) and relative speed (CLK Pin) of the knob
- The SW Pin detects if the push button is activated, we need to code in a De-Bounce, to avoid having too many clicks registered in one go.
- The GND and + are connected to the Arduino Ground and 5V pins
Learnings from Output Device (MAX7219)¶
I think this is a pretty unique display that not many would choose to go with, but it provides excellent flexibility in displaying text, it is also very bright and large. It is however limited to one color only, and draws quite a bit of power. Here is how the display works:
- Each dot is assigned to a row or column, and dots are lit very quickly in batches of 8. It happens so fast that to the human eye we are able to see text or shapes on the display.
- This is all controlled via the MAX7219 Integrated Chip (IC)
- To simplify this whole process there is Library called MD Parola, which makes it much easier to control everything and display text