Category Archives: Arduino
Pengetahuan Dasar Menggunakan Timer ESP32 dgn Arduino IDE
Draft
ESP32 mempunyai 4 timer hardware, yang masing-masing merupakan counter up/down 64-bit dengan prescaler 16-bit. Kecuali ESP32-C3 yang hanya mempunyai 2 timer yang masing-masing 54 bit saja. Timer ESP32 juga memiliki kemampuan memuat ulang otomatis (auto-reloading ) di akhir periode counting.
Setiap timer ESP32 menggunakan clock APB (APB_CLK biasanya dgn frekuensi 80 MHz) sebagai clock dasar. Clock ini kemudian diperkecil (dibagi) oleh prescaler 16-bit yang menghasilkan time-base tick time . Kita bisa mengubah nilai prescaler untuk mengontrol waktu tick timer.
Prescaler 16-Bit dapat membagi APB_CLK dengan faktor dari 2 ~ 65536. Saat kita menetapkan nilai prescaler menjadi 1 atau 2, pembagi clocknya adalah 2. Ketika kita mengatur prescaler ke 0, pembagi clocknya adalah 65536. Untuk prescaler lainnya akan menyebabkan clock dibagi dengan nilai yang sama dengan nilai precaler yang kita tulis ke register prescaler.
ESP32 timers dapat mentriger Event/kejadian alarm yang menyebabkab timer reload atau terjadi interrupt tergantung konfigurasi yg kita buat. Alarm event ditrigger ketika nilai di alarm register yg kita set sama dengan nilai timer saat ini. kondisi ini digunakan untuk interupsi periodik di dalam projek kita.
Rumus durasi interupsi periodik Timer ESP32
Untuk menghasilkan event periodik , kita akan menggunakan pembangkitan event alarm serta prescaler untuk mencapai periodik interupsi yang diinginkan. Ada 3 kasus khusus untuk persamaan Timer di bawah ini, yaitu Ketika Prescaler=1 atau 2, maka rumusnya T OUT = TimerTicks x (2/APB_CLK) . Ketika Prescaler=0, maka rumusnya T OUT = TimerTicks x (65536/APB_CLK) . selain itu ( nilai presclaer bukan 0,1 dan 2) gunakan rumus di bawah.
Contoh-1
Kita akan membuat LED kedip setiap 1 ms Untuk ini, kita akan menggunakan persamaan di atas, APB_CLK default adalah 80MHz atau 80.000.000Hz. T OUT yang diinginkan untuk periode interupsi di mana kita akan mengaktifkan LED adalah 1ms, Jadi T OUT = 1ms atau 0.001s . Hanya dua yang tidak diketahui sekarang adalah nilai Prescaler dan jumlah TimerTicks yang akan kita set di event alarmnya.
Kita dapat mengatur Prescaler ke nilai apa pun yang kita inginkan tetapi untuk menyederhanakan perhitungan, kita set Prescaler =80 . sekarang tinggal nilai TimerTicks yg akan kita cari dengan rumus persamaan untuk TimerTicks:
dengan rumus diatas kita memperoleh nilai TimerTicks = 1000 .
Code programnya :
#define LED 2 // pin LED tergantung type ESP32 boardnya
hw_timer_t *Timer_LED = NULL;
void IRAM_ATTR Timer0_ISR()
{
digitalWrite(LED, !digitalRead(LED));
}
void setup()
{
pinMode(LED, OUTPUT);
Timer_LED = timerBegin(0, 80, true); //(timer0, prescalar=80, true=countUp)
timerAttachInterrupt(Timer_LED, &Timer0_ISR, true);//aktifkan interupsi
timerAlarmWrite(Timer_LED, 1000, true); // (ISR, timerTick=1000, reload =true)
timerAlarmEnable(Timer_LED);//aktifkan timer berjalan terus menerus
}
void loop()
{
}
Contoh 2 :
Kita akan membuat led berkedip tiap 1 detik
#define LED 2
hw_timer_t *My_timer = NULL;
void IRAM_ATTR onTimer()
{
digitalWrite(LED, !digitalRead(LED));
}
void setup()
{
pinMode(LED, OUTPUT);
My_timer = timerBegin(1, 80, true);
timerAttachInterrupt(My_timer, &onTimer, true);
timerAlarmWrite(My_timer, 1000000, true); //interupsi tiap 1 detik
timerAlarmEnable(My_timer);
}
void loop()
{
}
============================================
Contoh-3
const byte LED_GPIO = 2;
volatile int interruptCounter;
volatile int blinkCounter = 0;
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
void IRAM_ATTR onTimer()
{
portENTER_CRITICAL_ISR(&timerMux);
interruptCounter++;
blinkCounter++;
portEXIT_CRITICAL_ISR(&timerMux);
}
void setup() {
Serial.begin(9600);
pinMode(LED_GPIO, OUTPUT);
timer = timerBegin(0, 80, true);
timerAttachInterrupt(timer, &onTimer, true);
timerAlarmWrite(timer, 1000000, true);
// Start the timer
timerAlarmEnable(timer);
}
void loop() {
if (interruptCounter > 0)
{
Serial.print(blinkCounter);
Serial.print(" ");
portENTER_CRITICAL(&timerMux);
interruptCounter--;
// timerAlarmDisable(timer);
if (blinkCounter % 2 == 0)
{
timerAlarmWrite(timer, 5000000, true);
}
else
{
timerAlarmWrite(timer, 500000, true);
}
// timerAlarmEnable(timer);
portEXIT_CRITICAL(&timerMux);
toggleLED();
}
}
void toggleLED()
{
digitalWrite(LED_GPIO, HIGH);
delay(50);
digitalWrite(LED_GPIO, LOW);
}
Berikut ini daftar lengkap fungsi yang dapat kita gunakan dalam memprogram timer ESP32 :
void timerEnd(hw_timer_t * timer);
void timerStart(hw_timer_t * timer);
void timerStop(hw_timer_t * timer);
void timerRestart(hw_timer_t * timer);
void timerWrite(hw_timer_t * timer, uint64_t val);
uint64_t timerRead(hw_timer_t * timer);
uint64_t timerReadMicros(hw_timer_t * timer);
uint64_t timerReadMilis(hw_timer_t * timer);
double timerReadSeconds(hw_timer_t * timer);
uint32_t timerGetFrequency(hw_timer_t * timer);
void timerAttachInterrupt(hw_timer_t * timer, void (*userFunc)(void));
void timerAttachInterruptArg(hw_timer_t * timer, void (*userFunc)(void*), void * arg);
void timerDetachInterrupt(hw_timer_t * timer);
void timerAlarm(hw_timer_t * timer, uint64_t alarm_value, bool autoreload, uint64_t reload_count);1
referensi
Contoh Code Arduino Modbus RTU ESP32 sebagai Slave
Tool yang diperlukan
sotware
- Arduino IDE
Hardware :
- PC/laptop
- ESP32 yg sudah di program sbg Master
- ESP32 yg akan di program sbg Slave
- modul TTL to rs485 automatic 2 pcs
Pada contoh berikut ESP32 sebagai Modbus slave dengan ID=1.
komunikasi melalaui RX2-TX2 pada pin GPIO 16 (RX2) dan GPIO 17 (Tx2) ESP32.
#include <ModbusRTU.h>
#define RXD2 16
#define TXD2 17
#define DIR 2 // pin untuk arah modul ttl-rs485 non automatic
#define REGN 2
#define SLAVE_ID 1
ModbusRTU mb;
void setup() {
Serial.begin(9600);
Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2);
mb.begin(&Serial2, DIR);
mb.slave(SLAVE_ID);//Initializng modbus slave device with ID 1
//buat 4 buah holding register
mb.addHreg(0); // add the register 40001
mb.addHreg(1); // add the register 40002
mb.addHreg(2); // add the register 40003
mb.addHreg(3); // add the register 40004
// mb.Hreg(1, 123); // isi register 40002 dgn nilai 123
}
unsigned long lastMillis = 0;
void loop()
{
mb.task();
yield();
long currentMillis = millis();
if (currentMillis - lastMillis > 5000)
{
//tampilkan data register
Serial.println(mb.Hreg(0x0)); //register 40001
Serial.println(mb.Hreg(0x1)); //register 40002
Serial.println(mb.Hreg(0x2)); //register 40003
Serial.println(mb.Hreg(0x3)); //register 40004
lastMillis = currentMillis;
}
}
Contoh Code Arduino Modbus RTU ESP32 sebagai Master
Tool yang diperlukan
sotware
- Arduino IDE
- ModbusSlave simulator
Hardware :
- PC/laptop
- ESP32
- modul usb to Rs485
- modul TTL to rs485 automatic
Pada contoh berikut ESP32 sebagai Modbus Master yang akan menulis nilai 700 ke Register 40003 sebuah slave dengan ID=1.
komunikasi melalaui RX2-TX2 pada pin GPIO 16 (RX2) dan GPIO 17 (Tx2) ESP32.
#include <ModbusMaster.h>
#include <Arduino.h>
#define RS485Serial Serial2
#define SLAVE_ADD 1
#define RX_PIN 16 //RX2
#define TX_PIN 17 //TX2
ModbusMaster modbus;
void setup() {
Serial.begin(115200, SERIAL_8N1);
RS485Serial.begin(9600, SERIAL_8N2, RX_PIN, TX_PIN);
modbus.begin(SLAVE_ADD, RS485Serial);
}
unsigned long lastMillis = 0;
void loop() {
long currentMillis = millis();
if (currentMillis - lastMillis > 1000)
{
Serial.println("Slave " + (String)SLAVE_ADD);
//FC 06 : writeSingleRegister(uint16_t reg, uint16_t nilai);
// contoh berikut REGISTER 40003 di slave akan diisi dgn nilai 700
uint8_t result = modbus.writeSingleRegister(0x02, 700);
if (result == modbus.ku8MBSuccess)
{
Serial.print("berhasil");
}
else{
getMsgError(&modbus, result);
Serial.print("gagal");
}
lastMillis = currentMillis;
Serial.println();
}
}
bool getMsgError(ModbusMaster *node, uint8_t result)
{
String tmpstr2 = "\r\n";
switch (result)
{
case node->ku8MBIllegalFunction:
tmpstr2 += "Illegal Function";
break;
case node->ku8MBIllegalDataAddress:
tmpstr2 += "Illegal Data Address";
break;
case node->ku8MBIllegalDataValue:
tmpstr2 += "Illegal Data Value";
break;
case node-> ku8MBSlaveDeviceFailure:
tmpstr2 += "Slave Device Failure";
break;
case node->ku8MBInvalidSlaveID:
tmpstr2 += "Invalid Slave ID";
break;
case node->ku8MBInvalidFunction:
tmpstr2 += "Invalid Function";
break;
case node->ku8MBResponseTimedOut:
tmpstr2 += "Response Timed Out";
break;
case node->ku8MBInvalidCRC:
tmpstr2 += "Invalid CRC";
break;
default:
tmpstr2 += "Unknown error: " + String(result);
break;
}
Serial.println(tmpstr2);
return false;
}
Berikut ini hasil penulisan nilai 700 ke reg 40003 esp32 master ke modbus slave simuator
Contoh Code ESP32 sebagai AP Hotspot dan web server untuk Input Data dan bisa update program Via wifi
Contoh Kode ESP32 dengan fitur:
- ESP32 sebagai Access Point / hotspot
- Authentification : login user-password
- Bisa update program via wifi (OTA )
- form input data
- On – OFF Relay
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <AsyncElegantOTA.h>
#define LED_BUILTIN 2
AsyncWebServer server(80);
// Replace with your network credentials
const char* ssid = "ESP32";
const char* password = "123456789";
IPAddress local_ip(192, 168, 123, 4); //ip address untuk akses ESP32
IPAddress gateway(192, 168, 123, 1); //gateway
IPAddress subnet(255, 255, 255, 0); //subnet
const char* http_username = "admin";
const char* http_password = "admin";
// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* PARAM_INPUT_1 = "input1";
const char* PARAM_INPUT_2 = "input2";
const char* PARAM_INPUT_3 = "input3";
const char* PARAM_INPUT_4 = "state";
const int output = 2;
int par1=0;
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<title>ESP Web Server</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {font-family: Arial; display: inline-block; text-align: center;}
h2 {font-size: 2.6rem;}
body {max-width: 600px; margin:0px auto; padding-bottom: 10px;}
.switch {position: relative; display: inline-block; width: 120px; height: 68px}
.switch input {display: none}
.slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
.slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
input:checked+.slider {background-color: #2196F3}
input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>
</head>
<body style="background-color:#2cc932;">
<h2>CounterProduksi.com</h2>
<h2>WA : 0812-1925-1068 </h2>
<table >
<tr>
<form action="/get">
<td>
PLAN:
</td>
<td>
<input type="text" name="input1">
</td>
<td>
<input type="submit" value="Submit">
</td>
</form>
</tr>
<tr>
<form action="/get">
<td>
ACTUAL:
</td>
<td>
<input type="text" name="input2">
</td>
<td>
<input type="submit" value="Submit">
</td>
</form>
</tr>
<tr>
<form action="/get">
<td>
MODEL:
</td>
<td>
<input type="text" name="input3">
</td>
<td>
<input type="submit" value="Submit">
</td>
</form>
</tr>
</table>
<br>
<br>
<button onclick="logoutButton()">Logout</button>
<p>Status Counter : <span id="state">%STATE%</span></p>
%BUTTONPLACEHOLDER%
<script>
function toggleCheckbox(element)
{
var xhr = new XMLHttpRequest();
if(element.checked){
xhr.open("GET", "/updatex?state=1", true);
document.getElementById("state").innerHTML = "ON";
}
else {
xhr.open("GET", "/updatex?state=0", true);
document.getElementById("state").innerHTML = "OFF";
}
xhr.send();
}
function logoutButton()
{
var xhr = new XMLHttpRequest();
xhr.open("GET", "/logout", true);
xhr.send();
setTimeout(function(){ window.open("/logged-out","_self"); }, 1000);
}
</script>
</body>
</html>
)rawliteral";
const char logout_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<p>Logged out or <a href="/">kembali</a>.</p>
<p><strong>CopyRight:</strong> counterproduksi.com-2024</p>
</body>
</html>
)rawliteral";
void notFound(AsyncWebServerRequest *request) {
request->send(404, "text/plain", "Not found");
}
// Replaces placeholder with button section in your web page
String processor(const String& var){
//Serial.println(var);
if(var == "BUTTONPLACEHOLDER"){
String buttons ="";
String outputStateValue = outputState();
buttons+= "<p><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label></p>";
return buttons;
}
if (var == "STATE")
{
if(digitalRead(output)){
return "ON";
}
else {
return "OFF";
}
}
return String();
}
String outputState(){
if(digitalRead(output)){
return "checked";
}
else {
return "";
}
return "";
}
void setup(){
// Serial port for debugging purposes
Serial.begin(115200);
pinMode(output, OUTPUT);
digitalWrite(output, LOW);
WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
if(!request->authenticate(http_username, http_password))
return request->requestAuthentication();
request->send_P(200, "text/html", index_html, processor);
});
server.on("/logout", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(401);
});
server.on("/logged-out", HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", logout_html, processor);
});
// Send a GET request to <ESP_IP>/update?state=<inputMessage>
server.on("/updatex", HTTP_GET, [] (AsyncWebServerRequest *request) {
if(!request->authenticate(http_username, http_password))
return request->requestAuthentication();
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_4)) {
inputMessage = request->getParam(PARAM_INPUT_4)->value();
inputParam = PARAM_INPUT_4;
digitalWrite(output, inputMessage.toInt());
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});
//===========
// Send a GET request to <ESP_IP>/get?input1=<inputMessage>
server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request)
{
String inputMessage;
String inputParam;
// GET input1 value on <ESP_IP>/get?input1=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
}
// GET input2 value on <ESP_IP>/get?input2=<inputMessage>
else if (request->hasParam(PARAM_INPUT_2)) {
inputMessage = request->getParam(PARAM_INPUT_2)->value();
inputParam = PARAM_INPUT_2;
}
// GET input3 value on <ESP_IP>/get?input3=<inputMessage>
else if (request->hasParam(PARAM_INPUT_3)) {
inputMessage = request->getParam(PARAM_INPUT_3)->value();
inputParam = PARAM_INPUT_3;
}
else {
inputMessage = "No message sent";
inputParam = "none";
}
par1= inputMessage.toInt() ; // par1=par1 + 3;
request->send(200, "text/html", "No-HP : " + inputParam +
"Usia : " + par1 +
"<br><a href=\"/\">Kembali</a>");
});
//===========
server.onNotFound(notFound);
AsyncElegantOTA.begin(&server); // Start AsyncElegantOTA update program via wifi :
// ketik http://ip_address/update
server.begin();
}
void loop() {
}
untuk upgrade program via wifi menggunakan OTA langkah langkahnya sbb:
- convert code program yg akan di upload ke esp32 ke dlm bentuk file *.bin
- hidupkan ESP32 ( yg sdh diupload contoh code diatas via USB serial )
- konek laptop ke hotspot esp32
- ketik di browser http://ipaddress/update misal http://192.168.123.4./update
- maka akan muncul halaman spt pada gb berikut ini:
Contoh Code Arduino Modbus Master RTU Menulis dan Membaca Slave
draft
#include <ModbusRtu.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
uint16_t au16data[16]; //!< data array for modbus network sharing
uint8_t u8state; //!< machine state
uint8_t u8query; //!< pointer to message query
/**
* Modbus object declaration
* u8id : node id = 0 for master, = 1..247 for slave
* u8serno : serial port (use 0 for Serial)
* u8txenpin : 0 for RS-232 and USB-FTDI
* or any pin number > 1 for RS-485
*/
Modbus master(0,3,0); // menggunakan RX3-TX3
/**
* This is an structe which contains a query to an slave device
*/
modbus_t telegram[2];
unsigned long u32wait;
int data=0;
void setup() {
Wire.begin();
lcd.init();
lcd.backlight();
lcd.setCursor(0,0);
lcd.print("Modbus Master");
delay(1000);
// telegram 0: read registers
telegram[0].u8id = 1; // slave address
telegram[0].u8fct = 3; // function code (this one is registers read)
telegram[0].u16RegAdd = 0; // start address in slave
telegram[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino
// telegram 1: write a single register
telegram[1].u8id = 1; // slave address
telegram[1].u8fct = 6; // function code (this one is write a single register)
telegram[1].u16RegAdd = 4; // start address in slave
telegram[1].u16CoilsNo = 1; // number of elements (coils or registers) to read
telegram[1].au16reg = au16data+4; // pointer to a memory array in the Arduino
master.begin( 9600 ); // baudrate 9600
master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
u32wait = millis() + 1000;
u8state = u8query = 0;
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
master.query( telegram[u8query] ); // send query (only once)
u8state++;
u8query++;
if (u8query > 2) u8query = 0;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 1000;
lcd.setCursor(0,1);
lcd.print("FC03:"); lcd.print(au16data[1]); // hasil baca FC03 di tulis ke LCD
data++;
lcd.setCursor(8,1);
lcd.print("FC06:"); lcd.print(data); // Data yg akan ditulis dgn FC03 ditampilkan di LCD
}
break;
}
delay(1000);
au16data[4] = data; // ini data nya yg akan di write dgn FC06
}
Contoh Code Arduino merubah 2 register modbus menjadi Floating Point
Pada atikel ini kita akan membuat modbus slave serial pada arduino yg akan menerima data floating point dari sebuah master modbus misalnya berupa PLC atau arduino lainnya .
Biasanya device modbus menggunakan 2 register Modbus berturut-turut untuk mengkodekan nilai floating point
Contoh: untuk nilai floating-point 50,12 representasi floating point presisi tunggal IEE 754 adalah seperti yang ditunjukkan di bawah ini.
data dibagi menjadi duabuah 16 Bit Words (Register): HIGH WORD berisi 0x4248 dan LOW WORD berisi 0x7df4. misal disimpan d Modbus Holding Register 40001 & 40002. Beberapa produsen mengirimkan High Word terlebih dahulu, baru kemudian Low Word.
Pabrikan lain mengirimkan Low Word Pertama, lalu High Word.
untuk merubah ke nilai floating point terlebih dahulu gabungkan ke dua nilai hex di register tsb, baru dirubah ke nilai floating point
Code Arduino
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
const int numHoldingRegisters = 10;
union {
float f;
uint16_t reg[2];
} u;
void setup() {
Serial.begin(9600);
while (!Serial);
// start the Modbus RTU server, with (slave) id 42
if (!ModbusRTUServer.begin(1, 9600)) {
Serial.println("Failed to start Modbus RTU Server!");
while (1);
}
ModbusRTUServer.configureHoldingRegisters(0x00, numHoldingRegisters);
// contoh modbus master menulis datanya 50,12 dlm hex = 0x42487df4 ke slave modbus arduino kita
ModbusRTUServer.holdingRegisterWrite(0, 0x7df4); // 40001
ModbusRTUServer.holdingRegisterWrite(1, 0x4248); // 40002
}
void loop() {
// poll for Modbus RTU requests
ModbusRTUServer.poll();
uint16_t lowWord = ModbusRTUServer.holdingRegisterRead(0);
uint16_t highWord = ModbusRTUServer.holdingRegisterRead(1);
u.reg[0] = lowWord; //0x7df4;
u.reg[1] = highWord; //0x4248;
// Convert the union to a float
float hasilFloat = u.f; // hasilFloat akan bernilai 50.12
int komanya = (int) (hasilFloat * 100) % 100;
// untuk melihat hasil kita simpan hasil di reg 40003 dan 40004
ModbusRTUServer.holdingRegisterWrite(2, f); // simpan nilai 50 ke register 40003
ModbusRTUServer.holdingRegisterWrite(3, komanya); // simpan nilai 12 ke register 40004
//}
}
HAsil pembacaan register akan sbg berikut ini
Dasar Pemrograman STM32 Microcontroller menggunakan STM32duino
Dasar Pemrograman STM32 Microcontroller menggunakan STM32duino
[draft]
Pengetahuan Dasar Membaca Arus 4-20ma dengan Arduino
Langsung saja caranya ada disini : https://www.youtube.com/watch?v=zSiV1d5COys
Modul converter 4-20ma to voltage 3,3/5/10v dc
Specifications:
- Output : 0-3.3V/5V/10V
- Voltage Supply Voltage : 7-24v ( apabila output 10v, power suply harus di atas 12v).
- When the current input is minimum (0mA or 4mA), adjust the ZERO potentiometer, so that the output of VOUT is minimum (0.0V or other voltage)
- When the current input is the maximum (20mA), adjust the SPAN potentiometer, so that the VOUT output is the maximum value (3.3V or 5V or 10V, when the input is 4-20mA, the minimum output can be 2.5V).
4–20ma:
- 0-2.5V range: J1 1,2 feet short, 3,4 feet shorted
- 0 – 3.3V range: J1 1,2 feet off, 3,4 feet off
- 0 – 5.0V range: J1 1,2 feet short, 3,4 feet shorted
- 0–10.0V range: J1 1,2 feet short, 3,4 feet off
0–20ma:
- 0–3.3V range: J1 1,2 feet short, 3,4 feet shorted
- 0 – 5.0V range: J1 1,2 feet short, 3,4 feet shorted
- 0–10.0V range: J1 1,2 feet short, 3,4 feet off
Wiring Diagram
Contoh Code Arduino membaca data Analog ADC
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:
int sensorValue = analogRead(A0);
// print out the value you read:
Serial.println(sensorValue);
delay(1); // delay in between reads for stability
}
================================================
Dengan mengambil Nilai Rata Rata hasil analogRead
*/
// the loop routine runs over and over again forever:
void loop() {
i++;
int sensorValueA0 = analogRead(A0);
akumulasiA0=akumulasiA0 + sensorValueA0;
if(i==100)
{
i=0;
rata2A0 = (float) akumulasiA0/100;
delay(5);
akumulasiRata2A0=akumulasiRata2A0 + rata2A0;
j++;
rata2A0=0;
akumulasiA0=0;
if(j==10){
j=0;
rata2akumulasiRata2A0= akumulasiRata2A0/10;
float dataA0 = ((rata2akumulasiRata2A0/1023.00)*400.00)-200.00;
// Serial.print(“dataA0 = “);
Serial.println(dataA0,1);
akumulasiRata2A0=0;
delay(400);
}
}
}
untuk methode filter noise lainnya bisa dibaca disini
Contoh Code Arduino Untuk Membaca Keypad 4×4 Abjad atau Karakter
//================================================
// BACA ABJAD HURUF DAN ANGKA
//=================================================
#define kolom1 29
#define kolom2 28
#define kolom3 27
#define kolom4 26
#define baris1 25
#define baris2 24
#define baris3 23
#define baris4 22
void bacaAbjad()
{
int loop=1;
while(loop) {
numpressed=255; //reset
if (readKeypad()){ //scan keypad
timespressed=0; //reset
if (numpressed==0){ //ditekan 0
dozero(); //print zero
letter='0'; //
textstorage(1); //simpan huruf
}
if (numpressed=='D'){ //ditekan D / shift
textstorage(2); //simpan spasi
dospace(); //do a space
}
if (numpressed=='C'){ //ditekan C/ backspace
textstorage(3); //simpan backspace
dobackspace(); //do a backspace
}
if (numpressed=='#'){ //ditekan # / enter
// simpanModelKeRegister(); //selesai simpan string
simpanNamaModel(19);
resetAbjad();
lcd.setCursor(12,1);
displayString(19);
loop=0;
}
if (numpressed=='*'){ //ditekan *
lcd.clear();
resetAbjad();
loop=0;
}
if ((numpressed<10&&numpressed>0)||numpressed==11){
lastnumpressed=numpressed;
basetime=millis();
while (elapsed<wait){ //selama tombol ditekan cepat
if(readKeypad()){ //scan keypad
if (numpressed==lastnumpressed){ //if it was the same as before,
incrementtimespressed(); //increment "timespressed"
basetime=basetime+(wait-(wait-elapsed)); //roll up the base time, to allow another wait period until next press of the same button
definepress(); //use "numpressed" and "timespressed" to define "letter"
lcd.print(letter); //print the letter that was defined
lcd.setCursor(cursorx,cursory); //maintain cursor position
delay(preventholddelay);
}
else{
disablespacedelay=true;
break;
}
}
elapsed=millis()-basetime; //refresh the while loop
}
elapsed=0; //reset
textstorage(1); //store character
dospace();
}
}
if (positionintypedtext==(jumlahMaxHuruf+1))
{
resetAbjad();
loop=0;
}
} // while looop
}
bool readKeypad(){
bool pressfound=false;
digitalWrite(kolom1, LOW);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 'D' ; }
if(digitalRead(baris2) == 0){delay(100);pressfound=true;tone(buzzer, 3000, durasi); numpressed = '#' ;}//'#'
if(digitalRead(baris3) == 0){delay(100);pressfound=true;tone(buzzer, 3000, durasi); numpressed = 0 ; }
if(digitalRead(baris4) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = '*' ; }
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, LOW);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0){ delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 'C' ; }
if(digitalRead(baris2) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 9 ; }
if(digitalRead(baris3) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 8 ; }
if(digitalRead(baris4) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 7 ; }
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, LOW);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 'B' ; }
if(digitalRead(baris2) == 0){delay(100);pressfound=true;tone(buzzer, 3000, durasi); numpressed = 6 ; }
if(digitalRead(baris3) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 5 ; }
if(digitalRead(baris4) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 4 ; }
//==========================================
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, LOW);
if(digitalRead(baris1) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 'A' ; } //a=10
if(digitalRead(baris2) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 3 ; }
if(digitalRead(baris3) == 0){delay(100);pressfound=true; tone(buzzer, 3000, durasi);numpressed = 2 ; }
if(digitalRead(baris4) == 0){delay(100);pressfound=true;tone(buzzer, 3000, durasi); numpressed = 1; }
return pressfound;
}
void definepress(){ //uses "lastnumpressed" and "timespressed" to define "letter"
if (lastnumpressed==1){
if (timespressed==1){
letter='Q';
}
if (timespressed==2){
letter='Z';
}
if (timespressed==3){
letter='1';
}
}
if (lastnumpressed==2){
if (timespressed==1){
letter='A';
}
if (timespressed==2){
letter='B';
}
if (timespressed==3){
letter='C';
}
if (timespressed==4){
letter='2';
}
}
if (lastnumpressed==3){
if (timespressed==1){
letter='D';
}
if (timespressed==2){
letter='E';
}
if (timespressed==3){
letter='F';
}
if (timespressed==4){
letter='3';
}
}
if (lastnumpressed==4){
if (timespressed==1){
letter='G';
}
if (timespressed==2){
letter='H';
}
if (timespressed==3){
letter='I';
}
if (timespressed==4){
letter='4';
}
}
if (lastnumpressed==5){
if (timespressed==1){
letter='J';
}
if (timespressed==2){
letter='K';
}
if (timespressed==3){
letter='L';
}
if (timespressed==4){
letter='5';
}
}
if (lastnumpressed==6){
if (timespressed==1){
letter='M';
}
if (timespressed==2){
letter='N';
}
if (timespressed==3){
letter='O';
}
if (timespressed==4){
letter='6';
}
}
if (lastnumpressed==7){
if (timespressed==1){
letter='P';
}
if (timespressed==2){
letter='R';
}
if (timespressed==3){
letter='S';
}
if (timespressed==4){
letter='7';
}
}
if (lastnumpressed==8){
if (timespressed==1){
letter='T';
}
if (timespressed==2){
letter='U';
}
if (timespressed==3){
letter='V';
}
if (timespressed==4){
letter='8';
}
}
if (lastnumpressed==9){
if (timespressed==1){
letter='W';
}
if (timespressed==2){
letter='X';
}
if (timespressed==3){
letter='Y';
}
if (timespressed==4){
letter='9';
}
}
if (lastnumpressed==11){
if (timespressed==1){
letter='.';
}
if (timespressed==2){
letter='?';
}
if (timespressed==3){
letter='!';
}
if (timespressed==4){
letter=',';
}
if (timespressed==5){
letter='\'';
}
if (timespressed==6){
letter='"';
}
if (timespressed==7){
letter='-';
}
}
}
void incrementtimespressed(){
if (timespressed==maxtimespressed[lastnumpressed]){ //if at the maximum,
timespressed=1; //roll over timespressed to one
}
else{ //otherwise,
timespressed++;
}
}
void dozero(){ //prints zero
lcd.print('0'); //print 0
lcd.setCursor(cursorx,cursory);
dospace(); //space
}
void dospace(){
if (cursory==3){
if (cursorx==19){
cursorx=0; corner
cursory=0;
lcd.clear(); //clear the lcd
}
else{ //otherwise,
cursorx++;
}
}
else{
if (cursorx==19){
cursorx=0;corner
cursory=3;
}
else{ //otherwise,
cursorx++;
}
}
lcd.setCursor(cursorx,cursory);
if (disablespacedelay){
disablespacedelay=false;
}
else{ //otherwise,
delay(preventholddelay); //delay a bit
}
}
void doclear(){ //clears and returns to top-left of display
cursorx=0;
cursory=0;
lcd.clear();
lcd.setCursor(cursorx,cursory);
delay(preventholddelay);
}
void dobackspace(){
if (cursory==3){
if (cursorx==0){
cursorx=19;
cursory=0;
}
else{
cursorx--;
}
}
else{
if (cursorx==0){
cursorx=0;
cursory=0;
}
else{
cursorx--;
}
}
lcd.setCursor(cursorx,cursory);
lcd.print(" ");
lcd.setCursor(cursorx,cursory);
delay(preventholddelay);
}
void textstorage(byte mode){
if (mode==1){
typedtext[positionintypedtext]=letter;
positionintypedtext++;
}
if (mode==2){
typedtext[positionintypedtext]=' ';
positionintypedtext++;
}
if (mode==3){
positionintypedtext--;
typedtext[positionintypedtext]=' ';
}
}
void resetAbjad()
{
positionintypedtext=0;
promptreadKeypadpress=false;
elapsed=0;
cursory=0;
cursorx=0;
numpressed=255;
timespressed=0;
}//
void hapusbuffer()
{
for(int i=0;i<jumlahMaxHuruf;i++)
typedtext[i]=0x00;
}
Contoh Code Arduino Membaca Keypad 4×4 Membrane
pada contoh ini Keypad di hubungkan dengan pin D2 s/d pin D9 pada Arduino board
#define kolom1 2
#define kolom2 3
#define kolom3 4
#define kolom4 5
#define baris1 6
#define baris2 7
#define baris3 8
#define baris4 9
int inputData =0;
int key(void);
void bacaKeypadEnter(void);
void setup()
{
Serial.begin(9600);
pinMode(kolom1, OUTPUT);
pinMode(kolom2, OUTPUT);
pinMode(kolom3, OUTPUT);
pinMode(kolom4, OUTPUT);
pinMode(baris1, INPUT);
pinMode(baris2, INPUT);
pinMode(baris3, INPUT);
pinMode(baris4, INPUT);
digitalWrite(baris1, HIGH);
digitalWrite(baris2, HIGH);
digitalWrite(baris3, HIGH);
digitalWrite(baris4, HIGH);
//==============================================================
Serial.println(“tekan angka lalu tanda # “);
}//6
void loop()
{
bacaKeypadEnter();
}//loop
int key(void)
{
unsigned char delaykeypad=700;
char KEY = 1 ;
while(KEY){
digitalWrite(kolom1, LOW);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0)
{
delay(delaykeypad);
KEY = 0;
return 1 ;
}
if(digitalRead(baris2) == 0){delay(delaykeypad);KEY = 0; return 2 ; }
if(digitalRead(baris3) == 0){delay(delaykeypad);KEY = 0; return 3 ; }
if(digitalRead(baris4) == 0){delay(delaykeypad);KEY = 0; return ‘A’ ; }
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, LOW);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0){delay(delaykeypad);KEY = 0; return 4 ; } //c
if(digitalRead(baris2) == 0){delay(delaykeypad);KEY = 0; return 5 ; }
if(digitalRead(baris3) == 0){delay(delaykeypad);KEY = 0; return 6 ; }
if(digitalRead(baris4) == 0){delay(delaykeypad);KEY = 0; return ‘B’ ; }//B
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, LOW);
digitalWrite(kolom4, HIGH);
if(digitalRead(baris1) == 0){delay(delaykeypad);KEY = 0; return 7 ; }
if(digitalRead(baris2) == 0){delay(delaykeypad);KEY = 0; return 8 ; }
if(digitalRead(baris3) == 0){delay(delaykeypad);KEY = 0; return 9 ; }
if(digitalRead(baris4) == 0){delay(delaykeypad);KEY = 0; return ‘C’ ; }
//==========================================
//==========================================
digitalWrite(kolom1, HIGH);
digitalWrite(kolom2, HIGH);
digitalWrite(kolom3, HIGH);
digitalWrite(kolom4, LOW);
if(digitalRead(baris1) == 0){delay(delaykeypad);KEY = 0; return ‘*’ ; }
if(digitalRead(baris2) == 0){delay(delaykeypad);KEY = 0; return 0 ; }
if(digitalRead(baris3) == 0){delay(delaykeypad);KEY = 0; return ‘#’ ; }
if(digitalRead(baris4) == 0){delay(delaykeypad);KEY = 0; return ‘D’; }
//==========================================
KEY = 1 ;
}
}
//================
void bacaKeypadEnter(void)
{
int y=0;
int Loop = 1 ; // masuk loop baca keypad
while(Loop)
{
y = key();
if( y < 10 ) // ambil data 0~9 simpan di operand2
{
inputData = (inputData*10)+y ;
Serial.print(y);
}
else if(y == ‘#’)
{
delay(30);
y = 0 ;
Loop = 0 ;
//keluar loop2
Serial.println();
Serial.println(“===”);
Serial.print(“ANDA KETIK = “);
Serial.println(inputData);
Serial.println(“===”);
Serial.println(“tekan angka lalu tanda # “);
inputData=0;
return ;
}
} //end while loop
}