Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh

Komponen dan Perlengkapan

Tentang Proyek Ini

Pendahuluan

Jika Anda pemula, saya merekomendasikan membaca tutorial berikut:

Anda mungkin familiar dengan pola unlock saat mengakses ponsel Anda. Sekarang fitur ini tersedia di Arduino. Ini mencegah orang tidak berwenang untuk mengontrol/memantau Arduino.

Pengguna bebas menggunakan ulang kode dalam proyek ini untuk aplikasi lain. Untuk kesederhanaan, saya mengambil kontrol servo motor sebagai contoh.

Ide ini berasal dari dua proyek, yang ditulis untuk platform PHPoC:

Saya menyesuaikannya untuk Arduino.

Dalam proyek ini, saya menggunakan PHPoC WiFi Shield untuk menghubungkan Arduino ke Internet karena:

PHPoC Shield memiliki beberapa aplikasi web bawaan yang memungkinkan pengguna menggunakan aplikasi web embedded untuk mengontrol/memantau Arduino tanpa memerlukan pengetahuan pemrograman web.

Juga, PHPoC shield memungkinkan pengguna yang dapat memprogram aplikasi web untuk mengembangkan aplikasi web mereka sendiri dan menyimpannya pada PHPoC Shield.

Demonstrasi

Alur Data

Web browser <---> PHPoC WiFi Shield <---> Arduino

Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh

Cara Kerja

Ketika pengguna menggambar pola di web browser, pola dipetakan ke dalam string. String pola ini dikirim ke Arduino melalui WebSocket (melalui PHPoC Shield).

Ketika Arduino menerima string pola yang diterima, itu akan membandingkan string yang diterima dengan string pola yang hard-coded di Arduino. Jika cocok, Arduino mengirim kode ACCEPTED kembali ke klien (Web browser) dan mengatur variabel terautentikasi ke true. Jika tidak, Arduino mengirim kode DENIED ke klien dan mengatur variabel terautentikasi ke false.

Ketika Arduino menerima perintah kontrol dari pengguna, itu akan memeriksa nilai variabel terautentikasi terlebih dahulu. Jika nilainya true, Ini melakukan tugas yang sesuai dengan perintah. Jika nilainya false, Ini mengirim kode DENIED ke klien.

Pemetaan Pola

Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh

Pola akan dipetakan ke dalam string. Misalnya, pada gambar di atas, string pola adalah "1, 4, 8, 6, 3".

Sebuah timeout diatur. Setelah sekian waktu, jika pengguna tidak memiliki aktivitas apa pun, otentikasi kedaluwarsa, pengguna perlu memasukkan pola lagi untuk membuka kunci Arduino.

Kode sumber mencakup dua file:

Apa yang Harus Kita Lakukan

Mengatur Informasi WiFi untuk PHPoC Shield

Lihat instruksi ini.

Unggah Web UI baru ke PHPoC Shield

Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh
Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh

Tulis Kode Arduino

Coba

Kit Starter Arduino Terbaik untuk Pemula

Jika Anda mencari kit Arduino, lihat The Best Arduino Kit for Beginners

Referensi Fungsi

Kode

unlock.phpPHP

Ini adalah antarmuka pengguna web

<!DOCTYPE html> <html> <head> <title>Arduino - PHPoC Shield</title> <meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7"> <meta charset="utf-8"> <style> body { text-align: center; font-size: width/2pt; } h1 { font-weight: bold; font-size: width/2pt; } h2 { font-weight: bold; font-size: width/2pt; } button { font-weight: bold; font-size: width/2pt; } </style> <script> var CMD_AUTH = 0; var CMD_CTRL = 1; var ws; var authorized = false; /* unlock variable */ var unlock_width = 400, unlock_height = 400; var unlock_inner_radius = 14; var unlock_middle_radius = 22; var unlock_outer_radius = 34; var unlock_gap = 140; var unlock_touch_state = 0; var unlock_touch_x = 0, unlock_touch_y = 0; var unlock_touch_list = new Array(); var unlock_ratio = 1; /* control variable: change as you want, as your application */ var servo_width = 401, servo_height = 466; var servo_pivot_x = 200, servo_pivot_y = 200; var servo_bracket_radius = 160, servo_bracket_angle = 0; var servo_bracket_img = new Image(); var servo_click_state = 0; var servo_last_angle = 0; var servo_mouse_xyra = {x:0, y:0, r:0.0, a:0.0}; servo_bracket_img.src = "servo_bracket.png"; function init() { /* init unlock part */ var unlock = document.getElementById("unlock"); unlock.width = unlock_width; unlock.height = unlock_height; unlock.addEventListener("touchstart", unlock_mouse_down); unlock.addEventListener("touchend", unlock_mouse_up); unlock.addEventListener("touchmove", unlock_mouse_move); unlock.addEventListener("mousedown", unlock_mouse_down); unlock.addEventListener("mouseup", unlock_mouse_up); unlock.addEventListener("mousemove", unlock_mouse_move); var ctx = unlock.getContext("2d"); ctx.translate(unlock_width/2, unlock_height/2); ctx.shadowBlur = 20; ctx.shadowColor = "LightGray"; ctx.lineCap="round"; ctx.lineJoin="round"; /* init control part */ var servo = document.getElementById("servo"); servo.width = servo_width; servo.height = servo_height; servo.style.backgroundImage = "url('/servo_body.png')"; servo.addEventListener("touchstart", servo_mouse_down); servo.addEventListener("touchend", servo_mouse_up); servo.addEventListener("touchmove", servo_mouse_move); servo.addEventListener("mousedown", servo_mouse_down); servo.addEventListener("mouseup", servo_mouse_up); servo.addEventListener("mousemove", servo_mouse_move); ctx = servo.getContext("2d"); ctx.translate(servo_pivot_x, servo_pivot_y); update_view(); } function connect_onclick() { if(ws == null) { var ws_host_addr = "<?echo _SERVER("HTTP_HOST")?>"; if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "[") ) { ws_host_addr = ws_host_addr.replace(/[\[\]]/g, ''); ws_host_addr = ws_host_addr.replace(/:/g, "-"); ws_host_addr += ".ipv6-literal.net"; } ws = new WebSocket("ws://" + ws_host_addr + "/web_pattern", "text.phpoc"); document.getElementById("ws_state").innerHTML = "CONNECTING"; ws.onopen = ws_onopen; ws.onclose = ws_onclose; ws.onmessage = ws_onmessage; } else ws.close(); } function ws_onopen() { document.getElementById("ws_state").innerHTML = "<font color='blue'>CONNECTED</font>"; document.getElementById("bt_connect").innerHTML = "Disconnect"; update_view(); } function ws_onclose() { document.getElementById("ws_state").innerHTML = "<font color='gray'>CLOSED</font>"; document.getElementById("bt_connect").innerHTML = "Connect"; ws.onopen = null; ws.onclose = null; ws.onmessage = null; ws = null; authorized = false; update_view(); } function ws_onmessage(e_msg) { e_msg = e_msg || window.event; var resp = parseInt(e_msg.data); if(resp == 202) authorized = true; else if(resp == 401) authorized = false; else console.log("unknown:" + resp); update_view(); } function update_view() { if(!authorized) unlock_update_view(); else servo_update_view(); } function unlock_update_view() { document.body.style.backgroundColor = "black"; document.body.style.color = "white"; var unlock_area = document.getElementById('unlock_area'); var control_area = document.getElementById('control_area'); unlock_area.style.display = 'block'; control_area.style.display = 'none'; var unlock = document.getElementById("unlock"); var ctx = unlock.getContext("2d"); ctx.clearRect(-unlock_width/2, -unlock_height/2, unlock_width, unlock_height); ctx.lineWidth = 10; ctx.strokeStyle="white"; ctx.globalAlpha=1; ctx.beginPath(); for (var i = 0; i < unlock_touch_list.length; i++) { var temp = unlock_touch_list[i] - 1; var x = temp % 3 - 1; var y = Math.floor(temp / 3) - 1; ctx.lineTo(x*unlock_gap, y*unlock_gap); } if(unlock_touch_state) ctx.lineTo(unlock_touch_x, unlock_touch_y); ctx.stroke(); for (var i = 0; i < unlock_touch_list.length; i++) { var temp = unlock_touch_list[i] - 1; var x = temp % 3 - 1; var y = Math.floor(temp / 3) - 1; ctx.globalAlpha=0.2; ctx.fillStyle = "white"; ctx.beginPath(); ctx.arc(x*unlock_gap, y*unlock_gap, unlock_outer_radius, 0, 2 * Math.PI); ctx.fill(); } for(var y = -1; y <= 1; y++) { for(var x = -1; x <= 1; x++) { ctx.globalAlpha=0.5; ctx.fillStyle = "white"; ctx.beginPath(); ctx.arc(x*unlock_gap, y*unlock_gap, unlock_middle_radius, 0, 2 * Math.PI); ctx.fill(); ctx.globalAlpha=1; ctx.fillStyle = "Cyan"; ctx.beginPath(); ctx.arc(x*unlock_gap, y*unlock_gap, unlock_inner_radius, 0, 2 * Math.PI); ctx.fill(); } } } function unlock_process_event(event) { if(event.offsetX) { unlock_touch_x = event.offsetX - unlock_width/2; unlock_touch_y = event.offsetY - unlock_height/2; } else if(event.layerX) { unlock_touch_x = event.layerX - unlock_width/2; unlock_touch_y = event.layerY - unlock_height/2; } else { unlock_touch_x = (Math.round(event.touches[0].pageX - event.touches[0].target.offsetLeft)) - unlock_width/2; unlock_touch_y = (Math.round(event.touches[0].pageY - event.touches[0].target.offsetTop)) - unlock_height/2; } for(var i = 1; i <= 9; i++) { if(i == unlock_touch_list[unlock_touch_list.length - 1]) continue; var idx_x = (i-1)%3 - 1; var idx_y = Math.floor((i-1)/3) - 1; var center_x = idx_x*unlock_gap; var center_y = idx_y*unlock_gap; var dist = Math.sqrt( (unlock_touch_x - center_x)*(unlock_touch_x - center_x) + (unlock_touch_y - center_y)*(unlock_touch_y - center_y) ); if(dist < unlock_outer_radius) { unlock_touch_list.push(i); unlock_touch_state = 1; break; } } update_view(); } function unlock_mouse_down() { if(ws == null || authorized) return; event.preventDefault(); unlock_process_event(event); } function unlock_mouse_up() { if(ws == null || authorized) return; event.preventDefault(); if(ws != null && authorized == false) send_to_Arduino(CMD_AUTH, unlock_touch_list.toString()); unlock_touch_state = 0; unlock_touch_list.splice(0, unlock_touch_list.length); update_view(); } function unlock_mouse_move() { if(ws == null || authorized) return; event.preventDefault(); if(authorized) return; unlock_process_event(event); } function servo_update_view() { document.body.style.backgroundColor = "white"; document.body.style.color = "black"; var unlock_area = document.getElementById('unlock_area'); var control_area = document.getElementById('control_area'); unlock_area.style.display = 'none'; control_area.style.display = 'block'; var servo = document.getElementById("servo"); var ctx = servo.getContext("2d"); ctx.clearRect(-servo_pivot_x, -servo_pivot_y, servo_width, servo_height); ctx.rotate(servo_bracket_angle / 180 * Math.PI); ctx.drawImage(servo_bracket_img, -servo_pivot_x, -servo_pivot_y); ctx.rotate(-servo_bracket_angle / 180 * Math.PI); } function check_range_xyra(event, servo_mouse_xyra) { var x, y, r, a, rc_x, rc_y, radian; var min_r, max_r, width; if(event.touches) { var touches = event.touches; x = (touches[0].pageX - touches[0].target.offsetLeft) - servo_pivot_x; y = servo_pivot_y - (touches[0].pageY - touches[0].target.offsetTop); min_r = 60; max_r = servo_pivot_x; width = 40; } else { x = event.offsetX - servo_pivot_x; y = servo_pivot_y - event.offsetY; min_r = 60; max_r = servo_bracket_radius; width = 20; } r = Math.sqrt(x * x + y * y); a = Math.atan2(y, x); servo_mouse_xyra.x = x; servo_mouse_xyra.y = y; servo_mouse_xyra.r = r; servo_mouse_xyra.a = a; radian = servo_bracket_angle / 180 * Math.PI; rc_x = x * Math.cos(radian) - y * Math.sin(radian); rc_y = x * Math.sin(radian) + y * Math.cos(radian); if((r < min_r) || (r > max_r)) return false; if((rc_y < -width) || (rc_y > width)) return false; return true; } function servo_mouse_down() { if(event.touches && (event.touches.length > 1)) servo_click_state = event.touches.length; if(servo_click_state > 1) return; if(check_range_xyra(event, servo_mouse_xyra)) { servo_click_state = 1; servo_last_angle = servo_mouse_xyra.a / Math.PI * 180.0; } } function servo_mouse_up() { servo_click_state = 0; } function servo_mouse_move() { var angle; if(event.touches && (event.touches.length > 1)) servo_click_state = event.touches.length; if(servo_click_state > 1) return; if(!servo_click_state) return; if(!check_range_xyra(event, servo_mouse_xyra)) { servo_click_state = 0; return; } angle = servo_mouse_xyra.a / Math.PI * 180.0; if((Math.abs(angle) > 90) && (angle * servo_last_angle < 0)) { if(servo_last_angle > 0) servo_last_angle = -180; else servo_last_angle = 180; } servo_bracket_angle += (servo_last_angle - angle); servo_last_angle = angle; if(servo_bracket_angle > 90) servo_bracket_angle = 90; if(servo_bracket_angle < -90) servo_bracket_angle = -90; servo_update_view(); send_to_Arduino(CMD_CTRL, Math.floor(servo_bracket_angle)) debug = document.getElementById("debug"); debug.innerHTML = Math.floor(servo_bracket_angle); event.preventDefault(); } function send_to_Arduino(cmd, data) { if(ws.readyState == 1) { ws.send(cmd + ":" + data + "\r\n"); } } window.onload = init; </script> </head> <body> <p> <h1>Arduino - Web Pattern Unlock</h1> </p> <div id="unlock_area" style="display:block;"> <canvas id="unlock"></canvas> </div> <div id="control_area" style="display:none;"> <canvas id="servo"></canvas> <p>Angle : <span id="debug">0</span></p> </div> <h2> <p>WebSocket : <span id="ws_state">null</span></p> <button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button> </h2> </body> </html> 
ArduinoUnlockExampleArduino
/* arduino web server - pattern unlock */ #include "SPI.h" #include "Phpoc.h" #include <Servo.h> #define CMD_AUTH 0 #define CMD_CTRL 1 #define ACCEPTED "202" #define UNAUTHORIZED "401" PhpocServer server(80); Servo servo; String pattern; bool authenticated; unsigned long timeout; unsigned long lastActiveTime; void setup() { Serial.begin(9600); while(!Serial) ; Phpoc.begin(PF_LOG_SPI | PF_LOG_NET); server.beginWebSocket("web_pattern"); Serial.print("WebSocket server address : "); Serial.println(Phpoc.localIP()); servo.attach(8); servo.write(90); pattern = String("1,4,8,6,3"); authenticated = false; timeout = 10000; lastActiveTime = 0; } void loop() { PhpocClient client = server.available(); if (client) { String data = client.readLine(); if(data) { int pos = data.indexOf(':'); int cmd = data.substring(0, pos).toInt(); if(cmd == CMD_AUTH) { String reqPattern = data.substring(pos+1); reqPattern.remove(reqPattern.indexOf(13)); reqPattern.remove(reqPattern.indexOf(10)); if(pattern.equals(reqPattern)) { authenticated = true; sendResponse(ACCEPTED, 3); lastActiveTime = millis(); } else { authenticated = false; sendResponse(UNAUTHORIZED, 3); } } else if(cmd == CMD_CTRL) { if(authenticated) { int angle = data.substring(pos+1).toInt(); angle = map(angle, 90, -90, 0, 180); servo.write(angle); lastActiveTime = millis(); Serial.println(angle); } else { sendResponse(UNAUTHORIZED, 3); } } } } if (authenticated && ((millis() - lastActiveTime) > timeout)){ authenticated = false; sendResponse(UNAUTHORIZED, 3); } } void sendResponse(char *data, int len) { server.write(data, len); } 

Skematik

Amankan Arduino dengan Pola Unlock Web – Pengaturan Mudah dan Kendali Jarak Jauh

Proses manufaktur

  1. Evolusi dan Produksi Pola Pakaian Massal
  2. Sistem Pencahayaan DMX Dikonrol Web – Kontroler Master Arduino
  3. Membuat Spybot Arduino yang Dikontrol melalui Bluetooth
  4. FlickMote: Remote IR Kendali Gestur untuk Rumah Cerdas
  5. DIY Arduino TV B-Gone: Remote Universal untuk Semua TV
  6. Bangun Jam Master LED Kustom dengan Alarm – Terlihat dari Jarak 12 Meter
  7. Find Me: Pelacak Item Cerdas dengan Arduino dan Bluetooth
  8. Solusi Daya Teroptimasi untuk Proyek Arduino
  9. Tic Tac Toe Arduino dengan Matriks LED MAX7219 dan Kotak Kardus
  10. Membuat Robot Quadruped Arduino Cerdas: Panduan Langkah demi Langkah