Kembali ke STM8

Tujuh tahun lalu (2016) saya mencoba STM8 dan mendokumentasikannya di sini. Seiring waktu, teknologi yang dikembangkan secara sistematis untuk mempermudah pemrograman semakin matang. Saat ini STM8 sudah sedemikian mudah untuk diprogram dengan mempergunakan Arduino IDE dengan dialek bahasa turunan C dan C++.

Gambar 1.
Gambar 2.
Gambar 3.

 

Arduino IDE

Cara pertama di artikel ini adalah dengan melakukan standar pengujian kode kedip (blink).  LED di papan yang akan diatur terhubung dengan D3 (PB5).

Gambar 4.
[sourcecode] /*
* Kode kedip untuk menguji STM8 (STM8s103f3 | stm8s103?3)
*
*/

#define onBoardLED 3

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

void loop() {
digitalWrite(onBoardLED, HIGH); // LED OFF
delay(400);
digitalWrite(onBoardLED, LOW); // LED ON
delay(200);
}
[/sourcecode]

Gambar 5.

Eksekusi perintah “Burn Bootloader” seperti di Gambar 5 sebelum melakukan pemrograman sistem STM8 untuk pertama kali.
 

Gambar 6. Pemrograman telah berhasil dilakukan.

Berikutnya, dicoba pengaturan yang lebih kompleks, yaitu pemanfaatan fasilitas PWM.

[sourcecode] /*
Dimodifikasi dari kode aslinya

Blink without Delay
created 2005
by David A. Mellis
modified 8 Feb 2010
by Paul Stoffregen
modified 11 Nov 2013
by Scott Fitzgerald
modified 9 Jan 2017
by Arturo Guadalupi

This example code is in the public domain.

https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
*/

// constants won’t change. Used here to set a pin number:
const int ledPin = 3;// D3 (PB5 di papan STM8S103F3)
const int pwmTestA = 5;
const int pwmTestB = 13;

// Variables will change:
int pinState = LOW; // pinState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

// constants won’t change:
const long interval = 10; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(pwmTestA, OUTPUT);
pinMode(pwmTestB, OUTPUT);
}

void loop() {
// here is where you’d put code that needs to be running all the time.

// check to see if it’s time to blink the LED; that is, if the difference
// between the current time and last time you blinked the LED is bigger than
// the interval at which you want to blink the LED.
unsigned long currentMillis = millis();

if (currentMillis – previousMillis >= interval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (pinState == LOW) {
pinState = HIGH; //LED OFF
} else {
pinState = LOW; //LED ON
}

// set the LED with the pinState of the variable:
digitalWrite(ledPin, pinState);
analogWrite(pwmTestA, 50);
analogWrite(pwmTestB, 50);
}
}
[/sourcecode]

Cara pemrograman kode terakhir ini sama seperti sebelumnya. Dengan logic analyzer bisa dilihat lebar pulsa low kode kedip (Gambar 7) dan periode (frekuensi) PWM di D5 (PC3) di Gambar 8.

Gambar 7.
Gambar 8.

Berikutnya dengan bantuan oscilloscope ATTEN (f/w Siglent) bisa dilihat lebar pulsa high PWM di pin D13 (PD4).

Gambar 9.
Gambar 10.

Juga dengan bantuan fasilitas di oscilloscope bisa dilihat dengan lebih baik profil rise time dari sinyal digital yang dibangkitkan oleh fasilitas PWM di STM8 (dengan pemrograman via Arduino).

SDCC STM8FLASH

Hampir sama dengan sebelumnya, berikut dicoba kembali kode program kedip dengan SDCC. Versi SDCC yang dipakai adalah 3.8.0 #10562 (Linux).

[sourcecode] #include "stm8l.h"

int main() {
int d;
// Configure pins
PB_DDR = 0x20;
PB_CR1 = 0x20;
// Loop
do {
PB_ODR ^= 0x20;
for(d = 0; d < 29000; d++) { }
} while(1);
}
[/sourcecode]

Penetapan nilai heksadesimal 0x20 (0b00100000) untuk PB_DDR (DDR5), PB_CR1 (C15), dan PB_ODR (ODR5)  dapat dipelajari dari kutipan tabel berikut ini (sumber).

Jika papan stm8 baru pertama kali diprogram, beberapa perintah berikut ini perlu dijalankan untuk menghilangkan write protection (ROP /Read Out Protection ).

[intense_code type=”block”] echo “00” | xxd -r -p > ROP_CLEAR.bin
stm8flash -c stlinkv2 -p stm8s103?3 -s opt -w ROP_CLEAR.bin
[/intense_code]

Bisa juga mempergunakan versi berikut ini.

[intense_code type=”block”] echo “00 00 ff 00 ff 00 ff 00 ff 00 ff” | xxd -r -p > factory_defaults.bin
stm8flash -c stlinkv2 -p stm8s103?3 -s opt -w factory_defaults.bin
[/intense_code]

Berikutnya sebagai contoh program kedip disimpan di file yang diberi nama blinky.c. Untuk melakukan kompilasi, compiler sdcc yang dipergunakan. Sedangkan untuk memasukkan kode mesin hasil kompilasi, software stm8flash yang dipakai.

[intense_code type=”block”] sdcc -lstm8 -mstm8 –out-fmt-ihx blinky.c
stm8flash -c stlinkv2 -p stm8s103?3 -w blinky.ihx
[/intense_code]
Gambar 11. Hasil kompilasi dan flashing STM8.
Gambar 12.
Gambar 13.
Gambar 14. [Sumber]

Rujukan:

 

PCF8591: 8-bit A/D and D/A converter { ADC }

[ [ images & links ] ]

Gambar 1.

PCF8591Gambar 2. [einhugur.com]

Features

  • Module supports external voltage input of the 4-way acquisition (voltage input range of 0-5v)
  • integrated photoresistor
  • integrated thermistor
  • integrated potentiometer
  • Modules power indicator
  • Modules with DA output indicator, when the module DA output interface voltage reaches a certain value, will be lit panel the DA output indicator, the higher the voltage, the more obvious indicator brightness
  • Remove shunts to bypass on board integrated devices

 The left connector

  • AOUT chip DA output interface
  • AINO chip analog input interface 0
  • AIN1 chip analog input interface 1
  • AIN2 chip analog input interface 2
  • AIN3 chip analog input interface 3

  The right connector

  • SCL
  • SDA
  • GND
  • VCC – connected to  3.3v-5v

Gambar 3. [arduinolearning.com]

 

Gambar 4. [arduinolearning.com]

 

Gambar 5.[forum.arduino.cc]

 

Product Description [electrodragon.com]

Gambar 6.

Gambar 7.

 

Belajar penggunaan LCD “Nokia 5110” di sistem Arduino [video]

[ [ videos ] ]
[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video05″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video06″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]
[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video07″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video08″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video09″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video10″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video11″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video12″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]
[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video13″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video14″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video15″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

 

Logic level converter

[ [ images & links ] ]

Papan logic level converter sering diperlukan jika bekerja dengan dua atau lebih sistem yang mempergunakan tingkat tegangan yang berbeda. Sistem yang bekerja di tingkat tegangan 3.3 V dan tidak memiliki toleransi tegangan sampai 5 V akan sangat mungkin mengalami kerusakan. Untuk mencegahnya diperlukan sistem yang mengalihkan level logika digital dari sistem 5 V dari dan ke level 3.3 V.

Penggunaan sistemnya cukup sederhana, yang penting untuk diingat adalah bahwa sumber tegangan di kedua sisi perlu dihubungkan. Jika misalnya sisi 3.3 V tidak memiliki catau daya sendiri maka pergunakan sumber lain dengan tegangan yang sama sebesar 3.3 V. Contohnya dari papan Arduino, hubungkan 5 V dan 3.3 V ke pin masing-masing yang sesuai. Adapun pin Gnd sudah terhubung antar sisi, sehingga level yang dikonversi diukur berdasarkan acuan yang sama. Jadi, Gnd untuk sistem (termasuk untuk ground sisi 3.3 V) bisa didapatkan hanya dari satu hubungan ke GND pada papan Arduino.

 

Do you have a 3.3V I2C or SPI sensor that might go up in smoke if connected to a 5V Arduino? Or a 5V device that needs a workaround to be compatible with your 3.3V Raspberry Pi, Arduino Due or pcDuino?

To get over this obstacle you need a device that can shift 3.3V up to 5V or 5V down to 3.3V. This is called logic level shifting. Level shifting is a dilemma so common we designed a simple PCB assembly to make interfacing devices a little easier: the Bi-Directional Logic Level Converter.

MOSFET logic level shifting circuitGambar 1.

Annotated BD-LLCGambar 2.

 

~learn.sparkfun.com

 

I2c-Bi-Directional-021Gambar 3. [14core.com]

 

As digital devices get smaller and faster, once ubiquitous 5 V logic has given way to ever lower-voltage standards like 3.3 V, 2.5 V, and even 1.8 V, leading to an ecosystem of components that need a little help talking to each other. For example, a 5 V part might fail to read a 3.3 V signal as high, and a 3.3 V part might be damaged by a 5 V signal. This level shifter solves these problems by offering bidirectional voltage translation of up to four independent signals, converting between logic levels as low as 1.5 V on the lower-voltage side and as high as 18 V on the higher-voltage side, and its compact size and breadboard-compatible pin spacing make it easy to integrate into projects.

Gambar 4.

This logic level converter requires two supply voltages: the lower-voltage logic supply (1.5 V to 7 V) connects to the LV pin and the higher-voltage supply (LV to 18 V) connects to the HV pin. The HV supply must be higher than the LV supply for proper operation. Logic low voltages will pass directly from Hx to the corresponding Lx (and vice versa), while logic high voltages will be converted between the HV level to the LV level as the signal passes from Hx to Lx or Lx to Hx.

~www.pololu.com/product/2595

Gambar 5.

Sebagai awalan pengujian sebaiknya dilakukan hanya dengan tegangan DC yang relatif stabil (rata) di input terlebih dahulu. Ukur level tegangan input dan level tegangan output. Apakah nilai tegangan 5 V sudah benar turun (dikonversi) menjadi 3.3 V? Apakah, sebaliknya juga, level tegangan bisa naik dari 3.3 V ke 5 V? Berikutnya baru lakukan percobaan dengan penyakelaran gelombang kotak, karena bentuk gelombang ini adalah bentuk gelombang digital yang paling umum dipergunakaan. Mulailah dari frekuensi rendah dengan pulsa high yang cukup lebar, lalu persempit lebar pulsa high. Teruskan dengan menaikkan frekuensi dan ulangi prosedur mempersempit pulsa high seperti langkah sebelumnya. Demikian seterusnya sampai anda lihat batas lebar pulsa dan/atau batas frekuensi di mana logic converter tidak lagi berfungsi dengan baik.

Gambar 6.

Di Gambar 6, saya mencoba mengggunakan pembangkit gelombang kotak PWM yang sudah sangat banyak dijual bebas di pasaran. Frekuensi yang dipakai diatur sebesar 200 Hz (terukur 201 Hz) dan seperti terlihat di Gambar 6, duty cycle diatur sebesar 20%. Tegangan keluaran modul ini sekitar sebesar 5 V peak.


Gambar 7.

Di Gambar 7 terlihat percobaan pengukuran di sisi tegangan logic level yang lebih rendah. Frekuensi penyakelaran tetap 200 Hz, tetapi lebar pulsa hanya sebesar 40 μS. Tegangan Vpp yang terukur masih sekitar 3.97 V, level tegangan yang jelas masih lebih tinggi dari 3.3 V. 


Gambar 8.

Gambar 8 adalah contoh percobaan konversi dari level tegangan sistem digital 3.3 V ke sistem digital 5 V. Sistem sumber yang dipakai adalah yang menggunakan keluarga ARM STM32. Frekuensi diatur mendekati 500 Hz (496 Hz) dengan lebar pulsa high sebesar 14 μS. Hasil konversi akan terlihat seperti di Gambar 9, level tegangan output adalah Vmax 5.31 V atau Vpp 5.63 V menurut alat ukur yang dipakai.

Gambar 9.

[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video05″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

 

 

RTC DS3231

[ [ images, codes & links ] ]

Keterangan mengenai RTC (Real-Time Clock) sudah pernah disampaikan melalui kutipan di post terdahulu. Di halaman itu yang dibahas adalah komponen RTC DS1307, yang lazim diperdagangkan dalam bentuk papan yang ditandai sebagai Tiny RTC. Kali ini saya coba rangkumkan mengenai DS3231 dari berbagai sumber sebagai awalan untuk memperlajarinya. RTC ini dilaporkan memiliki akurasi yang lebih baik dari RTC DS1307.

Gambar 1.

 

With a backup button cell (e.g. CR2032) on the underside of the module, these DS1307 modules will keep time even when disconnected from the main power source for months and even years on end. However, in our experimental projects (using this RTC with an Arduino for dataloggers amongst other things), we have found these DS1307 modules to vary hugely in their time-keeping accuracy – some gaining/losing a few seconds per day, and others gaining/losing as much as 3-5 minutes per day. While they have proved to be very consistent – i.e. a unit which gains 3 minutes per day will gain 3 minutes per day every day – having to test each unit individually over a few days and then modifying the Arduino project code to cancel out errors is not practical.

Some of the error is caused by ambient temperature changes affecting the accuracy of the timing of the crystal resonator. Some more of the error is also caused by the quality of the crystal itself and its attachment to the PCB in these economical modules.

In extensive testing we have found the time-keeping of these modules to be excellent. The DS3231 chip on the module is marketed as being accurate to 2ppm (parts per million), which means less than one second lost or gained every 5 to 6 days. The units we have tested thus far have all come in at under 1ppm accuracy, so a couple of seconds at most lost or gained per month.

This accuracy is achieved in part by the incorporation of a temperature sensor in the DS3231 which can compensate for changes in ambient temperature. The measurements from this temperature sensor are also accessible to the user (accurate to +/- 3 Celcius) which makes for a handy extra feature. These DS3231 modules also have 32kb of available EEPROM memory which can be utilised by your projects, and many other useful features.

~reuk.co.uk

 

sumber: Benchmarks: Real Time Clocks – Results for Raspberry Pi/Arduino – DS3231 / PCF8563 / MCP79400 / DS1307

 

Gambar 2. [randomnerdtutorials.com]

 

Terdapat beberapa pustaka/library untuk tiap RTC. Dua yang disampaikan dalam “mashup ini adalah pustaka dari Adafruit dan pustaka dari Makuna.

Contoh-contoh kode program sistem Arduino untuk RTC DS3231.

Sistem ini dirancang untuk bekerja dengan menggunakan baterai “khusus”, yaitu baterai yang bisa diisi ulang (rechargeable) seperti LIR2032. Di papan sudah disediakan sistem pengisian ulang untuk baterai tersebut. Karena itu jika kita mempergunakan baterai tipe yang tidak bisa diisi ulang (non-rechargeable) seperti CR2032 maka ada perubahan yang perlu dilakukan. Hal ini untuk mencegah agar baterai primer yang tidak bisa diisi ulang itu tidak berusaha diisi oleh sistem. Caranya adalah dengan melepas/membuang diode seperti pada Gambar 3 berikut.

ds.jpgGambar 3. [sumber: tronixlabs.com]

 

[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video05″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

 

Save

RTC DS1307

[ [ images, codes & links ] ]

Gambar 1.

A real-time clock (RTC) is a computer clock (most often in the form of an integrated circuit) that keeps track of the current time.

Although the term often refers to the devices in personal computers, servers and embedded systems, RTCs are present in almost any electronic device which needs to keep accurate time.

<span class="su-quote-cite"><a href="https://en.wikipedia.org/wiki/Real-time_clock" target="_blank">Real-time clock</a></span>

What is an RTC?

A real time clock is basically just like a watch – it runs on a battery and keeps time for you even when there is a power outage! Using an RTC, you can keep track of long timelines, even if you reprogram your microcontroller or disconnect it from USB or a power plug.

Most microcontrollers, including the Arduino, have a built-in timekeeper called millis() and there are also timers built into the chip that can keep track of longer time periods like minutes or days. So why would you want to have a separate RTC chip? Well, the biggest reason is that millis() only keeps track of time since the Arduino was last powered – . That means that when the power is turned on, the millisecond timer is set back to 0. The Arduino doesn’t know that it’s ‘Tuesday’ or ‘March 8th’, all it can tell is ‘It’s been 14,000 milliseconds since I was last turned on’.

OK so what if you wanted to set the time on the Arduino? You’d have to program in the date and time and you could have it count from that point on. But if it lost power, you’d have to reset the time. Much like very cheap alarm clocks: every time they lose power they blink 12:00

While this sort of basic timekeeping is OK for some projects, some projects such as data-loggers, clocks, etc will need to have consistent timekeeping that doesn’t reset when the Arduino battery dies or is reprogrammed. Thus, we include a separate RTC! The RTC chip is a specialized chip that just keeps track of time. It can count leap-years and knows how many days are in a month, but it doesn’t take care of Daylight Savings Time (because it changes from place to place).

~DS1307 Real Time Clock Breakout Board Kit

 

What are Real Time Clocks?

Real time clocks (RTC), as the name recommends are clock modules. The DS1307 real time clock (RTC) IC is an 8 pin device using an I2C interface. The DS1307 is a low-power clock/calendar with 56 bytes of battery backup SRAM. The clock/calendar provides seconds, minutes, hours, day, date, month and year qualified data. The end date of each month is automatically adjusted, especially for months with less than 31 days.

They are available as integrated circuits (ICs) and supervise timing like a clock and also operate date like a calendar. The main advantage of RTC is that they have an arrangement of battery backup which keeps the clock/calendar running even if there is power failure. An exceptionally little current is required for keeping the RTC animated. We can find these RTCs in many applications like embedded systems and computer mother boards, etc.

~www.elprocus.com/rtc-ds1307/

 

 

Arduino Tiny RTC D1307 Tutorial

 

Gambar 2. [henrysbench.capnfatz.com]

Gambar 3. [henrysbench.capnfatz.com]

Gambar 4. [tronixstuff.com]

Connecting your module to an Arduino

Both modules use the I2C bus, which makes connection very easy. If you’re not sure about the I2C bus and Arduino, check out the I2C tutorials (chapters 20 and 21), or review chapter seventeen of my book “Arduino Workshop“.

Moving on – first you will need to identify which pins on your Arduino or compatible boards are used for the I2C bus – these will be knows as SDA (or data) and SCL (or clock).

~ tronixstuff.com

 

 

Tiny RTC

Gambar 5.

Features

  • 5V DC supply
  • Programmable Square-Wave output signal
  • Automatic Power-Fail detect and switch circuitry
  • Consumes less than 500nA in Battery-Backup Mode with Oscillator Running
  • 56-Byte, Battery-Backed, Nonvolatile (NV)RAM for data storage

Gambar 6.

TinyRTC hardware1.jpgGambar 7.

~www.elecrow.com

 

 

RTC DS-1307 with Arduino

DS 1307 RTC Pinout

Gambar 8.

Block Diagram of DS1307

Gambar 9. [Datasheet]

Gambar 10.

~www.theorycircuit.com

 

Terdapat beberapa pustaka/library untuk tiap RTC. Dua yang disampaikan dalam “mashup ini adalah pustaka dari Adafruit dan pustaka dari Makuna.

Contoh-contoh kode program sistem Arduino untuk RTC DS1307.

adafruit: ds1307.ino

[code lang=”C”]// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup ()
{
while (!Serial); // for Leonardo/Micro/Zero

// Serial.begin(57600);
Serial.begin(9600);

if (! rtc.begin())
{
Serial.println("Couldn’t find RTC");
while (1);
}

if (! rtc.isrunning())
{
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date &amp; time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date &amp; time, for example to set
// January 21, 2014 at 3am you would call:
// rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
}

void loop ()
{
DateTime now = rtc.now();

Serial.print(now.year(), DEC);
Serial.print(‘/’);
Serial.print(now.month(), DEC);
Serial.print(‘/’);
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(‘:’);
Serial.print(now.minute(), DEC);
Serial.print(‘:’);
Serial.print(now.second(), DEC);
Serial.println();

Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");

// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now + TimeSpan(7,12,30,6));

Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print(‘/’);
Serial.print(future.month(), DEC);
Serial.print(‘/’);
Serial.print(future.day(), DEC);
Serial.print(‘ ‘);
Serial.print(future.hour(), DEC);
Serial.print(‘:’);
Serial.print(future.minute(), DEC);
Serial.print(‘:’);
Serial.print(future.second(), DEC);
Serial.println();

Serial.println();
delay(3000);
}[/code]

[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

 

IR infrared remote control dengan Arduino

[ [ images & links ] ]

Gambar 1. [sumber]

Gambar 2. [sumber]

Infrared IR Receiver Module Wireless Remote Control Kit For Arduino

Description:

Arduino mini infrared wireless remote control kit consists of ultra-thin infrared remote control and 38KHz infrared receiver module. This mini slim infrared remote control with 20 function keys. Its transmit distances up to 8 meters. Ideal for handling a variety of equipment indoors.
IR receiver module can receive standard 38KHz modulation remote control signal. You can decode the remote control signal through Arduino programming. You can design a variety of remote control robots and interactive works.

Specification:

Transmission distance: up to 8m(depending on the surrounding environment, sensitivity of receiver etc)
Battery: CR2025 button battery
Battery capacity: 160mAh
Effective angle: 60°
Sticking material: 0.125mmPET
Effective life: 20,000 times
Static current: 3uA – 5uA
Dynamic current: 3mA – 5mA

~alexnld.com

MAKER Version Electronic Brick Set IR Remote

The IR Remote supplied with this Set looks like this (Others may also be supplied):

– Based on NEC protocol; Built-in 1 x AG10 battery;
– Remote control range: above 8m;
– Wavelength: 940Nm;
– Frequency: crystal oscillator: 455KHz; IR carrier frequency: 38KHz

This is especially good for remote control of a small robot, using the arrow buttons. Below is [ps2id url=’#terryyourduino’ offset=’300′]an example Software Sketch[/ps2id] for this remote. The reported buttons will be Forward, Left, Right, Reverse (for the 4 blue button), OK for the red ‘OK’ button, 1 to 0 for the white number buttons, and ‘*’ and ‘#’ for the bottom red buttons.

TYPES OF IR REMOTE CONTROLS
NOTE!! Most handheld remotes are shipped with a small clear plastic piece in the battery compartment that must be removed to activate it. You can usually just pull it out.
There are many different IR remote controls. Some from YourDuino.com are the low-cost IR Infrared Remote Control Kit 2 and also the THIS IR Remote (right) which has directional buttons that would be good for controlling a vehicle etc. Then, there are the typical TV and Stereo Remotes. All of these may have different encoding methods and number of physical buttons, and different codes received when a button is pressed. Below we will give [ps2id url=’#terryyourduino’ offset=’300′]example Software Sketches[/ps2id] for a few common IR Remotes.

IR-REMOTE LIBRARY:
Note: The following library must be installed in your Arduino installation for this to work!
CLICK HERE – IR REMOTE CONTROL: ARDUINO LIBRARY

NOTE!! If you have a late version of Arduino with a library IRRobotRemote, it may conflict and you may have to remove that library.
Make sure to delete Arduino_Root/libraries/RobotIRremote. Where Arduino_Root refers to the install directory of Arduino. The library RobotIRremote has similar definitions to IRremote and causes errors.

~arduino-info.wikispaces.com/IR-RemoteControl

Gambar 3. [sumber]

Gambar 4. [sumber]

Contoh salah satu tabel output dari IR remote control (cocok untuk IR RC Keyes warna hitam dengan tombol arah).

Untuk contoh kode lihat di [ps2id url=’#xindacode’ offset=’350′] bagian halaman ini.[/ps2id]

z3t0/Arduino-IRremote

Receiving and printing a code:

The following sketch will receive codes and print them to the serial port. This sketch is very useful for testing IR receiving, and for determining what code values to use in your code. A slightly more complex version is in the examples directory as IRrecvDump.

This sketch also illustrates how to perform an action while a button is pressed. In this example, the action is writing to the serial port.

#include <IRremote.h>
IRrecv irrecv(7); // Receive on pin 7
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}

void loop() 
{
  if (irrecv.decode(&results)) 
  {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Continue receiving
  }
}

 

IRrecvDemo.ino

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 7;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
}

void loop() 
{
  if (irrecv.decode(&results)) 
  {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}

IRrecvDump.ino

/*
 * IRremote: IRrecvDump - dump details of IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 * JVC and Panasonic protocol added by Kristian Lauszus (Thanks to zenwheel and other people at the original blog post)
 * LG added by Darryl Smith (based on the JVC protocol)
 */

#include <IRremote.h>

/* 
*  Default is Arduino pin D11. 
*  You can change this to another available Arduino Pin.
*  Your IR receiver should be connected to the pin defined here
*/
int RECV_PIN = 7;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}


void dump(decode_results *results) {
  // Dumps out the decode_results structure.
  // Call this after IRrecv::decode()
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.print("Unknown encoding: ");
  }
  else if (results->decode_type == NEC) {
    Serial.print("Decoded NEC: ");

  }
  else if (results->decode_type == SONY) {
    Serial.print("Decoded SONY: ");
  }
  else if (results->decode_type == RC5) {
    Serial.print("Decoded RC5: ");
  }
  else if (results->decode_type == RC6) {
    Serial.print("Decoded RC6: ");
  }
  else if (results->decode_type == PANASONIC) {
    Serial.print("Decoded PANASONIC - Address: ");
    Serial.print(results->address, HEX);
    Serial.print(" Value: ");
  }
  else if (results->decode_type == LG) {
    Serial.print("Decoded LG: ");
  }
  else if (results->decode_type == JVC) {
    Serial.print("Decoded JVC: ");
  }
  else if (results->decode_type == AIWA_RC_T501) {
    Serial.print("Decoded AIWA RC T501: ");
  }
  else if (results->decode_type == WHYNTER) {
    Serial.print("Decoded Whynter: ");
  }
  Serial.print(results->value, HEX);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
  Serial.print("Raw (");
  Serial.print(count, DEC);
  Serial.print("): ");

  for (int i = 1; i < count; i++) {
    if (i & 1) {
      Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
    }
    else {
      Serial.write('-');
      Serial.print((unsigned long) results->rawbuf[i]*USECPERTICK, DEC);
    }
    Serial.print(" ");
  }
  Serial.println();
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    dump(&results);
    irrecv.resume(); // Receive the next value
  }
}

Arduino Keyes / Xinda IR Remote Control Tutorial

 

IR Remote Tutorial Code Part 2

//  Henry's Bench IR Remote Tutorial 2

#include <IRremote.h>

int IR_PIN = 7;

IRrecv irDetect(IR_PIN);

decode_results irIn;

void setup()
{
  Serial.begin(9600);
  
  irDetect.enableIRIn(); // Start the Receiver
}

void loop() {
  if (irDetect.decode(&irIn)) {
    decodeIR();
    irDetect.resume(); 
  }
}

void decodeIR() // Indicate what key is pressed

{

  switch(irIn.value)

  {

  case 0xFF629D:  
    Serial.println("Up Arrow"); 
    break;

  case 0xFF22DD:  
    Serial.println("Left Arrow"); 
    break;

  case 0xFF02FD:  
    Serial.println("OK"); 
    break;

  case 0xFFC23D:  
    Serial.println("Right Arrow"); 
    break;

  case 0xFFA857:  
    Serial.println("Down Arrow"); 
    break;

  case 0xFF6897:  
    Serial.println("1"); 
    break;

  case 0xFF9867:  
    Serial.println("2"); 
    break;

  case 0xFFB04F:  
    Serial.println("3"); 
    break;

  case 0xFF30CF:  
    Serial.println("4"); 
    break;

  case 0xFF18E7:  
    Serial.println("5"); 
    break;

  case 0xFF7A85:  
    Serial.println("6"); 
    break;

  case 0xFF10EF:  
    Serial.println("7"); 
    break;

  case 0xFF38C7:  
    Serial.println("8"); 
    break;

  case 0xFF5AA5:  
    Serial.println("9"); 
    break;

  case 0xFF42BD:  
    Serial.println("*"); 
    break;

  case 0xFF4AB5:  
    Serial.println("0"); 
    break;

  case 0xFF52AD:  
    Serial.println("#"); 
    break; 

  default: 
   break;

  }
}

https://arduino-info.wikispaces.com/IR-RemoteControl  

/* YourDuino.com Example Software Sketch
 Brick Starter Set IR Remote Kit Test
http://yourduino.com/sunshop2/index.php?l=product_detail&p=364
 based on code by Ken Shirriff - http://arcfn.com
 Get Library at: https://github.com/shirriff/Arduino-IRremote
 Unzip folder into Libraries. RENAME folder IRremote
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/

#include "IRremote.h"

/*-----( Declare Constants )-----*/
int receiver = 7; // pin 1 of IR receiver to Arduino digital pin 7

/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);           // create instance of 'irrecv'
decode_results results;            // create instance of 'decode_results'
/*-----( Declare Variables )-----*/


void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);
  Serial.println("YourDuino IR Receiver Button Decode Test");
  Serial.println("Questions: terry@yourduino.com");  
  irrecv.enableIRIn(); // Start the receiver

}/*--(end setup )---*/


void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  if (irrecv.decode(&results)) // have we received an IR signal?

  {
//    Serial.println(results.value, HEX);  UN Comment to see raw values
    translateIR(); 
    irrecv.resume(); // receive the next value
  }  
}/* --(end main loop )-- */

/*-----( Declare User-written Functions )-----*/
void translateIR() // takes action based on IR code received

// describing KEYES Remote IR codes 

{

  switch(results.value)

  {

  case 0xFF629D: Serial.println(" FORWARD"); break;
  case 0xFF22DD: Serial.println(" LEFT");    break;
  case 0xFF02FD: Serial.println(" -OK-");    break;
  case 0xFFC23D: Serial.println(" RIGHT");   break;
  case 0xFFA857: Serial.println(" REVERSE"); break;
  case 0xFF6897: Serial.println(" 1");    break;
  case 0xFF9867: Serial.println(" 2");    break;
  case 0xFFB04F: Serial.println(" 3");    break;
  case 0xFF30CF: Serial.println(" 4");    break;
  case 0xFF18E7: Serial.println(" 5");    break;
  case 0xFF7A85: Serial.println(" 6");    break;
  case 0xFF10EF: Serial.println(" 7");    break;
  case 0xFF38C7: Serial.println(" 8");    break;
  case 0xFF5AA5: Serial.println(" 9");    break;
  case 0xFF42BD: Serial.println(" *");    break;
  case 0xFF4AB5: Serial.println(" 0");    break;
  case 0xFF52AD: Serial.println(" #");    break;
  case 0xFFFFFFFF: Serial.println(" REPEAT");break;  

  default: 
    Serial.println(" other button   ");

  }// End Case

  delay(500); // Do not get immediate repeat


} //END translateIR

/* ( THE END ) */

Gambar 5.

[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self” content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video05″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

Penggunaan rotary encoder di sistem Arduino

[ [ images, codes & links ] ]

A rotary encoder, also called a shaft encoder, is an electro-mechanical device that converts the angular position or motion of a shaft or axle to an analog or digital signal.

There are two main types: absolute and incremental (relative). The output of absolute encoders indicates the current position of the shaft, making them angle transducers. The output of incremental encoders provides information about the motion of the shaft, which is typically further processed elsewhere into information such as speed, distance and position.

Rotary encoders are used in many applications that require precise shaft unlimited rotation—including industrial controls, robotics, special purpose photographic lenses, computer input devices (such as optomechanical mice and trackballs), controlled stress rheometers, and rotating radar platforms.

~https://en.wikipedia.org/wiki/Rotary_encoder

A rotary encoder is a type of position sensor which is used for determining the angular position of a rotating shaft. It generates an electrical signal, either analog or digital, according to the rotational movement.

Gambar 1.

Gambar 2.

This rotary encoder is also known as quadrature encoder or relative rotary encoder and its output is a series of square wave pulses.

How Rotary Encoder Works  [click to read more]

~howtomechatronics.com

Incremental Encoder Quadrature Output Waveform

An incremental rotary encoder generates two output signals while its shaft is rotating which is also called quadrature ouptut. Depending on the direction, one of the signals leads the other. You can see the output signal waveforms of an incremental rotary encoder and the expected bit sequence below.

Gambar 3.

As you can see from the figure, both of the outputs stays HIGH at the initial state. When the encoder shaft starts to rotate in clockwise direction, Output A falls to LOW first and Output B follows it with a lag. In a counter-clockwise direction the operation turns opposite. Time intervals on the waveform depend on the rotation speed but the signal lagging is guaranteed in encoder operation. We will build the whole scenario on this characteristic of the incremental rotary encoder.

~How to Use a Rotary Encoder in an MCU-Based Project

Mengenal Keyes KY-04 dan mencoba kode program sederhana.

Contoh kode dari:

http://henrysbench.capnfatz.com

[code lang=”C”] int pinA = 6; // Connected to CLK on KY-040. Gantidari pin 2
int pinB = 7; // Connected to DT on KY-040. Ganti dari pin 3
int encoderPosCount = 0;
int pinALast;
int aVal;
boolean bCW;

void setup() {
pinMode (pinA,INPUT);
pinMode (pinB,INPUT);
/* Read Pin A
Whatever state it’s in will reflect the last position
*/
pinALast = digitalRead(pinA);
Serial.begin (9600);
}

void loop() {
aVal = digitalRead(pinA);
if (aVal != pinALast){ // Means the knob is rotating
// if the knob is rotating, we need to determine direction
// We do that by reading pin B.
if (digitalRead(pinB) != aVal) { // Means pin A Changed first – We’re Rotating Clockwise
encoderPosCount ++;
bCW = true;
} else {// Otherwise B changed first and we’re moving CCW
bCW = false;
encoderPosCount–;
}
Serial.print (“Rotated: “);
if (bCW){
Serial.println (“clockwise”);
}else{
Serial.println(“counterclockwise”);
}
Serial.print(“Encoder Position: “);
Serial.println(encoderPosCount);

}
pinALast = aVal;
}
[/code]

Contoh kode dari:

http://howtomechatronics.com/tutorials/arduino/rotary-encoder-works-use-arduino/

[code lang=”C”] /* Arduino Rotary Encoder Tutorial
*
* by Dejan Nedelkovski, www.HowToMechatronics.com
*
*/

#define outputA 6
#define outputB 7

int counter = 0;
int aState;
int aLastState;

void setup() {
pinMode (outputA,INPUT);
pinMode (outputB,INPUT);

Serial.begin (9600);
// Reads the initial state of the outputA
aLastState = digitalRead(outputA);
}

void loop() {
aState = digitalRead(outputA); // Reads the “current” state of the outputA
// If the previous and the current state of the outputA are different, that means a Pulse has occured
if (aState != aLastState){
// If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
if (digitalRead(outputB) != aState) {
counter ++;
} else {
counter –;
}
Serial.print(“Position: “);
Serial.println(counter);
}
aLastState = aState; // Updates the previous state of the outputA with the current state
}
[/code]

Description of the code: So first we need to define the pins to which our encoder is connected and define some variables needed for the program. In the setup section we need to define the two pins as inputs, start the serial communication for printing the results on the serial monitor, as well as read the initial value of the output A and put the value into the variable aLastState.

Then in the loop section we read the output A again but now we put the value into the aState variable. So if we rotate the encoder and a pulse is generated, these two values will differ and the first “if” statement will become true. Right after that using the second “if” statement we determine the rotation direction. If the output B state differ from the output A state the counter will be increased by one, else it will be decreased. At the end, after printing the results on the serial monitor, we need to update the aLastState variable with aState variable.

That’s all we need for this example. If upload the code, start the Serial Monitor and start rotating the encoder we will start getting the values in the serial monitor. The particular module that I have makes 30 counts each full cycle.

Gambar 20.

Berikut contoh-contoh kode program, silakan membaca situs sumber aslinya untuk lebih memahami. Beberpa kode memerlukan pustaka/library yang dapat dicari melalui halaman sumber kode.

Contoh kode program dari https://github.com/PaulStoffregen/Encoder (Basic.pde)

[code lang=”C”] /*
* Dimodifikasi dari kode contoh:
* Encoder Library – Basic Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/

#include <Encoder.h>

// Change these two numbers to the pins connected to your encoder.
// Best Performance: both pins have interrupt capability.
// Pin 2 & pin 3 di Arduino Uno
// Good Performance: only the first pin has interrupt capability
// Low Performance: neither pin has interrupt capability
Encoder myEnc(6, 7);
// avoid using pins with LEDs attached

void setup()
{
Serial.begin(9600);
Serial.println(“Basic Encoder Test:”);
}

long oldPosition = -999;
//long oldPosition = 0;

void loop()
{
long newPosition = myEnc.read();
if (newPosition != oldPosition)
{
oldPosition = newPosition;
Serial.println(newPosition);
// Serial.println(newPosition/4);
}
}[/code]

Contoh kode program dari https://github.com/PaulStoffregen/Encoder (NoInterrupts.pde)

[code lang=”C”] /* Encoder Library – NoInterrupts Example
* http://www.pjrc.com/teensy/td_libs_Encoder.html
*
* This example code is in the public domain.
*/

// If you define ENCODER_DO_NOT_USE_INTERRUPTS *before* including
// Encoder, the library will never use interrupts. This is mainly
// useful to reduce the size of the library when you are using it
// with pins that do not support interrupts. Without interrupts,
// your program must call the read() function rapidly, or risk
// missing changes in position.
#define ENCODER_DO_NOT_USE_INTERRUPTS
#include <Encoder.h>

// Beware of Serial.print() speed. Without interrupts, if you
// transmit too much data with Serial.print() it can slow your
// reading from Encoder. Arduino 1.0 has improved transmit code.
// Using the fastest baud rate also helps. Teensy has USB packet
// buffering. But all boards can experience problems if you print
// too much and fill up buffers.

// Change these two numbers to the pins connected to your encoder.
// With ENCODER_DO_NOT_USE_INTERRUPTS, no interrupts are ever
// used, even if the pin has interrupt capability
Encoder myEnc(6, 7);
// avoid using pins with LEDs attached

void setup() {
Serial.begin(9600);
Serial.println(“Basic NoInterrupts Test:”);
}

long position = -999;

void loop() {
long newPos = myEnc.read();
if (newPos != position) {
position = newPos;
Serial.println(position);
}
// With any substantial delay added, Encoder can only track
// very slow motion. You may uncomment this line to see
// how badly a delay affects your encoder.
//delay(50);
}[/code]

Contoh kode program dari https://github.com/mathertel/RotaryEncoder (InterruptRotator.ino)

[code lang=”C”] // —–
// InterruptRotator.ino – Example for the RotaryEncoder library.
// This class is implemented for use with the Arduino environment.
// Copyright (c) by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a BSD style license. See http://www.mathertel.de/License.aspx
// More information on: http://www.mathertel.de/Arduino
// —–
// 18.01.2014 created by Matthias Hertel
// —–

// This example checks the state of the rotary encoder in the loop() function.
// The current position is printed on output when changed.

// Hardware setup:
// Attach a rotary encoder with output pins to A2 and A3.
// The common contact should be attached to ground.

#include <RotaryEncoder.h>

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);

void setup()
{
// Serial.begin(57600);
Serial.begin(9600); //diubah

Serial.println(“SimplePollRotator example for the RotaryEncoder library.”);

// You may have to modify the next 2 lines if using other pins than A2 and A3
PCICR |= (1 << PCIE1); // This enables Pin Change Interrupt 1 that covers the Analog input pins or Port C.
PCMSK1 |= (1 << PCINT10) | (1 << PCINT11); // This enables the interrupt for pin 2 and 3 of Port C.
} // setup()

// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3: exactly where we need to check.
ISR(PCINT1_vect)
{
encoder.tick(); // just call tick() to check the state.
}

// Read the current position of the encoder and print out when changed.
void loop()
{
static int pos = 0;

int newPos = encoder.getPosition();
if (pos != newPos)
{
Serial.print(newPos);
Serial.println();
pos = newPos;

// Just to show, that long lasting procedures don’t break the rotary encoder:
// When newPos is 66 the ouput will freeze, but the turned positions will be recognized even when not polled.
// The interrupt still works.
// The output is correct 6.6 seconds later.
if (newPos == 66)
{
// delay(6600);
delay(3000); //diubah
} // if newPOS
} // if
} // loop ()

// The End
[/code]

Penggunaan sensor ultrasonic

[ [ images & links ] ]

Sensor ultrasonic (ultrasonik) seperti srf04 dan srf05 dipergunakan untuk mengukur jarak suatu obyek.

SRF04Gambar 1. [sumber]

Gambar 2. [sumber]

 

Gambar 5. [sumber]

Ultrasonic ConeGambar 6. [sumber]Ojbects SameGambar 7. [sumber] Ultasonic FailGambar 8. [sumber]

Gambar 9. [sumber]

Gambar 10. [sumber]

Gambar 11. [sumber]

Working of HC-SR04 Ultrasonic SensorGambar 12. [sumber]

Gambar 13. [sumber]

Hubungan ke pin pada Gambar 13 dapat diubah sesuai keperluan, tidak mutlak harus menggunakan pin 12 dan pin 13. Perhatikan perbedaan pin antara SR04/SRF04 dengan SR05/SRF05 seperti pada Gambar 14.

Gambar 14. [sumber]

Sebelum melanjutkan ke tahap yang lebih detail, bisa dicoba kode program yang relatif sederhana sebagai bahan untuk memahami proses kerja sensor lebih lanjut. Kode untuk SRF05 (jika menudukung) dengan menggunakan satu pin bisa dilihat di qqtrading.com.my.

Pengaturan mengikuti Gambar 14 (dua pin sinyal), dengan kode sederhana sebagai berikut:

[code lang=”C”] #define TRIG_PIN 7
#define ECHO_PIN 6

const uint8_t BATAS_BAWAH = 4;
const uint16_t BATAS_ATAS = 300;

int sonar(void);

void setup()
{
Serial.begin(9600);
pinMode(ECHO_PIN, INPUT);
pinMode(TRIG_PIN, OUTPUT);
}

void loop()
{
int jarak = sonar();
Serial.print("Jarak dalam satuan cm: ");
// Serial.println( sonar() );
if(jarak<BATAS_BAWAH)
{
Serial.println("Obyek terlalu dekat");
}
else if(jarak>BATAS_ATAS)
{
Serial.println("Terlalu jauh");
}
else
{
Serial.println(jarak);
}

delay(1000);
}

int sonar(void)
{
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);

int jarak = pulseIn(ECHO_PIN, HIGH);

return (jarak = jarak / 58);
}
[/code]

Gambar 15.

 

Gambar 16. Hasil pengukuran jarak

SRF04 Specifications (eprolabs)

    • Operating Voltage:5V

 

    • Operating Frequency: 40Hz

 

    • Max Range: 4m

 

    • Min Range: 2cm

 

    • Measuring Angle: 15 degree

 

    • Trigger Input Signal: 10uS  TTL pulse

 

    • Echo Output Signal: TTL level signal, proportional to distance

 

The SRF04 Timing diagram is shown below. You only need to supply a short 10uS pulse to the trigger input to start the ranging. The SRF04 will send out an 8 cycle burst of ultrasound at 40khz and raise its echo line high. It then listens for an echo, and as soon as it detects one it lowers the echo line again. The echo line is therefore a pulse whose width is proportional to the distance to the object. By timing the pulse it is possible to calculate the range in inches/centimeters or anything else. If nothing is detected then the SRF04 will lower its echo line anyway after about 36mS.

Gambar 17.

In operation, the processor waits for an active low trigger pulse to come in. It then generates just eight cycles of 40khz. The echo line is then raised to signal the host processor to start timing. The raising of the echo line also shuts of the MAX232. After a while – no more than 10-12mS normally, the returning echo will be detected and the PIC will lower the echo line. The width of this pulse represents the flight time of the sonic burst. If no echo is detected then it will automatically time out after about 30mS (Its two times the WDT period of the PIC). Because the MAX232 is shut down during echo detection, you must wait at least 10mS between measurement cycles for the +/- 10v to recharge. Performance of this design is, I think, quite good. It will reliably measure down to 3cm and will continue detecting down to 1cm or less but after 2-3cm the pulse width doesn’t get any smaller. Maximum range is a little over 3m. As and example of the sensitivity of this design, it will detect a 1inch thick plastic broom handle at 2.4m. Average current consumption is reasonable at less than 50mA and typically about 30mA. Calculating the Distance The SRF04 provides an echo pulse proportional to distance. If the width of the pulse is measured in uS, then dividing by 58 will give you the distance in cm, or dividing by 148 will give the distance in inches. uS/58=cm or uS/148=inches.

Changing beam pattern and beam width You can’t! This is a question which crops up regularly, however there is no easy way to reduce or change the beam width that I’m aware of. The beam pattern of the SRF04 is conical with the width of the beam being a function of the surface area of the transducers and is fixed.  The beam pattern of the transducers used on the SRF04, taken from the manufacturers data sheet, is shown below.

 

Gambar 18.

<span class="su-quote-cite"><a href="http://www.robot-electronics.co.uk/htm/srf04tech.htm" target="_blank">SRF04 - Ultra-Sonic Ranger Technical Specification</a></span>
SRF05  
At a quick glance there are only small differences between these two (www.f15ijp.com):

Untuk dapat lebih memahami dasar perhitungan, berikut ada beberapa sumber bacaan yang baik dan menarik. Dari beberapa artikel ini, misalnya, bisa diketahui dari mana angka (konstanta) 58 pada contoh kode sebelumnya didapat, dan apa maknanya.

Gambar 19. [sumber]

Gambar 20. [sumber]

Sebagai catatan, situs penyedia layanan (sengpielaudio.com) di halaman tersebut mencantumkan bahwa perhitungan hanya dijamin akurat sampai suhu 30° C saja. Nilai pada Gambar 20 hanya sebagai perbandingan. Jika suhu diturunkan menjadi 30° C maka berdasarkan perhitungan di halaman itu kecepatan suara menjadi 350.7 m/s.

Dari semua bahan di atas dapat disarikan beberapa perhitungan yang berguna untuk memahami dan mengerjakan sistem dengan sensor ultrasonik. Pertama, mencari pendekatan terhadap nilai kecepatan suara (speed of sound).  

   

c : Kecepatan suara (speed of sound) dalam satuan meter per second (m/S) 331.3 : Nilai speed of sound (dalam m/s) pada suhu 0° C dan 0% humidity T : Suhu (temperatur) dalam ° C H : % Humidity (relative humidity)

  Jika memiliki sensor suhu dan kelembapan di sistem/papan mikrokontroler maka nilai c ini dapat dihitung saat kode program dieksekusi.


Sebagai contoh untuk beberapa nilai suhu dan nilai persen kelembapan relatif, dibuat tabel berikut:

 

 


Berdasarkan tabel di atas jika nilai c diambil senilai   351.36 m/s   maka nilai ini sama artinya dengan

Untuk mencari berapa jarak yang ditempuh (menggunakan nilai c yang sama) selama 1 μS:

Untuk mencari berapa waktu yang diperlukan (menggunakan nilai c yang sama) untuk menempuh 1 cm:

 


Jika menggunakan nilai 28.46 uS/cm maka untuk jarak 100 cm  diperlukan waktu 2846 μS. Tetapi perlu diingat untuk penggunaan sensor ultrasonik, pengukuran dilakukan untuk waktu pengiriman dan waktu pantulan terdeteksi kembali. Jadi untuk obyek yang berjarak 100 cm, pengukuran dilakukan untuk 200 cm (100 cm untuk waktu pengiriman dan ditambah 100 cm untuk waktu pantulan). Perhitungannya menjadi:

 


Skenario berikutya adalah jika waktu tempuh yang diukur menggunakan sensor ultrasonik  diketahui. Misalnya terukur waktu tempuh sebesar 1138 μS, berapakah jarak obyek di depan sensor ultrasonik?

Waktu yang ditempuh adalah untuk jarak sekitar 40 cm, tetapi ini waktu untuk “berangkat + pulang” sinyal ultrasonik. Bisa dilihat dari perhitungan, jarak obyek adalah separuhnya yang artinya dalam hal ini adalah sekitar 20 cm.


Beberapa artikel dan kode menggunakan langkah yang nampak sedikit berbeda untuk menentukan jarak obyek di depan sensor ultrasonik, walaupun jika diperhatikan sebenarnya sama saja. Berikut keterangan untuk memudahkan:

 

 

 

 

Beberapa orang melakukan pembulatan untuk efisiensi perhitungan, misalnya:

  Jika menggunakan speed of sound yang berbeda, beberapa orang menuliskan persamaan sebagai berikut:

Untuk beberapa keperluan yang tidak membutuhkan nilai akurasi yang sangat tinggi (yang didukung oleh akurasi dan resolusi sensor dan mikrokontroler), pembulatan bisa dilakukan. Misalnya: (28.46 μS/cm x 2) = 56.92 μS/cm, dapat dibulatkan menjadi 29 μS/cm dan 57 μS/cm. Dengan cara yang sama di beberapa kode bisa ditemui pembulatan dengan nilai 29 μS/cm dan 58 μS/cm.
Jika diperhatikan umumnya perhitungan maupun kode program mempergunakan satuan microsecond, mengapa? Jawabannya adalah pada cara pengukuran waktu pada sensor ultrasonik. Sebagai contoh, pada sistem Arduino telah disediakan rutin pulseIn() yang mengukur dalam (dan mempergunakan) satuan microsecond.
Berikut ada beberapa contoh kode yang, untuk kemudahan dan cadangan, saya kumpulkan dari Internet. Silakan menuju situs asalnya untuk memperoleh keterangan lengkap dan untuk membaca kode pada bagian ini silakan klik pada kotak “tombol”.

Ada beberapa keunggulan ekosistem Arduino. Antara lain jumlah shield yang cukup banyak yang memudahkan pengguna untuk melakukan implementasi program untuk komponen pada shield ke dalam sistem. Komponen dan shield pun banyak yang sudah dilengkapi dengan pustaka (library). Ini mempercepat proses pengerjaan kode program.

Pustaka seperti ini bukanlah hal yang unik atau aneh. Cara semacam ini sudah lama dikenal dan juga dipakan di ekosistem lain. Misalnya di ekosistem bahasa pemrograman Java, ekosistem Python, ekosistem Perl, ekosistem C++ dan bahkan di ekosistem bahasa C. Dengan adanya pustaka, pemrogram tidak perlu menghabiskan waktu untuk mengulangi membuat kode program yang sama. Sumber dayanya bisa dialihkan untuk mengerjakan hal yang lain dalam penyelesaian masalah.

Untuk pemrograman ekosistem Arduino yang mempergunakan sensor ultrasonik terdapat satu pustaka yang diberi nama NewPing.

newping2.jpgGambar 21. [sumber]

Berikut adalah contoh-contoh kode yang disalin langsung dari situs arduino-new-ping/wiki/.

Gambar 22. Pengujian kode [ps2id url=’#SimpleNewPingSketch’ offset=’300′]Simple NewPing Sketch[/ps2id]

Gambar 23.

Mengenai risiko akurasi dan kestabilan pembacaan untuk peletakan obyek pada Gambar 22, bisa kembali melihat [ps2id url=’#gambar7′ offset=’300′]Gambar 7[/ps2id].

Berikut ini beberapa Gambar proses pengujian beberapa cara untuk melakukan pengukuran jarak obyek dengan sensor ultrasonik.

Gambar 24. Percobaan membandingkan hasil pengukuran alat-alat ukur dan cara pengukuran

Gambar 25. Hasil pengukuran dengan pulseIn (float)

Pada Gambar 25 terlihat bahwa pengukuran jarak obyek dengan menggunakan pulseIn dan pembagian (float), tidak memberikan hasil yang mendekati dua alat ukur lainnya. Hasil dari pengukuran dari alat laser distance meter sama dengan penunjukkan pada tape rule. Jarak terukur 1.2 m (120.5 cm), sedangakan pembacaan sensor ultrasonik oleh program Arduino menunjukkan 153.90 cm.

Adadua kemungkinan, sumber kesalahan ada pada sensor atau ada pada Arduino. Pada sensor bisa jadi resolusi dan/atau akurasi, sedang pada Arduino bisa jadi ada pada hardware atau pada software. Pada software bisa jadi ada pada fungsi/pustaka dari perangkat lunak Arduino atau bisa jadi dari kode program oleh pengguna.

Pengujuan pertama dengan mengganti sensor (Gambar 24), hasilnya sama, nilai kesalahan masih pada kisaran yang sama. Percobaan berikutnya adalah dengan mengganti cara pembacaan dan pengolahan data dari sensor. Perhitungan dilakukan di dalam pustaka, pengguna mendapatkan hasil pengukuran dalam cm.

Gambar 26.

Dengan menggunakan library NewPing, akurasi hasil pengukuran bisa lebih dapat dicapai. Pengukuran dengan sensor ultrasonik menggunakan pustaka NewPing sama dengan hasil pengukuran dua alat lainnya pada setup percobaan yang sama.

Gambar 27. Percobaan pembandingan untuk jarak dekat

[intense_tabs direction=”right” active_tab_background_color=”#000000″ active_tab_font_color=”#ffff00″ trigger=”click”] [intense_tab title=”Video01″ border=”3px solid #e8e8e8″ link_target=”_self”  content_background_color=”#000000″ content_font_color=”#ffffff” icon_size=”1″ icon_position=”left”]

[/intense_tab] [intense_tab title=”Video02″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″  content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video03″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video04″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [intense_tab title=”Video05″ border=”3px solid #e8e8e8″ link_target=”_self” icon_size=”1″ content_background_color=”#000000″ content_font_color=”#ffffff” icon_position=”left”]

[/intense_tab] [/intense_tabs]

 

 

Penggunaan PIR (Passive Infrared Sensor) pada sistem Arduino

[ [ images & links ] ]

PIR (Passive infRared) sensor, adalah sensor yang mengukur radiasi infra merah dari suatu obyek. Seperti yang terlihat dari namanya, PIR diketahui bekerja secara pasif, artinya hanya menerima radiasi saja dan tidak memancarkan radiasi. PIR memberikan sinyal saat ada perubahan dari tingkat radiasi infra merah, karenanya PIR dipakai sebagai sensor gerakan. Keterangan lebih jauh bisa dipelajari dari beberapa kutipan berikut:

PIR SensorGambar 3. [sumber]HC-SR501 PIR MOTION SENSORGambar 4. [sumber]proximity_PIRbackLabeled.jpgGambar 5. [sumber]

Gambar 6. [sumber]

Specifications:

  • Operating voltage range: DC 4.5-20V
  • Quiescent Current: <50uA
  • Level output: High 3.3 V /Low 0V
  • Trigger: L can not be repeated trigger/H can be repeated trigger (Default repeated trigger)
  • Delay time: 5-200S(adjustable) the range is (0.xx second to tens of second) 
  • Block time: 1S(default) Can be made a range(0.xx to tens of seconds 
  • Board Dimensions: 32mm*24mm
  • Angle Sensor: <100 ° cone angle
  • Operation Temp: -15℃-+70℃
  • Lens size sensor: Diameter:23mm(Default)

Features:

  • the automatic sensor: to enter the sensor output range is high, people leave the sensor range of the automatic delay off high, output low.
  • the photosensitive control (optional, factory is not set) may set the photosensitive control during the day or light intensity without induction.
  • the temperature compensation (optional, factory is not set): In the summer when the ambient temperature rises to 30 ~ 32 ℃, slightly shorter detection range, temperature compensation can be used as a performance compensation.
  • two trigger mode: (can be selected by jumpers) a, can not repeat the trigger: the sensor output high, the delay time is over, the output will automatically become low from high; b, repeatable trigger: the sensor output high after the delay period, if the human body in its sensing range activities, its output will remain high until after the delay will be left high to low (sensor module review Measured activities of each body will be automatically extended after a delay time, and the final event of the delay time Starting point of time).
  • with induction blocking time (the default setting: 2.5S block time): sensor module, after each sensor output (high change Into a low level),you can set up a blockade followed by time period, in this time period the sensor does not accept any sensor signal. This feature can have a “sensor output time” and “blocking time” the interval between the work produced can be applied to detect the interval Products; also inhibit this function during load switching for a variety of interference. (This time can be set at zero seconds – Tens of seconds).
  • the working voltage range: the default voltage DC4.5V-20V.
  • micro-power consumption: static current “50 microamps, especially for battery-powered automatic control products.
  • the output high level signals: types of circuits can be easily and docking.
  • the working voltage range: the default voltage DC4.5V-20V.
  • the working voltage range: the default voltage DC4.5V-20V.

Instructions:

  • Sensing module for about a minute after power initialization time, during the interval to the output module 0-3 times a minute in standby mode.
  • Should avoid direct lighting such as interference sources close the surface of the lens module so as to avoid the introduction of interference signal generator malfunction; use of the environment to avoid the flow of the wind, the wind sensor will also cause interference.<50uA
  • Sensor module using a dual probe, the probe’s window is rectangular, dual (A per B million) in the direction of the ends of long, when the body passed from left to right or right to left when the reach the dual IR time, distance difference, the greater the difference, more sensitive sensors, when the body from the front to the probe or from top to bottom or from bottom to top direction passing, dual IR not detected changes in the distance, no difference value, the sensor insensitive or does not work; so the sensors should be installed dual direction of the probe with human activities as much as possible parallel to the direction of maximum to ensure that the body has been passed by the dual sensor probe. To increase the sensing range of angles, the module using a circular lens, the probe also makes sense on all four sides, but still higher than the upper and lower left and right direction of sensing range, sensitivity and strong, still as far as possible by the above installation requirements.VCC, trig (control side), echo (receiving end), GND

Note:

  • The potentiometer clockwise to adjust the distance, sensing range increases (about 7 meters), on the contrary, sensing range decreases (about 3 meters).Delay adjustment potentiometer clockwise rotation, sensor delay longer (about 300S), the other hand, induction by the short delay (about 5S).
<span class="su-quote-cite"><a href="http://www.ebay.com/itm/10pcs-HC-SR501-Adjust-IR-Pyroelectric-Infrared-PIR-Motion-Sensor-Detector-Module-/131028677440" target="_blank">eBay</a></span>
  • In the beginning you might notice some seemingly erratic behavior – this is perfectly normal. We need to understand a few things before we can tweak the settings.
  • When connecting the battery, the sensor will take up to 30 to 60 seconds to stabilize (warm up).
  • Place your setup in such a way that there will be no motion and wait until the LED remains OFF.
<span class="su-quote-cite"><a href="https://www.tweaking4all.com/hardware/pir-sensor/" target="_blank">Testing and Playing with PIR sensors (motion sensor)</a></span>

DELAY TIME

SENSITIVITY ADJUST/DETECTING RANGE

Gambar 9. [sumber]

RETRIGER/RETRIGGERING

 

Testing your PIR with a Battery, LED and a ResistorGambar 10. [sumber]

IMG_0669Gambar 11. [sumber]

Untuk pengujian alat, proses belajar awal dan bahkan untuk tuning, konfigurasi seperti pada Gambar 10 dan Gambar 11 adalah yang paling memudahkan. Tidak ada delay tambahan dari program dan proses lain pada mikrokontroler. Pengguna dapat lebih mudah untuk memperhatikan dan mempelajari respon modul PIR. Pengaturan delay time dan sensitivity menjadi lebih mudah dilakukan dengan cara ini.

Gambar 12.

Contoh pengujuan seperti pada Gambar 12, menggunakan dua indikator bantuan. LED memudahkan kita untuk mengetahui tingkat tegangan sebagai penunjuk langsung kondisi deteksi modul. Kondisi LED yang menyala atau tidak menyala membantu proses analisis program untuk mikrokontroler (dalam hal ini sistem papan Arduino). Seberapa cepat respon program yang kita buat bila dibandingkan dengan kondisi deteksi modul PIR.

Setelah proses pengaturan awal menggunakan cara pada Gambar 10 dan Gambar 11, pemrograman pada Gambar 12 menggunakan kode berikut. Tentu dapat dan perlu dilakukan coba-coba, proses trial & error, tinkering untuk hasil yang sesuai seperti yang dikehendaki.

/*************************************************************************************

  Mark Bramwell, July 2010

  This program will test the LCD panel and the buttons.When you push the button on the shield,
  the screen will show the corresponding one.
 
  Connection: Plug the LCD Keypad to the UNO(or other controllers)

  **************************************************************************************/

#include <LiquidCrystal.h>
#include <Wire.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);           // select the pins used on the LCD panel



#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5


const uint8_t INPUT_PIR = 12;

// define some values used by the panel and buttons
int lcd_key     = 0;
int adc_key_in  = 0;


int val = 0; 
uint8_t pirState = LOW;

int read_LCD_buttons()
{               // read the buttons
  adc_key_in = analogRead(0);       // read the value from the sensor 

  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  // We make this the 1st option for speed reasons since it will be the most likely result

  if (adc_key_in > 1000) return btnNONE; 

  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 250)  return btnUP; 
  if (adc_key_in < 450)  return btnDOWN; 
  if (adc_key_in < 650)  return btnLEFT; 
  if (adc_key_in < 850)  return btnSELECT;  

  // For V1.0 comment the other threshold and use the one below:
  /*
  if (adc_key_in < 50)   return btnRIGHT;  
  if (adc_key_in < 195)  return btnUP; 
  if (adc_key_in < 380)  return btnDOWN; 
  if (adc_key_in < 555)  return btnLEFT; 
  if (adc_key_in < 790)  return btnSELECT;   
  */

  return btnNONE;                // when all others fail, return this.
}


void lcdTest001(void)
{
  lcd.begin(16, 2);               // start the library
  lcd.setCursor(0,0);             // set the LCD cursor   position 
  lcd.print("Uji PIR >>");  // print a simple message on the LCD
}

void lcdShieldTest001(void)
{
  lcd.setCursor(9,1);             // move cursor to second line "1" and 9 spaces over
  lcd.print(millis()/1000);       // display seconds elapsed since power-up

  lcd.setCursor(0,1);             // move to the begining of the second line
  lcd_key = read_LCD_buttons();   // read the buttons

  switch (lcd_key)
  {               // depending on which button was pushed, we perform an action

    case btnRIGHT:
    {             //  push button "RIGHT" and show the word on the screen
      lcd.print("RIGHT ");
      break;
    }
    case btnLEFT:
    {
      lcd.print("LEFT   "); //  push button "LEFT" and show the word on the screen
      break;
    }    
    case btnUP:
    {
      lcd.print("UP    ");  //  push button "UP" and show the word on the screen
      break;
    }
    case btnDOWN:
    {
      lcd.print("DOWN  ");  //  push button "DOWN" and show the word on the screen
      break;
    }
    case btnSELECT:
    {
      lcd.print("SELECT");  //  push button "SELECT" and show the word on the screen
      break;
    }
    case btnNONE:
    {
      lcd.print("NONE  ");  //  No action  will show "None" on the screen
      break;
    }//EOF btnNONE
  }//EOF switch
}//EOF lcdShieldTest001


void pirinit(void)
{
  pinMode(INPUT_PIR, INPUT);     // declare sensor as input
}

/*
  Fungsi adapirtest disalin dari:
  https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor?view=all

*/
void adapirtest(void)
{

  val = digitalRead(INPUT_PIR);  // read input value
  if (val == HIGH) // check if the input is HIGH
  {            

    lcd.clear();
    // digitalWrite(ledPin, HIGH);  // turn LED ON
    lcd.setCursor(0,0);
    lcd.print("val = HIGH");
    if (pirState == LOW) 
    {
      // we have just turned on
      // Serial.println("Motion detected!");
      lcd.setCursor(0,1);
      lcd.print("Motion detected!");
      delay(3000);

      // We only want to print on the output change, not state
      pirState = HIGH;
    }
    delay(1000);
  } 
  else 
  {
    lcd.clear();
    // digitalWrite(ledPin, LOW); // turn LED OFF
    lcd.setCursor(0,0);
    lcd.print("val = LOW");
    if (pirState == HIGH)
    {
      // we have just turned of
      // Serial.println("Motion ended!");
      lcd.setCursor(0,1);
      lcd.print("Motion ended!");
      delay(3000);

      // We only want to print on the output change, not state
      pirState = LOW;
    }
    delay(1000);
  }


}


void setup()
{

  // Serial.begin(9600);

  lcd.begin(16, 2);               // start the library
  lcd.setCursor(0,0);             // set the LCD cursor   position 

  lcdTest001();
  delay(1000);
  lcd.clear();

  pirinit();
}

void loop()
{
  // lcdShieldTest001();
  adapirtest();
  // delay(1000);

}