9. Output Devices

For this week's development, we were asked to implement outputs or output devices. In my case, I will be using an OLED display and a servo motor. I will use the same board I developed last week, as the purpose of that board was to conduct tests and use it for future weeks. First, I will explain a bit about what outputs are and what types of outputs exist. Additionally, I will explain how the components I am going to use work.

Output

Digital outputs can be in one of two states: high (HIGH) or low (LOW), which corresponds to a high voltage (typically 5V in most Arduino boards) or a low voltage (0V). They are used to turn devices on and off, such as LEDs, relays, and motors. Digital outputs can also send pulses to control devices like servomotors or blinking LEDs. For more information GROUP PAGE .

PWM outputs allow simulating an analog signal using a digital signal that rapidly switches between high and low states. This technique controls the amount of power delivered to a device by varying the width of the pulses in a given time period. PWM outputs are used to control the speed of motors, the brightness of LEDs, and other devices that require a variable analog signal. By adjusting the duty cycle (the percentage of time the signal is high within a cycle), PWM can effectively manage devices that need varying levels of power.

materials

  • Development Board made in week 8
  • OLED screen
  • Servomotors
  • Potentiometer

component operation

I will briefly explain how the components I am going to use work and their characteristics, along with some examples.

OLED screen

The SSD1306 OLED screen is widely used in various microcontroller projects, including platforms like Arduino, Raspberry Pi, and ESP8266/ESP32. It is also ideal for wearable devices due to its low power consumption and compact size. It is used in indicators and meters to display critical information such as temperature and voltage.

    Features

  • Technology: OLED, no backlight needed.
  • Resolution: 128x64 or 128x32 pixels.
  • Controller: SSD1306.
  • Interface: I2C and SPI.
  • Size: Between 0.96 and 1.3 inches.
  • Power consumption: Very low.
  • Color: Monochrome (white, blue, or yellow).

The SSD1306 OLED screen requires specific commands to initialize and configure the controller. It uses I2C or SPI communication interfaces to receive data from the microcontroller. Each pixel on the screen can be controlled individually, allowing for high precision in graphic representation. Using libraries such as Adafruit_SSD1306 and U8g2 significantly simplifies the process of drawing and controlling pixels.

OLED screens are used in a wide range of technological devices. They are popular in mobile devices like smartphones and tablets for their high image quality and energy efficiency. In televisions, they stand out for displaying vibrant colors and deep blacks. They are also ideal for wearables, such as smartwatches, due to their compact size and low power consumption.

Servo Motor

The MG90S servo motor is widely used in various microcontroller projects, including platforms like Arduino, Raspberry Pi, and ESP8266/ESP32. It is ideal for applications requiring precise control of rotational position, such as robotics, RC vehicles, and mechanical arms.

    Features

  • Type: Micro servo motor.
  • Operating Voltage: 4.8V - 6.0V.
  • Torque: 1.8 kg/cm (4.8V), 2.2 kg/cm (6.0V).
  • Speed: 0.1s/60 degrees (4.8V), 0.08s/60 degrees (6.0V).
  • Control Method: PWM.
  • Dimensions: 22.8 x 12.2 x 28.5 mm.
  • Weight: 13.4g.

The PWM signal (pulse width modulation) is used to control servomotors like the MG90S through a square wave with an adjustable duty cycle. It operates at a frequency of 50 Hz, repeating 50 times per second. The pulse duration, which ranges from 1 ms to 2 ms, determines the position of the servomotor: 1 ms for 0 degrees, 1.5 ms for 90 degrees, and 2 ms for 180 degrees. This technique allows for precise control of the servomotor's position.

Board and jumpers

The features and functionalities of the board are explained in week 8. The jumpers will be used for the connections between the board and the servomotor. The OLED screen will be connected directly to the board.

code

Before starting with the code, I already had an idea of what I wanted to do. I wanted to be able to move a servo with two buttons that the board has and display the angle on the screen.Before starting with the code, I already had an idea of what I wanted to do. I wanted to be able to move a servo with two buttons that the board has and display the angle on the screen.

Below, you can see the complete code for this practice. Further down, it is detailed and explained how it was done. CODE




Here is a more detailed description of each part of the code.

code9

This section of the code initializes libraries and configurations for an Arduino project involving an OLED display and servo motors. It includes the Wire library for I2C communication, the Adafruit SSD1306 library for the OLED display, and the Servo library for servo control. The code defines the screen dimensions and I2C pins, and initializes the SSD1306 display instance with these settings.

#include <Wire.h> // Includes the Wire library for I2C communication
#include <Adafruit_SSD1306.h> // Includes the Adafruit library for the OLED display
#include <Servo.h> // Includes the Servo library to control servos

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.

#define OLED_RESET -1 // Reset pin (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C // Address for the OLED display; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // OLED display instance

code9

This section of the code defines a constant array named `FAB` with hexadecimal data for a 128x64 pixel logo stored in program memory (`PROGMEM`). This data allows the OLED display to render the logo correctly, enabling custom graphics to be displayed in the Arduino project.

// 'logo-1', 128x64px
const unsigned char FAB[] PROGMEM = {
// Image data for the logo in hexadecimal format
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Continue declaration of the image data for the logo
// (omitting data here for brevity, but all the logo data would be included)
};

code9

This section of the code initializes the OLED display with voltage generated internally from 3.3V. If the initialization fails, it prints an error message "SSD1306 allocation failed" to the serial monitor and enters an infinite loop, preventing the program from proceeding further. This ensures that the program halts if the display cannot be properly set up.

// Starts the OLED display with voltage generated internally from 3.3V
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed")); // Prints error if initialization fails
for (;;); // Do not proceed, loop forever
}

code9

This section of the code clears the OLED display, sets its rotation to 180 degrees, draws the logo defined by the FAB array at coordinates (0, 0) with a width of 128 pixels and height of 64 pixels, and finally updates the display to show the drawn content.

display.clearDisplay(); // Clears the display
display.setRotation(2); // Sets the display rotation
display.drawBitmap(0, 0, FAB, 128, 64, WHITE); // Draws the logo on the display
display.display(); // Displays the content on the screen

code9

This section of the code sets the display rotation, clears the screen, and configures the text size and color. It positions the cursor at the top-left corner and prints "FAB," "ACADEMY," and "WEEK 9 OUTPUT" on the OLED display. Finally, it updates the display to show the new content and waits for 2 seconds.

display.setRotation(2); // Sets the display rotation
display.clearDisplay(); // Clears the display
display.setTextSize(3); // Sets the text size
display.setTextColor(WHITE); // Sets the text color
display.setCursor(0, 0); // Sets the cursor to position (0, 0)
display.println("FAB"); // Displays the text "FAB"
display.println("ACADEMY"); // Displays the text "ACADEMY"
display.setTextSize(1); // Sets the text size to 1
display.setTextColor(WHITE); // Sets the text color
display.println("WEEK 9 OUTPUT");// Displays the text "WEEK 9 OUTPUT"
display.display(); // Displays the content on the screen
delay(2000); // Waits for 2 seconds

code9

This section of the code checks if pin 4 reads a high value. If true, it turns on the LED connected to pin 13. Additionally, if the servo position is less than 180 degrees, it increases the position by 20 degrees, moves the servo to the new position, and includes a small delay to avoid bouncing.

if (digitalRead(4) == 1) { // If pin 4 reads a high value
digitalWrite(13, HIGH); // Turns on the LED on pin 13
if (pos < 180) { // If the position is less than 180 degrees
pos += 20; // Increases the position by 20 degrees
myservo.write(pos); // Moves the servo to the new position
delay(200); // Small delay to avoid bouncing
}
}

Steps to Convert an Image to Hexadecimal Data Using Image2cpp


  1. Go to Image2cpp.
  2. Upload the image using "Choose file".
  3. Set the output dimensions according to your screen.
  4. Adjust the options:
    • Select the color mode and output format as hexadecimal.
    • Adjust rotation and mirroring if necessary.
  5. Generate the code by clicking "Generate Code".
  6. Copy the generated code and paste it into your project.

connections

The connections made for the practice can be seen below. The OLED screen was connected directly to the pins coming out of the board. The servomotor was connected using jumpers. To see the corresponding pins, visit the page for week number 8.

final results

These are the results for week 9. You can see how the OLED screen displays the FAB logo for a few seconds when the program starts, followed by "FAB Academy, week 9, outputs." Next, it shows the current angle of the servo. Finally, I used a small, widely available claw to make it look more appealing. You can find the STL model of the claw at the following link STL Model.

what I learned?

Thanks to this practice, I learned what a digital output is and how, with the help of a digital output, we can generate pulses called PWM to simulate analog outputs. This practice will be very useful for my final project and any other project I have in mind, as this is a key concept in electronics and how it works.