Trik menyimpan bilangan random dengan arduino

Dengan arduino kita bisa menghasilkan bilangan acak (random generator) dengan menggunakan sketch/program:

long randNumber;

void setup(){
  Serial.begin(9600);
  Serial.println("Menyimpan bilangan acak/random");
  Serial.println("https://www.project.semesin.com");

  randomSeed(analogRead(0));
}

void loop() {
  // print bilangan acak dari 0 hingga 299
  randNumber = random(300);
  Serial.println(randNumber);

  delay(1000);
}

Nilai acak/random yang dihasilkan oleh mesin digital seperi arduino tidaklah sepenuhnya acak, karena secara pandang digital diperlukan metode matematis (contohnya LFSR – linear-feedback shift register) dengan menerapkan suatu persamaan dimana bilangan berikutnya dihitung dari bilangan yang ada sekarang.

Dengan demikian nilai random yang dihasilkan merupakan perulangan terus menerus dan berulang. Agar deretan acak ini menghasilkan deretan berbeda setiap waktu, maka diberikan nilai awal (seed). salah satu contoh pepuler adalah perintah analogRead(pin):

  nilaiAwal = analogRead(0);
  randomSeed(nilaiAwal);

Untuk kembali ke bilangan sebelumnya kita bisa menyimpan deret bilangan ke dalam array, namun tidak efisien untuk jumlah bilangan yang besar. Untuk itu kita bisa menggunakan trik yaitu dengan melakukan perulangan dengan memberi nilai awal (seed) yang sama.

contohnya seperti sketch berikut:

long randNumber;
uint16_t nilaiAwal;

void setup(){
  Serial.begin(9600);

  nilaiAwal = analogRead(0);
  randomSeed(nilaiAwal);
}

void loop() {
  randNumber = ambilDeretAcak(nilaiAwal, 100, 300);
  Serial.println(randNumber);
  
  delay(1000);
}

uint16_t ambilDeretAcak(uint16_t nilaiawal, uint16_t urutan, uint16_t nilaiAcakMaksimal)
{
  uint16_t nilaiAcak;

  randomSeed(nilaiawal);
  for(uint16_t i=0;i<urutan;i++)
  {
    nilaiAcak = random(nilaiAcakMaksimal);
  }
  return nilaiAcak;
}

fungsi ambilDeretAcak akan menghasilkan bilangan yang berada di urutan tertentu dalam deret acak dengan nilai awal tertentu.

Konversi penanggalan Masehi ke Hijriah menggunakan Arduino

Penanggalan masehi mengacu pada peredaran matahari, satu tahun masehi terhitung sebesar 365,25 hari, sedangkan Kalender hijriah mengacu pada peredaran bulan, waktu 12 kali peredaran bulan terhitung sebesar 354,367068 hari.
Untuk konversi masehi ke hijriah mengikuti kaidah berikut ini :

  1. Basis perhitungan Masehi ditetapkan pada 18 April 1999.
  2. Basis perhitungan Hijriah ditetapkan pada 1 Muharram 1420.
  3. Jumlah hari dalam satu bulan Hijriah adalah: 30, 29, 30, 29, 30, 29, 30, 29, 30, 29, 30, 29(30).
  4. Berlaku dari jam 00.00 hingga waktu Maghrib karena penanggalan Hijriah berganti hari pada waktu Maghrib

penerapan dalam Arduino bisa menggunakan program/sketch berikut ini:

double tahunBulan = 354.367068;
double tahunMatahari = 365.25;

String namaBulanHijriah[] = {"Muharram","Safar","Rabiul awal","Rabiul akhir","Jumadil awal","Jumadil akhir","Rajab","Sya'ban","Ramadhan","Syawal","Dzulkaidah","Dzulhijjah"};
String namaBulanMasehi[] = {"Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"};
uint16_t jumlahHariPerBulanHijriah[] = {0,30,59,89,118,148,177,207,236,266,295,325,354};
uint16_t jumlahHariPerBulanMasehi[]={0,31,59,90,120,151,181,212,243,273,304,334};

void setup() {
  Serial.begin(9600);
  Serial.println("Konversi Penanggalan Masehi ke Hijriah");
  Serial.println("https://www.project.semesin.com");
}

void loop() {
  uint32_t jumlahHari;
  double jumlahHariMatahari;
  
  byte tanggalMasehi = 16;
  byte bulanMasehi = 3;
  uint16_t tahunMasehi = 2018;

  byte tanggalHijriah;
  byte bulanHijriah;
  uint16_t tahunHijriah;

  jumlahHari = jumlahHariDariTanggal(tanggalMasehi, bulanMasehi, tahunMasehi - 2000);
  masehiKeHijriah(jumlahHari, &tanggalHijriah, &bulanHijriah, &tahunHijriah);

  Serial.print(tanggalMasehi);
  Serial.print(" ");
  Serial.print(namaBulanMasehi[bulanMasehi-1]);
  Serial.print(" ");
  Serial.print(tahunMasehi);

  Serial.print(" == ");

  Serial.print(tanggalHijriah);
  Serial.print(" ");
  Serial.print(namaBulanHijriah[bulanHijriah-1]);
  Serial.print(" ");
  Serial.println(tahunHijriah);

  while(1);
}

//tanggal mulai dari 1
//bulan mulai dari 1
//tahun dua digit
//minggu = 1, sabtu = 7
//base 18 April 1999
uint32_t jumlahHariDariTanggal(byte tanggal, byte bulan, uint16_t tahun)
{
  uint32_t jumlahHari = (uint32_t)tahun * 365;
  for (uint16_t i = 0; i < tahun; i++) 
  {
    if (!(i%4))
    {
      jumlahHari++;
    }
  }
  jumlahHari += jumlahHariPerBulanMasehi[bulan-1];
  if ( (bulan >= 2) && !(tahun % 4)) 
  { 
    jumlahHari++;
  }
  jumlahHari+= tanggal;
  return jumlahHari + 259;// base 18 April 1999
}

void masehiKeHijriah(uint32_t HariMasehi, byte *tanggal, byte *bulan, uint16_t *tahun)
{
  uint16_t sisaHari;
  *tahun = floor(HariMasehi/tahunBulan);
  sisaHari = HariMasehi - (tahunBulan * *tahun);

  for(byte i=0;i<sizeof(jumlahHariPerBulanHijriah);i++)
  {
    if(sisaHari <= jumlahHariPerBulanHijriah[i])
    {
      sisaHari -= jumlahHariPerBulanHijriah[i-1];
      *bulan = i;
      break;
    }
  }
  *tanggal = sisaHari;
  *tahun += 1420;
}

hasil keluaran di serial monitor:

Catatan : metode ini memiliki kekurangan yaitu menghitung penanggalan Hijriah dengan jumlah bulan yang tetap (hanya bagus untuk mengenal prinsip konversi) untuk konversi yang lebih presisi bisa menggunakan metode Julian Date :
Konversi masehi ke Pasaran Jawa dan Hijriah dengan metode Julian Date

Komunikasi dua arah Arduino dengan Web Browser menggunakan MySQL, XAMPP/web hosting dan ESP8266

Untuk komunikasi jarak jauh atau komunikasi tanpa kabel menggunakan Arduino bisa menggunakan ESP8266 (wifi shield) yang akan menghubungkan arduino ke internet/jaringan lokal. Disamping itu harus pula dibangun server yang berfungsi sebagai penyedia layanan sehingga sistem komunikasi bisa berjalan timbal balik. Dalam server juga dibutuhkan media untuk merekam komunikasi tersebut, salah satu yang populer adalah database MySQL. Ini adalah salah satu cara menghubungkan arduino dengan database yang paling efisien.

Menghubungkan MySQL – Arduino dibutuhkan bahasa php sebagai penerjemah query (bahasa database), baik permintaan (GET request) dari arduino – MySQL dan web browser – MySQL. Jika skema ini sudah terbangun maka kita bisa mengkomunikasikan arduino – web browser (lokal / internet).

Menyimpan data dari arduino ke mysql esp8266 bisa dilaksanakan dengan cara ini, data dari arduino ditransmisikan melalui jaringan wifi dan diterima oleh web server. Data tersebut kemudian di proses oleh php dan juka diizinkan maka data tersebut akan disimpan dalam database.

Mengirim perintah dari browser ke arduino dengan esp8266 juga dapat dilakukan dengan cara sebaliknya.

Webserver yang digunakan dalam perancangan ini adalah XAMPP di PC lokal dan jasa server hosting.

Langkah perancangannya sebagai berikut:

  1. Merangkai Arduino + ESP8266
  2. Membuat sketch Arduino untuk mengirim dan menerima data dari database
  3. Konfigurasi koneksi ESP8266 ke access point wifi (AP)
  4. Install XAMPP server dan mengaktifkannya
  5. Untuk web server hosting, membuat database, user account dan priveleged-nya
  6. Membuat program php, dariArduino.php, keArduino.php, dariBrowser.php serta program php pendukung.

Arduino + ESP8266

Rangkaian yang digunakan:

Diagram:

Untuk menghubungkan arduino dengan jaringan, salah satu yang bisa digunakan adalah modul wifi shiel ESP8266. kali ini saya menggunakan library “WiFiEsp.h”.

Catatan, untuk terhubung ke web hosting, pastikan wifi terhubung ke internet (bridge connection)

sebelum menggunakannya konfigurasi dahulu modul tersebut, editlah bagian berikut:


char ssid[] = "ArduinoMySQL";        // Isi dengan nama profil Wifi
char pass[] = "12345678";            // password wifi
//char server[] = "192.168.123.1";     // alamat access point yang 
char server[] = "semesin.com";     // alamat server hosting 

sketch atau program berikut memiliki fitur:

  1. Menerima masukan string/text dari serial monitor dan mengirimkannya ke webserver untuk disimpan ke database MySQL.
  2. Menerima data perintah dari webserver dalam jangka waktu tertentu contoh kali ini setiap 5 detik.

sketch atau program lengkapnya sebagai berikut:

#include "WiFiEsp.h"

char ssid[] = "ArduinoMySQL";        // Isi dengan nama profil Wifi
char pass[] = "12345678";            // password wifi
//char server[] = "192.168.123.1";     // alamat access point yang telah terinstall XAMPP local host
char server[] = "semesin.com";     // alamat web hosting

char namaVariabel[] = "Variabel";
String text = "";
String Respon = "";
bool responDariServer = false;

bool statusKomunikasiWifi = false;
long waktuMulai;
long waktuMintaData = 5000; //minta data setiap 5000ms

WiFiEspClient client;
int status = WL_IDLE_STATUS;

void setup()
{
  Serial.begin(9600);
  Serial.println("Koneksi arduino dengan mySql menggunakan ESp8266 dan XAMPP");
  Serial.println("Ketik pesan yang akan dikirim (pastikan setting serial ke \"both NL & CR\")");
  Serial.println("https://www.project.semesin.com");
  Serial.println();

  Serial1.begin(115200);
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  // you're connected now, so print out the data
  Serial.println("You're connected to the network");
  
  printWifiStatus();
  waktuMulai = millis();
}

void loop()
{
  //tunggu imputan nilai dari untuk dikirim ke server
  while(Serial.available())
  {
    char c = Serial.read();
    if((c != '\r') && (c != '\n'))
    {
      text += c;
    }
    if(c == '\n')
    {
      statusKomunikasiWifi = kirimKeDatabase("dataDariSerial",text);
      text = "";
      waktuMulai = millis();
    }
  }

  if(waktuMintaData < millis() - waktuMulai)
  {
    statusKomunikasiWifi = ambilDatabase("perintah");
    waktuMulai = millis();
  }
  
  // periksa respon dari server
  if(statusKomunikasiWifi)
  {
    // if there are incoming bytes available
    // from the server, read them and print them
    while (client.available()) 
    {
      char c = client.read();
      Respon += c;
    }
  
    // if the server's disconnected, stop the client
    if (!client.connected()) {
      Serial.println("Disconnecting from server...");
      client.stop();
      statusKomunikasiWifi = false;
      responDariServer = true;
    }
  }

  // penanganan data yang diretima dari server
  if(responDariServer)
  {
    responDariServer = false;
    //Serial.println(Respon);
    int posisiData = Respon.indexOf("\r\n\r\n");
    String Data = Respon.substring(posisiData+4);
    Data.trim();

    String variabel;
    String nilai;

    Serial.println("Data dari server");
    posisiData = Data.indexOf('=');
    if(posisiData > 0)
    {
      variabel = Data.substring(0,posisiData);
      nilai = Data.substring(posisiData+1);
  
      //===========Penanganan respon disini
      Serial.print(variabel);
      Serial.print(" = ");
      Serial.println(nilai);
    }
    Respon = "";
  }
}
bool ambilDatabase(String variabel)
{
  Serial.println();
  Serial.println("Starting connection to server...");
  // if you get a connection, report back via serial
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request
    client.print("GET /arduino_mysql/keArduino.php?variabel=");
    client.print(variabel);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

    long _startMillis = millis();
    while (!client.available() and (millis() - _startMillis < 2000));

    return true;
  }
  return false;
}

bool kirimKeDatabase(String namaVariabel, String nilai)
{
  Serial.println();
  Serial.println("Starting connection to server...");
  // if you get a connection, report back via serial
  if (client.connect(server, 80)) {
    Serial.println("Connected to server");
    // Make a HTTP request

    // parameter 1
    client.print("GET /arduino_mysql/dariArduino.php?");
    client.print("variabel=");
    client.print(namaVariabel);
    
    // parameter 2 dan selanjutnya
    client.print("&");
    client.print("nilai=");
    client.print(nilai);
    
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

    return true;
  }
  return false;
}

void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");

  IPAddress gateway = WiFi.gatewayIP();
  Serial.print("gateway:");
  Serial.print(gateway);
  Serial.println(" ");
}

tampilan serial monitor dari arduino:

 

XAMPP webserver + database MySQL

untuk membuat webserver di komputer lokal instal XAMPP (saya menggunakan v3.2.2) atau bundel webserver lain yang termasuk didalamnya MySQL.

untuk memulainya jalankan/aktifkan webserver dan MySQL

 

Web Hosting + Database MySQL

catatan: huruf besar/kecil berpengaruh (case-sensitif)

Server hosting umumnya memiliki fitur kemanan, untuk itu kita harus masuk ke cpanel kemudian membuat sebuah database dengan memilih menu ‘MySQL® Database Wizard‘ dan mengisi nama database, misalnya ‘arduino_mysql’.

selanjutnya ‘next step’ buatlah akun dengan memasukkan nama dan paswword (nama dan password ini akan dimasukkan ke ‘fungction.php’).

selanjutnya prilih privileges yang akan digunakan.

sebagai webserver dan database server yang akan berhubungan timbal balik dengan arduino, maka kita buat halaman web berbasis bahasa PHP dan memiliki fitur:

  1. Menerima data dari Arduino menggunakan metode ‘GET’ dengan parameter ‘variabel’, ‘nilai’, dan ‘status’.
  2. Menyimpan data dari entri data di webserver, dan akan mengirimkannya ke Arduino saat diminta.
  3. Menyedian halaman tampilan database ke halaman web.

fitur-fitur ini saya buatkan dalam beberapa program PHP, untuk menggunakannya extract file Arduino MySQL dan copy ke folder “/arduino_mysql” (untuk XAMPP root folder “C:\xampp\htdocs\arduino_mysql”, untuk web hosting “public_html/arduino_mysql”) dengan program berikut:

file php yang digunakan diuraikan disini:

function.php

sebelum menggunakan file ini edit dahulu bagian sesuai kebutuhan:

    $servername = "localhost";
    $username = "******_Arduino";
    $password = "Arduino";
    $database = "******_arduino_mysql";

kode lengkap function.php

  <?php

 function databaseConnect()
  {
    /* XAMPP
    $servername = "localhost";
    $username = "root";
    $password = "";
    $database = "arduino_mysql";
    */
    
    $servername = "localhost";
    $username = "******_Arduino";
    $password = "Arduino";
    $database = "******_arduino_mysql";
    
    // Create connection
    $conn = new mysqli($servername, $username, $password);

    // Check connection
    if ($conn->connect_error) {
      die("Connection failed: " . $conn->connect_error);
    }
    echoDebug("Connected successfully<br>");
    
    // Create database
    $sql = "CREATE DATABASE IF NOT EXISTS ".$database;
    if ($conn->query($sql) === TRUE) {
      echoDebug("Database created successfully<br>");
    } else {
      echoDebug("Error creating database: " . $conn->error);
    }
    
    // Connect to database
    $conn = new mysqli($servername, $username, $password, $database);
    // Check connection
    if ($conn->connect_error) {
      die("Database connection failed: " . $conn->connect_error);
    }
    echoDebug("Database connected successfully<br>");
    
    // sql to create table
    $sql = "CREATE TABLE IF NOT EXISTS arduino_data (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    variabel VARCHAR(30) NOT NULL,
    nilai VARCHAR(30) NOT NULL
    )";
    
    if ($conn->query($sql) === TRUE) {
      echoDebug("Table arduino_data created successfully</br>");
    } else {
      echoDebug("Error creating table: " . $conn->error);
    }
    // sql to create table
    $sql = "CREATE TABLE IF NOT EXISTS browser_data (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    variabel VARCHAR(30) NOT NULL,
    nilai VARCHAR(30) NOT NULL
    )";
    
    if ($conn->query($sql) === TRUE) {
      echoDebug("Table arduino_data created successfully</br>");
    } else {
      echoDebug("Error creating table: " . $conn->error);
    }
    return $conn;
  }
  function echoDebug($message) 
  {
    // hapus komen '//' jika ingin men-debug pesan
    //echo $message;
  }
?> 

index.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();

  if(isset($_GET['message']))
  {
    echo $_GET['message'];
    echo "<br>";
    echo "<br>";
  }
  $sql = "SELECT * FROM arduino_data";
  $result = $conn->query($sql);

  echo "<html>";
  echo "<head>";
  echo "<meta http-equiv='refresh' content='10'>";
  echo "</head>";
  echo "<body>";
  echo "Arduino Data";
  echo "<table border='1'>";
  echo "<tr>";
  echo "<td width='50'>id</td><td width='100'>Variabel</td><td width='200'>Nilai</td>";
  echo "</tr>";
  if ($result->num_rows > 0) {
    // output data of each row
    while($row = $result->fetch_assoc()) {
      echo "<tr>";
      echo "<td>".$row["id"]."</td><td>".$row["variabel"]."</td><td>".$row["nilai"]. "</td>";
      echo "</tr>";
    }
  } else {
    echo "<td colspan='3'>";
    echo("tidak ada hasil");
    echo "</td>";
  }
  echo "</table>";
  
  echo "<form action='dariBrowser.php' method=GET>";
  echo "<input type='hidden' name='aksi' value='hapus'><br>";
  echo "<input type='submit' value='Hapus semua data'>";
  echo "</form>";

  echo "<br>Kirim data ke Arduino<br>";
  echo "<form action='dariBrowser.php' method=GET>";
  echo "Nama variabel:<br><input type='text' name='variabel'><br>";
  echo "Nilai:<br><input type='text' name='nilai'><br>";
  echo "<input type='submit' value='Kirim'>";
  echo "</form>";
  echo "</body>";
  echo "</html>";

  $conn->close();
?> 

keArduino.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  // Kirim respon bila ada
  if(isset($_GET["variabel"]))
  {
    $variabel = $_GET["variabel"];
    $sql = "SELECT * FROM browser_data WHERE variabel='".$variabel."'";

    if($result = $conn->query($sql))
    {
      $row = $result->fetch_assoc();
      echo $row["variabel"]."=".$row["nilai"];
    }
  }
  
  $conn->close();
?> 

dariArduino.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  if(isset($_GET["variabel"]) && isset($_GET["nilai"]))
  {
    // Simpan data yang diterima ke database
    $variabel = $_GET["variabel"];
    $nilai = $_GET["nilai"];

    $sql = "INSERT INTO arduino_data (variabel, nilai) VALUES ('".$variabel."', '".$nilai."')";

    if ($conn->query($sql) === TRUE) {
      echoDebug("New record created successfully</br>");
    } else {
      echoDebug("Error: " . $sql . "<br>" . $conn->error);
    }
  }
  $conn->close();
?> 

dariBrowser.php

 <?php
  include("function.php");
  
  $conn = databaseConnect();
  
  if(isset($_GET["variabel"]) && isset($_GET["nilai"]))
  {
    // Simpan data yang diterima ke database
    $variabel = $_GET["variabel"];
    $nilai = $_GET["nilai"];
    
    $sql = "SELECT * FROM browser_data WHERE variabel='".$variabel."'";
    $result = $conn->query($sql);

    if ($result->num_rows > 0)
    {
      $sql = "UPDATE browser_data SET nilai='".$nilai."' WHERE variabel='".$variabel."'";
      if ($conn->query($sql) === TRUE) {
        echoDebug("Record updated successfully</br>");
      } else {
        echoDebug("Error updating record: " . $sql . "<br>" . $conn->error);
      }
    }
    else
    {
      $sql = "INSERT INTO browser_data (variabel, nilai) VALUES ('".$variabel."', '".$nilai."')";
      if ($conn->query($sql) === TRUE) {
        echoDebug("New record created successfully</br>");
      } else {
        echoDebug("Error: " . $sql . "<br>" . $conn->error);
      }
    }
      echo "<script type='text/javascript'> document.location = 'index.php?message=Entri data berhasil'; </script>";
    exit();
  }
  else if(isset($_GET['aksi']))
  {
    if($_GET['aksi'] == "hapus")
    {
      // sql to delete a record
      $sql = "TRUNCATE arduino_data";

      if ($conn->query($sql) === TRUE) {
        echoDebug("Record deleted successfully");
      } else {
        echoDebug("Error deleting record: " . $conn->error);
      }
      echo "<script type='text/javascript'> document.location = 'index.php?message=database telah dikosongkan'; </script>";
      exit();
    }
  }
  $conn->close();
?> 

Cara penggunaan

  • Nyalakan wifi (pastikan terhubung ke internet)
  • Masukkan perintah dari serial monitor, data akan tercatat dalam tabel ‘arduino_data’, dalam contoh ini nama variabelnya adalah ‘dataDariSerial’ dengan nilai sesuai dengan entry dari Serial monitor (pastikan setting serial ke “both NL & CR”)
  • Buka halaman “localhost/arduino_mysql/” atau “**nama server**/arduino_mysql/” di browser untuk melihat data yang dikirim dari arduino.
  • Masukan perintah dari formulir di halaman web, dan klik kirim untuk mengirim data ke Arduino, (dalam contoh ini arduino membaca variabel ‘perintah’ jadi masukkan nama variabel sebagai ‘perintah’ serta isikan juga kotak ‘nilai’nya)
  • Arduino akan membaca perintah setiap 5 detik dan akan dilaporkan di Serial monitor.

tampilan halaman web:

library : WiFiEsp.zip

Koneksi Arduino dan Android melalui bluetooth dan MIT App Inventor

Bluetooth dan Arduino bisa digunakan untuk berkomunikasi dengan Android menggunakan MIT App Inventor, berikut langkahnya:

Arduino + bluetooth

Mempersiapkan rangkaian yang terdiri dari Arduino mega dan modul bluetooth HC-05.

Masukkan program atau sketch berikut

String text = "";
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);

  Serial.println("Koneksi arduino dengan app inventor melalui bluetooth");
  Serial.println("Ketik pesan yang akan dikirim (pastikan setting serial ke \"both NL &amp; CR\"");
  Serial.println("https://www.project.semesin.com");
}

void loop() {
  while(Serial.available())
  {
    char c = Serial.read();
    text += c;
    if(c == '\n')
    {
      Serial1.print(text);
      text = "";
    }
  }
  while(Serial1.available())
  {
    Serial.print(char(Serial1.read()));
  }
}

Sketch ini akan menerima text dari “Serial Monitor” dan meneruskannya ke sambungan bluetooth

Begitu juga apabila ada data yang masuk melalui hubungan bluetooth akan ditampilkan ke Serial monitor.

 

Android + App Inventor

Instal apk ini di android BluetoothConnection.apk

Atau bisa mengedit Design MIT App Inventor berikut BluetoothConnection.aia

Design:

Block :

Blok inisialisasi merupakan block yang pertama kali dipanggil ketika aplikasi dijalankan, Jika bluetooth tidak aktif maka blok ini akan memberikan peringatan dan jika bluetooth aktif maka daftar perangkat bluetooth yang terhubung dimasukkan dalam daftar (list)

Blok buttonConnect.Click memiliki dua fungsi yaitu menghubungkan bluetooth dengan perangkat arduino dan memutuskan koneksi bluetooth. Jika bluetooth belum terhubung maka fungsi ini akan memanggil fungsi ListPicker1 yang menampilkan daftar perangkat bluetooth yang terhubung ke android.

Blok ListPicker1.AfterPicking merupakan sebuah even yang berjalan ketika daftar perangkat bluetooth sudah dipilih. Kemudian android diperintahkan untuk membuat sambungan bluetooth dengan perangkat arduino.

Blok buttonSend.Click bekerja saat pengguna menekan tombol kirim dan akan mengirimkan data yang ditulis di textBox.

Blok Clock1.Timer bekerja setiap interval untuk memantau adanya pengiriman data dari perangkat arduino, kemudian akan ditampilkan di layar aplikasi.

Blok Screen1.ErrorOccured merupakan sistem penanganan apabila aplikasi bermasalah dan akan memutuhkan hubungan bluetoothnya.

Block lengkapnya:

Artikel terkait : https://www.project.semesin.com/2018/06/02/komunikasi-data-bluetooth-dengan-app-inventor/

Sistem kontrol PID dengan Arduino

Sistem kontrol adalah suatu sistem untuk mengendalikan keadaan sehingga diperoleh hasil bersesuaian dengan nilai yang diinginkan se-efektif mungkin.

diagram diatas merupakan sistem kontrol terbuka (open loop), dalam sistem ini tidak ada pemberitahuan (klarifikasi).

Dalam suatu sistem pasti terdapat gangguan dan variabel didalam dan dari luar sistem yang mengakibatkan ketidaksesuaian antara hasil yang diperoleh dan nilai yang diinginkan.

diagram diatas merupakan sistem kontrol tertutup (close loop), dengan adanya umpan balik maka sistem bisa melakukan koreksi.

Untuk menjadikan sistem se-efektif mungkin, perlu dilakukan pemodelan terhadap sistem yang dibangun yakni:

    1. Pemodelan masukan (input)
    2. Pemodelan sistem kontrol
      • hidup mati (on/off)
      • proporsional (P)
      • integral (I)
      • proporsional + integral (PI)
      • proporsional + derivative (PD)
      • proporsional + integral + derivative (PID)
    3. Pemodelan gangguan baik baik dari dalam maupun dari luar, dari dalam lebih kepada keandalan pelaksana/actuator (contohnya motor, pemanas, dll) dan gangguan dari luar adalah kondisi-kondisi yang dapat mempengaruhi kinerja pelaksana (contohnya penambahan beban pada motor, sumber panas lain pada pemanas)
    4. pemodelan pelaksana/actuator adalah karakteristik respon dari pelaksana terhadap perintah/sinyal yang diberikan (contohnya perubahan kecepatan motor terhadap setiap level sinyal yang diberikan)
    5. pemodelan objek/plant menyangkut sifat dan variasi perubahan yang akan terjadi pada objek.
    6. pemodelan sensor juga mencakup karakteristik pembacaan sensor terhadap perubahan dari perangkat pelaksana yang diukur.

Adanya model dari sistem yang dibangun akhirnya dapat diperoleh hasil akhir berikut ini:

Keluaran (objek) = Sistem kontrol x masukan

penyederhanaan ini bisa dilakukan dengan metode laplace. persamaan diatas adalah bagaimana hubungan antara masukan dan keluaran sehingga tergambar perilaku dinamik dari sistem kontrol.

apabila variabel-variabel sistem kontrol tidak memberikan respon yang efektif seperti yang diinginkan, maka dilakukan penyesuaian (tuning)

Sistem kontrol PID (Proportional–Integral–Derivative)

PID merupakan mekanisme pengambil keputusan dalam merespon adanya nilai kesalahan. Mekanisme ini memiliki 3 variabel (Kp, Ki, Kd) yang bisa disesuaikan guna memperoleh respon yang efektif.
Sistem kontrol itu berbasis dengan waktu, untuk memperoleh nilai kesalahan berbasis waktu digunakan :

 	kesalahan = input - sensor;
 	integralKesalahan += kesalahan;
 	derivatifKesalahan = kesalahan - kesalahanLalu;
 	kesalahanLalu = kesalahan;
  1. Proporsional adalah faktor kali dari nilai kesalahan saat ini (berbanding lurus), nilai ini berpengaruh langsung terhadap sensitifitas dan responsifitas suatu sistem. Jika nilai Kp dibuat lebih tinggi maka sistem menjadi lebih responsif terhadap nilai kesalahan, tetapi apabila nilai kesalahan terlalu tinggi maka sistem akan terlalu sensitif.
     	Respon = Kp * kesalahan;
    
  2. Integral adalah faktor kali dari nilai kesalahan sebelumnya, nilai Ki merupakan penjumlahan dari nilai-nilai kesalahan yang berfungsi untuk mempercepat sistem menuju nilai yang diinginkan. Jika nilai Ki terlalu tinggi maka dikhawatirkan sistem akan menjadi tidak stabil (overshoot)
     	Respon += Ki * integralKesalahan;
    
  3. Derivatif adalah faktor kali dari kemungkinan nilai kesalahan yang akan datang, nilai Kd berfungsi untuk memprediksi nilai kesalahan beikutnya disebut juga faktor redam karena nilai Kd akan memperlambat tercapainya nilai yang diinginkan namun membuat sistem lebih stabil
     	Respon += Kd * derivatifKesalahan;
    

sketch/program lengkapnya seperti berikut

float kesalahan;
float integralKesalahan;
float derivatifKesalahan;
float kesalahanLalu = 0;
float Kp, Ki, Kd;
float input;

//Pin
byte sensorPin = A0;
byte Pemanas = 2;

//konstanta
#define Ksensor 0.2 //faktor koreksi sensor panas

void setup() {
  pinMode(Pemanas, OUTPUT);
  Serial.begin(9600);
  Serial.println("Sistem kendali PID dengan Arduino");
  Serial.println("https://www.project.semesin.com");
  
  input = 100;
  Kp = 1;
  Ki = 0.5;
  Kd = -0.2;
}

void loop() {
  float sensor = 1.0 * analogRead(sensorPin) * Ksensor;
  
  float respon = hitungPID(input, sensor);
  analogWrite(Pemanas, respon);
  Serial.print(input);
  Serial.print(",");
  Serial.println(sensor);
}

float hitungPID(float input, float sensor)
{
  kesalahan = input - sensor;
  integralKesalahan += kesalahan;
  derivatifKesalahan = kesalahan - kesalahanLalu;
  kesalahanLalu = kesalahan;
  
  return (Kp * kesalahan) + (Ki * integralKesalahan) + (Kd * derivatifKesalahan);
}

loadcell / sensor berat

loadcell adalah sensor yang menghasilkan sinyal listrik dimana besarnya sinyal sebanding dengan berat yang diukur.

beberapa jenis loadcell :

  1. resistansi ketegangan bahan (strain gauge)
  2. piezzoelectric
  3. hidrolik
  4. pneumatik

Dalam artikel ini hanya membahas loadcell jenis resistansi ketegangan bahan

Merupakan jenis loadcell yang sering digunakan, loadcell ini memanfaatkan perubahan resistansi yang sebanding dengan perubahan ketegangan bahan akibat tekanan berat yang diukur. bahan yang digunakan bersifat :

  1. kaku
  2. bisa digunakan dalam jangka yang panjang
  3. memiliki elastisitas yang bagus

pengukuran resistansi ketegangan bahan menggunakan konfigurasi jembatan wheatstone.

Dengan menerapkan tegangan referensi pada dua titik berlawanan maka akan menghasilkan perbedaan tegangan pengukuran pada dua titik lainnya biasanya hanya beberapa miliVolt. Untuk mengetahui besaran ini bisa menggunakan penguat tegangan atau komponen differential analog to digital.

loadcell resistansi ketegangan bahan (strain gauge) tersedia dalam berbagai ukuran, formasi dan karakteristik. Contoh ukuran yang sering digunakan seperti 1, 2, 5,  … 200Kg, sedangkan formasinya bermacam-macam seperti :

  1. Balok dengan tekanan di ujungnya
  2. Balok ganda dengan tekanan berat di tengah.
  3. tipe-S untuk mengukur berat menggantung
  4.  kompresi
  5. tali digunakan pada crane

untuk rangkaiannya tersedia pula dalam bentuk 4 jembatan (full bridge) dan 2 jembatan (half bridge)

Karakteristik yang menentukan kualitas loadcell adalah sensitifitas dalam satuan mV/V, yaitu perbandingan output tegangan di titik pengukuran (A+ dan A-) dengan tegangan dititik sumber (E+ dan E-). Semakin besar nilainya maka pengukuran akan semakin bagus karena mampu mendeteksi perubahan resistansi ketegangan bahan lebih kecil.

catatan dalam penggunaan loadcell jenis resistansi ketegangan bahan :

  1. Bantalan (mounting) harus terukur atau dibuat nol dengan menempatkannya pada tempat yang benar-benar tidak bergerak. Bantalan yang buruk akan menghasilkan histeresis yang mengurangi tingkat presisi pengukuran.
  2. Memberi batas mekanik untuk menghindari kelebihan beban yang dapat mengakibatkan elastisitas sensor berkurang atau hilang.
  3. Menghindari gesekan dengan benda lain. Gesekan akan menghasilkan gaya redam tekanan.
  4. Tegangan referensi yang stabil dan terhindar dari gangguan riak dari rangkaian diluarnya.
  5. adakalanya loadcell perlu dikalibrasi ulang akibat adanya pengaruh suhu, elastisitas bahan dan variasi tegangan.
  6. Ukuran loadcell perlu disesuaikan dengan kapasitas berat yang akan diukur.

contoh rangkaian loadcell:

warna kabel :

  1. merah, E+
  2. hitam, E-
  3. hijau, A+
  4. putih, A-

Pemasangan loadcell 4 kabel

Pemasangan loadcell 4 x 3 kabel

Pemasangan loadcell 2 x 3 kabel

suara bilangan hingga 999.999 dengan arduino

Modul suara arduino yang ada sudah memenuhi kebutuhan perancangan multimedia saat ini, seperti modul suara WTV020SD, mini TF MP3 player, MP3 shield dan lain-lain. Suara arduino bisa digunakan sebagai alarm peringatan, pengisi suara, suara latar, pemberitahuan dan keperluan lainnya.

Dalam perancangam suara dengan arduino kali ini diperuntukkan sebagai pembilang angka dan bisa diterapkan dalam berbagai proyek arduino. Angka/bilangan berasal dari pembacaan sensor dan dikirim ke modul suara.

Pada modul suara sudah disimpan dalam memorinya (microSD) berbagai macam kemungkinan suara angka dengan urutan tertentu. Arduino berfungsi sebagai pengatur suara angka yang akan diputar.

Suara pembilang arduino dimulai dengan kata pembuka contohnya “nomor antrian”, kemudian diikuti suara deret angka dan terakhir satuannya misalnya “di loket 1”.

Suara bilangan sampai 999.999 dengan komponen :

  1. arduino mega 2560
  2. MP3 DFPlayer
  3. Ampli modul LM386 (bila ada)

Bisa dikombinasikan sebagai pemberi suara :

  1. Mesin timbangan yang menginformasikan berat terukur
  2. Pemberi tahu bila jarak terlalu dekat pada sistem keamanan parkir
  3. Pengingat suhu dan kelembaban dengan sensor humidity
  4. Informasi kecepatan kendaraan kecepatan
  5. Suara antrian pada mesin antrian di perkantoran
  6. Pembilang total belanja
  7. dll

Video:

skema suara informasi arduino:

sketch/program:


#include <miniMP3.h>

#define belas 12 //belas.mp3
#define puluh 13 //puluh.mp3
#define seratus 14 //seratus.mp3
#define ratus 15 //ratus.mp3
#define seribu 16 //seribu.mp3
#define ribu 17 //ribu.mp3
#define koma 18 //Koma.mp3

#define berat 110 //berat.mp3
#define gram 111 //gram.mp3
#define kiloGram 112 //kilogram.mp3
#define jarak 120 //jarak.mp3
#define sentiMeter 121 //sentimeter.mp3
#define meter 122 //meter.mp3
#define suhu 130 //suhu.mp3
#define derajat 131 //derajat_celsius.mp3
#define ph 140 //P_H.mp3
#define kelembaban 150 //Kelembaban.mp3
#define persen 151 //Persen.mp3
#define kecepatan 160 //kecepatan.mp3
#define meterPerDetik 161 //meter_per_detik.mp3
#define kilometerPerJam 162 //kilometer_per_jam.mp3
#define nomorantrian 170 //nomor antrian.mp3
#define totalBelanja 180 //total belanja.mp3
#define rupiah 181 //rupiah.mp3

void setup() {
  mp3_set_serial (Serial1, 17);
  mp3_set_volume(30);

  uint32_t beratTimbangan = 0;
  
  mp3_play(berat);
  suaraBilangan(beratTimbangan);
  mp3_play(gram);
}

void loop() {

}

void suaraBilangan(uint32_t Bilangan)
{
  if (Bilangan < 12)
  {
    mp3_play(Bilangan);
  }
  else if (Bilangan < 20)
  {
    suaraBelasan(Bilangan);
  }
  else if (Bilangan < 100)
  {
    suaraPuluhan(Bilangan);
  }
  else if (Bilangan < 1000)
  {
    suaraRatusan(Bilangan);
  }
  else
  {
    suaraRibuan(Bilangan);
  }
}
void suaraBelasan(uint8_t Bilangan)
{
  mp3_play(Bilangan - 10);
  mp3_play(belas);
}
void suaraPuluhan(uint8_t Bilangan)
{
  uint8_t puluhan = Bilangan / 10;
  mp3_play(puluhan);
  mp3_play(puluh);

  uint8_t satuan = Bilangan % 10;
  if (satuan)
  {
    suaraBilangan(satuan);
  }
}
void suaraRatusan(uint16_t Bilangan)
{
  uint8_t ratusan = (uint8_t)(Bilangan / 100);
  if (ratusan == 1)
  {
    mp3_play(seratus);
  }
  else
  {
    mp3_play(ratusan);
    mp3_play(ratus);
  }
  byte puluhan = Bilangan % 100;
  if(puluhan)
  {
    suaraBilangan(puluhan);
  }
}
void suaraRibuan(uint32_t Bilangan)
{
  uint16_t ribuan = Bilangan / 1000;
  if (ribuan == 1)
  {
    mp3_play(seribu);
  }
  else
  {
    suaraBilangan(ribuan);
    mp3_play(ribu);
  }
  uint16_t ratusan = Bilangan % 1000;
  if (ratusan)
  {
    suaraBilangan(ratusan);
  }
}

file pendukung:
Suara : Suara bilangan mp3
Library : miniMP3

running text anti flicker (improved DMD) dengan arduino

DMD (dot matrix display) yang dikontrol dengan arduino dengan segala keterbatasannya memiliki permasalahan saat panel DMD disusun dalam lebih dari 4 panel. Flicker terjadi karena proses pengiriman data serial dari arduino harus mengantri sekian lama sehingga pergantian aktifasi baris per baris tertangkap oleh mata seperti berayun (berkedip) dan tentu membuat mata tidak nyaman.

Untuk itu saya melakukan improvisasi terhadap library arduino –DMD2– dengan prinsip kerja satu clock untuk lebih dari satu baris. contohnya untuk ukuran panel 4 kolom 2 baris kelompok DMD dibagi menjadi 2 bagian (baris 1 dan baris 2) dengan entri data yang sama setiap clock-nya.

Kelebihan alat DMD2 arduino:

  1. Sensor DHT11 untuk memantau keadaan suhu dan kelembaban sekitar
  2. Database waktu sholat 5 waktu (statis) dan dilengkapi buzzer yang menandakan waktu sholat telah masuk.

 

Komponen yang dibutuhkan :

  1. 8 Panel P10
  2. Arduino Mega 2560
  3. RTC DS1307
  4. DHT11
  5. Buzzer

DS1307 dapat diganti dengan DS3231 untuk keperluan presisi RTC.

berikut skema-nya :

berserta sketch atau program nya:

 

#include <DMD2.h>
#include <fonts/SystemFont5x7.h>
#include <fonts/Arial14.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
#include "DHT.h"

byte DataPins[2] = {33, 35}; //pin jalur out
SoftDMD dmd(4, 2, 23, 25, 27, 31, 29, 2, DataPins); //kolom, baris, OE, A, B, SCK, CLK, jumlah jalur out, pin jalur out
//SoftDMD dmd(4,2,23,25,27,31,29,33); //standard

DMD_TextBox box(dmd, 0, 0, 78, 32);

DHT dht(A0, DHT11);
String namaSholat[] = {"  Subuh", "  Zuhur", "   Asar", " Maghrib", "   Isya"};
byte waktuSholat[][2] = {{5, 12},
                        {12, 32},
                        {15, 45},
                        {18, 35},
                        {19, 44}
};

#define waktunyaSholat 1
#define pesanSMS 2

int n = 123;
byte lastSecond = 60;
byte lastDay = 32;
byte lastH = 60;
byte lastT = 32;
String Sholat;
String pesanDisplay;
byte pesan;
int buzzer = 8;
bool buzz;
byte buzzCounter;

void setup() {
  Serial.begin(9600);
  Serial.println("Running text dengan Arduino bebas kedip");
  Serial.println("https://www.project.semesin.com");
  dht.begin();
  dmd.setBrightness(255);
  dmd.begin();

  pesan = pesanSMS;
  pesanDisplay = "  Selamat\n  datang";
  dmd.selectFont(Arial14);
  box.print(pesanDisplay);
}

void loop()
{
  tmElements_t tm;
  byte h = (byte)dht.readHumidity();
  byte t = (byte)dht.readTemperature();
  RTC.read(tm);

  if (pesan == waktunyaSholat)
  {
    buzzCounter++;
    if (!(buzzCounter % 32))
    {
      buzz = !buzz;
      digitalWrite(buzzer, buzz);
      pinMode(buzzer, OUTPUT);
    }
  }

  if (tm.Second != lastSecond)
  {
    String waktu = "";
    if (tm.Hour < 10)
      waktu += "0";
    waktu += tm.Hour;
    waktu += ":";
    if (tm.Minute < 10)
      waktu += "0";
    waktu += tm.Minute;
    waktu += ":";
    if (tm.Second < 10)
      waktu += "0";
    waktu += tm.Second;
    lastSecond = tm.Second;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 0, waktu);

    if ((pesan == waktunyaSholat) && (tm.Second >= 58))
    {
      box.clear();
      dmd.selectFont(Arial14);
      box.print(pesanDisplay);
      pesan = pesanSMS;
      digitalWrite(buzzer, LOW);
    }
    else if (tm.Second <= 1)
    {
      for (byte i = 0; i < 5; i++)
      {
        if ((waktuSholat[i][0] == tm.Hour) && (waktuSholat[i][1] == tm.Minute))
        {
          Sholat = namaSholat[i];
          box.clear();
          dmd.selectFont(Arial14);
          box.println("  Sholat");
          box.print(Sholat);
          pesan = waktunyaSholat;
        }
      }
    }
  }
  if (tm.Day != lastDay)
  {
    String tanggal = "";
    if (tm.Day < 10)
      tanggal += "0";
    tanggal += tm.Day;
    tanggal += "/";
    if (tm.Month < 10)
      tanggal += "0";
    tanggal += tm.Month;
    tanggal += "/";
    if (tmYearToCalendar(tm.Year) < 10)
      tanggal += "0";
    tanggal += tmYearToCalendar(tm.Year);
    lastDay = tm.Day;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 8, tanggal);
  }
  if ((h != lastH) || (t != lastT))
  {
    String suhu = "";
    if (t < 10)
      suhu += "0";
    suhu += t;
    suhu += "'C ";
    if (h < 10)
      suhu += "0";
    suhu += h;
    suhu += "%";

    lastT = t;
    lastH = h;

    dmd.selectFont(SystemFont5x7);
    dmd.drawString(80, 16, suhu);
  }
}

dokumentasi Galeri DMD arduino anti flicker

Library yang sudah dimodifikasi: DMD-GL

Jika menginginkan jadwal sholat yang dinamis (waktu matahari) bisa menggunakan library “PrayerTimes.h”.

Timbangan digital presisi dan lcd pabrikan dengan arduino

dalam projek msin timbangan otomatis ini saya memanfatkan timbangan digital merk Quattro yang sudah tidak berfungsi normal. Fokus proyek ini adalah untuk memanfatkan Sensor berat/loadcell yang presisi dan linear serta LCD pabrikannya sehingga timbangan bisa dimanfatkan kembali.

komponen yang digunakan:

  1. Arduino Uno
  2. Loadcell
  3. HX711
  4. LCD pabrikan (driver HT1621)

Diagram:

Loadcell

Loadcell atau sensor berat pada perangkat quttro yang digunakan memiliki ukuran lebih besar dari loadcell yang ada dipasaran namun memiliki kesamaan cara kerja dan pengkabelan, kabel terdiri dari empat warna yaitu merah – E+, hitam – E-,  putih – A/B+ dan hijau – A/B-.

HX711

komponen (modul) ini berfungsi sebagai ADC – analog to digital converter 24 bit yang akan mengkonversi nilai resistansi dari jembatan Wheatstone menjadi nilai yang berbanding lurus dengan berat benda yang ditimbang

LCD pabrikan

LCD yang digunakan merupakan bawaan perangkat timbangan quattro yang khusus dipakai untuk jenis timbangan ini saja. karakter Terdiri dari 6 digit seven segmen, 3 digit character segmen (seperti seven segmen digabung dengan garis diagonal), 10 bar/garis penanda berat, dan tampilan penunjuk lainnya.

LCD ini dikontrol oleh driver HT1621 dengan 4 jalur input, saya hanya menggunakan 3 saja yaitu CS, WR dan Data. sedangkan  untuk tampilannya saya hanya menggunakan 6 seven segmen dan 2 character segment untk text “Gr”.

 

Skema:

program/sketch:

#include "HX711.h"

HX711 scale(8,9);

#define jumlahSegmen 15
 
//Command
#define  ComMode	0x52
#define  RCosc	  0x30
#define  LCD_on	 0x06
#define  LCD_off	0x04  
#define  Sys_en	 0x02
#define  CTRl_cmd   0x80  
#define  Data_cmd   0xa0  

//pin
int CS = A3;
int WR = A1;
int Data = A0;
int backLight = 7;
int buttonESC = 5;
int buttonPCS = 4;
int buttonUNIT = 3;
int buttonTARE = 6;
int buttonZERO = 2;

byte angka[] = {0xBE, 0x06, 0x7C, 0x5E, 0xC6, 0xDA, 0xF2, 0x0E, 0xFE, 0xCE};
byte byteArrayBerat[8];
byte strBerat[6];
 
void SendBit_1621(byte sdata,byte cnt)
{ 
  for(byte i=0;i<cnt;i++) 
  { 
	digitalWrite(WR, LOW);
	
	if(sdata&0x80) 
	  digitalWrite(Data, HIGH); 
	else 
	  digitalWrite(Data, LOW);
	  
	digitalWrite(WR, HIGH);
	sdata<<=1; 
  } 
}
 
void SendCmd_1621(byte command) 
{ 
  digitalWrite(CS, LOW); 
  SendBit_1621(0x80,4);  
  SendBit_1621(command,8); 
  digitalWrite(CS, HIGH);					 
}
 
void Write_1621(byte addr,byte sdata)
{ 
  addr<<=3; 
 digitalWrite(CS, LOW); 
 SendBit_1621(0xa0,3);	 
 SendBit_1621(addr,6);	 
 SendBit_1621(sdata,8);   
 digitalWrite(CS, HIGH); 
} 

void doubleToDecArray(double value, byte *byteArray)
{
  double divider = 1000.0;
  for(byte i=0;i<8;i++)
  {
	byte divValue = value / divider;
	byteArray[i] = divValue;
	value = value - (divValue * divider);
	divider /= 10;
  }
}

void setup() {
  pinMode(CS, OUTPUT);
  pinMode(WR, OUTPUT);
  pinMode(Data, OUTPUT);
  pinMode(backLight, OUTPUT);
  pinMode(buttonESC, INPUT_PULLUP);
  pinMode(buttonPCS, INPUT_PULLUP);
  pinMode(buttonUNIT, INPUT_PULLUP);
  pinMode(buttonTARE, INPUT_PULLUP);
  pinMode(buttonZERO, INPUT_PULLUP);

  digitalWrite(backLight,LOW);
  digitalWrite(CS, HIGH);
  digitalWrite(Data, HIGH);
  digitalWrite(WR, HIGH);

  Serial.begin(9600);
  Serial.println("Timbangan Arduino");
  Serial.println("https://www.project.semesin.com");
  
  delay(50);
  SendCmd_1621(Sys_en);
  SendCmd_1621(RCosc);	
  SendCmd_1621(ComMode);  
  SendCmd_1621(LCD_on);

  for(byte i=0;i<jumlahSegmen;i++) 
  {
	Write_1621(i,0xff); 
  } 
  delay(1000);
  for(byte i=0;i<jumlahSegmen;i++) 
  {
	Write_1621(i,0x00); 
  } 
  Write_1621(6,0x85);// huruf 'G'
  Write_1621(7,0xA6);
  Write_1621(10,0x02);//Huruf 'r'
  Write_1621(11,0x40);

  scale.set_scale(2280.f);
  scale.tare();
  }
 
void loop() {

  double Berat = scale.get_units(10);
  Serial.println(Berat);
  
  bool getNum = false;
  byte numPointer = 0;
  byte numCounter = 0;
  
  if(Berat < 0)
  {
	Berat = 0;
  }
  else
  {
	doubleToDecArray(Berat, byteArrayBerat);
	for(byte i=0;i<8;i++)
	{
	  if(byteArrayBerat[i] != 0)
	  {
		getNum = true;
	  }
	  if(getNum)
	  {
		numCounter++;
		strBerat[numPointer] = angka[byteArrayBerat[i]];
		if(i==3)
		{
		  strBerat[numPointer] |= 0x01;//Koma
		}
		if(numPointer++ == 6)
		{
			numCounter--;
			break; 
		}
	  }
	  else if(i==3)
	  {
		getNum = true;
		strBerat[numPointer++] = angka[0] | 0x01;
	  }
	}
	byte j=0;
	for(int8_t i=0;i<6-numCounter;i++)
	{
	  Write_1621(i,0x00); 
	}
	for(byte i=6-numCounter;i<6;i++)
	{
	  Write_1621(i,strBerat[j++]); 
	}
  }

  if(!digitalRead(buttonTARE))
  {
	delay(200);
	if(!digitalRead(buttonTARE))
	{
	  scale.tare();
	  while(!digitalRead(buttonTARE));
	}
  }
  delay(50);
}

Fitur-fitur modul HX711:

  1. Memiliki 2 block differential ADC sehingga bisa dengan gain yang berbeda disesuaikan dengan tingkat presisi yang diinginkan , yang tersedia 32, 64 dan 128.
  2. Memiliki regulator tegangan sendiri untuk loadcell dan ADC.
  3. Interface serial yang disederhanakan.
  4. Frekuensi keluaran dapat diatur 10SPS dan 80sps
  5. Penyaring/filter riak 50Hz dan 60Hz.

Dengan spesifikasi:

  1. Tegangan operasional dc 2.6 ~ 5.5v.
  2. ADC 24 bit yang presisi.
  3. frekuensi Internal clock 11.0592 MHz.
  4. Konsumsi arus, 1500uA (normal), 0,5uA (power down).

dokumentasi Galeri timbangan digital presisi

Library : HX711.zip

Menentukan nama hari dari tanggal [Arduino]

Untuk memperoleh nama hari dari tanggal yang diberikan dapat mengikuti dengan langkah berikut:

  1. Menetapkan basis hari, misalnya 1 januari 2000 jatuh pada hari sabtu = 7
  2. Menghitung jumlah hari dari basis hari hingga tanggal yang ditentukan dengan memperhitungkan:
    • tahun x 365
    • jumlah tahun kabisat
    • jumlah hari dalam setiap bulan
    • tanggal
  3. dan terakhir mencari nilai sisa setelah dibagi dengan 7

berikut program atau sketch fungsi yang dapat digunakan:

String namaHari[] = {"Minggu","Senin","Selasa","Rabu","Kamis","Jum'at","Sabtu"};
uint16_t jumlahHariPerBulan[]={0,31,59,90,120,151,181,212,243,273,304,334};

void setup() {
  Serial.begin(9600);
  Serial.println("fungsi mendapatkan Nama hari dari tanggal yang diberikan");
  Serial.println("https://www.project.semesin.com");
}

void loop() {
  byte hari;
  byte tanggal = 4;
  byte bulan = 3;
  byte tahun = 18;
  
  hari = hariDariTanggal(tanggal, bulan, tahun);

  Serial.print(tanggal);  
  Serial.print("/");  
  Serial.print(bulan);  
  Serial.print("/");  
  Serial.print(tahun);  
  Serial.print(" => ");  
  Serial.print(hari);  
  Serial.print(" : ");  
  Serial.println(namaHari[hari - 1]);  

  while(1);
}

//tanggal mulai dari 1
//bulan mulai dari 1
//tahun dua digit
//minggu = 1, sabtu = 7
//basis 1 Januari 2000
byte hariDariTanggal(byte tanggal, byte bulan, uint16_t tahun)
{
  uint32_t jumlahHari = tahun * 365;
  uint16_t tahunKabisat = tahun/4;
  for (byte i = 0; i < tahun; i++) 
  {
    if (!(i%4))
    {
      jumlahHari++;
    }
  }
  jumlahHari += jumlahHariPerBulan[bulan-1];
  if ( (bulan >= 2) && !(tahun % 4)) 
  { 
    jumlahHari++;
  }
  jumlahHari+= tanggal;
  return ((jumlahHari + 5) % 7) + 1;
}