12. Output devices
LCD screen
We are going to connect the LCD screen that came with our Arduino. There are 12 connections to be made!
We write our code:
#include <LiquidCrystal.h>
int rs=7;
int en=8;
int d4=9;
int d5=10;
int d6=11;
int d7=12;
bool firstTime = true;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
lcd.begin(16, 2); // 16 col, 2 rows
}
void loop() {
lcd.setCursor(0,0);
if (firstTime == true) {
lcd.print("LCD WORKING!");
delay(2000);
lcd.clear();
firstTime = false;
}
lcd.print("Let's count!");
delay(1000);
for (int i=1; i<=10; i++) {
lcd.setCursor(0,1);
lcd.print(i);
delay(500);
}
lcd.clear();
}
And it works:
Piezo motor
We will connect a Piezo motor with a joystick.
The joystick is basically 2 potentiometers in parallel - one for X and one for Y. In this project, we will only use the X one but pretend we also use the Y one as a proof of concept.
The X and Y pins will be connected to analog inputs on the Arduino. The switch pin is the button pin - the joypad can also act as a button. Since it returns a boolean value, we will connect it to a digital input.
We will also make a pull-up resistor the software way by writing digitalWrite(switchPin, HIGH);
Once the connections are made, we can write our code:
#include <Servo.h>
Servo servo;
int Xpin=A0;
int Ypin=A1;
int switchPin=2;
int Xval;
int Yval;
int switchVal;
int servoPin = 7;
float angle;
void setup() {
Serial.begin(9600);
pinMode(Xpin, INPUT);
pinMode(Ypin, INPUT);
pinMode(switchPin, INPUT);
digitalWrite(switchPin, HIGH); // to make a pull-up resistor
servo.attach(servoPin);
}
void loop() {
// read the joystick movement
Xval=analogRead(Xpin);
Yval=analogRead(Ypin);
switchVal=digitalRead(switchPin);
delay(200);
// print the values
Serial.print(" X = ");
Serial.print(Xval);
Serial.print(" Y = ");
Serial.print(Yval);
Serial.print(" Switch= ");
Serial.println(switchVal);
// move the servo
angle = Xval /1023.*180.;
servo.write(angle);
Serial.println(angle);
}
Now it works.
The only problem is that I used a continuous Servo, so it never stops. And it interprets the number I send it as a speed, not a direction.
LCD calculator
Let’s use the LCD to make a calculator. The program will ask for a number, a second number, an operator (+ - * or /). The user can enter this data from the Serial Monitor on the Arduino IDE.
Let’s use the same connections and rewrite our code:
#include <LiquidCrystal.h>
int rs = 7;
int en = 8;
int d4 = 9;
int d5 = 10;
int d6 = 11;
int d7 = 12;
float firstNum;
float secondNum;
float answer;
String op;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
lcd.begin(16, 2); // 16 col, 2 rows
Serial.begin(9600);
}
void loop() {
// Ask for first number
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Type 1st number");
while (Serial.available() == 0) {}
firstNum = Serial.parseFloat();
while (Serial.available() > 0) {
Serial.read();
}
// Ask for second number
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Type 2nd number");
while (Serial.available() == 0) {}
secondNum = Serial.parseFloat();
while (Serial.available() > 0) {
Serial.read();
}
// Ask for operator
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Choose -+/*");
while (Serial.available() == 0) {}
op = Serial.readString()[0];
while (Serial.available() > 0) {
Serial.read();
}
// Choose operator
if (op == "+") {
answer = firstNum + secondNum;
}
if (op == "-") {
answer = firstNum - secondNum;
}
if (op == "*") {
answer = firstNum * secondNum;
}
if (op == "/") {
answer = firstNum / secondNum;
}
// Clear screen
lcd.clear();
lcd.setCursor(0, 0);
// Print answer
lcd.print(firstNum);
lcd.print(op);
lcd.print(secondNum);
lcd.print(" = ");
lcd.print(answer);
delay(3000);
}
A few problems we had We had a few issues: when writing if (op == "+") {
we should be careful to use double quotes and not single quotes
Also, the serial monitor was sending a carriage return after each line, which created a strange bug: a weird symbol appeared and the processor would always return 0.
The solution was to remove the “Line ending” that the serial monitor would send with every input
But in the end it works!