---
# System prepended metadata

title: Ardunesia

---

# Ardunesia
## Tujuan
Mempelajari cara menggunakan board Ardunesia berbasis proyek

## Cara Mengatur Board Ardunesia pada Arduino IDE =
<p style="text-align:justify;">Ada 2 hal yang harus dilakukan sebelum kita bisa menggunakan Board Ardunesia, yang pertama lakukanlah hal dibawah ini :</p>

1. Buka "Arduino IDE"
2. Klik "File"
3. Klik "Preferences"
4. Mengisi kolom "Additional Boards Manager URLs" dengan https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectronics_index.json (copy-paste)
6. Klik "OK"
7. Selanjutnya Klik "Tools" -> "Board" -> "Board Manager"
8. Mencari kata "STM32" pada kolom Search
9. Klik "Install" STM32
10. Setelah berhasil di Install, sambungkan Board Ardunesia dengan PC

<br>

**Setelah itu lakukanlah prosedur di bawah ini** 
1. Buka Folder -> Documents -> Folder Arduino
2. Buatlah folder baru bernama "hardware"
3. Buka folder "hardware", buatlah folder baru bernama "xooey"
4. Buka folder "xooey", buatlah folder baru bernama "sam-one"
5. Unzip "sam-one.zip" pada folder tersebut
(download sam-one.zip pada link [disini](https://drive.google.com/file/d/1zFF_R7BCsqKKy0cVz8OQEl1Ulfa2d4ML/view?usp=sharing))
7. Sambungkan Board Ardunesia dengan PC
8. Buka "Arduino IDE"
9. Klik "Tools" -> "Board" -> "Arduino Boards" -> pilih "Ardunesia Bootloaded"
10. Selanjutnya Klik "Tools" -> "CPU Frequency" -> pilih "40MHz"
11. Board Ardunesia sudah bisa digunakan

<br>

# 1. LED Blink dengan Board Ardunesia
## Komponen yang digunakan
1. Board Ardunesia
2. LED
3. Resistor 220 ohm
4. Protoboard
5. Kabel Jumper

## Wiring 
Tabel.1. Wiring Board Ardunesia dengan LED
| Board Ardunesia | LED | 
| -------- | -------- | 
| Pin Digital 4     | Kaki Anoda (+) LED    |
| GND     | Kaki Katoda (-) LED    |

## Code
```
#define pinLed 4                //Deklarasi variabel pinLed adalah 4

void setup() {
pinMode(pinLed, OUTPUT);        //Mengatur mode pinLed sebagai OUTPUT 
}

void loop() {
digitalWrite(pinLed, HIGH);   // menyalakan LED (tegangan 5V atau HIGH)
delay(1000);                 // menunggu selama 1 detik
digitalWrite(pinLed, LOW);   // mematikan LED (tegangan 0V atau LOW)
delay(1000);                 // menunggu selama 1 detik
}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code dapat langsung mengamati hasilnya
![](https://i.imgur.com/pWhxxnW.jpg)
[Gambar Wiring Board Ardunesia dengan LED](https://drive.google.com/file/d/1lLge_k5zcyiFNiCEeu14Q_otunq_keR3/view?usp=sharing)



---

<br>

# 2. Buzzer Aktif dan Pasif dengan Board Ardunesia

<p style="text-align:justify;">Buzzer aktif memiliki sumber osilasi internal yang membuat bel berbunyi setiap kali daya dialirkan. Bel aktif banyak digunakan di komputer, printer, mesin fotokopi, alarm, mainan elektronik, elektronik mobil, telepon, pengatur waktu, dan perangkat suara produk elektronik lainnya.</p>

<p style="text-align:justify;">Buzzer pasif tidak memiliki sumber osilasi internal dan perlu digerakkan oleh gelombang persegi dan frekuensi yang berbeda. Buzzer pasif bertindak seperti speaker elektromagnetik, dan sinyal input yang berubah menghasilkan suara, bukan nada secara otomatis. </p>

## Komponen yang digunakan
1. Board Ardunesia
2. Buzzer Aktif
3. Buzzer Pasif
4. Protoboard
5. Kabel Jumper

## Wiring 
Tabel.2. Wiring Board Ardunesia dengan Buzzer Aktif dan Pasif
| Board Ardunesia | Buzzer Aktif / Pasif | 
| -------- | -------- | 
| Pin Digital 5     | Kaki (+) Buzzer    |
| GND     | Kaki (-) Buzzer    |

## Code Buzzer Aktif
```
int buzzer = 5;    
void setup ()
{
  pinMode (buzzer, OUTPUT) ;
}
void loop ()
{

      digitalWrite (buzzer, HIGH) ;     //Buzzer berbunyi
      delay (100) ;
      digitalWrite (buzzer, LOW) ;     //Buzzer tidak berbunyi
      delay (100) ;
      digitalWrite (buzzer, HIGH) ;
      delay (100) ;
      digitalWrite (buzzer, LOW) ;
      delay (100) ;
}
```


## Code Buzzer Pasif
```
#define buzzer 5
int i;

void setup() {
pinMode(buzzer,OUTPUT);
}

void loop() {
for (i = 0; i <80; i++) // When a frequency sound
    {
    digitalWrite (buzzer, HIGH) ; //send tone
    delay (1) ;
    digitalWrite (buzzer, LOW) ; //no tone
    delay (1) ;
    }
}
```

## Ilustrasi Gambar
![](https://i.imgur.com/jB5cD0o.jpg)
[Gambar Wiring Board Ardunesia dengan Buzzer Aktif / Pasif](https://drive.google.com/file/d/1FVLTXPpHLw6hKGZPsPIP82zm7lpz7rZk/view?usp=sharing)
![](https://i.imgur.com/yig1AEw.gif)

[Hasil Board Ardunesia dengan Buzzer Aktif / Pasif](https://drive.google.com/file/d/1Zd85G6m2jmXe8yZWwGzaHk5TZlbxujNQ/view?usp=sharing)

---
<br>

# 3. Push Button pengatur LED dengan Board Ardunesia
## Komponen yang digunakan
1. Board Ardunesia
2. Tacktile Push Button
3. LED
4. Resistor 220 Ohm
5. Protoboard
6. Kabel Jumper

## Wiring 
Tabel.3. Wiring Board Ardunesia dengan LED
| Board Ardunesia | LED | 
| -------- | -------- | 
| Pin Digital 4     | Kaki Anoda (+) LED    |
| GND     | Kaki Katoda (-) LED    |

Tabel.4. Wiring Board Ardunesia dengan Push Button
| Board Ardunesia | Push Button| 
| -------- | -------- | 
| Pin Digital 6     | Kaki Kiri Push Button    |
| GND     | Kaki Kanan Push Button    |


## Code
```
//membuat variabel untuk mengatur nomor pin menggunakan tipe data konstanta (nilai tidak akan berubah)
const int buttonPin = 6;     // nomor pin pushbutton
const int ledPin =  4;      // nomor pin LED

// membuat variabel untuk menyimpan status push button (nilai ini akan berubah)
int buttonState = 0;         // variabel untuk membaca status tegangan pushbutton

void setup() {
pinMode(ledPin, OUTPUT);    // inisialisasi pin LED sebagai OUTPUT
pinMode(buttonPin, INPUT);  // inisialisasi pin pushbutton sebagai INPUT
}

void loop() {
buttonState = digitalRead(buttonPin); //membaca nilai status push button 1 atau 0
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {      //Jika nilai status push button 1 
    digitalWrite(ledPin, HIGH);   //Maka LED menyala
  } 
  else {                          //Jika nilai status push button selain 1 (nilainya 0)
    digitalWrite(ledPin, LOW);    //Maka LED mati
  }
}
```
## Ilustrasi Gambar
Setelah berhasil Upload Code dapat langsung mengamati hasilnya
![](https://i.imgur.com/m3qPyMG.jpg)
[Gambar Wiring Board Ardunesia dengan Switch dan LED](https://drive.google.com/file/d/1lFHEl_vz044PSQPw20acwQkUKyXhGiFd/view?usp=sharing)

---
<br>

# 4. Sensor Suhu dan Kelembapan (DHT11) dengan Board Ardunesia
## Komponen yang digunakan
1. Board Ardunesia
2. Modul Sensor Suhu DHT11
5. Protoboard
6. Kabel Jumper
## Library yang digunakan
* DHT11
    (#include "DHT.h")
    [Referensi Library](https://github.com/adafruit/DHT-sensor-library) 

## Wiring 
Tabel.5. Wiring Board Ardunesia dengan DHT11
| Board Ardunesia | DHT11| 
| -------- | -------- | 
| Pin Digital 3     | Digital Output / Signal pin     |
| 5V     | VCC     |
| GND     | GND    |

## Code
```
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor

#include "DHT.h"

#define DHTPIN 3     // Digital pin connected to the DHT sensor
// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
// Pin 15 can work but DHT must be disconnected during program upload.

// Uncomment whatever type you're using!
#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 3 (on the right) of the sensor to GROUND (if your sensor has 3 pins)
// Connect pin 4 (on the right) of the sensor to GROUND and leave the pin 3 EMPTY (if your sensor has 4 pins)
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(9600);
  Serial.println(F("DHTxx test!"));

  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(t);
  Serial.print(F("°C "));
  Serial.print(f);
  Serial.print(F("°F  Heat index: "));
  Serial.print(hic);
  Serial.print(F("°C "));
  Serial.print(hif);
  Serial.println(F("°F"));
}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code, Buka Serial Monitor dan amati hasilnya
![](https://i.imgur.com/C0c5Ido.jpg)
[Gambar Wiring Board Ardunesia dengan Sensor Suhu dan Kelembapan DHT11](https://drive.google.com/file/d/1StWX17M5oiD1Y--jrVkgY8Dm7lc2SpQO/view?usp=sharing)
![](https://i.imgur.com/uihjF6L.jpg)
[Gambar Hasil Board Ardunesia dengan Sensor Suhu dan Kelembapan DHT11 pada Serial Monitor](https://drive.google.com/file/d/15u9LXa2pSDKzxferZH5XdchSW6e91F5c/view?usp=sharing)

<br>

---

# 5. Sensor Tekanan dan Suhu (BMP280) dengan Board Ardunesia
<p style="text-align:justify;">Sensor BMP280 yaitu sensor tekanan yang popular digunakan untuk membaca tekanan udara di tempat tentu sensor ini juga dapat digunakan untuk membaca ketinggian diatas permukaan laut serta suhu disekitarnya.</p>
## Komponen yang digunakan
1. Board Ardunesia
2. Modul Sensor Tekanan BMP280
5. Protoboard
6. Kabel Jumper

## Library yang digunakan
* Seeed BMO280
    (#include <Seeed_BMP280.h>)
* Wire
    (#include <Wire.h>)

## Wiring 
Tabel.6. Wiring Board Ardunesia dengan BMP280
| Board Ardunesia | BMP280| 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |

## Code
```
/*
 * bmp280_example.ino
 * Example sketch for BMP280
 *
 * Copyright (c) 2016 seeed technology inc.
 * Website    : www.seeedstudio.com
 * Author     : Lambor, CHN
 * Create Time:
 * Change Log :
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "Seeed_BMP280.h"
#include <Wire.h>

BMP280 bmp280;

void setup()
{
  Serial.begin(9600);
  if(!bmp280.init()){
    Serial.println("Device error!");
  }
}

void loop()
{
  float pressure;
  
  //get and print temperatures
  Serial.print("Temp: ");
  Serial.print(bmp280.getTemperature());
  Serial.println("C"); // The unit for  Celsius because original arduino don't support speical symbols
  
  //get and print atmospheric pressure data
  Serial.print("Pressure: ");
  Serial.print(pressure = bmp280.getPressure());
  Serial.println("Pa");
  
  //get and print altitude data
  Serial.print("Altitude: ");
  Serial.print(bmp280.calcAltitude(pressure));
  Serial.println("m");
  
  Serial.println("\n");//add a line between output of different times.

  delay(1000);
}
```
## Ilustrasi Gambar
Setelah berhasil Upload Code, Buka Serial Monitor dan amati hasilnya
![](https://i.imgur.com/M6HiGXe.jpg)
[Gambar Wiring Board Ardunesia dengan Sensor Sensor Tekanan dan Suhu (BMP280)](https://drive.google.com/file/d/14WxzGgvJD8HJH8tGSH6dWAdtzPT062lc/view?usp=sharing)
![](https://i.imgur.com/wVCxVcs.jpg)
[Gambar Hasil Board Ardunesia dengan Sensor Sensor Tekanan dan Suhu (BMP280) pada Serial Monitor](https://drive.google.com/file/d/1HiuP7EPzCx7HZzIUIwXUbXULOVfjLJal/view?usp=sharing)

<br>



# 6. Sensor 3 Axis Digital (LIS3DHTR) dengan Board Ardunesia
<p style="text-align:justify;">Apa itu akselerometer tiga sumbu? Akselerometer 3-sumbu mengukur percepatan yang terjadi sehubungan dengan 3 sumbu koordinat Cartesius. Dengan kata lain, ia dapat mengukur perubahan kecepatan suatu titik.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul Sensor LIS3DHTR
3. Protoboard
4. Kabel Jumper

## Library yang digunakan
* LIS3DHTR Grove
    (#include <LIS3DHTR.h>) 
* Wire
    (#include <Wire.h>)

## Wiring 
Tabel.7. Wiring Board Ardunesia dengan Sensor 3 Axis Digital (LIS3DHTR)
| Board Ardunesia | LIS3DHTR| 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |

## Code
```
//Setting 3 Axis Digital Accelerometer
#include <LIS3DHTR.h>
#include <Wire.h> //Komunikasi menggunakan I2C jalurnya SDA dan SCL
LIS3DHTR<TwoWire> myLIS;
float x,y,z;
#define GROVE_WIRE   Wire

void setup() {
//Setting 3 Axis Digital
myLIS.begin(GROVE_WIRE, 0x19);
delay(100);
myLIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
if(!myLIS)
Serial.println("LIS3DHTR not detected!");
}

void loop() {
x = myLIS.getAccelerationX(); 
y = myLIS.getAccelerationY();
z = myLIS.getAccelerationZ();
Serial.print(" x: ");
Serial.print(x);
Serial.print(" y:");
Serial.print(y);
Serial.print(" z:");
Serial.print(z);
Serial.println();
}
```
## Ilustrasi Gambar
Setelah berhasil Upload Code, Buka Serial Monitor dan amati hasilnya
![](https://i.imgur.com/mfJPI1m.jpg)
[Gambar Wiring Board Ardunesia dengan 3 Axis Digital (LIS3DHTR)](https://drive.google.com/file/d/1jm3g7hdLsR8DbHAIADcxTi7-BwK98BZd/view?usp=sharing)

<br>


---
# 7. OLED dengan Board Ardunesia
<p style="text-align:justify;">Organic Light-Emitting Diode (OLED) adalah merupakan sebuah semikonduktor sebagai pemancar cahaya yang terbuat dari lapisan organik. OLED digunakan dalam teknologi elektroluminensi, seperti pada tampilan layar atau display. Teknologi ini terkenal fleksibel dengan ketipisannya yang mencapai kurang dari 1 mm.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul OLED
3. Protoboard
4. Kabel Jumper

## Library yang digunakan
* Grove OLED
    (<U8x8lib.h>)

## Wiring 
Tabel.8. Wiring Board Ardunesia dengan OLED
| Board Ardunesia | LIS3DHTR| 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |

## Code
```
//Setting OLED
#include <U8x8lib.h>
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

void setup() {
u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFlipMode(1);
u8x8.setFont(u8x8_font_chroma48medium8_r);
}

void loop() {
u8x8.setCursor(0, 0);    //Tulisan pada Baris 0 dan Kolom 0
u8x8.print("Tulis Nama Disini");
}
```
## Ilustrasi Gambar
Setelah berhasil Upload Code, lihatlah modul OLED dan amati hasilnya
![](https://i.imgur.com/zIKq1Xu.jpg)
[Gambar Wiring Board Ardunesia dengan OLED](https://drive.google.com/file/d/171oyVDluyGJPe6ts4pOuNbCoSWZW4U3P/view?usp=sharing)
<br>


---
# 8. Servo (SG-90) dengan Board Ardunesia
Motor servo adalah sebuah motor yang dapat diatur sudutnya menggunakan pulsa.

## Komponen yang digunakan
1. Board Ardunesia
2. Servo SG-90
3. Protoboard
4. Kabel Jumper

## Library yang digunakan
* XST_Servo
    (#include <XST_Servo.h>) 

## Wiring 
Tabel.9. Wiring Board Ardunesia dengan Servo (SG-90)
| Board Ardunesia | Servo| 
| -------- | -------- | 
| Pin Digital 2 | Signal     |
| 5V     | VCC    |
| GND     | GND    |

## Code
```
#include <XST_Servo.h>
 
Servo myservo;
int a;
 
void setup() {
  delay(1000);
 
  // attach servo to pin 2
  myservo.attach(2);
  Serial.begin(115200);
 
  // write angle in microseconds
  myservo.writeMicroseconds(500);
 
  // read and print current angle in microseconds and degrees
  a = myservo.readMicroseconds();
  Serial.println(a);
  a = myservo.read();
  Serial.println(a);
  delay(1000);
 
  // write angle in microseconds
  myservo.writeMicroseconds(2500);
 
  // read and print current angle in microseconds and degrees
  a = myservo.readMicroseconds();
  Serial.println(a);
  a = myservo.read();
   Serial.println(a);
  delay(1000);
}
 
void loop() {
  // repeatedly change servo angle from 0 to 90 to 180 degrees
  // print current angle every change in degrees
 
  // 0 degree
  myservo.write(0);
  a = myservo.read();
  Serial.println(a);
  delay(1000);
 
  // 90 degrees
  myservo.write(90);
  a = myservo.read();
  Serial.println(a);
  delay(1000);
 
  // 180 degrees
  myservo.write(180);
  a = myservo.read();
  Serial.println(a);
  delay(1000);
}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code, lihatlah Servo dan amati hasilnya
![](https://i.imgur.com/0kcyGOz.jpg)
[Gambar Wiring Board Ardunesia dengan Servo (SG-90)](https://drive.google.com/file/d/1rR8S00Jr665SsTzqU0cD17pimYyJ9jVx/view?usp=sharing)
<br>


# 9. Modul Grove Beginner Kit dengan Board Ardunesia
<p style="text-align:justify;">Grove adalah sistem prototyping modular yang terdiri dari base unit dan berbagai modul I/O dengan jenis konektor yang sudah distandarkan. Base unit di sini umumnya merupakan board mikrokontroler/mikroprosesor yang berfungsi untuk mengontrol, memproses, dan berkomunikasi dengan berbagai modul I/O grove.</p>

<p style="text-align:justify;">Dengan sistem konektor yang sudah distandarkan, artinya modul-modul I/O grove dapat dipasangkan ke konektor grove yang ada pada base unit atau base unit HAT secara plug-and-play tanpa perlu menata kabel secara manual dan tidak perlu lagi khawatir kabel akan terbalik karena seluruh peletakan pinout pada modul-modul grove sudah distandarkan, sehingga memudahkan pengguna, terutama pengguna baru dalam memasangkan modul grove ke base unit (Ardunesia, Arduino, Raspberry Pi, Microbit, dsb).</p>

<p style="text-align:justify;">Komunikasi pada Modul Grove Beginner Kit menggunakan Inter Integrated Circuit atau sering disebut I2C adalah standar komunikasi serial dua arah menggunakan dua saluran yang didisain khusus untuk mengirim maupun menerima data. Sistem I2C terdiri dari saluran SCL (Serial Clock) dan SDA (Serial Data) yang membawa informasi data antara I2C dengan pengontrolnya. Piranti yang dihubungkan dengan sistem I2C Bus dapat dioperasikan sebagai Master dan Slave. Master adalah piranti yang memulai transfer data pada I2C Bus dengan membentuk sinyal Start, mengakhiri transfer data dengan membentuk sinyal Stop, dan membangkitkan sinyal clock. Slave adalah piranti yang dialamati master.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul Grove Beginner Kit
Berisikan Modul-Modul sebagai berikut =
Modul LED
Modul Buzzer (Piezzo Buzzer)
Modul OLED Display 0.96 inch (SSD1315)
Push Button
Sensor Suhu dan Kelembapan (DHT11)
Sensor Tekanan Udara / Barometer (BMP280)
Sensor 3-Axis-Acceleration
4. Kabel Jumper

## Library yang digunakan
* DHT11, untuk sensor DHT11
    (#include "DHT.h")
* Seeed BMO280, untuk sensor BM0280
    (#include <Seeed_BMP280.h>)
* LIS3DHTR, digunakan untuk sensor 3-Axis-Acceleration 
    (#include <LIS3DHTR.h>)
* Wire, digunakan untuk sensor 3-Axis-Acceleration 
    (#include <Wire.h>)
* Grove OLED, digunakan untuk OLED
    (<U8x8lib.h>)

## Wiring 
Tabel.10. Wiring Board Ardunesia dengan Modul Grove Beginner Kit
| Board Ardunesia | LED | 
| -------- | -------- | 
| Pin Digital 4     | Kaki Anoda (+) LED    |
| GND     | Kaki Katoda (-) LED    |

| Board Ardunesia | Buzzer | 
| -------- | -------- | 
| Pin Digital 5     | Kaki (+) Buzzer    |
| GND     | Kaki (-) Buzzer    |

| Board Ardunesia | Push Button| 
| -------- | -------- | 
| Pin Digital 6     | Kaki Kiri Push Button    |
| GND     | Kaki Kanan Push Button    |

| Board Ardunesia | DHT11| 
| -------- | -------- | 
| Pin Digital 3     | Digital Output / Signal pin     |
| 5V     | VCC     |
| GND     | GND    |

| Board Ardunesia | BMP280| 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |

| Board Ardunesia | LIS3DHTR| 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |


## Code
```
//Setting OLED
#include <U8x8lib.h>
U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);

//Setting BMP280
#include <Seeed_BMP280.h>
int pressure;
double BMPtemp;
BMP280 myBMP280;

//Setting DHT11
#include "DHT.h"
#define DHTPIN 3
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
float h,t;

//Setting 3 Axis Digital Accelerometer
#include <LIS3DHTR.h>
#include <Wire.h> //Komunikasi menggunakan I2C jalurnya SDA dan SCL
LIS3DHTR<TwoWire> myLIS;
float x,y,z;
#define GROVE_WIRE   Wire

//Setting Buzzer Pin D5
//Pin D5 dia
int buzzer = 5 ;

void read_3_Axis(){
x = myLIS.getAccelerationX(); 
y = myLIS.getAccelerationY();
z = myLIS.getAccelerationZ();
u8x8.setCursor(0, 0); u8x8.print("x:");
u8x8.setCursor(3, 0); u8x8.print(x);
u8x8.setCursor(0, 1); u8x8.print("y:");
u8x8.setCursor(3, 1); u8x8.print(y);
u8x8.setCursor(0, 3); u8x8.print("z:");
u8x8.setCursor(3, 3); u8x8.print(z);

Serial.print(" x: ");
Serial.print(x);
Serial.print(" y:");
Serial.print(y);
Serial.print(" z:");
Serial.print(z);
Serial.println();
  }
  
void read_DHT11(){
h = dht.readHumidity();
t = dht.readTemperature();
// check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)){
    Serial.println("Failed to read from DHT");}
    else {
        Serial.print("Humidity: "); 
        Serial.print(h);
        Serial.print(" %\t");
        Serial.print("Temperature: "); 
        Serial.print(t);
        Serial.println(" *C");
        u8x8.setCursor(0, 7);
        u8x8.print("Temp DHT:");
        u8x8.setCursor(10, 7);
        u8x8.print(t);
        u8x8.setCursor(14, 7);
        u8x8.print("^C");
    }
}
  
void read_BMP20(){
BMPtemp = myBMP280.getTemperature();
pressure = myBMP280.getPressure();
Serial.print("BMP280: ");
Serial.print(BMPtemp);
Serial.print(" C  ");
Serial.print("Pressure: ");
Serial.print(pressure);
Serial.print(" Pa  ");

u8x8.setCursor(0, 4);
u8x8.print("Pressure:");
u8x8.setCursor(9, 4);
u8x8.print(pressure);
u8x8.setCursor(14, 4);
u8x8.print("Pa");

u8x8.setCursor(0, 5);
u8x8.print("Temp:");
u8x8.setCursor(7, 5);
u8x8.print(BMPtemp);
u8x8.setCursor(13, 5);
u8x8.print("C");

u8x8.setCursor(0, 6);
u8x8.print("C Alt:");
u8x8.setCursor(7, 6);
u8x8.print(myBMP280.calcAltitude(pressure));
u8x8.setCursor(14, 6);
u8x8.print("m");
  }
  
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
pinMode(4,OUTPUT);
pinMode(6,INPUT);
pinMode(buzzer,OUTPUT);

u8x8.begin();
u8x8.setPowerSave(0);
u8x8.setFlipMode(1);
u8x8.setFont(u8x8_font_chroma48medium8_r);
//u8x8.setCursor(0, 0);
//u8x8.print("AMEILIAWULANDARI");

//BMP280
if(!myBMP280.init())
Serial.println("BMP280 not detected!");

//DHT11
dht.begin(); 

//Setting 3 Axis Digital
myLIS.begin(GROVE_WIRE, 0x19);
delay(100);
myLIS.setOutputDataRate(LIS3DHTR_DATARATE_50HZ);
if(!myLIS)
Serial.println("LIS3DHTR not detected!");
}

void loop() {

read_BMP20();
read_DHT11();
read_3_Axis();

int baca=digitalRead(6);
if(baca==HIGH){
  unsigned char i;
  
  digitalWrite(4,HIGH);
//   while(1){
   for (i = 0; i <80; i++) // When a frequency sound
    {
    digitalWrite (buzzer, HIGH) ; //send tone
    delay (1) ;
    digitalWrite (buzzer, LOW) ; //no tone
    delay (1) ;
    }
//   }
  }

if(baca==LOW){
  digitalWrite(4,LOW);
  }
  // put your main code here, to run repeatedly:

}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code, lihatlah hasilnya pada Grove Beginner Kit dan amati hasilnya
![](https://i.imgur.com/DRcNPry.jpg)
[Gambar Wiring Board Ardunesia dengan Grove Beginner Kit](https://drive.google.com/file/d/1pGI_UDm7pkpu4W0q3-616E7TSDT3515K/view?usp=sharing)
<br>

# 10. Modul Max30102 dengan Board Ardunesia
<p style="text-align:justify;">Maxim Integrated MAX30102 Sensor adalah modul monitor denyut nadi dan denyut jantung terintegrasi. MAX30102 mencakup LED internal, detektor foto, elemen optik, dan elektronik dengan noise rendah dengan penolakan cahaya sekitar. Perangkat yang sangat sensitif ini beroperasi pada catu daya 1,8V tunggal dan catu daya 5,0V terpisah untuk LED internal. Komunikasi dilakukan melalui antarmuka standar yang kompatibel dengan I2C. Sensor ini dapat dimatikan melalui perangkat lunak dengan arus siaga nol, memungkinkan rel daya tetap bertenaga setiap saat.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul Max30102
3. Modul OLED
4. Resistor 220 Ohm
5. Kabel Jumper

## Library yang digunakan
* #include <Wire.h>
* #include "MAX30105.h"
* #include "heartRate.h"
* #include <Adafruit_GFX.h>
* #include <Adafruit_SSD1306.h>

## Wiring 
Tabel.11. Wiring Board Ardunesia dengan Modul Max30102
| Board Ardunesia | Max30102 SP02 | 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |

Tabel.12. Wiring Board Ardunesia dengan OLED
| Board Ardunesia | OLED | 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |


## Code Pengecekan Rata-Rata BPM di tampilkan di Serial Monitor
```
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"


MAX30105 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
 
float beatsPerMinute;
int beatAvg;
 
void setup()
{
Wire.begin();
Serial.begin(115200);
Serial.println("Initializing...");
if (!particleSensor.begin(Wire, I2C_SPEED_FAST ))//Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while(1);
}
Serial.println("Place your index finger on the sensor with steady pressure.");
particleSensor.setup(); //Configure sensor with default settings
particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}

void loop()
{

long irValue = particleSensor.getIR();

if (checkForBeat(irValue) == true)
{
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();
beatsPerMinute = 60 / (delta / 1000.0);
 
if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
rateSpot %= RATE_SIZE; //Wrap variable
 
//Take average of readings
beatAvg = 0;
for (byte x = 0 ; x < RATE_SIZE ; x++)
beatAvg += rates[x];
beatAvg /= RATE_SIZE;
}
}

Serial.print("IR=");
Serial.print(irValue);
Serial.print(", BPM=");
Serial.print(beatsPerMinute);
Serial.print(", Avg BPM=");
Serial.print(beatAvg);
if (irValue < 50000)
Serial.print(" No finger?");
Serial.println();
}


```

## Code Pengecekan Spo2 di tampilkan di Serial Monitor
```
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"

MAX30105 particleSensor;

#define MAX_BRIGHTNESS 255

#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.
uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100];  //red LED sensor data
#else
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100];  //red LED sensor data
#endif

int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid

byte pulseLED = 11; //Must be on PWM pin
byte readLED = 13; //Blinks with each data read

void setup()
{
  Serial.begin(115200); // initialize serial communication at 115200 bits per second:

  pinMode(pulseLED, OUTPUT);
  pinMode(readLED, OUTPUT);

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
    Serial.println(F("MAX30105 was not found. Please check wiring/power."));
    while (1);
  }

  Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
  //while (Serial.available() == 0) ; //wait until user presses a key
  Serial.read();

  byte ledBrightness = 60; //Options: 0=Off to 255=50mA
  byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
}

void loop()
{
  bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps

  //read the first 100 samples, and determine the signal range
  for (byte i = 0 ; i < bufferLength ; i++)
  {
    while (particleSensor.available() == false) //do we have new data?
      particleSensor.check(); //Check the sensor for new data

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();
    particleSensor.nextSample(); //We're finished with this sample so move to next sample

    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
  }

  //calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second
  while (1)
  {
    //dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
    for (byte i = 25; i < 100; i++)
    {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }

    //take 25 sets of samples before calculating the heart rate.
    for (byte i = 75; i < 100; i++)
    {
      while (particleSensor.available() == false) //do we have new data?
        particleSensor.check(); //Check the sensor for new data

      //digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read

      redBuffer[i] = particleSensor.getRed();
      irBuffer[i] = particleSensor.getIR();
      particleSensor.nextSample(); //We're finished with this sample so move to next sample

      //send samples and calculation result to terminal program through UART
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);
      /*Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);
      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);*/
      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);
      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }

    //After gathering 25 new samples recalculate HR and SP02
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
  }   
}
```

## Code Pengecekan rata-rata BPM di tampilkan di OLED

```
#include <Adafruit_GFX.h>        //OLED libraries
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include "MAX30105.h"           //MAX3010x library
#include "heartRate.h"          //Heart rate calculating algorithm

MAX30105 particleSensor;

const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET    -1 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display)

static const unsigned char PROGMEM logo2_bmp[] =
{ 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10,              //Logo2 and Logo3 are two bmp pictures that display on the OLED if called
0x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88,
0x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60,
0x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00,  };

static const unsigned char PROGMEM logo3_bmp[] =
{ 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00  };


void setup() {  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C); //Start the OLED display
  display.display();
  delay(3000);
  // Initialize sensor
  particleSensor.begin(Wire, I2C_SPEED_FAST); //Use default I2C port, 400kHz speed
  particleSensor.setup(); //Configure sensor with default settings
  particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running

}

void loop() {
 long irValue = particleSensor.getIR();    //Reading the IR value it will permit us to know if there's a finger on the sensor or not
                                           //Also detecting a heartbeat
if(irValue > 7000){                                           //If a finger is detected
    display.clearDisplay();                                   //Clear the display
    display.drawBitmap(5, 5, logo2_bmp, 24, 21, WHITE);       //Draw the first bmp picture (little heart)
    display.setTextSize(2);                                   //Near it display the average BPM you can display the BPM if you want
    display.setTextColor(WHITE); 
    display.setCursor(50,0);                
    display.println("BPM");             
    display.setCursor(50,18);                
    display.println(beatAvg); 
    display.display();
    
  if (checkForBeat(irValue) == true)                        //If a heart beat is detected
  {
    display.clearDisplay();                                //Clear the display
    display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE);    //Draw the second picture (bigger heart)
    display.setTextSize(2);                                //And still displays the average BPM
    display.setTextColor(WHITE);             
    display.setCursor(50,0);                
    display.println("BPM");             
    display.setCursor(50,18);                
    display.println(beatAvg); 
    display.display();
    tone(3,1000);                                        //And tone the buzzer for a 100ms you can reduce it it will be better
    delay(100);
    noTone(3);                                          //Deactivate the buzzer to have the effect of a "bip"
    //We sensed a beat!
    long delta = millis() - lastBeat;                   //Measure duration between two beats
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);           //Calculating the BPM

    if (beatsPerMinute < 255 && beatsPerMinute > 20)               //To calculate the average we strore some values (4) then do some math to calculate the average
    {
      rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
      rateSpot %= RATE_SIZE; //Wrap variable

      //Take average of readings
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
  }

}
  if (irValue < 7000){       //If no finger is detected it inform the user and put the average BPM to 0 or it will be stored for the next measure
     beatAvg=0;
     display.clearDisplay();
     display.setTextSize(1);                    
     display.setTextColor(WHITE);             
     display.setCursor(30,5);                
     display.println("Please Place "); 
     display.setCursor(30,15);
     display.println("your finger ");  
     display.display();
     noTone(3);
     }

}
```

## Ilustrasi Gambar
Setelah berhasil Upload Code, lihatlah hasil Max30102 pada serial monitor dan amati hasilnya
![](https://i.imgur.com/TIXOypx.jpg)
[Gambar Wiring Board Ardunesia dengan Sensor Sensor Max30102](https://drive.google.com/file/d/1mrj0BOyoM21eGn7uBmeKTfn6QMOrYC73/view?usp=sharing)
![](https://i.imgur.com/gRYUTyB.jpg)
[Gambar Wiring Board Ardunesia dengan Sensor Sensor Max30102 dan OLED](https://drive.google.com/file/d/1UYoPFKYJ57-4bn2If-9ZbOu0DhC5c4YR/view?usp=sharing)
![](https://i.imgur.com/8pu4Bc2.jpg)
[Gambar Hasil Board Ardunesia dengan Max30102 Pengecekan Rata-Rata BPM pada Serial Monitor](https://drive.google.com/file/d/14oV5IShAzzPwcmyvExChqw1xYsC5zm7C/view?usp=sharing)
![](https://i.imgur.com/AXwhRNu.jpg)
[Gambar Hasil Board Ardunesia dengan Max30102 Pengecekan Spo2 pada Serial Monitor](https://drive.google.com/file/d/14i3Kmlbj3TmspbNRlorI-iFKpTZIPhPr/view?usp=sharing)
![](https://i.imgur.com/Mlqr4uf.jpg)
[Gambar Hasil Board Ardunesia dengan Max30102 Pengecekan Spo2 pada OLED](https://drive.google.com/file/d/1y8V9MKSS6v1-_BR7LhOrHLNSdO__cuLc/view?usp=sharing)

<br>

# 11. Modul RTC DS1307 dengan Board Ardunesia
<p style="text-align:justify;">Modul DS1307 adalah sebuah modul Real-Time Clock (Jam Dunia Nyata). Modul ini dapat memberikan informasi waktu nyata saat ini.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul RTC DS1307 
3. Kabel Jumper

## Library yang digunakan
* #include "Arduino.h"
* #include "uRTCLib.h"


## Wiring 
Tabel.13. Wiring Board Ardunesia dengan RTC DS1307 
| Board Ardunesia | RTC DS1307  | 
| -------- | -------- | 
| Pin Digital 20 (SDA) | pin SDA     |
| Pin Digital 21 (SCL)     | pin SCL     |
| 5V     | VCC    |
| GND     | GND    |


## Code
```
#include "Arduino.h"
#include "uRTCLib.h"

// uRTCLib rtc;
uRTCLib rtc(0x68);

void setup() {
delay (2000);
    Serial.begin(9600);
    Serial.println("Serial OK");

    #ifdef ARDUINO_ARCH_ESP8266
        URTCLIB_WIRE.begin(0, 2); // D3 and D4 on ESP8266
    #else
        URTCLIB_WIRE.begin();
    #endif

    rtc.set(0, 42, 16, 6, 2, 5, 15);
    //  RTCLib::set(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year)
}

void loop() {
    rtc.refresh();

    Serial.print("RTC DateTime: ");
    Serial.print(rtc.year());
    Serial.print('/');
    Serial.print(rtc.month());
    Serial.print('/');
    Serial.print(rtc.day());

    Serial.print(' ');

    Serial.print(rtc.hour());
    Serial.print(':');
    Serial.print(rtc.minute());
    Serial.print(':');
    Serial.print(rtc.second());

    Serial.print(" DOW: ");
    Serial.print(rtc.dayOfWeek());

    Serial.print(" - Temp: ");
    Serial.print(rtc.temp()  / 100);

    Serial.println();

    delay(1000);
}
```
## Ilustrasi Gambar
Setelah berhasil Upload Code, bukalah Serial Monitor dan amati hasilnya
![](https://i.imgur.com/FSEa9aP.jpg)
[Gambar Wiring Board Ardunesia dengan RTC DS1307 ](https://drive.google.com/file/d/1qJGOwMlhV9H64E4-Pc1-uCsrHnEAHeVl/view?usp=sharing)
![](https://i.imgur.com/HZRvEKS.jpg)
[Gambar Hasil Board Ardunesia dengan RTC DS1307 pada Serial Monitor](https://drive.google.com/file/d/1I1mFwmsur6_C56SpToJ8f-NsaSoSbmSZ/view?usp=sharing)
*Catatan : Nilai Temp = 0 karena DS1307 tidak memiliki kapabilitas mengukur suhu.
<br>

# 12. LCD 16x2 dengan Board Ardunesia
<p style="text-align:justify;">LCD (Liquid Crystal Display) 16x2 adalah jenis media tampilan atau Display dari bahan cairan kristal sebagai penampil utama. LCD 16x2 dapat menampilkan sebanyak 32 karakter yang terdiri dari 2 baris dengan tiap baris menampilkan 16 karakter.</p>


## Komponen yang digunakan
1. Board Ardunesia
2. LCD 16x2 
3. Kabel Jumper

## Library yang digunakan
* #include <cobalcd.h>

## Wiring 
Tabel.14. Wiring Board Ardunesia dengan LCD 16x2
| Board Ardunesia | LCD 16x2 | 
| -------- | -------- | 
| pin digital 7 |RS |
| pin digital 6     | D6     |
| pin digital 5 | D4|
| pin digital 4     |  D5    |
| pin digital 3  | D6|
| pin digital 2     |D7      |
| Not Connected     | IRQ    |
| pin digital 9     | RST    |
| 5V     | VDD    |
| GND     | VSS    |
| 3,3V     | A    |
| GND     | K    |


## Code
```
#include <cobalcd.h>

cobalcd lcd(7, 6, 5, 4, 3, 2);
 
void setup() {
 lcd.begin(16, 2);
 lcd.setCursor(0, 0);
 lcd.print("                "); 
 lcd.setCursor(0, 0);
 lcd.print("Selamat Datang");
 lcd.setCursor(0, 1);
 lcd.print("di PT. Xirka");
}

void loop() {
    for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
    lcd.scrollDisplayLeft();
    delay(200);
  }
 }

}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code, lihatlah layar LCD 16x2 dan amati hasilnya
![](https://i.imgur.com/KMgeONe.jpg)

[Gambar Wiring Board Ardunesia dengan LCD 16x2](https://drive.google.com/file/d/1-V225XAs3aHS98mr0pqw8rbB4CYybpdB/view?usp=sharing)

---
<br>

# 13. Modul RFID dengan Board Ardunesia
<p style="text-align:justify;">Teknologi Modul RFID atau Radio Frequency Identification adalah merupakan suatu teknik identifikasi obyek yang dilakukan dengan menggunakan pancaran gelombang radio. Modul RFID akan memancarkan frekwensi ke kartu ataupun gantungan kunci (key chain) yang dalam hal ini berfungsi sebagai transponder.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul RFID tipe RC522
3. LCD 16x2
4. Kabel Jumper

## Library yang digunakan
* #include <SPI.h>
* #include <MFRC522.h>
* #include <cobalcd.h>

## Wiring 
Tabel.15. Wiring Board Ardunesia dengan RFID RC522
| Board Ardunesia | RFID RC522 | 
| -------- | -------- | 
| pin digital 20 (SDA) |SDA |
| pin digital 13     | SCK     |
| pin digital 11 | MOSI|
| pin digital 12     |  MISO    |
| pin digital 20 (SDA) | SDA|
| pin digital 13     |SCK      |
| Not Connected     | IRQ    |
| Pin Digital 9     | RST    |
| 5V     | VCC    |
| GND     | GND    |

Tabel.16. Wiring Board Ardunesia dengan LCD 16x2
| Board Ardunesia | LCD 16x2 | 
| -------- | -------- | 
| pin digital 7 |RS |
| pin digital 6     | D6     |
| pin digital 5 | D4|
| pin digital 4     |  D5    |
| pin digital 3  | D6|
| pin digital 2     |D7      |
| Not Connected     | IRQ    |
| pin digital 9     | RST    |
| 5V     | VDD    |
| GND     | VSS    |
| 3,3V     | A    |
| GND     | K    |


## Code Menampilkan ID dari RFID Tag menggunakan RC522 pada Serial Monitor
```
//Program ini berguna untuk menampilkan ID dari card yang dikehendaki.
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN         9          
#define SS_PIN          20       

MFRC522 mfrc522(SS_PIN, RST_PIN);  

void setup() {
  Serial.begin(9600); 
  SPI.begin();      
  mfrc522.PCD_Init();  
  delay(4);       
  mfrc522.PCD_DumpVersionToSerial();  
  Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {

  if ( ! mfrc522.PICC_IsNewCardPresent()) {
    return;
  }

  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
}
```

## Code Uji Pemilihan Akses dari ID yang dibaca menggunakan RC522 pada Serial Monitor
<p style="text-align:justify;">Program ini berguna untuk menampilkan ID dari card yang dikehendaki dan kemudian melakukan seleksi apakah suatu kartu diberikan akses atau tidak. Bagian penyeleksian berada pada baris perintah dengan rekursi (if). Apabila syarat pada rekursi tersebut terpenuhi, maka ID card tersebut aksesnya diterima begitu juga sebaliknya.</p>

```
#include <SPI.h>
#include <MFRC522.h>
 
#define SS_PIN 20
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);  

void setup() {
  Serial.begin(9600);   
  SPI.begin();      
  mfrc522.PCD_Init();  
  Serial.println("Dekatkan kartu anda...");
  Serial.println();
}
void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent()){
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  Serial.print("ID Pengguna:");
  String content="";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++){
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Akses: ");
  content.toUpperCase();
  if (content.substring(1) == "E5 EB 54 70"){
    Serial.println("Terima");
    Serial.println(); 
    delay(1000);
  }
 
 else{
    Serial.println("Tolak");
    Serial.println();
    delay(1000);
  }
}
```

 
## Code Kombinasi RC522 dan LCD 16x2 dengan Board Ardunesia

<p style="text-align:justify;">Uji coba ini dilakukan untuk menyeleksi kartu NFC apakah akses diterima atau ditolak. Penyeleksian ini menggunakan konsep yang sama dengan uji coba penyeleksian dengan RFID yang hasilnya ditampilkan pada serial monitor. Hal yang membedakan hanya pada bagian deklarasi baris perintah penampilan yang sebelumnya menggunakan serial monitor kemudian diubah menjadi penampil dengan LCD. </p>

```
#include <SPI.h>
#include <MFRC522.h>
#include <cobalcd.h>

#define SS_PIN 20
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);  
cobalcd lcd(7, 6, 5, 4, 3, 2);

void setup() {
  SPI.begin();      
  mfrc522.PCD_Init();  
  lcd.begin(16, 2);
  lcd.setCursor(0,0);
  lcd.print("Dekatkan kartu");
}

void loop() {
  if ( ! mfrc522.PICC_IsNewCardPresent()){
    return;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  Serial.print("ID Pengguna:");
  String content="";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++){
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  content.toUpperCase();
  if (content.substring(1) == "E5 E4 50 75"){//ganti id card dengan kartu yang dikehendaki
    lcd.setCursor(0,0);
    lcd.print("Dekatkan kartu");
    lcd.setCursor(0,1);
    lcd.print("Akses diterima");
    delay(2000);
    lcd.setCursor(0,1);
    lcd.print("                ");
  }
 
 else{
    lcd.setCursor(0, 1);
    lcd.print("                ");
    lcd.setCursor(0,0);
    lcd.print("Dekatkan kartu");
    lcd.setCursor(0, 1);
    lcd.print("Akses ditolak");
    delay(2000);
    lcd.setCursor(0,1);
    lcd.print("                ");
  }
}
```
 
## Ilustrasi Gambar
Setelah berhasil Upload Code, bukalah Serial Monitor dan amati hasilnya
![](https://i.imgur.com/NPQTy4d.jpg)
[Gambar Wiring Board Ardunesia dengan RC522 ](https://drive.google.com/file/d/1yo9XFwtYfkO15svgq6jvqiknHI27tzfx/view?usp=sharing)
![](https://i.imgur.com/tqSpx2b.jpg)
[Gambar Wiring Board Ardunesia dengan RC522 dan LCD 16x2 ](https://drive.google.com/file/d/1uoWbZrOrubXVGaBmJBzWLU63_bh5g0Of/view?usp=sharing)

---

<br>


# 14. Capasitive Keypad dengan Board Ardunesia
<p style="text-align:justify;">Capacitive keypad merupakan jenis keypad yang menggunakan prinsip kapasitansi seperti pada kapasitor dalam bekerja. Lempengan bidang sentuh akan menghasilkan kapasitansi ketika diberikan tegangan. Ketika bidang sentuh tersebut mengenai kulit manusia, maka akan ada perubahan kapasitansi. Perubahan tersebut yang kemudian diproses oleh mikrokontroler sebagai sebuah perintah sehingga dihasilkan suatu respon yang dapat berupa angka atau huruf pada perangkat penampil.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Capasitive Keypad
4. Kabel Jumper

## Library yang digunakan
* #include <CSKeypad.h>

## Wiring 
Tabel.15. Wiring Board Ardunesia dengan Capasitive Keypad
| Board Ardunesia | Capasitive Keypad | 
| -------- | -------- | 
| pin digital 9 |R23 |
| pin digital 8     | R13     |
| pin digital 7 |R8 |
| pin digital 6     | R7     |
| pin digital 5 | R2|
| pin digital 3  | VCC2|
| pin digital 2     |VCC1      |
| GND     | GND    |

## Code
```
#include <CSKeypad.h>

CSKeypad cskeypad (2, 3, 4, 5, 6, 7, 8, 9);

void setup() {
Serial.begin(9600);
cskeypad.init_cskey();
}

void loop() {
char keys;
keys = cskeypad.get_cskey();
if (keys){
  Serial.println(keys);
  }
}
```
<p style="text-align:justify;">Kode tersebut merupakan bagian dari pemilihan jenis output yang hendak di tuliskan pada serial monitor. Output dipilih sesuai dengan label penampang pada capasitive keypad. Apabila kita menekan penampang dengan label “1” maka pada serial monitor akan ditampilkan angka 1 dan juga seterusnya. Dalam hal ini, kita menggunakan variable tambahan “keys” sebagai tempat penyimpanan bacaan data yang kemudian nilainya yang sudah dideklarasikan pada library akan dipilih untuk ditampilkan.</p>

## Ilustrasi Gambar
Setelah berhasil Upload Code, coba lah menekan capasitive keypad lalu amati hasilnya pada serial monitor
![](https://i.imgur.com/Nn8VOUN.jpg)
[Gambar Wiring Board Ardunesia dengan Keypad](https://drive.google.com/file/d/1Geua4hxkjFEfmiGZsIfOb1IZXVL50JBY/view?usp=sharing)

---
<br>


# 16. PWM (Pulse Width Modulation) dengan Board Ardunesia

<p style="text-align:justify;">Pulse-width modulation atau PWM merupakan sebuah teknik yang digunakan untuk menciptakan keluaran yang bersifat analog secara digital. Kendali digital digunakan untuk membuat sinyal kotak dengan waktu antara sinyal nyala dan mati yang dapat divariasikan. Durasi waktu menyala sinyal tersebut disebut sebagai “pulse width” dan untuk mendapatkan nilai analog yang berbeda kita ubah atau modulasikan “pulse width” tersebut.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. LED x 3
3. Resistor 220 ohm 
4. Buzzer 
5. Kabel Jumper

## Library yang digunakan
* #include <XST_IOT_PWM.h>

## Wiring 
Tabel.17. Wiring Board Ardunesia dengan Capasitive Keypad
| Board Ardunesia | Capasitive Keypad | 
| -------- | -------- | 
| pin digital 2 |Kaki Anoda (+) LED 1 |
| pin digital 5     |Kaki Anoda (+) LED 2    |
| pin digital 8 |Kaki Anoda (+) LED 3 |
| pin digital 13     | Kaki (+) Buzzer     |
| GND     | Kaki Katoda (-) LED 1   |
| GND     | Kaki Katoda (-) LED 2   |
| GND     | Kaki Katoda (-) LED 3  |
| GND     | Kaki (-) Buzzer    |

## Code
```
#include <XST_IOT_PWM.h>
 
#define LED_1 2
#define LED_2 5
#define LED_3 8
#define buzzer 13
#define PWM_MAX 65535
 
void setup() {
  Serial.begin(115200);
  Serial.println("Program start.");
  
  analogWrite(LED_1, 0);
  analogWrite(LED_2, 0);
  analogWrite(LED_3, 0);
 
  delay(2000);
  
  analogWrite(LED_1, PWM_MAX);
  analogWrite(LED_2, (PWM_MAX+1)/8);
  analogWrite(LED_3, 0);
  tone(buzzer, 261);
  delay(400);
  noTone(buzzer);
  delay(100);
  
  tone(buzzer,261);
  delay(400);
  noTone(buzzer);
  delay(100);
  
  tone(buzzer,392);
  delay(400);
  noTone(buzzer);
  delay(100);
 
  tone(buzzer,392);
  delay(400);
  noTone(buzzer);
  delay(100);
 
  tone(buzzer,440);
  delay(400);
  noTone(buzzer);
  delay(100);
 
  tone(buzzer,440);
  delay(400);
  noTone(buzzer);
  delay(100);
 
  tone(buzzer,392);
  delay(800);
  noTone(buzzer);
  delay(200);
  
  Serial.println("Finished. Now looping for LED 3...");
}
 
void loop() {
  for(int i=0; i<=PWM_MAX; i+=100){
    analogWrite(LED_3,i);
    delay(1);
  }
  for(int i=PWM_MAX; i>=0; i-=100){
    analogWrite(LED_3,i);
    delay(1);
  }
 
}

```
## Ilustrasi Gambar
Setelah berhasil Upload Code, coba lah amati hasilnya
![](https://i.imgur.com/NLUFDDx.jpg)
[Gambar Wiring Board Ardunesia dengan LED dan Buzzer untuk Aplikasi PWM](https://drive.google.com/file/d/1IBADcO3P2HWXoWl-2I34w96kISaNbxGw/view?usp=sharing)
![](https://i.imgur.com/b6zOWSN.jpg)
[Gambar Hasil Board Ardunesia dengan LED dan Buzzer untuk Aplikasi PWM](https://drive.google.com/file/d/1cm78PvhBJ8r5PVsStjBg1PIjsDAoGpje/view?usp=sharing)

---

<br>

# 17. Modul Ethernet ENC28J60 dengan Board Ardunesia

<p style="text-align:justify;">Modul ENC28J60 menggunakan Serial Peripheral Interface (SPI) dalam melakukan komunikasi. Serial Peripheral Interface (SPI) adalah antarmuka komunikasi serial sinkron yang digunakan untuk komunikasi jarak pendek, terutama dalam sistem embedded. SPI dikembangkan oleh Motorola pada pertengahan 1980-an dan telah menjadi standar de facto.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul Ethernet ENC28J60
3. Koneksi Jaringan Internet
4. Kabel Ethernet RJ45 
5. Kabel Jumper

## Library yang digunakan
* UIPEthernet
#include <UIPEthernet.h>
* SPI
#include <SPI.h>


## Wiring 
Tabel.18. Wiring Board Ardunesia dengan Modul Ethernet ENC28J60
| Board Ardunesia | Capasitive Keypad | 
| -------- | -------- | 
| pin digital 12 |MISO |
| pin digital 11     |MOSI  |
| pin digital 13 |SCK |
| pin digital 10     | CS     |
| 3V3     | VCC   |
| GND     | GND   |

*Catatan : Selain itu, sambungkan kabel Ethernet RJ45 yang terhubung dengan internet dengan modul ENC28J60.

## Code
```
#include <SPI.h>
#include <UIPEthernet.h>
 
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0xE1, 0xA0, 0x00, 0x09, 0x12, 0x33
};
IPAddress ip(192, 168, 137, 5);
 
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
 
void setup() {
 
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("Ethernet WebServer Example");
 
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
 
  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
 }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
 
  // start the server
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}
 
 
void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          // output 
          client.println("Hello World");
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}
```
### Penjelasan Code
<p style="text-align:justify;">Kode tersebut menunjukan penggunaan SPI0 pada board Ardunesia dalam melakukan komunikasi serial. Jika menggunakan antarmuka SPI yang lain maka perlu disesuaikan. Untuk mencoba modul ENC28J60 pada board Ardunesia, digunakan example WebServer.ino untuk menjadikan board sebagai server web. Ubah ethernet.h menjadi UIPEthernet.h serta sesuaikan nilai IP Address dengan jaringan yang terhubung. Selain itu, ubah bagian isi dari pesan yang ditampilkan. Pesan yang asli berupa pembacaan nilai analog input pada Arduino. Pada contoh ini, pesan yang ditampilkan berupa tulisan “Hello World”.</p>

## Ilustrasi Gambar
<p style="text-align:justify;">Setelah berhasil Upload Code, Jika koneksi terpasang serta program terkompilasi dengan baik, maka Ardunesia berfungsi sebagai web server. Gunakan web browser yang tersambung dengan network yang sama dan masukkan IP Address (192.168.137.5) sebagai web address yang dituju. Jika tidak ada masalah akan, terlihat tulisan Hello World pada page yang diakses</p>

![](https://i.imgur.com/udV06zZ.jpg)
[Gambar Wiring Board Ardunesia dengan Modul Ethernet ENC28J60](https://drive.google.com/file/d/1XpFYR_hO1_KAAkzfJUL3vfCjjOjRW5DG/view?usp=sharing)

![](https://i.imgur.com/QFhV2MC.jpg)
[Gambar Hasil Board Ardunesia dengan Modul Ethernet ENC28J60 pada IP Address (192.168.137.5) dan Serial Monitor](https://drive.google.com/file/d/17kcRln0-Ljyd12SUVqJEwduRRyK-uA5b/view?usp=sharing)

---

<br>


# 18. Perangkat Internet of Things (IoT) Oximeter dengan Board Ardunesia
## Komponen yang digunakan
1. Board Ardunesia
2. Arduino Mega/Due
3. ESP32	
4. Modul Oximeter (MAX30102)
5. Modul 0.96” OLED I2C
6. Dragino LoRa Gateway OLG02
7.  Protoboard
8.   Kabel Jumper

## Library yang digunakan
* PubSubClient.h
* WiFi.h
* #include <DFRobot_MAX30102.h>
* #include "MAX30100_PulseOximeter.h" 
* #include <Wire.h>
* #include <Adafruit_GFX.h>
* #include <Adafruit_SSD1306.h>


## Wiring 
Tabel.19. Wiring Board Ardunesia dengan Oximeter, OLED, Modul ESP32, dan Modul LoRa
| Board Ardunesia | Oximeter MAX30102 | 
| -------- | -------- | 
| pin digital 20 |SDA |
| pin digital 21     |SCL  |
| 5V     | VCC   |
| GND     | GND   |

| Board Ardunesia | OLED | 
| -------- | -------- | 
| pin digital 20 |SDA |
| pin digital 21     |SCL  |
| 5V     | VCC   |
| GND     | GND   |

| Board Ardunesia | Modul ESP32 | 
| -------- | -------- | 
| pin digital 0 (RX) |TXD |
| pin digital 1 (TX)     |RXD  |
| 5V     | VCC   |
| GND     | GND   |

<br>

Tabel.20.Wiring Board Arduino Mega dengan Oximeter, OLED, Modul ESP32, dan Modul LoRa
| Board Arduino Mega | Oximeter MAX30102 | 
| -------- | -------- | 
| pin digital 20 |SDA |
| pin digital 21     |SCL  |
| 5V    | VCC   |
| GND     | GND   |

| Board Arduino Mega | OLED | 
| -------- | -------- | 
| pin digital 20 |SDA |
| pin digital 21     |SCL  |
| 5V    | VCC   |
| GND     | GND   |

| Board Arduino Mega | Modul ESP32 | 
| -------- | -------- | 
| pin digital 0 (RX) |TXD |
| pin digital 1 (TX)     |RXD  |
| 5V     | VCC   |
| GND     | GND   |


## Code Master
<p style="text-align:justify;">Digunakan komunikasi UART dengan Ardunesia/ Arduino Mega sebagai master yang akan melakukan perhitungan dan ESP32 sebagai slave yang akan mengirim data ke Xirka IoT Platform.</p>

```
#include <DFRobot_MAX30102.h>
#include "MAX30100_PulseOximeter.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


DFRobot_MAX30102 particleSensor;


const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
int count;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
uint16_t irBuffer;
uint16_t redBuffer;

const unsigned char bitmap [] PROGMEM={ //ardunesia logo
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x3f, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0x0f, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc7, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xe1, 0xff, 0xff,
0xff, 0xff, 0x80, 0x00, 0x0f, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0x00, 0x00, 0x7c, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfc, 0x7f, 0xff,
0xff, 0xfe, 0x00, 0x03, 0xc0, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0xff,
0xff, 0xfe, 0x00, 0x07, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x87, 0xff, 0x3f, 0xff,
0xff, 0xfc, 0x00, 0x1c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe3, 0xff, 0x9f, 0xff,
0xff, 0xf8, 0x00, 0x3c, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xf0, 0xff, 0xcf, 0xff,
0xff, 0xf0, 0x00, 0x64, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x7f, 0xc7, 0xff,
0xff, 0xf0, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x3f, 0xe7, 0xff,
0xff, 0xe0, 0x01, 0x84, 0x00, 0x00, 0x00, 0x60, 0x00, 0x03, 0xfe, 0x0f, 0xff, 0x3f, 0xf3, 0xff,
0xff, 0xe0, 0x03, 0x04, 0x00, 0x00, 0x00, 0x30, 0x00, 0x07, 0x1e, 0x01, 0xff, 0x9f, 0xf3, 0xff,
0xff, 0xc0, 0x02, 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x0e, 0x0f, 0x00, 0x7f, 0x8f, 0xf9, 0xff,
0xff, 0xc0, 0x06, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1c, 0x0f, 0xf0, 0x3f, 0xcf, 0xf9, 0xff,
0xff, 0xc0, 0x0c, 0x04, 0x00, 0x86, 0x00, 0x0c, 0x00, 0x1c, 0x1f, 0xfc, 0x1f, 0xe7, 0xf8, 0xff,
0xff, 0x80, 0x0c, 0x04, 0x00, 0x86, 0x00, 0x04, 0x00, 0x3c, 0x7f, 0x3e, 0x0f, 0xe3, 0xfc, 0xff,
0xff, 0x80, 0x08, 0x04, 0x00, 0x86, 0x00, 0x06, 0x00, 0x60, 0xfe, 0x0f, 0x87, 0xf3, 0xfc, 0xff,
0xff, 0x80, 0x18, 0x04, 0x00, 0x86, 0x00, 0x06, 0x00, 0xc1, 0xfe, 0x03, 0x87, 0xf3, 0xfc, 0xff,
0xff, 0x00, 0x10, 0x06, 0x00, 0x86, 0x00, 0x03, 0x01, 0xc3, 0xff, 0x81, 0xc3, 0xf1, 0xfc, 0x7f,
0xff, 0x00, 0x10, 0x07, 0xff, 0x86, 0x00, 0x03, 0x03, 0xc7, 0xff, 0xf0, 0xe3, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x30, 0x00, 0x00, 0x86, 0x00, 0x03, 0x07, 0xc7, 0xff, 0xf8, 0xe3, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x30, 0x00, 0x00, 0x86, 0x00, 0x01, 0x0f, 0xe7, 0xfe, 0x38, 0x61, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x86, 0x00, 0x01, 0x1f, 0xcf, 0xff, 0x1c, 0x71, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x86, 0x00, 0x01, 0x1f, 0x0f, 0xff, 0x0c, 0x71, 0xf8, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x87, 0xff, 0xff, 0x3f, 0x0f, 0xfe, 0x0c, 0x71, 0xf8, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x87, 0xff, 0xff, 0x3f, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x86, 0x00, 0x01, 0x3f, 0x0f, 0xff, 0xff, 0xff, 0xf8, 0xfe, 0x7f,
0xff, 0x00, 0x20, 0x00, 0x00, 0x86, 0x00, 0x01, 0x9f, 0x8f, 0xff, 0xff, 0xff, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x30, 0x00, 0x00, 0x86, 0x00, 0x03, 0x9f, 0xe7, 0xff, 0xff, 0xef, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x30, 0x00, 0x00, 0x86, 0x00, 0x07, 0x9f, 0xc7, 0xff, 0xff, 0xc7, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x10, 0x07, 0xff, 0x86, 0x00, 0x0f, 0x9f, 0xc7, 0xff, 0xff, 0xc7, 0xf9, 0xfe, 0x7f,
0xff, 0x00, 0x10, 0x06, 0x1b, 0x86, 0x00, 0x1f, 0x9f, 0xc3, 0xff, 0xff, 0x83, 0xf1, 0xfe, 0x7f,
0xff, 0x80, 0x18, 0x04, 0x00, 0x86, 0x00, 0x3f, 0xcf, 0xc1, 0xff, 0xff, 0x07, 0xf3, 0xfc, 0xff,
0xff, 0x80, 0x18, 0x04, 0x00, 0x86, 0x00, 0x7f, 0xcf, 0xe0, 0xff, 0xfe, 0x07, 0xf3, 0xfc, 0xff,
0xff, 0x80, 0x08, 0x04, 0x00, 0x86, 0x00, 0xff, 0xc7, 0xfc, 0x7f, 0xfc, 0x7f, 0xe3, 0xfc, 0xff,
0xff, 0x80, 0x0c, 0x04, 0x00, 0x86, 0x01, 0xff, 0xe7, 0xfc, 0x1f, 0xf8, 0x7f, 0xe7, 0xfc, 0xff,
0xff, 0xc0, 0x06, 0x04, 0x00, 0x00, 0x03, 0xff, 0xe3, 0xfc, 0x03, 0x80, 0x7f, 0xc7, 0xf9, 0xff,
0xff, 0xc0, 0x06, 0x04, 0x00, 0x00, 0x07, 0xff, 0xf3, 0xfc, 0x00, 0x00, 0x7f, 0xcf, 0xf9, 0xff,
0xff, 0xe0, 0x03, 0x04, 0x00, 0x00, 0x0f, 0xff, 0xf9, 0xff, 0x10, 0x11, 0xff, 0x9f, 0xf3, 0xff,
0xff, 0xe0, 0x01, 0x84, 0x00, 0x00, 0x1f, 0xff, 0xf8, 0xff, 0xf8, 0x3f, 0xff, 0x1f, 0xf3, 0xff,
0xff, 0xf0, 0x00, 0xc4, 0x00, 0x00, 0x3f, 0xff, 0xfc, 0x7f, 0xfc, 0x7f, 0xfe, 0x3f, 0xe7, 0xff,
0xff, 0xf0, 0x00, 0x64, 0x00, 0x00, 0x3f, 0xff, 0xfe, 0x3f, 0xff, 0xff, 0xfc, 0x7f, 0xe7, 0xff,
0xff, 0xf8, 0x00, 0x3c, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x1f, 0xff, 0xff, 0xf8, 0xff, 0xcf, 0xff,
0xff, 0xfc, 0x00, 0x1c, 0x00, 0x00, 0xff, 0xff, 0xff, 0x87, 0xff, 0xff, 0xe1, 0xff, 0x8f, 0xff,
0xff, 0xfc, 0x00, 0x0e, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe1, 0xff, 0xff, 0x87, 0xff, 0x1f, 0xff,
0xff, 0xfe, 0x00, 0x03, 0x80, 0x03, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xfe, 0x0f, 0xfe, 0x3f, 0xff,
0xff, 0xff, 0x00, 0x00, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xfc, 0x07, 0xc0, 0x3f, 0xfc, 0x7f, 0xff,
0xff, 0xff, 0x80, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xf8, 0xff, 0xff,
0xff, 0xff, 0xc0, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xf1, 0xff, 0xff,
0xff, 0xff, 0xf0, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0xff, 0xff,
0xff, 0xff, 0xf8, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xff, 0xff,
0xff, 0xff, 0xfe, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff, 0xff,
0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x7f, 0xff, 0xff,
0xff, 0xff, 0xff, 0xe0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x03, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

static const unsigned char PROGMEM logo2_bmp[] = //little heart
{ 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10,              //Logo2 and Logo3 are two bmp pictures that display on the OLED if called
0x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88,
0x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60,
0x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00  };

static const unsigned char PROGMEM logo3_bmp[] = //big heart
{ 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00  };

static const unsigned char PROGMEM hourglass[] = //hourglass
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x00, 0x0f, 0xff, 0x00, 0x07, 0xfe, 0x00, 0x07,
0xfe, 0x00, 0x07, 0x0e, 0x00, 0x02, 0x0c, 0x00, 0x01, 0x98, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0,
0x00, 0x01, 0xf0, 0x00, 0x03, 0xf8, 0x00, 0x07, 0xfc, 0x00, 0x07, 0x1e, 0x00, 0x06, 0x06, 0x00,
0x0c, 0x02, 0x00, 0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  };

void setup()
{
  count = 0;
  //Init serial
  Serial.begin(115200);
  /*!
   *@brief Init sensor 
   *@param pWire IIC bus pointer object and construction device, can both pass or not pass parameters (Wire in default)
   *@param i2cAddr Chip IIC address (0x57 in default)
   *@return true or false
   */
  while (!particleSensor.begin()) {
    Serial.println("MAX30102 was not found");
    delay(1000);
  }

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
  Serial.println(F("SSD1306 allocation failed"));
  for(;;);
  }
  delay(2000); // Pause for 2 seconds

  // Clear the buffer.
  display.clearDisplay();
  
  // Draw bitmap on the screen
  display.drawBitmap(0, 0, bitmap, 128, 64, 1);
  display.display();
  delay(3000);

  /*!
   *@brief Use macro definition to configure sensor 
   *@param ledBrightness LED brightness, default value: 0x1F（6.4mA), Range: 0~255（0=Off, 255=50mA）
   *@param sampleAverage Average multiple samples then draw once, reduce data throughput, default 4 samples average
   *@param ledMode LED mode, default to use red light and IR at the same time 
   *@param sampleRate Sampling rate, default 400 samples every second 
   *@param pulseWidth Pulse width: the longer the pulse width, the wider the detection range. Default to be Max range
   *@param adcRange ADC Measurement Range, default 4096 (nA), 15.63(pA) per LSB
   */
  particleSensor.sensorConfiguration(/*ledBrightness=*/50, /*sampleAverage=*/SAMPLEAVG_4, \
                        /*ledMode=*/MODE_MULTILED, /*sampleRate=*/SAMPLERATE_100, \
                        /*pulseWidth=*/PULSEWIDTH_411, /*adcRange=*/ADCRANGE_16384);

  
}

int32_t SPO2; //SPO2
int8_t SPO2Valid; //Flag to display if SPO2 calculation is valid
int32_t heartRate; //Heart-rate
int8_t heartRateValid; //Flag to display if heart-rate calculation is valid 

void loop()
{
 long irValue = particleSensor.getIR();    //Reading the IR value it will permit us to know if there's a finger on the sensor or not
                                           //Also detecting a heartbeat                                           
if(irValue > 7000){ //If a finger is detected
    particleSensor.heartrateAndOxygenSaturation(/**SPO2=*/&SPO2, /**SPO2Valid=*/&SPO2Valid, /**heartRate=*/&heartRate, /**heartRateValid=*/&heartRateValid);
    int temperature = particleSensor.readTemperatureC();
    //bufferLength = 100 -> stores 4 seconds of samples running at 25 sps (samples per second)
    if(heartRate > 0 && SPO2 > 0){                           //all datas valid
      display.clearDisplay();                                //Clear the display
      display.drawBitmap(10, 5, logo2_bmp, 24, 21, WHITE);    //Draw the heart
      display.setTextSize(1);                                 
      display.setTextColor(WHITE);             
      display.setCursor(60,0);                
      display.println("BPM");             
      display.setCursor(60,18);                
      display.println(heartRate); 
      display.setCursor(60,36);                
      display.println("SPO2");    
      display.setCursor(60,54);  
      display.println(SPO2);    
      display.setCursor(80,54);  
      display.println("%");       
      display.setCursor(5, 36);
      display.println("TEMP");
      display.setCursor(5, 54);
      display.println(temperature);
      display.setCursor(25,54);  
      display.println("C"); 
      display.display();
    }
    else if(heartRate > 0 && SPO2 < 0){                      //spo2 not valid
      display.clearDisplay();                                //Clear the display
      display.drawBitmap(10, 5, logo2_bmp, 24, 21, WHITE);    //Draw the heart
      display.setTextSize(1);                                //And still displays the average BPM
      display.setTextColor(WHITE);             
      display.setCursor(60,0);                
      display.println("BPM");             
      display.setCursor(60,18);                
      display.println(heartRate); 
      display.setCursor(60,36);                
      display.println("SPO2");      
      display.drawBitmap(60, 45, hourglass, 20, 20, WHITE);   //draws hourglass (loading)
      SPO2 = 0;
      display.setCursor(5, 36);
      display.println("TEMP");
      display.setCursor(5, 54);
      display.println(temperature);        
      display.setCursor(25,54);  
      display.println("C");         
      display.display();      
    }
    else if(heartRate < 0 && SPO2 > 0){                      //heart rate not valid
      display.clearDisplay();                                //Clear the display
      display.drawBitmap(10, 5, logo2_bmp, 24, 21, WHITE);    //Draw the heart
      display.setTextSize(1);                                //And still displays the average BPM
      display.setTextColor(WHITE);             
      display.setCursor(60,0);                
      display.println("BPM");                            
      display.drawBitmap(60, 9, hourglass, 20, 20, WHITE);   //draws hourglass (loading)
      heartRate = 0;
      display.setCursor(60,36);                
      display.println("SPO2");    
      display.setCursor(60,54);  
      display.println(SPO2);
      display.setCursor(80,54);  
      display.println("%"); 
      display.setCursor(5, 36);
      display.println("TEMP");
      display.setCursor(5, 54);
      display.println(temperature);   
      display.setCursor(25,54);  
      display.println("C");                    
      display.display();      
    }    
    else {                                                   //heart rate and spo2 not valid
      display.clearDisplay();                                //Clear the display
      display.drawBitmap(10, 5, logo2_bmp, 24, 21, WHITE);    //Draw the heart
      display.setTextSize(1);                                //And still displays the average BPM
      display.setTextColor(WHITE);             
      display.setCursor(60,0);                
      display.println("BPM");                        
      display.drawBitmap(60, 9, hourglass, 20, 20, WHITE);    //draws hourglass (loading heart rate)
      heartRate = 0;
      display.setCursor(60,36);                
      display.println("SPO2");      
      display.drawBitmap(60, 45, hourglass, 20, 20, WHITE);   //draws hourglass (loading spo2)
      SPO2 = 0;
      display.setCursor(5, 36);
      display.println("TEMP");
      display.setCursor(5, 54);
      display.println(temperature); 
      display.setCursor(25,54);  
      display.println("C");       
      display.display();     
    }      
    Serial.write('h'); 
    Serial.write(heartRate);   
    Serial.write('s');     
    Serial.write(SPO2); 
    Serial.write('t');  
    Serial.write(temperature); 
    Serial.write('c');
    Serial.write(count);
    count++;
}
  if (irValue < 7000){       //If no finger is detected it inform the user and put the average BPM to 0 or it will be stored for the next measure
     beatAvg=0;
     display.clearDisplay();
     display.setTextSize(0.5);                    
     display.setTextColor(WHITE);             
     display.setCursor(27,2);                
     display.println("Please place"); 
     display.setCursor(30,12);
     display.println("your finger ");  
     display.drawBitmap(50, 27, logo2_bmp, 24, 21, WHITE);       //Draw the little heart
     display.setCursor(5,57);
     display.println("and wait for a while ");  
     display.display();   
     delay(1000);
     display.clearDisplay();
     display.setTextSize(0.5);                    
     display.setTextColor(WHITE);             
     display.setCursor(27,2);                
     display.println("Please place"); 
     display.setCursor(30,12);
     display.println("your finger ");   
     display.drawBitmap(45, 22, logo3_bmp, 32, 32, WHITE);       //Draw the big heart
     display.setCursor(5,57);
     display.println("and wait for a while ");  
     display.display();   
     delay(100);   
     }

}
```

## Code Slave
```
//for esp
#include <PubSubClient.h>
#include <WiFi.h>

char result;
char code;
int heartRate;
int SPO2;
int temperature;
int count;

//WiFi configuration
// 1. KONFIGURASI WIFI
const char* ssid = "(MASUKKAN SSID)";
const char* password = "(MASUKKAN PASSWORD)";

// 2. KONFIGURASI MQTT CLIENT
char CLIENT[]= "app-oximeter1";
char CLIENT_PASSWORD[]="AjNDCq6GEX1uZfLXtHcOqEt7NRwizA";

// 3. KONFIGURASI MQTT BROKER SERVER
const char* mqtt_server = "202.148.1.57";
const int mqtt_port = 1883;

// 4. INISIASI MQTT CLIENT
WiFiClient espClient;
PubSubClient client(espClient);

// 5. INISIASI PESAN
long lastMsg = 0;
char msg[50];
int value = 0;
char payload[512];


// 6. KONFIGURASI BUILTIN LED ESP32
const int ledPin = 2;

void setup() {
  // put your setup code here, to run once:
  //Init serial
  Serial.begin(115200);

  setup_wifi();     
  client.setServer(mqtt_server, mqtt_port);       
  client.setCallback(callback);   
//  n=0;
}

void setup_wifi() {   
     delay(10);  
     Serial.println();   
     Serial.print("Connecting to ");   
     Serial.println(ssid);     
     // PERCOBAAN UNTUK MENGHUBUNGKAN KE WIFI    
     WiFi.begin(ssid, password);     
     while (WiFi.status() != WL_CONNECTED) {     
          delay(500);     
          Serial.print(".");   
     }   
     Serial.println("");   
     Serial.println("WiFi connected");   
     Serial.println("IP address: ");   
     Serial.println(WiFi.localIP());    
}

void callback(char* topic, byte* message, unsigned int length) {
     Serial.print("Message arrived on topic: ");   
     Serial.print(topic);   
     Serial.print(". Message: ");   
     String messageTemp;     
     for (int i = 0; i < length; i++) {     
          Serial.print((char)message[i]);     
          messageTemp += (char)message[i];  
     } 
     Serial.println(messageTemp);     
     if (String(topic) == "esp/switch") {     
          Serial.print("Changing output to ");     
         if(messageTemp == "{\"payload\":{\"message\":\"on\"}}"){           
               Serial.println("on");       
               digitalWrite(ledPin, HIGH);     
         }  else if(messageTemp == "{\"payload\":{\"message\":\"off\"}}"){
               Serial.println("off");       
               digitalWrite(ledPin, LOW);     
         }   
     } 
}

void reconnect() {   
     // LOOPING SAMPAI TERHUBUNG KE MQTT   
     while (!client.connected()) {     
           Serial.print("Attempting MQTT connection...");     
           if (client.connect("espclient", CLIENT, CLIENT_PASSWORD)) {                  
                 Serial.println("connected");       
                 // Subscribe TOPIK      
                // Nilai ESP32 disesuaikan dengan nama perangkat       
                client.subscribe("esp/switch");     
           } else {       
                 Serial.print("failed, rc=");       
                 Serial.print(client.state());       
                 Serial.println(" try again in 5 seconds");       
                // Wait 5 seconds before retrying       
                delay(5000);     
          }  
     } 
}

void loop() {
  // put your main code here, to run repeatedly:

  if (!client.connected()) {     
         reconnect();   
  }   
  client.loop(); 

    if(Serial.available()>0){
      result = Serial.read();
    }
    if(result == 'h' || result == 's' || result == 't' || result == 'c'){
      code = result;
    }
    else if(code == 'h'){
      heartRate = (int)result;
      Serial.print ("heartRate = ");
      Serial.println (heartRate);
      code = '0';
    }
    else if(code == 's'){
      SPO2 = (int)result;
      Serial.print ("spo2 = ");
      Serial.println (SPO2);    
      code = '0';
    }
    else if(code == 't'){
      temperature = (int)result;
      Serial.print ("temperature = ");
      Serial.println (temperature);   
    }
    else if(code == 'c'){
      count = (int)result;
      Serial.print ("count = ");
      Serial.println (count);       
      sprintf(payload,"{\"payload\":{\"heartbeat\":%d, \"spo2\":%d, \"temperature\":%d, \"count\":%d}}", heartRate, SPO2, temperature, count);     
      client.publish("esp", payload);     
      code = '0';  
    }  
}

```
Catatan =
<p style="text-align:justify;">Dapat dilihat pada bagian loop, slave akan membaca data yang dikirimkan oleh master. Jika data yang didapatkan berupa char 1 huruf, maka data tersebut adalah kode untuk data selanjutnya. Berikut ini adalah keterangan kode yang ada pada source code.</p>

Tabel.21.Kode dan Variabel
| Kode| Variabel | 
| -------- | -------- | 
| h    | Heartrate     | 
| s    | SPO2    | 
| t    | Temperature     | 
| c    | Count     | 

<p style="text-align:justify;">Dengan ini, maka data yang dikirimkan setelah kode tersebut adalah data untuk variabel dari kode tersebut. Saat data terakhir telah diterima, akan diatur data yang akan dikirimkan dengan format json yang tepat, kemudian data akan dipublish dengan topic “esp”. (Topiknya disamakan dengan nama device yang dibuat pada Xirka IoT Platform). Variabel count hanya berfungsi untuk melihat jika ada data yang terlewat dalam pengirimannya, dapat dihapus saja.</p>
<p style="text-align:justify;">Setelah programnya diupload, keluaran pada master sama dengan keluaran yang dihasilkan sebelumnya, yaitu OLED akan menampilkan hasil perhitungan heartrate, spo2, dan temperature. Sedangkan, pada slave, pertama-tama ESP32 akan terkoneksi dengan WiFi sesuai dengan ssid dan password yang telah diatur.</p>

## Ilustrasi Gambar
Setelah berhasil Upload Code dapat langsung mengamati hasilnya

![](https://i.imgur.com/TRiO3k9.jpg)
[Gambar Wiring Board Ardunesia Projek IoT](https://drive.google.com/file/d/1NU7PVr8RGh_DMUrlWTUqEHFwKeOwWMx1/view?usp=sharing)

![](https://i.imgur.com/wsKrtjC.jpg)
[Gambar Hasil Board Ardunesia Projek IoT](https://drive.google.com/file/d/18M8FjAI4MahkdmD-9WOabTG4gdaB8RQk/view?usp=sharing)

---

<br>

# 19. Motor Servo SG-90 Tanpa Library
<p style="text-align:justify;">Motor servo dapat dikendalikan dengan memanipulasi duty cycle dari suatu sinyal kotak periodik yang terbentuk. Duty cycle dalam rentang tertentu berbanding lurus dengan posisi motor servo, dari 0 hingga 180 derajat. Pada project ini, akan di-generate suatu sinyal kotak berperiode 10 ms. Dari hasil eksperimen, diperoleh bahwa posisi 0 derajat motor servo akan diperoleh ketika duty cycle yang dihasilkan adalah 5% dan posisi 180 derajat diperoleh ketika duty cycle 25%.</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Motor Servo SG-90
3. Kabel Jumper

## Wiring 
Tabel 22. Wiring Board Ardunesia dengan Motor Servo
| Board Ardunesia | Motor Servo | 
| -------- | -------- | 
| Pin Digital 2     | Signal    |
| GND     | GND (Coklat)    |
| 5V     | VCC (Merah)    |

## Code
```
volatile int bgload = FOSC*10.0/1000.0 - 1;

void setup() {
  XSTIOT_CLKCON |= XSTIOT_CLKCON_DUALTIMER0_Msk;
  CMSDK_DUALTIMER0A->TimerLoad   = bgload;
  CMSDK_DUALTIMER0A->TimerBGLoad = bgload;
  CMSDK_DUALTIMER0A->TimerComp   = bgload - FOSC*500.0/1000000.0;
  CMSDK_GPIO8->ALTFUNCSET   = (1<<2);
  CMSDK_GPIO8->OUTENABLESET = (1<<2);
  CMSDK_DUALTIMER0A->TimerControl = (0b01UL << CMSDK_DUALTIMER_CTRL_PWMSEL_Pos) // Select P8[2] as PWM output channel
                                  | CMSDK_DUALTIMER_CTRL_PWMEN_Msk              // Enable PWM output
                                  | CMSDK_DUALTIMER_CTRL_EN_Msk                 // Enable timer
                                  | CMSDK_DUALTIMER_CTRL_MODE_Msk               // Reload from BGLOAD
                                  | CMSDK_DUALTIMER_CTRL_SIZE_Msk               // 32-bit count size
                                  ;
}

void loop() {
  // put your main code here, to run repeatedly:
  writeServoPin2(0);
  delay(1000);
  writeServoPin2(90);
  delay(1000);
  writeServoPin2(180);
  delay(1000);
  writeServoPin2(90);
  delay(1000);
}

void writeServoPin2(int degree) {
  float limit = float(degree)*2000.0/180.0 + 500.0;
  CMSDK_DUALTIMER0A->TimerComp = bgload - FOSC*limit/1000000.0;
}

```
<p style="text-align:justify;">Hasilnya, motor berputar sesuai dengan arah-arah dalam derajat yang telah dituliskan pada void loop().</p>

## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring untuk project ini.</p>

![](https://i.imgur.com/EgTKIl7.png)

---

<br>

# 20. Motor DC dan Motor Driver L298N
<p style="text-align:justify;">Pada bagian ini, akan dipaparkan pengendalian motor DC menggunakan motor driver L298N. Motor DC akan dikendalikan dengan kecepatan ratingnya tetapi dengan arah putaran yang berubah-ubah untuk periode waktu tertentu. </p>

## Komponen yang digunakan
1. Board Ardunesia
2. Motor DC
3. Motor Driver L298N
4. Potensiometer
5. Power Supply 12V
6. Kabel Jumper

## Wiring 
Tabel 23. Wiring Ardunesia dengan Motor Driver L298N
| Ardunesia | Motor Driver | 
| -------- | -------- | 
| Pin Digital 8     | IN1    |
| Pin Digital 9     | IN2    |
| 5V     | 5V    |
| GND     | GND    |

<br>

Tabel 24. Wiring Power Supply dengan Motor Driver
| Power Supply | Motor Driver | 
| -------- | -------- | 
| Kutub Positif     | 12V    |
| Kutub Negatif     | GND    |

<br>

Tabel 25. Wiring Motor Driver dengan Motor DC
| Motor Driver | Motor DC | 
| -------- | -------- | 
| OUT1     | Kutub Positif    |
| OUT2     | Kutub Negatif    |

## Code
```
/// Define pin
#define IN_1 8
#define IN_2 9

void setup() {
  // Setup pin output
  pinMode(IN_1, OUTPUT);
  pinMode(IN_2, OUTPUT);
}

void loop() {
  // Motor diam selama 1 detik
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, LOW);
  delay(1000);
  
  // Memutar motor d engan arah tertentu selama 2 detik
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, HIGH);
  delay(2000);

  // Motor diam selama 1 detik
  digitalWrite(IN_1, LOW);
  digitalWrite(IN_2, LOW);
  delay(1000);

  // Memutar motor dengan arah yang berlawanan dengan sebelumnya selama 2 detik
  digitalWrite(IN_1, HIGH);
  digitalWrite(IN_2, LOW);
  delay(2000);
}
```

## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring untuk project ini.</p>

![](https://i.imgur.com/CEmZJFs.png)

---

<br>

# 21. Motor Stepper 28byj-48 dan Motor Driver ULN2003
<p style="text-align:justify;">Motor stepper merupakan motor yang bergerak dalam satuan langkah (step). Satu step dari motor berupa perputaran beberapa derajat, baik searah maupun berlawanan arah jarum jam. Spesifikasi dari motor menentukan derajat perputaran setiap satu step, atau jumlah step yang diperlukan setiap satu putaran penuh motor (STEPS PER REVOLUTION).</p>
<p style="text-align:justify;">Pada project ini akan dipaparkan pengendalian motor stepper menggunakan library Stepper.h, menggunakan board Ardunesia dan motor driver ULN2003.
</p>

## Komponen yang digunakan
1. Board Ardunesia
2. Motor Stepper 28byj-48
3. Motor Driver ULN2003
4. Kabel Jumper

## Library yang digunakan
#include <Stepper.h>

## Wiring 
Tabel 26. Wiring Ardunesia dengan Motor Driver ULN2003
| Ardunesia | ULN2003 | 
| -------- | -------- | 
| Pin Digital 50     | IN1    |
| Pin Digital 51    | IN2    |
| Pin Digital 52     | IN3    |
| Pin Digital 53     | IN4    |
| 5V     | Power+    |
| GND     | Power-    |

<p style="text-align:justify;">Wiring motor stepper dengan motor driver disesuaikan dengan mounting yang telah tertanam.
</p>

## Code
```
#include <Stepper.h>

// Definisikan spesifikasi motor
const float STEPS_PER_REV = 32;

const float GEAR_RED = 64;

const float STEPS_PER_OUT_REV = STEPS_PER_REV * GEAR_RED;

int StepsRequired;

// Deklarasi stepper motor
Stepper steppermotor(STEPS_PER_REV, 50, 52, 51, 53);

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // Memutar motor dengan arah tertentu sebanyak setengah revolusi, dengan speed 400
  StepsRequired = STEPS_PER_OUT_REV / 2;
  steppermotor.setSpeed(400);
  steppermotor.step(StepsRequired);
  delay(2000);

  // Memutar motor dengan arah berlawanan sebanyak setengah revolusi, dengan speed 900
  StepsRequired = - STEPS_PER_OUT_REV / 2;
  steppermotor.setSpeed(900);
  steppermotor.step(StepsRequired);
  delay(2000);
}

```
<p style="text-align:justify;">Catatan: </p>
<p style="text-align:justify;">Library Stepper.h pada awalnya menggunakan pewaktu micros(). Namun, micros() pada Ardunesia menghasilkan pewaktu yang kacau dan tidak stabil. Untungnya, fungsi pewaktu millis() masih dapat digunakan, sehingga perlu diganti pewaktu micros() dengan millis() pada library Stepper.h, tentunya dengan melakukan sedikit konfigurasi terhadap beberapa konstanta. </p>

## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring untuk project ini.</p>

![](https://i.imgur.com/lk9Ee6f.png)



---

<br>

# 22. Motor DC dengan Rotary Encoder Built-in
<p style="text-align:justify;">Pada bagian ini akan dipaparkan pengendalian kecepatan motor DC dengan rotary encoder built-in sebagai sensor yang mengamati kecepatan motor. </p>

## Komponen yang digunakan
1. Board Ardunesia
2. Motor DC dengan Rotary Encoder Built-in
3. Motor Driver L298N
4. Kabel Jumper
5. Potensiometer

## Wiring
Tabel 27. Wiring Ardunesia dengan Motor Driver L298N
| Ardunesia | Motor Driver | 
| -------- | -------- | 
| Pin Digital 3     | ENB    |
| Pin Digital 4     | IN3    |
| Pin Digital 5     | IN4    |
| 5V     | 5V    |
| GND     | GND    |

<br>

Tabel 28. Wiring Ardunesia dengan Potensiometer
| Ardunesia | Potensiometer | 
| -------- | -------- | 
| Pin Analog A0     | Kaki tengah    |
| 3.3V     | Kaki kiri    |
| GND     | Kaki kanan    |

<br>

Tabel 29. Wiring Power Supply dengan Motor Driver
| Power Supply | Motor Driver | 
| -------- | -------- | 
| Kutub Positif     | 12V    |
| Kutub Negatif     | GND    |

<br>

Tabel 30. Wiring Motor Driver dengan Motor DC
| Motor Driver | Motor DC | 
| -------- | -------- | 
| OUT3     | Kutub Positif    |
| OUT4     | Kutub Negatif    |

<br>

Tabel 31. Wiring Rotary Encoder dengan Ardunesia
| Ardunesia | Rotary Encoder | 
| -------- | -------- | 
| 3.3V     | power+    |
| GND     | power-    |
| Pin Digital 6     | pin A    |
| Pin Digital 7     | pin B    |

## Code
```
/// Define pin
#define IN_3 4
#define IN_4 5
#define EN_B 3

unsigned long int prevTime;

// Deklarasikan variabel input analog dan PWM
int analogInput;
int PWM;

#define PULSE_PER_ROT 480
// Periode pengukuran kecepatan: 50 ms
#define PERIOD_MS 50

int state=0;
long int posisi=0;
float rotation;
float kecsudut;

void doEncoderA() {
  digitalRead(7) ? posisi-- : posisi++;
}

void setup() {
  // Setup pin output
  pinMode(IN_3, OUTPUT);
  pinMode(IN_4, OUTPUT);
  // Setup pin input
  pinMode(6,INPUT_PULLUP);
  pinMode(7,INPUT_PULLUP);

  attachInterrupt(6, doEncoderA, RISING);
}

void loop() {
  // Baca input analog dari potensiometer
  analogInput = analogRead(A0);

  // Ubah skala pembacaan input analog untuk mendapatkan sinyal PWM
  PWM = 65535.0*float(analogInput)/1023.0;

  // Putar motor dengan arah tertentu
  digitalWrite(IN_3, LOW);
  digitalWrite(IN_4, HIGH);

  // Atur kecepatan motor pada pin EN_B sesuai dengan nilai PWM yang didapatkan
  analogWrite(EN_B, PWM);

  if (millis() - prevTime > PERIOD_MS) {
    prevTime = millis();
    rotation = (float)posisi/PULSE_PER_ROT;
    kecsudut = float(rotation)/PERIOD_MS*60.0*1000.0;
    Serial.println(kecsudut);
    posisi = 0;
  }
}

```


## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring untuk project ini.</p>

![](https://i.imgur.com/qN0jpIW.png)

<p style="text-align:justify;">Berikut ini merupakan kecepatan motor yang ditampilkan pada serial plotter.</p>

![](https://i.imgur.com/nP4CC4k.png)


---

<br>

# 23. Humidifier (Water Atomizer)
<p style="text-align:justify;">Humidifier berarti pelembab. Modul Grove Water Atromizer bekerja mengubah air menjadi molekul-molekul kecil dengan bantuan gelombang ultrasonik, sehingga muncul uap air yang melembabkan ruangan. </p>

## Komponen yang digunakan
1. Board Ardunesia
2. Modul Grove Water Atomizer
3. Kabel Jumper Secukupnya
4. Air

## Wiring
Tabel 32. Wiring Water Atomizer dengan Ardunesia
| Ardunesia | Water Atomizer | 
| -------- | -------- | 
| 5V     | VCC    |
| GND     | GND    |
| Pin Digital 49     | SIG    |
| -     | NC    |
<p style="text-align:justify;">Pemancar ultrasonik pada modul Grove Water Atomizer diletakkan di atas permukaan air.</p>

## Code
```
#define humidifierPin 49

void setup() {
  // set pin humidifier sebagai output
  pinMode(humidifierPin, OUTPUT);
}

void loop() {
  // set pin humidifier menjadi high untuk menyalakan humidifier
  digitalWrite(humidifierPin, HIGH);
  delay(3000);
  // set pin humidifier menjadi low untuk mematikan humidifier
  digitalWrite(humidifierPin, LOW);
  delay(1500);
}
```


## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring untuk project ini.</p>

![](https://i.imgur.com/xHMKwIB.png)


---

<br>

# 24. Sensor 3 – Axis Digital Accelerometer 
<p style="text-align:justify;">Module 3 – Axis Digital Accelerometer merupakan sensor modul yang dapat digunakan untuk mendeteksi pergerakan serta orientasi arah gerak.  </p>

## Komponen yang digunakan
1.	Board Ardunesia
2.	Module 3 – Axis Digital Accelerometer
3.	Kabel Jumper
4.	Protoboard


## Library yang digunakan
•	#include <Wire.h>
•	#include "MMA7660.h"


## Wiring
Tabel 33. Wiring Board Ardunesia dengan module 3 – axis digital accelerometer
| Ardunesia | Module 3 – axis digital accelerometer | 
| -------- | -------- | 
| SDA     | SDA   |
| SCL     | SCL   |
| 5V     | VCC    |
| GND    | GND    |

## Code
```
#include <Wire.h>
#include "MMA7660.h"
MMA7660 accelemeter;
void setup()
{
  accelemeter.init();  
  Serial.begin(9600);
}
void loop()
{
  float ax,ay,az;

  //Get acceleration value from module
  accelemeter.getAcceleration(&ax,&ay,&az);
  Serial.println("accleration of X/Y/Z: ");
  Serial.print(ax);
  Serial.println(" g");
  Serial.print(ay);
  Serial.println(" g");
  Serial.print(az);
  Serial.println(" g");
  Serial.println("*************");
  delay(500);
}

```


## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring dan hasil untuk project ini.</p>

![](https://i.imgur.com/VPi5OW8.png)
![](https://i.imgur.com/3QLSpbU.png)

---

<br>

# 25. Sensor Module DHT11 
<p style="text-align:justify;">Module DHT11 merupakan modul sensor yang dapat mengukur temperature/suhu dan kelembaban. Sensor kapasitif pada modul ini digunakan untuk mengukur kelembaban dan NTC (Temperature Coefficient Thermistor) negatif digunakan untuk mengukur suhu.  </p>

## Komponen yang digunakan
1.	Board Ardunesia
2.	Module DHT11
3.	LCD 16 x 2
4.	Kabel Jumper
5.	Protoboard


## Library yang digunakan
•	#include <Wire.h>
•	#include "rgb_lcd.h"
•	#include "DHT.h"



## Wiring
Tabel 34. Wiring Board Ardunesia dengan LCD 16 x 2
| Ardunesia | LCD 16 x 2 | 
| -------- | -------- | 
| SDA     | SDA   |
| SCL     | SCL   |
| 5V     | VCC    |
| GND    | GND    |

Tabel 35. Wiring Board Ardunesia dengan Module DHT11
| Ardunesia | Module DHT11 | 
| -------- | -------- | 
| Digital Pin 2     | SIG   |
| -     | NC   |
| 5V    | VCC    |
| GND    | GND   |

## Code
```
#include <Wire.h>
#include "rgb_lcd.h"
rgb_lcd lcd;
const int colorR = 255;
const int colorG = 0;
const int colorB = 0;

#include "DHT.h"
#define DHTSensor 2
#define DHTTYPE DHT11

DHT dht(DHTSensor, DHTTYPE);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  lcd.begin(16, 2);

  lcd.setRGB(colorR, colorG, colorB);

  delay(1000);
  dht.begin();
}

void loop() {
  //Find humidity and temperature value
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
  //Checking first if sensor read the value
  if(isnan(h) || isnan(h)){
    Serial.println("Tidak terbaca");
  }
  
  else{
    lcd.setCursor(0, 0);
    lcd.print("Hum: ");
    lcd.print(h);
    lcd.print(" %");
    Serial.print("Hum: ");
    Serial.print(h);
    Serial.print(" %");

    Serial.println();
    Serial.print("Temp: ");
    Serial.print(t);
    Serial.print(" *C");
    Serial.println();
    lcd.setCursor(0, 1);
    lcd.print("Temp: ");
    lcd.print(t);
    lcd.print(" *C");
    delay(100);
  }
}



```


## Ilustrasi Gambar
<p style="text-align:justify;">Berikut ini merupakan ilustrasi wiring dan hasil untuk project ini..</p>

![](https://i.imgur.com/8Q1fDVi.png)
![](https://i.imgur.com/V8CGXpU.png)
![](https://i.imgur.com/KXT1wkD.png)




