Community project

Four-Channel Inverted BCD

Arduino
Photo of Four-Channel Inverted BCD
Generated with AI

Saravanan Sugumar

Published October 8, 2026

This project builds a four-channel inverted BCD (Binary Coded Decimal) output controller using an Arduino Uno. The 4×4 matrix keypad lets you enter decimal values (0–9) for each of the four channels, which are then encoded as inverted BCD signals on the 2×8 pin header. The SSD1306 OLED display shows your current entry and applied values in real time.

The guide includes a complete wiring diagram, parts list, and Arduino firmware that handles keypad input, BCD encoding, and display updates. Follow the assembly steps to connect the OLED screen and keypad ribbon, wire the four inverted-BCD output pins, then use the keypad to enter and apply your values to each channel.

Wiring diagram

Wiring diagram for Four-Channel Inverted BCD

Gather all the parts

QtyComponent
1

4x4 Matrix Keypad

A 16-button (4 rows × 4 columns) membrane matrix keypad that uses 8 digital I/O lines (4 row + 4 column) to scan all keys. No dedicated power rail is required — rows and columns are driven directly by GPIO. Compatible with the Arduino Keypad library.

1

SSD1306 OLED

0.96 inch 128x64 OLED display with I2C interface

1

2×8 2.54 mm Pin Header

A 16-pin connector that carries four separate 4-bit inverted-BCD outputs to external control equipment.

Assemble it in 4 steps

1. Connect the OLED screen

Connect the OLED VCC pin to the Mega 5V pin (power), OLED GND to Mega GND (ground), OLED SDA to Mega D20 (data), and OLED SCL to Mega D21 (clock).

  • Make sure VCC and GND are not swapped — swapped power can damage the screen.

2. Connect the keypad ribbon

Connect the 4×4 keypad pins in the order printed on its ribbon: R1 → Mega D30 (signal), R2 → D31 (signal), R3 → D44 (signal), R4 → D45 (signal), C1 → D46 (signal), C2 → D26 (signal), C3 → D27 (signal), and C4 → D28 (signal).

  • The keypad needs no VCC or GND wire; its eight ribbon wires go directly to the Mega pins.

3. Wire the four inverted-BCD outputs

Use the 16-pin header for external BCD equipment: channel 1 has D22=8, D23=4, D24=2, D25=1; channel 2 has D29=8, D6=4, D7=2, D8=1; channel 3 has D9=8, D10=4, D11=2, D12=1; channel 4 has D13=8, D14=4, D15=2, D16=1. Each pin is an inverted output: LOW represents a BCD bit of 1, and HIGH represents a BCD bit of 0.

  • Only connect these 5 V logic outputs to equipment that accepts 5 V logic. Use a level converter if the other equipment requires 3.3 V.

4. Enter and apply the four values

After deploying, press four number keys in order: the first is channel 1, then channel 2, channel 3, and channel 4. Press # to copy the values to the four inverted-BCD output groups. Press * to erase the entered values before applying them.

  • The OLED shows each entered digit and the four final inverted BCD bits for every channel.

Review all connections

1. Connections between "keypad_4x4" and "Arduino"

Functionkeypad_4x4Arduino
digitalR1GPIO 30
digitalR2GPIO 31
digitalR3GPIO 44
digitalR4GPIO 45
digitalC1GPIO 46
digitalC2GPIO 26
digitalC3GPIO 27
digitalC4GPIO 28

2. Connections between "oled_1" and "Arduino"

Functionoled_1Arduino
powerVCC5V
groundGNDGND
i2cSDAGPIO 20
i2cSCLGPIO 21

3. Connections between "bcd_output_header" and "Arduino"

Functionbcd_output_headerArduino
digitalCH1_8GPIO 22
digitalCH1_4GPIO 23
digitalCH1_2GPIO 24
digitalCH1_1GPIO 25
digitalCH2_8GPIO 29
digitalCH2_4GPIO 6
digitalCH2_2GPIO 7
digitalCH2_1GPIO 8
digitalCH3_8GPIO 9
digitalCH3_4GPIO 10
digitalCH3_2GPIO 11
digitalCH3_1GPIO 12
digitalCH4_8GPIO 13
digitalCH4_4GPIO 14
digitalCH4_2GPIO 15
digitalCH4_1GPIO 16

Deploy the firmware

#include <Arduino.h>
#include <Wire.h>
#include <Keypad.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

const uint8_t CH1_8_PIN = 22;
const uint8_t CH1_4_PIN = 23;
const uint8_t CH1_2_PIN = 24;
const uint8_t CH1_1_PIN = 25;
const uint8_t CH2_8_PIN = 29;
const uint8_t CH2_4_PIN = 6;
const uint8_t CH2_2_PIN = 7;
const uint8_t CH2_1_PIN = 8;
const uint8_t CH3_8_PIN = 9;
const uint8_t CH3_4_PIN = 10;
const uint8_t CH3_2_PIN = 11;
const uint8_t CH3_1_PIN = 12;
const uint8_t CH4_8_PIN = 13;
const uint8_t CH4_4_PIN = 14;
const uint8_t CH4_2_PIN = 15;
const uint8_t CH4_1_PIN = 16;

const uint8_t bcdPins[4][4] = {
  {CH1_8_PIN, CH1_4_PIN, CH1_2_PIN, CH1_1_PIN},
  {CH2_8_PIN, CH2_4_PIN, CH2_2_PIN, CH2_1_PIN},
  {CH3_8_PIN, CH3_4_PIN, CH3_2_PIN, CH3_1_PIN},
  {CH4_8_PIN, CH4_4_PIN, CH4_2_PIN, CH4_1_PIN}
};

const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {30, 31, 44, 45};
byte colPins[COLS] = {46, 26, 27, 28};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

Adafruit_SSD1306 display(128, 64, &Wire, -1);
uint8_t enteredValues[4] = {0, 0, 0, 0};
uint8_t outputValues[4] = {0, 0, 0, 0};
uint8_t entryPosition = 0;

void writeInvertedBcd(uint8_t channel, uint8_t value) {
  for (uint8_t bit = 0; bit < 4; bit++) {
    uint8_t mask = static_cast<uint8_t>(8 >> bit);
    digitalWrite(bcdPins[channel][bit], (value & mask) ? LOW : HIGH);
  }
}

void applyOutputs() {
  for (uint8_t channel = 0; channel < 4; channel++) {
    outputValues[channel] = enteredValues[channel];
    writeInvertedBcd(channel, outputValues[channel]);
  }
}

void printInvertedBits(uint8_t value) {
  for (int8_t bit = 3; bit >= 0; bit--) {
    display.print((value & (1 << bit)) ? '0' : '1');
  }
}

void drawScreen() {
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println(F("4CH INVERTED BCD"));
  display.println(F("Enter 4 digits: 0-9"));
  for (uint8_t channel = 0; channel < 4; channel++) {
    display.print(F("CH"));
    display.print(channel + 1);
    display.print(F(":"));
    display.print(enteredValues[channel]);
    display.print(channel == entryPosition && entryPosition < 4 ? F(" < ") : F("   "));
    display.print(F("OUT:"));
    printInvertedBits(outputValues[channel]);
    display.println();
  }
  display.println(F("#=RUN  *=CLEAR"));
  display.display();
}

void clearEntry() {
  for (uint8_t channel = 0; channel < 4; channel++) enteredValues[channel] = 0;
  entryPosition = 0;
}

void setup() {
  for (uint8_t channel = 0; channel < 4; channel++) {
    for (uint8_t bit = 0; bit < 4; bit++) pinMode(bcdPins[channel][bit], OUTPUT);
    writeInvertedBcd(channel, 0);
  }
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) for (;;) { }
  drawScreen();
}

void loop() {
  char key = keypad.getKey();
  if (key == NO_KEY) return;
  if (key >= '0' && key <= '9' && entryPosition < 4) {
    enteredValues[entryPosition++] = static_cast<uint8_t>(key - '0');
    drawScreen();
  } else if (key == '*') {
    clearEntry();
    drawScreen();
  } else if (key == '#') {
    applyOutputs();
    entryPosition = 0;
    drawScreen();
  }
}

Remix this project

Make it yours in one click

Open a full copy of this project in your own Schematik workspace — diagram, code, parts, and assembly steps included. Swap the sensor, add features, or redesign the whole thing with AI. The author's original stays untouched.

Open in Schematik