ADC (Analog to Digital Converter) adalah perangkat yang mengubah sinyal analog menjadi sinyal digital. Besaran analog di sini maksudnya adalah besaran yang mempunyai nilai kontinyu pada waktu kontinyu, sedangkan digital di sini maksudnya adalah memiliki representasi diskrit pada waktu yang diskrit.
Perubahan waktu kontinyu menjadi waktu diskrit menggunakan proses pencuplikan (sampling). Perubahan amplitudo kontinyu menjadi amplitudo diskrit menggunakan proses kuantisasi.
Bentuk fisik ADC dapat berupa sebuah chip, bisa juga dibuat menggunakan komponen diskrit (transistor, gerbang logika, op-amp), ataupun sudah menyatu dengan mikrokontroler.
Berikut ini contoh skema suatu Integrating ADC (sumber)
Parameter ADC
Parameter-parameter ADC adalah sebagai berikut
resolusi: menyatakan berapa jumlah nilai diskrit yang dapat dihasilkan untuk merepresentasikan nilai masukan analog. Umumnya dinyatakan dalam jumlah bit pada output ADC
kecepatan sampling: parameter ini menyatakan berapa banyak konversi analog ke digital yang dapat dilakukan setiap detik.
Resolusi
Konsep resolusi ADC dapat dilihat pada contoh ini. Berikut ini contoh pemetaan nilai analog (0 sampai 1.0) ke nilai biner terkait dari suatu ADC 8 bit (sumber)Pencuplikan
Sinyal analog bersifat kontinyu pada domain waktu. Untuk mengubah sinyal analog ini menjadi digital, perlu didefinisikan seberapa cepat nilai digital dicuplik dari sinyal analog. Kecepatan menghasilkan nilai digital ini adalah kecepatan sampling atau frekuensi sampling (sampling rate / sampling frequency).
Sinyal analog dapat dicuplik menjadi sinyal digital dan kemudian dapat dikembalikan lagi ke bentuk analog dengan syarat kecepatan samplingnya lebih tinggi dari dua kali frekuensi maksimum pada sinyal analog tersebut. Kriteria ini adalah disebut juga sebagai teorema pencuplikan Nyquist-Shannon.
Antar Muka ADC
ADC umumnya dipakai bersamaan dengan elemen komputasi seperti mikroprosesor/mikrokontroler ataupun FPGA (Field Programmable Array) . Antar muka antara ADC dengan elemen komputasi dapat dengan berbagai cara, seperti:
Terintegrasi dalam 1 chip, seperti ADC pada mikrokontroler ATmega328 di modul Arduino UNO / Arduino Nano / ESP32
Bus data mikroprosesor paralel
Komunikasi serial I2C (Inter Integrated Circuit)
Komunikasi serial SPI (Serial Peripheral Interface)
Komunikasi serial proprietary
Contoh ADC terintegrasi adalah mikrokontroler Arduino Nano yang di dalamnya ada ADC 10 bit.
Arduino Nano
Contoh ADC yang menggunakan komunikasi bus data adalah ADC0804 (sumber). Berikut ini contoh skema rangkaian interkoneksi antara mikroprosesor dengan ADC0804
Bentuk fisik ADC0804
Skema rangkaian ADC0804
Pada saat ini jarang sekali orang menggunakan teknik ini, karena biasanya mikrokontroler tidak memiliki bus yang dapat diakses.
Contoh ADC dengan bus I2C adalah ADS1115 buatan Texas Instruments . ADC ini banyak dijual sebagai modul yang sudah disolder.
Modul ADS1115
Contoh ADC dengan koneksi SPI adalah MCP3008 buatan Microchip
MCP3008
Aplikasi ADC
ADC dipakai untuk berbagai aplikasi seperti
Perekaman suara
Pengolahan sinyal meliputi perekaman, penyimpanan dan pengiriman sinyal melalui media tertentu
Instrumentasi ilmiah untuk merekam sinyal dari berbagai sensor
// Profiling kecepatan konversi ADC MCP3008 di ESP32
// menggunakan modified header dari https://github.com/bakercp/MCP3XXX
#include "MCP3XXXZ.h" // custom header
MCP3008 adc;
void setup() {
Serial.begin(115200);
Serial.println("start");
// Use the default SPI hardware interface.
adc.begin();
// Or use custom pins to use a software SPI interface.
// adc.begin(SS, MOSI, MISO, SCK);
pinMode(22, OUTPUT); // digital output for monitoring
pinMode(21, OUTPUT);
adc.spistart(); //
}
int counter = 0, last_time = 0, current_time = 0;
float durasi=0;
int jumlah_iterasi=100000;
void loop() {
for (;;) {
digitalWrite(22, HIGH); // turn the LED on (HIGH is the voltage level)
adc.analogRead(0);
digitalWrite(22, LOW); // turn the LED on (HIGH is the voltage level)
counter = counter + 1;
if (counter == jumlah_iterasi) { // tiap 10000x berhenti
counter = 0;
current_time = millis();
durasi = (float)(current_time - last_time) / (float) jumlah_iterasi;
Serial.print("durasi (ms) ");
Serial.println(durasi,4);
last_time = current_time;
}
}
}
Kode header sebagai berikut
//
// Copyright (c) 2018 Christopher Baker <https://christopherbaker.net>
//
// SPDX-License-Identifier: MIT
//
#pragma once
#include <Arduino.h>
#include <SPI.h>
/// \brief A template class supporting MCP3XXX ADC SPI chips.
///
/// \tparam NumBits Number of ADC bits.
/// \tparam NumChannels Number of input channels.
/// \tparam MaxSPIClockSpeed Maximum SPI communication speed rate in Hz.
/// \tparam SPITransferLength The number of bytes transferred over SPI.
template<uint8_t NumBits,
uint8_t NumChannels,
uint32_t MaxSPIClockSpeed,
uint8_t SPITransferLength = 3>
class MCP3XXX_
{
public:
enum
{
/// \brief ADC error value.
ADC_ERROR_INVALID_CHANNEL = -1,
/// \brief ADC error value.
ADC_UNSUPPORTED_CONFIGURATION = -2,
/// \brief Number of ADC bits.
NUM_BITS = NumBits,
/// \brief A bit mask based on the number of bits.
BIT_MASK = (1 << NUM_BITS) - 1,
/// \brief Number of input channels.
NUM_CHANNELS = NumChannels,
/// \brief Maximum SPI communication speed rate in Hz.
MAX_SPI_CLOCK_SPEED = MaxSPIClockSpeed,
/// \brief The number of bytes transferred over SPI.
SPI_TRANSFER_LEGNTH = SPITransferLength
};
/// \brief Construct a default MCP3XXX_ device.
MCP3XXX_()
{
}
/// \brief Destroy the MCP3XXX_ device.
~MCP3XXX_()
{
}
void spistart(){
SPI.beginTransaction(SPISettings(MAX_SPI_CLOCK_SPEED, MSBFIRST, SPI_MODE0));
}
/// \brief Set up the ADC using default hardware SPI pins.
///
/// Hardware SPI pins vary based on the board being used. These default pins
/// are represented by the constants SS, MOSI, MISO and SCK.
///
/// \sa https://www.arduino.cc/en/Reference/SPI
/// \param csPin Chip Select Pin. Default value is SS.
void begin(uint8_t csPin = SS)
{
_useHardwareSPI = true;
_csPin = csPin;
_mosiPin = MOSI;
_misoPin = MISO;
_sckPin = SCK;
// Set up pin modes.
pinMode(_csPin, OUTPUT);
// Begin software SPI.
// Initializes the SPI bus by setting SCK, MOSI, and SS to outputs,
// pulling SCK and MOSI low, and SS high.
digitalWrite(_csPin, HIGH); // Redundant.
SPI.begin();
}
/// \brief Set up the ADC using custom software SPI pins.
///
/// This method forces the SPI to be accesed via software methods rather
/// than hardware SPI. This is true, even if the default hardware SPI pins
/// are used.
///
/// \param csPin Chip Select Pin.
/// \param mosiPin MOSI pin.
/// \param misoPin MISO pin.
/// \param sckPin Clock pin.
void begin(uint8_t csPin, uint8_t mosiPin, uint8_t misoPin, uint8_t sckPin)
{
_useHardwareSPI = false;
_csPin = csPin;
_mosiPin = mosiPin;
_misoPin = misoPin;
_sckPin = sckPin;
// Set up pin modes manually.
pinMode(_csPin, OUTPUT);
pinMode(_mosiPin, OUTPUT);
pinMode(_misoPin, INPUT);
pinMode(_sckPin, OUTPUT);
// Begin software SPI. We initiate CS Pin HIGH to prepare it to go LOW
// on our first read.
digitalWrite(_csPin, HIGH);
}
/// \brief Read the analog value.
///
/// Reads a single-ended analog value using the given channel.
///
/// \param channel The channel (channel < NUM_CHANNELS) to read.
/// \returns values [0, MAX_VALUE) on success or an error code on failure.
uint32_t analogRead(uint8_t channel) const
{
if (channel < NUM_CHANNELS)
return _read(channel, false);
return ADC_ERROR_INVALID_CHANNEL;
}
/// \brief Read a differential analog value by specifying the IN+ channel.
///
/// Consecutive channel pairs can be differentially read. For instance, if
/// inPositiveChannel == 0, inNegativeChannel will be 1.
/// If inPositiveChannel == 1, then inNegativeChannel will be 0. Thus if
/// inPositiveChannel is odd, inNegativeChannel == (inPositiveChannel - 1).
/// if inPositiveChannel is even, inNegativeChannel == (inPositiveChannel + 1).
///
/// \param inPositiveChannel The channel that should be input positive.
/// \returns Differential values. See the data sheet for information on how
/// to interpret these return values.
uint32_t analogReadDifferential(uint8_t inPositiveChannel) const
{
if (inPositiveChannel < NUM_CHANNELS)
return _read(inPositiveChannel, true);
return ADC_ERROR_INVALID_CHANNEL;
}
/// \returns the number of ADC channels.
size_t numChannels() const
{
return NUM_CHANNELS;
}
/// \returns the number of ADC bits.
size_t numBits() const
{
return NUM_BITS;
}
private:
MCP3XXX_(const MCP3XXX_&);
MCP3XXX_& operator = (const MCP3XXX_&);
/// \brief Read the value from the given channel using the given mode.
/// \param channel The channel to read.
/// \param differential If true, use differential read mode.
uint32_t _read(uint8_t channel, bool differential) const
{
// Data transfers are done using "8-bit segments" approach in data sheet.
// The sent data alignment resuls in correctly aligned return bytes after
// the SPI transfer.
uint8_t data[SPI_TRANSFER_LEGNTH];
// Check for MCP3004
if (NUM_CHANNELS == 2)
{
if (NUM_BITS == 10)
{
// Start bit.
data[0] = 0b01000000;
// Differential bit.
data[0] |= (differential ? 0b00000000 : 0b00100000);
// Channel bit.
data[0] |= (channel == 0 ? 0b00000000 : 0b00010000);
// MSBF bit is set to 1. See section 5.1 of the data sheet.
data[0] |= 0b00001000;
// It doesn't matter what data[1] is set to.
}
else
{
return ADC_UNSUPPORTED_CONFIGURATION;
}
}
else
{
if (NUM_BITS == 10)
{
// The start bit. We position it here to align our output data.
data[0] = 0b00000001;
// Set the differential / single bit and the channel bits.
data[1] = (differential ? 0b00000000 : 0b10000000) | (channel << 4);
// It doesn't matter what data[2] is set to.
}
else
{
return ADC_UNSUPPORTED_CONFIGURATION;
}
}
if (_useHardwareSPI)
{
// Here we replace the sent data with the received data.
// SPI.beginTransaction(SPISettings(MAX_SPI_CLOCK_SPEED, MSBFIRST, SPI_MODE0));
// digitalWrite(21, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(_csPin, LOW);
for (size_t i = 0; i < SPI_TRANSFER_LEGNTH; ++i)
{
data[i] = SPI.transfer(data[i]);
}
digitalWrite(_csPin, HIGH);
// digitalWrite(21, LOW); // turn the LED on (HIGH is the voltage level)
// SPI.endTransaction();
}
else
{
// Slower, but can use any pin.
// We could save a few operations by skipping some digitalWrites(),
// using bitwise operators and doing direct port-manipulation.
// But this is used because it is "easier" to read.
digitalWrite(_csPin, LOW);
for (size_t i = 0; i < SPI_TRANSFER_LEGNTH; ++i)
{
for (size_t j = 8; j-- > 0;)
{
// Set MOSI data.
digitalWrite(_mosiPin, bitRead(data[i], j));
// Set Clock HIGH.
digitalWrite(_sckPin, HIGH);
// Read MISO data.
bitWrite(data[i], j, digitalRead(_misoPin));
// Set Clock LOW.
digitalWrite(_sckPin, LOW);
}
}
digitalWrite(_csPin, HIGH);
}
// Here we take the second two bytes returned as our value.
// This value is already correctly aligned since we are using the 8-bit
// segments approach. The BIT_MASK is calculated based on the number out
// bits specified in the template parameters.
return ((data[SPI_TRANSFER_LEGNTH - 2] << 8) | data[SPI_TRANSFER_LEGNTH - 1]) & BIT_MASK;
}
/// \brief Use hardware SPI to communicate.
bool _useHardwareSPI = true;
/// \brief Chip Select pin.
uint8_t _csPin = SS;
/// \brief MOSI pin.
uint8_t _mosiPin = MOSI;
/// \brief MISO pin.
uint8_t _misoPin = MISO;
/// \brief SCLK pin.
uint8_t _sckPin = SCK;
};
/// \brief A typedef for the MCP3002.
/// Max clock frequency for 2.7V: 1200000 Hz
/// Max clock frequency for 5.0V: 3200000 Hz
/// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21294E.pdf
typedef MCP3XXX_<10, 2, 1200000, 2> MCP3002;
/// \brief A typedef for the MCP3004.
/// Max clock frequency for 2.7V: 1350000 Hz
/// Max clock frequency for 5.0V: 3600000 Hz
/// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21295C.pdf
typedef MCP3XXX_<10, 4, 1350000> MCP3004;
/// \brief A typedef for the MCP3008.
/// Max clock frequency for 2.7V: 1350000 Hz
/// Max clock frequency for 5.0V: 3600000 Hz
/// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21295C.pdf
//typedef MCP3XXX_<10, 8, 1350000> MCP3008;
typedef MCP3XXX_<10, 8, 3000000> MCP3008;
// /// \brief A typedef for the MCP3202.
// /// Max clock frequency for 2.7V: 900000 Hz
// /// Max clock frequency for 5.0V: 1800000 Hz
// /// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21034D.pdf
// typedef MCP3XXX_<12, 2, 900000> MCP3202;
//
// /// \brief A typedef for the MCP3204.
// /// Max clock frequency for 2.7V: 1000000 Hz
// /// Max clock frequency for 5.0V: 2000000 Hz
// /// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf
// typedef MCP3XXX_<12, 4, 1000000> MCP3204;
//
// /// \brief A typedef for the MCP3208.
// /// Max clock frequency for 2.7V: 1000000 Hz
// /// Max clock frequency for 5.0V: 2000000 Hz
// /// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21298c.pdf
// typedef MCP3XXX_<12, 8, 1000000> MCP3208;
//
// /// \brief A typedef for the MCP3208.
// /// Max clock frequency for 2.7V: 1050000 Hz
// /// Max clock frequency for 5.0V: 2100000 Hz
// /// \sa http://ww1.microchip.com/downloads/en/DeviceDoc/21697e.pdf
// typedef MCP3XXX_<13, 8, 1050000> MCP3304;
# Applying the filter to a signal s can be as simple as writing # s = np.convolve(s, h)
x = np.linspace(0,1, 20001)
# filter digital signal_frequency=8000 # diubah-ubah sesuai keperluan y=np.sin(x*2*math.pi * signal_frequency) # Applying the filter to a signal s can be as simple as writing y_out = np.convolve(y, h) plt.figure(figsize=(16,6)) plt.plot(x, y_out[0:20001],label="output") plt.plot(x, y[0:20001],label="input") plt.title("signal:{} Hz".format(signal_frequency)) plt.legend() plt.axis('tight') plt.xlim([0, 0.01]) plt.savefig("simulasi-signal-{}.jpg".format(signal_frequency))
Hasil simulasi untuk frekuensi 8 Hz
Hasil simulasi untuk frekuensi 80 HzHasil simulasi untuk frekuensi 800 Hz
Hasil simulasi untuk frekuensi 8000 Hz
Simulasi dengan C di Desktop
Pada percobaan ini filter disimulasikan di Desktop PC untuk mengecek ketepatan perhitungan dibandingkan dengan versi Python.
// zeros y_history for (i=0; i<orde_filter; i++) { y_history[i]=0; } for (i=0; i<20000; i++) { printf("."); float t,y; t=(float)i/(float)20000; // time axis y=sin(2 * M_PI *signal_frequency* t); // fprintf(fp,"%f,%f\n",t,y);
// hitung history signal for (j=orde_filter-1; j>=1; j--) { int src=j-1; int dst=j; y_history[dst]=y_history[src]; // printf("%d %d\n",src,dst); } y_history[0]=y;
sinyal 80 Hz nampak teredam sedikit sekali dan ada lag
Tampilan Visualisasi untuk sinyal 800 Hz
nampak sinyal 800 Hz teredam sekitar 50%
Tampilan Visualisasi untuk sinyal 8000 Hz
nampak sinyal 8000 Hz teredam hampir semuanya
Simulasi dengan C di ESP32
pada percobaan ini kode dijalankan di ESP32 namun input adalah simulasi bukan dari generator sinyal. Output direkam ke port serial, bukan ke osiloskop.
Kode ESP32 adalah sebagai berikut
#define ORDE_FILTER 53
void setup() {
Serial.begin(115200);
//
int i, j, k;
char filename[100];
// simulasi 1 detik saja
float signal_frequency = 8; // frekuensi input signal
Berikut ini beberapa cara menyambungkan beberapa input analog ke suatu mikrokontroler.
Pencuplikan Sekuensial Konversi Sekuensial
Cara pertama adalah dengan menggunakan 1 buah ADC yang dipakai untuk membaca semua kanal secara bergantian. Agar dapat membaca beberapa kanal, maka di depan ADC dipasang sebuah multiplekser analog, yang dapat memilih input analog mana yang akan dibaca. Pada metode ini , pencuplikan / sampling pada setiap kanal input terjadi tidak serentak, namun secara berurutan.
Input analog sekuensial
Pencuplikan terjadi di waktu yang tidak sama, sehingga dapat menjadi noise/ jitter, terutama kalau waktu konversi ADC agak panjang.
Pencuplikan Serentak Konversi Sekuensial
Cara kedua adalah dengan menggunakan beberapa komponen sample/hold, agar memungkinkan terjadinya pencuplikan semua kanal pada waktu yang bersamaan. Konversi dari analog ke digital dilakuan satu per satu dengan sebuah ADC. Cara ini memiliki kelebihan yaitu semua data diambil pada waktu yang bersamaan, sehingga lebih mudah untuk pengolahan sinyal digitalnya.
Input analog serentak versi 1
Pencuplikan Serentak Konversi Serentak
Cara ketiga adalah melakukan pencuplikan secara bersamaan, dan melakukan konversi analog ke digital secara bersamaan juga. Cara ini lebih cepat dibandingkan cara kedua.
ADC dapat menggunakan ADC yang sudah built in di mikrokontroler, ataupun ADC eksternal seperti ADC MCP3008
Multiplexer analog dapat menggunakan built-in multiplekser di dalam ATMega328, atau menggunakan ADC yang sudah ada multiplexer (MCP3008), atau menggunakan switch analog seperti CD4066
Saat ini mikroprosesor sudah tersedia dalam bentuk mikrokontroler seperti ATmega328 yang sudah mengintegrasikan CPU, memori dan periferal input output di dalamnya. Akibatnya untuk membuat suatu sistem mikroprosesor tidak lagi diperlukan banyak komponen pendukung lain. Mikrokontroler ini masih memerlukan kristal, power supply dan beberapa komponen lain.
Selain itu juga banyak yang sudah tersedia dalam bentuk modul, seperti Arduino UNO, Arduino Nano, Blue Pill dan sebagainya. Pada modul seperti ini, kita dapat menjalankan sistem mikroprosesor tersebut cukup hanya dengan menambahkan catu daya USB saja.
Namun demikian, kadang-kadang fasilitas yang disediakan oleh mikrokontroler ataupun modul tersebut masih kurang, sehingga masih diperlukan tambahan komponen pendukung. Berikut ini beberapa komponen pendukung yang sering dipakai.
Mikroprosesor / CPU
Komponen utama suatu sistem mikroprosesor adalah sebuah CPU (Central Processing Unit). CPU ini belum dilengkapi dengan memori, sehingga untuk dapat dijalankan sebagai sistem minimum, CPU ini masih perlu ditambah memori RAM dan EEPROM. Berikut ini keluarga CPU yang (dulu) populer di Indonesia:
Keluarga Z80 buatan Zilog
Keluarga 6800 buatan Motorola
Zilog Z0840004PSC
Pada saat ini penggunaan CPU sudah jarang, biasanya kita menggunakan mikrokontroler yang lebih praktis.
Berikut ini contoh rangkaian mikroprosesor berbasis CPU tipe 6802, dari keluarga 6800 buatan Motorola. (https://www.sbprojects.net/projects/nano6802/index.php)
Sistem minimum 6802
Pada rangkaian tersebut, komponen utamanya adalah sebagai berikut:
6802 sebagai CPU
2732A sebagai EPROM
6821 sebagai antar muka digital
Pada rangkaian tersebut tidak ada SRAM, karena di dalam 6802 sudah ada RAM sebanyak 128 byte.
Sumber Clock
Mikroprosesor yang kita pakai sekarang umumnya termasuk ke dalam sistem digital sinkron sekuensial, sehingga suatu mikroprosesor memerlukan clock. Sumber clock yang umum digunakan adalah osilator internal menggunakan resistor dan kapasitor, serta bisa juga menggunakan kristal. Rangkaian osilator dengan resistor dan kapasitor sangat sederhana, namun kurang teliti. Kristal menghasilkan clock yang lebih teliti. Jika diperlukan ketelitian waktu yang lebih tinggi, dapat dilihat di artikel “Sumber Clock pada Rangkaian Elektronik“
Kristal 12 MHz dan resonator 18.083 MHz
RAM
RAM (Random Access Memori) fungsinya sebagai memori yang dapat dibaca dan ditulis oleh mikroprosesor.
Salah satu jenis static RAM yang populer dipakai adalah tipe 6264. RAM ini berkapasitas 8 kilobyte (8192 byte).
Static Random Access Memori 6264
Mikrokontroler versi terbaru umumnya sudah dilengkapi RAM di dalamnya, sehingga kita tidak perlu menambahkan RAM lagi.
Selain static RAM (SRAM), ada juga dynamic RAM (DRAM). DRAM lebih murah dibandingkan SRAM, namun rangkaiannya lebih kompleks. DRAM populer digunakan pada mikroprosesor yang memerlukan RAM besar.
EPROM atau Erasable Programmable Read Only Memory, adalah memori yang dapat diprogram dengan menggunakan perangkat programmer, dan dapat dihapus dengan menggunakan cahaya ultraviolet.
EPROM yang populer digunakan adalah tipe 27C64. EPROM ini berkapasitas 8 kilobyte (8192 byte)
EPROM 27C64
Input Output Digital Mikroprosesor
Untuk antar muka digital dari bus di dalam sistem mikroprosesor ke luar, diperlukan komponen antar muka digital. Komponen yang populer dipakai adalah IC PPI (Programmable Peripheral Interface) tipe 8255 buatan Intel dan 6821 dari Motorola.
Berikut ini PPI 8255 yang sering dipakai bersama mikroprosesor keluaran Intel, seperti 8088 dan 8086
Intel PPI 8255
Berikut ini IC Peripheral Interface Adapter (PIA) model MC6820 dan MC6821. Keduanya sering dipakai bersama mikroprosesor keluaran Motorola, seperti 6802 dan 6805.
Motorola MC6820 dan MC6821
Fungsi input output digital dari bus mikroprosesor juga dapat dilakukan dengan komponen IC digital berikut ini
Pada mikroprosesor model lama seperti Z80 dan Motorola 6800, masih diperlukan komponen register pada bus mikroprosesor. Pada mikrokontroler model baru seperti ATmega328 dan ESP32, bus mikroprosesor sudah built-in, jadi tidak perlu diutak atik lagi oleh pendesain sistem.
Komponen yang dipakai pada bus antara lain sebagai berikut:
74HC138 Multiplexer, sebagai address decoder
74HC245 buffer 2 arah 8 bit, sebagai input output digital , ataupun bus driver
74HC573 latch 8 bit, sebagai bus multiplexer
Input Digital
Mikrokontroler zaman sekarang sudah memiliki input output digital built-in, sehingga tidak memerlukan tambahan PPI atau PIA. Namun kadang perlu komponen tambahan untuk menambah jumlah port, ataupun untuk konversi tegangan.
Berikut ini beberapa komponen yang umum dipakai pada sistem mikroprosesor untuk menambah kemampuan input digital:
74HC164 serial input parallel output shift register tanpa output latch, dipakai untuk menambah jumlah port output
74HC165 parallel input serial output shift register, dipakai untuk menambah jumlah port input
PCF8574 untuk menambah jumlah port input output , antar muka ke mikrokontroler menggunakan protokol I2C
Level Converter jika tegangan input dari sensor/transduser tidak sama dengan tegangan input mikrokontroler. Detail dibahas di artikel “Teknik Input Digital“. Salah satu cara yang praktis dengan menggunakan bidirectional logic level converter.
Output Digital
Berikut ini beberapa komponen yang umum dipakai pada sistem mikroprosesor untuk menambah output digital:
74HC595 serial input parallel output shift register dengan output latch, dipakai untuk menambah jumlah port output
PCF8574 untuk menambah jumlah port input output , antar muka ke mikrokontroler menggunakan protokol I2C
Output digital dari mikrokontroler juga kadang-kadang perlu diperkuat arusnya, ataupun diubah tegangannya. Berikut ini beberapa komponen yang sering dipakai:
ULN2803 Darlington driver, untuk memperkuat arus dari port mikroprosesor, dapat menangani arus sampai 500 mA
Digital Level Converter jika tegangan output mikrokontroler tidak sama dengan tegangan perangkat yang dikendalikan. Salah satu cara yang praktis dengan menggunakan modul bidirectional logic level converter.
Transistor NPN, PNP, MOSFET kanal N, kanal P sebagai penguat arus. Dibahas detail di artikel “Teknik Output Digital“
3.3V 5V Bi Directional Level Converter
Referensi
https://www.ti.com/product/PCF8574
Penguat Output Dengan H-Bridge
H-Bridge adalah rangkaian output khusus untuk menggerakkan motor DC dengan 2 arah. Pada umumnya komponen utamanya adalah 4 buah transistor BJT/MOSFET yang dapat dikonfigurasikan sehingga polaritas output dapat dibalik.
Untuk input analog diperlukan ADC (Analog to Digital Converter). Pada mikrokontroler seperti ATmega328 sudah dilengkapi ADC. Jika ADC ini tidak cukup , atau mikrokontroler tidak ada ADC, maka kita perlu menambah ADC eksternal.
Contoh ADC yang mudah dipakai untuk mikrokontroler:
MCP3008: 8 kanal 10 bit, antar muka SPI
ADS1115: 4 kanal 16 bit, antar muka I2C
HX711: 2 kanal 24 bit, antar muka serial digital. Umumnya dipakai untuk timbangan digital.
Untuk output analog diperlukan DAC (Digital to Analog to Converter). Mikrokontroler seperti ESP32 sudah dilengkapi DAC 8 bit, namun umumnya mikrokontroler tidak dilengkapi DAC.
Komunikasi digital ke periferal sering menggunakan protokol I2C ataupun SPI. Namun jika level tegangan dengan periferal berbeda, maka perlu tambahan komponen bidirectional logic converter.
Mikrokontroler umumnya memiliki port komunikasi serial asinkron dengan level tegangan 3,3 volt ataupun 5 volt, sesuai dengan tegangan kerja mikrokontroler tersebut. Supaya dapat dihubungkan dengan perangkat lain yang menggunakan level tegangan RS232, perlu ada konverter TTL ke RS232, seperti MAX232
Jika komunikasi menggunakan RS-485, maka perlu mengubah level tegangan TTL menjadi RS-485 dengan komponen seperti MAX485.
Jika ingin menghubungkan port komunikasi asinkron dengan port USB di komputer, maka perlu menggunakan modul USB to Serial. Modul USB to serial yang populer adalah yang berbasis chipset FTDI dan chipset CH340
Modul USB to Serial TTL CH340
Regulator DC
Jika tegangan dari power supply/baterai tidak sama dengan tegangan kerja mikrokontroler, maka perlu ditambahkan regulator yang sesuai.
Regulator yang umum dipakai adalah dari tipe linear dan tipe switching.
Contoh regulator linear yang umum:
LM7805
LM317
Regulator LM7805
Contol regulator step down DC to DC converter adalah LM2596. IC ini sudah tersedia dalam bentuk modul, sehingga tidak perlu dirakit lagi dari komponen diskrit.
DC to DC Converter step down LM2596
Jika diinginkan konversi energi yang lebih efisien, lebih baik menggunakan DC to DC converter. Saat ini sudah banyak dijual berbagai macam modul DC to DC converter.
Power supply / adaptor diperlukan untuk mengubah tegangan jala-jala listrik 220 volt menjadi tegangan rendah yang dapat dipakai untuk mikroprosesor. Umumnya mikroproser memerlukan tegangan 5 volt DC, namun kadang ada juga perangkat seperti motor DC yang memerlukan tegangan 12 volt DC.
Jika memerlukan beberapa tegangan, dapat dipakai beberapa power supply, atau 1 power supply ditambah dengan regulator untuk mengubah tegangan output ke tegangan lain yang diinginkan. Misal jika diperlukan tegangan 12 volt dan 5 volt, bisa saja dipakai 1 power supply dengan output 12 volt DC dan ditambah regulator DC to DC converter step down 12 volt ke 5 volt DC.
Power Supply 12 volt 5 ampere
Power supply yang hemat energi adalah dari tipe switching power supply, misal power supply 12 volt berikut ini.
Beberapa macam power supply 12 volt
Baterai
Jika perangkat dirancang untuk mobile atau tidak ada akses ke jala-jala listrik, maka perlu sumber daya internal berupa baterai. Alternatif lain menggunakan sel surya plus baterai.
Baterai 18650 4200 mWh
Tegangan baterai jarang yang sesuai dengan tegangan kerja mikroprosesor. Tegangan baterai juga berubah (menurun) tergantung kapasitas baterai yang terpakai. Untuk menjaga tegangan supply yang konstan, biasanya output dari baterai ini perlu disambungkan ke regulator atau DC to DC converter.
Komponen lain yang diperlukan namun belum dibahas di artikel ini:
LED (Light Emitting Diode) untuk display dan indikator