Skip to content

5. Week 5: Input & Output Devices

This week I learned how to use different types input and output devices with microcontroller boards.

KidsIOT

Buzzer

This code uses the KidsIOT microcontroller board to turn on a piezo buzzer alarm. To know which pin should be used in the code for the buzzer, I used the picture below.

Since I connected the buzzer to port #8, the pin number I should use in the code is 5. This was determined by looking at the color of the buzzer casing (red) and finding the pin number written in the same color in the diagram.

Code used:

from machine import Pin # Imports the pin class from the machine module 
import time # Imports the time class 

Buzzer = Pin(5, Pin.OUT)  #initialize digital pin 5 as an output.

while True:            
    Buzzer.value(1)   # Turning the Buzzer on
    time.sleep(1)     #Buzzer Stays on for 0.5 second
    Buzzer.value(0)   # Turning the Buzzer off
    time.sleep(1)     #Buzzer Stays off for 0.5 second

    Buzzer.value(1)   # Turning the Buzzer on
    time.sleep(1)     #Buzzer Stays on for 0.5 second
    Buzzer.value(0)   # Turning the Buzzer off
    time.sleep(1)     #Buzzer Stays off for 0.5 second

Download the code

Code output:

Elegoo UNO R3

LEDs and a Button

This code is based on an existing example code in Arduino IDE. To access the code, go to File -> Examples -> 0.2Digital -> Button.

The code basically uses the status of a button to turn on 2 LEDs: 1-Off Status: A red LED is turned on and a message is written in the serial monitor to indicate that the button is not pressed. 2-On Status: A green LED is turned on and a message is written in the serial monitor to indicate that the button is pressed.

Circuit connections

Code used

/*
  Button

  Turns on and off a light emitting diode(LED) connected to digital pin 13,
  when pressing a pushbutton attached to pin 2.

  The circuit:
  - LED attached from pin 13 to ground through 220 ohm resistor
  - pushbutton attached to pin 2 from +5V
  - 10K resistor attached to pin 2 from ground

  - Note: on most Arduinos there is already an LED on the board
    attached to pin 13.

  created 2005
  by DojoDave <http://www.0j0.org>
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

  https://www.arduino.cc/en/Tutorial/BuiltInExamples/Button
*/

// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2;  // the number of the pushbutton pin
const int ledPin = 13;    // the number of the LED pin green
const int ledPin2 = 11;    // the number of the LED pin red
// variables will change:
int buttonState = 0;  // variable for reading the pushbutton status

void setup() {
  pinMode(ledPin, OUTPUT);    // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT);    // initialize the LED pin as an output:
  pinMode(buttonPin, INPUT);  // initialize the pushbutton pin as an input:
  Serial.begin(9600);         // initialize the serial monitor
}

void loop() {
  buttonState = digitalRead(buttonPin);   // read the state of the pushbutton value:

  // checks if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    digitalWrite(ledPin, HIGH); // turn green led on
    digitalWrite(ledPin2, LOW); // turn red led off
    Serial.println("Button pressed = Green light"); // write the sentence in the serial monitor
  } else {
    digitalWrite(ledPin, LOW); // turn green led off
    digitalWrite(ledPin2, HIGH); // turn red led on
    Serial.println("Button not pressed = Red light"); // write the sentence in the serial monitor
  }
}

Download the code

Code output

Reference video

LCD

This code is used to display text on a Liquid Crystal Display (LCD). Furthermore, it uses a potentiometer to adjust the brightness of the LCD. LCDs have 16 pins on them as seen in the image below. However, you do not need to use them all to switch the LCD on. This type of LCD has two operating modes:

4 bits: uses 4 data pins which reduces the number of wires on the circuit and the speed of data transfer (requires twice the time compared to the 8 bit mode) and allows for the unused pins to be used for other electronics.

8 bits: uses 8 data pins which increases the number of wires in the circuit and takes up many digital pins in the microcontroller that could be used for other electronics. On the the hand, it transfers data twice as fast compared to the 4-bit mode.

In this code example, I utilized the LCD screen using the 4-bit mode.

Circuit connections


Installing a Library

Before starting the coding process, I needed to download the LiquidCrystal library. A library is a file written in C or C++ which provides the arduino sketch (code file) with extra function to be able to control varies electronic components such as LCDs. To install the library, I went to the library manager and search for the library I needed (LiquidCrystal) and pressed the install button to install it.

To include the library in the sketch, go to Sketch -> Include Library -> LiquidCrystal.


Alternately, you can simply write #include to add the library you want to your sketch after downloading it. Every library has a set of functions included in it that are used to program the specific electronic component the module is made for. The image below shows the list of functions that are available in the LiquidCrystal Library.

Columns and Rows

To specify which column and row the start displaying from, I used the image above and the following code function:

setCursor(column,row)

Code used

#include <LiquidCrystal.h> //adding the lcd library

LiquidCrystal lcd(1, 2, 4, 5, 6, 7);
// creating a variable of type LiquidCrystal. Basically, letting the arduino know which pin is connected to which pin.
// lcd pins (RS, Rw, E, D4, D5, D6, D7).

void setup() {
  lcd.begin(16, 2); // setting the dimension of the lcd.

}

void loop() {

  lcd.setCursor(2,0); //determining the location of the text on the lcd "setCursor(Coloumn, Row)".
  lcd.print("Testing LCD"); // Printing the text on the lcd

  lcd.setCursor(2,1); //determining the location of the text on the lcd.
  lcd.print("Without I2C.."); // Printing the text on the lcd

  lcd.setCursor(15,1); //determining the location of the text on the lcd.
  lcd.blink(); //printing a blinking character
  delay(3000); // determining the duration it stays on

  lcd.clear(); //clears the display

  lcd.setCursor(3,0); //determining the location of the text on the lcd.
  lcd.print("It works!"); // Printing the text on the lcd
  lcd.setCursor(12,0); //determining the location of the text on the lcd.
  lcd.blink(); //printing a blinking character
  delay(3000); // determining the duration it stays on

  lcd.clear(); //clears the display

}

Download the code

Code output

The potentiometer is being used to adjust the brightness of the LCD.

Reference video

LCD with I2C

Wiring an LCD takes up many pins on the microcontroller as well as many wire which increases the likelihood of wrong connections. To solve all of these issues, an I2C board can be used.

I2C

I2C (Inter-Integrated Circuit) is a two-wire communication protocol used in electronics for connecting low-speed devices like sensors and microcontrollers. It uses a serial data line (SDA) and a serial clock line (SCL) to transfer data between multiple master and slave devices. Each device has a unique address, and data is sent in bytes. I2C supports different speed modes and is valued for its simplicity and low pin count, making it ideal for embedded systems and on-board communications.

Using I2C with an LCD will reduce the number of pins from 16 pins to 4 pins, which means that number of wires will be reduced to 1/4th. Before starting coding the I2C LCD screen, I needed to download and install the LiquidCrystal I2C library.

To install the library in the Arduino IDE, go to Sketch ->Include Library-> Add .ZIP Library and select the downloaded zip file.


Circuit connections

Code used

#include <Wire.h>  //library to communicate with I2C devices
#include <LiquidCrystal_I2C.h> //Adding the library of the LCD I2C

LiquidCrystal_I2C lcd(0x27, 16, 2); //stating the address and size of the lcd

void setup() {
  lcd.init();  //Initializing the lcd
  lcd.backlight(); //starting the backlight of the lcd
}

void loop() {
  lcd.setCursor(2,0); //determining the location of the text on the lcd "setCursor(Coloumn, Row)".
  lcd.print("Testing LCD"); // Printing the text on the lcd

  lcd.setCursor(3,1); //determining the location of the text on the lcd.
  lcd.print("with I2C.."); // Printing the text on the lcd

  lcd.setCursor(13,1); //determining the location of the text on the lcd.
  lcd.blink(); //printing a blinking character
  delay(3000); // determining the duration it stays on

  lcd.clear(); //clears the display

  lcd.setCursor(3,0); //determining the location of the text on the lcd.
  lcd.print("It works!"); // Printing the text on the lcd
  lcd.setCursor(1,1);  //determining the location of the text on the lcd.
  lcd.print("Much easier! :)"); // Printing the text on the lcd
  delay(3000); // determining the duration it stays on

  lcd.clear(); //clears the display

}

Download the code

Adjusting brightness

One of the useful features of the I2C boards is that it includes a built-in potentiometer to adjust the brightness of the screen.

Code output

Reference video

Ultrasonic Sensor

An ultrasonic sensor is a device that uses ultrasonic sound waves to measure distance to an object. It works by emitting a high-frequency sound wave (usually beyond the range of human hearing, typically above 20 kHz) and then listening for the echo that bounces back from the object. By measuring the time it takes for the sound wave to return, the sensor can calculate the distance to the object.

The ultrasonic sensor has 4 pins:
1-VCC: input voltage (5V).
2-GND: ground.
3-Trigger: used to trigger the ultrasonic sound pulses.
4-Echo: produces a pulse when the reflected signal is received. The length of the pulse is proportional to the time it took for the transmitted signal to be detected.

The code used is based on the ELEGOO Super Starter Kit for UNO Tutorial. I had to install the SR04 in the Arduino IDE for the code to work (The libary is included in the ELEGOO kit tutorial files).

Circuit connections

Code used

//www.elegoo.com
//2016.12.08

#include "SR04.h"
#include <LiquidCrystal_I2C.h>
#include <Wire.h>

LiquidCrystal_I2C lcd(0x27, 16, 2); //stating the address and size of the lcd

#define TRIG_PIN 9
#define ECHO_PIN 10
SR04 sr04 = SR04(ECHO_PIN,TRIG_PIN);

long a;

void setup() {
  lcd.init();  //Initializing the lcd
  lcd.backlight(); //starting the backlight of the lcd

}

void loop() {
   a=sr04.Distance();
   lcd.clear();
   lcd.print("Distance (cm):");
   lcd.setCursor(0,1);
   lcd.print(a);
   delay(500);

}

Download the code

Code output

Rotary Encoder

A rotary encoder is an electromechanical device that converts the angular position or motion of a shaft or axle into a digital or analog signal. It is used to measure rotation, speed, and direction, providing feedback in systems that require precise control of position and movement.

The rotary encoder has five pins:
1- +: Power supply (5V).
2-GND: Ground connection.
3-CLK(Channel A): Outputs a signal corresponding to the angular position or change in position.
4-DT(Channel B):Used in conjunction with Output A to determine the direction of rotation. (For incremental encoders).
5-SW button/switch.

I have used the rotary encoder alongside with a LCD to create a menu for my group’s final project (automatic pill dispenser). My teammembers Saeed and Ali helped me with the coding process.

Rotary encoder working

#include <LiquidCrystal_I2C.h>
#include  <Wire.h>

#define outputA 2
#define outputB 3

int counter = 0; 
int aState, bState;
int aLastState;
String Medicine1 = "Panadol"; 
String Medicine2 = "Accutane"; 
String Medicine3 = "strepsils"; 
String Medicine4 = "Vicks"; 
String Medicine5 = "Vitamin C"; 

LiquidCrystal_I2C lcd(0x27,  16, 2);

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

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


  //initialize lcd screen. screen messes up without this
  lcd.init();
  // turn on the backlight
  lcd.backlight();

 } 

 void loop() { 
   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 ++;
       if ( counter > 30)  counter = 0;

     } else {
       counter --;
       if ( counter < 0)  counter = 30;
     }
     lcd.setCursor(0, 0);
     lcd.print("Med: ");
     if (counter >= 0 && counter < 7){
     lcd.clear();
     lcd.print("Medicine #1");
     lcd.setCursor(0,1);
     lcd.print(Medicine1);
     }

     if (counter > 6 && counter < 13){
     lcd.clear();
     lcd.print("Medicine #2");
     lcd.setCursor(0,1);
     lcd.print(Medicine2);
     }

    if (counter > 12 && counter < 19){
     lcd.clear();
     lcd.print("Medicine #3");
     lcd.setCursor(0,1);
     lcd.print(Medicine3);
     }

    if (counter > 18 && counter < 25){
     lcd.clear();
     lcd.print("Medicine #4");
     lcd.setCursor(0,1);
     lcd.print(Medicine4);
     }

    if (counter > 24 && counter < 31){
     lcd.clear();
     lcd.print("Medicine #5");
     lcd.setCursor(0,1);
     lcd.print(Medicine5);
     }

     } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
 }

Download the code

Code output

Reference video


Last update: August 30, 2024