Components and supplies
1
PHPoC WiFi Shield for Arduino
1
Jumper wires
1
Pushbutton switch 12mm
1
Arduino UNO
1
LED (generic)
1
Rotary Angle Sensor
Project description
Code
remote_io.php
php
This is the embeded web app code. It is uploaded to PHPoC Wifi Shield (or PHPoC Shield)
1<!DOCTYPE html> 2<html> 3<head> 4<title>Arduino - PHPoC Shield</title> 5<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7"> 6<meta charset="utf-8"> 7<style> 8body { text-align: center; font-size: width/2pt; } 9h1 { font-weight: bold; font-size: width/2pt; } 10h2 { font-weight: bold; font-size: width/2pt; } 11button { font-weight: bold; font-size: width/2pt; } 12 13</style> 14<script> 15var CMD_NONE = 0x00; 16var CMD_ARDUINO_SET_MODE = 0x01; 17var CMD_ARDUINO_SET_STATE = 0x02; 18var CMD_ARDUINO_GET_MODE = 0x03; 19var CMD_ARDUINO_GET_STATE = 0x04; 20 21var CMD_WEB_UPDATE_STATE = 0x10; 22var CMD_WEB_UPDATE_MODE = 0x11; 23 24var PIN_MODE_FLAG_IO = 0x00; 25var PIN_MODE_FLAG_COMM = 0x10; // communication 26 27var PIN_MODE_INPUT = 0x00; 28var PIN_MODE_OUTPUT = 0x01; 29var PIN_MODE_ANALOG = 0x03; 30var PIN_MODE_PWM = 0x04; 31var PIN_MODE_SPI = 0x10; 32var PIN_MODE_I2C = 0x11; 33var PIN_MODE_UART = 0x12; 34 35var PIN_STATE_OFF = 0; 36var PIN_STATE_ON = 1; 37 38var canvas_width = 450, canvas_height = 500; 39var img_width = 405, img_height = 333; 40var img_ratio = 0.7; 41var arduino_img = new Image(); 42var pos_d0 = {x: 231, y: 5 }; 43var pos_d13 = {x: 130, y: 79 }; 44var pos_a0 = {x: 380, y: 107 }; 45var pos_a5 = {x: 343, y: 135 }; 46 47var pos_d_list = new Array(); 48var pos_a_list = new Array(); 49 50var canvas; 51var ctx; 52var ws = null; 53 54var pin_d_mode = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 55var pin_a_mode = [3, 3, 3, 3, 3, 3]; 56 57var pin_d_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 58var pin_a_state = [0, 0, 0, 0, 0, 0]; 59 60var X_D_POS_LEVEL_0 = 25; 61var X_D_POS_LEVEL_1 = 100; 62var X_D_POS_LEVEL_2 = 190; 63var X_D_POS_PWM_BTN = 280; 64var X_D_POS_SLIDER = 280; 65var X_A_POS_LEVEL_0; 66var X_A_POS_LEVEL_1; 67var X_A_POS_LEVEL_2; 68var X_A_POS_LEVEL_3; 69 70var Y_D_START, Y_D_END; 71var Y_A_START, Y_A_END; 72var Y_GAP; 73 74var BOX_HEIGHT = 40; 75var AN_BOX_WIDTH = 70; 76var DIO_BOX_WIDTH = 70; 77var ONOFF_BOX_WIDTH = 80; 78var STATE_BOX_WIDTH = 70; 79var PWM_WIDTH = 200; 80 81var click_state = 0; 82var mouse_xyra = {x:0, y:0, r:0.0, a:0.0}; 83 84arduino_img.src = "arduino_2.jpg"; 85 86var buffer = ""; 87 88function init() 89{ 90 var width = window.innerWidth; 91 var height = window.innerHeight; 92 93 //if(width < height) 94 ratio = (width - 50) / canvas_width; 95 //else 96 //ratio = (height - 50) / canvas_width; 97 98 canvas_width = Math.round(canvas_width*ratio); 99 canvas_height = Math.round(canvas_height*ratio); 100 101 img_width = Math.round(img_width*ratio); 102 img_height = Math.round(img_height*ratio); 103 104 img_width *= img_ratio; 105 img_height *= img_ratio; 106 107 X_A_POS_LEVEL_0 = canvas_width - X_D_POS_LEVEL_0; 108 X_A_POS_LEVEL_1 = canvas_width - X_D_POS_LEVEL_1; 109 X_A_POS_LEVEL_2 = canvas_width - X_D_POS_LEVEL_2; 110 X_A_POS_LEVEL_3 = canvas_width - 280; 111 112 for (var pin_id = 0; pin_id <= 14; pin_id++) 113 { 114 if(pin_id == 8) 115 continue; 116 117 var x = pos_d0.x + ( pos_d13.x - pos_d0.x)/ 14.0 * pin_id; 118 var y = pos_d0.y + ( pos_d13.y - pos_d0.y)/ 14.0 * pin_id;; 119 120 x = x * img_ratio * ratio + (canvas_width - img_width) / 2 - 100; 121 y = y * img_ratio * ratio + (canvas_height - img_height); 122 123 pos_d_list.push(new Array(Math.round(x), Math.round(y))); 124 } 125 126 for (var pin_id = 0; pin_id <= 5; pin_id++) 127 { 128 var x = pos_a0.x + ( pos_a5.x - pos_a0.x)/ 5.0 * pin_id; 129 var y = pos_a0.y + ( pos_a5.y - pos_a0.y)/ 5.0 * pin_id;; 130 131 x = x * img_ratio * ratio + (canvas_width - img_width) / 2 - 100; 132 y = y * img_ratio * ratio + (canvas_height - img_height); 133 134 pos_a_list.push(new Array(Math.round(x), Math.round(y))); 135 } 136 137 Y_D_START = 30; 138 Y_D_END = pos_d_list[13][1] - 20; 139 Y_GAP = Math.round((Y_D_END - Y_D_START) / 14); 140 Y_A_START = Y_D_START + 5 * Y_GAP; 141 Y_A_END = Y_D_START + 10 * Y_GAP;; 142 143 canvas = document.getElementById("canvas"); 144 ctx = canvas.getContext("2d"); 145 146 canvas.width = canvas_width; 147 canvas.height = canvas_height; 148 149 canvas.addEventListener("touchstart", mouse_down); 150 canvas.addEventListener("touchend", mouse_up); 151 canvas.addEventListener("touchmove", mouse_move); 152 canvas.addEventListener("mousedown", mouse_down); 153 canvas.addEventListener("mouseup", mouse_up); 154 canvas.addEventListener("mousemove", mouse_move); 155 156 update_view(); 157} 158function connect_onclick() 159{ 160 if(ws == null) 161 { 162 var ws_host_addr = "<?echo _SERVER("HTTP_HOST")?>"; 163 if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "[")) 164 { 165 // network resource identifier to UNC path name conversion 166 ws_host_addr = ws_host_addr.replace(/[\\[\\]]/g, ''); 167 ws_host_addr = ws_host_addr.replace(/:/g, "-"); 168 ws_host_addr += ".ipv6-literal.net"; 169 } 170 171 ws = new WebSocket("ws://" + ws_host_addr + "/arduino_io", "text.phpoc"); 172 document.getElementById("ws_state").innerHTML = "CONNECTING"; 173 ws.onopen = ws_onopen; 174 ws.onclose = ws_onclose; 175 ws.onmessage = ws_onmessage; 176 } 177 else 178 ws.close(); 179} 180function ws_onopen() 181{ 182 document.getElementById("ws_state").innerHTML = "<font color='blue'>CONNECTED</font>"; 183 document.getElementById("bt_connect").innerHTML = "Disconnect"; 184 185 setTimeout(function(){ 186 for(var pin = 0; pin <= 13; pin ++) 187 { 188 send_to_Arduino("D" + pin, CMD_ARDUINO_GET_MODE, 0); 189 send_to_Arduino("D" + pin, CMD_ARDUINO_GET_STATE, 0); 190 } 191 192 for(var pin = 0; pin <= 5; pin ++) 193 { 194 send_to_Arduino("A" + pin, CMD_ARDUINO_GET_MODE, 0); 195 send_to_Arduino("A" + pin, CMD_ARDUINO_GET_STATE, 0); 196 } 197 }, 100); 198} 199function ws_onclose() 200{ 201 document.getElementById("ws_state").innerHTML = "<font color='gray'>CLOSED</font>"; 202 document.getElementById("bt_connect").innerHTML = "Connect"; 203 ws.onopen = null; 204 ws.onclose = null; 205 ws.onmessage = null; 206 ws = null; 207 update_view(); 208} 209function ws_onmessage(e_msg) 210{ 211 e_msg = e_msg || window.event; // MessageEvent 212 213 buffer += e_msg.data; 214 buffer = buffer.replace(/\ \ 215/g, "\ 216"); 217 buffer = buffer.replace(/\ /g, "\ 218"); 219 220 while(buffer.indexOf("\ 221") == 0) 222 buffer = buffer.substr(1); 223 224 while(buffer.indexOf("\ 225") >= 0) // because may update data come at the same time 226 { 227 var str = buffer.substr(0, buffer.indexOf("\ 228")); 229 buffer = buffer.substr(buffer.indexOf("\ 230") + 1); 231 232 var arr = str.split(":"); 233 var pin = arr[0]; 234 var cmd = parseInt(arr[1]); 235 var state = arr[2]; 236 237 var pin_group = pin.charAt(0); 238 var pin_number = pin.substr(1); 239 240 if(cmd == CMD_WEB_UPDATE_MODE) 241 { 242 if(pin_group == "D") 243 pin_d_mode[pin_number] = parseInt(state); 244 else 245 if(pin_group == "A") 246 pin_a_mode[pin_number] = parseInt(state); 247 } 248 else 249 if(cmd == CMD_WEB_UPDATE_STATE) 250 { 251 if(pin_group == "D") 252 { 253 if(pin_d_mode[pin_number] == PIN_MODE_INPUT || pin_d_mode[pin_number] == PIN_MODE_OUTPUT) 254 state = parseInt(state); 255 256 pin_d_state[pin_number] = state; 257 } 258 else 259 if(pin_group == "A") 260 { 261 if(pin_a_mode[pin_number] == PIN_MODE_INPUT || pin_a_mode[pin_number] == PIN_MODE_OUTPUT) 262 state = parseInt(state); 263 264 pin_a_state[pin_number] = state; 265 } 266 } 267 } 268 269 update_view(); 270} 271function draw_pin(x, y, pin) 272{ 273 ctx.fillStyle = "#00979d"; 274 ctx.beginPath(); 275 ctx.arc(x, y, 15, 0, 2 * Math.PI); 276 ctx.fill(); 277 278 ctx.fillStyle = "white"; 279 ctx.fillText(pin, x, y); 280} 281function draw_analog_mode(x, y, mode) 282{ 283 ctx.fillStyle = "Gray"; 284 ctx.beginPath(); 285 ctx.arc(x - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 286 ctx.arc(x + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 287 ctx.fill(); 288 289 ctx.fillStyle = "DeepPink"; 290 ctx.beginPath(); 291 if(mode == PIN_MODE_ANALOG) 292 ctx.arc(x + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 293 else 294 ctx.arc(x - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2* Math.PI); 295 296 ctx.fill(); 297 298 ctx.fillStyle = "white"; 299 ctx.fillText("A", x + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y); 300 ctx.fillText("D", x - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y); 301} 302function draw_digital_mode(x, y, mode) 303{ 304 ctx.fillStyle = "Gray"; 305 ctx.beginPath(); 306 ctx.arc(x - (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 307 ctx.arc(x + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 308 ctx.fill(); 309 310 ctx.fillStyle = "red"; 311 ctx.beginPath(); 312 313 if(mode == PIN_MODE_OUTPUT) 314 ctx.arc(x + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2* Math.PI); 315 else 316 ctx.arc(x - (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 317 318 ctx.fill(); 319 320 ctx.fillStyle = "white"; 321 ctx.fillText("DI", x - (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y); 322 ctx.fillText("DO", x + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y); 323} 324function draw_on_off(x, y, state) 325{ 326 ctx.fillStyle = "Gray"; 327 ctx.beginPath(); 328 ctx.arc(x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 329 ctx.arc(x + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 330 ctx.fill(); 331 332 ctx.fillStyle = "#1E90FF"; 333 ctx.beginPath(); 334 335 if(state == PIN_STATE_ON) 336 { 337 ctx.arc(x + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2 - 5, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 338 ctx.arc(x + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 339 } 340 else 341 { 342 ctx.arc(x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 343 ctx.arc(x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2 + 5, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 344 } 345 346 ctx.fill(); 347 348 ctx.fillStyle = "white"; 349 ctx.fillText("OFF", x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y); 350 ctx.fillText("ON", x + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y); 351} 352function draw_comm(x, y, state) 353{ 354 ctx.fillStyle = "Gray"; 355 ctx.beginPath(); 356 ctx.arc(x - (STATE_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 357 ctx.arc(x + (STATE_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 358 ctx.closePath(); 359 ctx.fill(); 360 361 ctx.fillStyle = "White"; 362 ctx.fillText(state, x, y); 363} 364function draw_state(x, y, state) 365{ 366 ctx.save(); 367 ctx.strokeStyle="#1E90FF"; 368 ctx.fillStyle = "white"; 369 ctx.lineWidth = 6; 370 ctx.beginPath(); 371 ctx.arc(x - (STATE_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 372 ctx.arc(x + (STATE_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 373 ctx.closePath(); 374 ctx.fill(); 375 ctx.stroke(); 376 377 ctx.fillStyle = "#1E90FF"; 378 ctx.fillText(state, x, y); 379 ctx.restore(); 380} 381function draw_pwm_button(x, y, state) 382{ 383 if(state == "PWM") 384 ctx.fillStyle = "#FFA500"; 385 else 386 ctx.fillStyle = "red"; 387 388 ctx.beginPath(); 389 ctx.arc(x, y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 390 ctx.closePath(); 391 ctx.fill(); 392 393 ctx.fillStyle = "White"; 394 ctx.fillText(state, x, y); 395} 396function draw_slider(x, y, value) 397{ 398 ctx.save(); 399 ctx.strokeStyle="#1E90FF"; 400 ctx.lineWidth = 12; 401 ctx.beginPath(); 402 ctx.lineTo(x - PWM_WIDTH / 2, y + 0.5); 403 ctx.lineTo(x + PWM_WIDTH / 2, y + 0.5); 404 ctx.stroke(); 405 406 x = x - PWM_WIDTH / 2 + value * PWM_WIDTH / 255; 407 ctx.fillStyle = "#FF4500"; 408 ctx.beginPath(); 409 ctx.arc(x , y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 410 ctx.fill(); 411 ctx.restore(); 412} 413function update_view() 414{ 415 ctx.clearRect(0, 0, canvas_width, canvas_height); 416 ctx.drawImage(arduino_img, (canvas_width - img_width) / 2 - 100, canvas_height - img_height, img_width, img_height); 417 418 ctx.lineWidth = 3; 419 ctx.strokeStyle="gray"; 420 ctx.globalAlpha=1; 421 ctx.font="bold 16px Arial"; 422 ctx.textBaseline="middle"; 423 ctx.textAlign="center"; 424 425 for (var pin_id = 0; pin_id <= 13; pin_id++) 426 { 427 ctx.fillStyle = "DeepPink"; 428 ctx.beginPath(); 429 ctx.arc(pos_d_list[pin_id][0] + 0.5, pos_d_list[pin_id][1] + 0.5, 4, 0, 2 * Math.PI); 430 ctx.fill(); 431 432 var x, y; 433 434 x = 0; 435 436 if(pin_id < 8) 437 y = Y_D_START + pin_id * Y_GAP; 438 else 439 y = Y_D_START + (pin_id + 1) * Y_GAP; 440 441 ctx.beginPath(); 442 ctx.lineTo(x + 0.5, y + 0.5); 443 ctx.lineTo(pos_d_list[pin_id][0] + 0.5, y + 0.5); 444 ctx.lineTo(pos_d_list[pin_id][0] + 0.5, pos_d_list[pin_id][1] + 0.5); 445 ctx.stroke(); 446 447 draw_pin(X_D_POS_LEVEL_0, y, "D" + pin_id.toString()); 448 449 if(pin_d_mode[pin_id] & PIN_MODE_FLAG_COMM) 450 { 451 if(pin_d_mode[pin_id] == PIN_MODE_UART) 452 draw_comm(X_D_POS_LEVEL_1, y, "UART"); 453 else 454 if(pin_d_mode[pin_id] == PIN_MODE_SPI) 455 draw_comm(X_D_POS_LEVEL_1, y, "SPI"); 456 else 457 if(pin_d_mode[pin_id] == PIN_MODE_I2C) 458 draw_comm(X_D_POS_LEVEL_1, y, "I2C"); 459 460 draw_state(X_D_POS_LEVEL_2, y, pin_d_state[pin_id]); 461 continue; 462 } 463 464 if(pin_d_mode[pin_id] == PIN_MODE_PWM) 465 { 466 draw_pwm_button(X_D_POS_LEVEL_1, y, "I/O") 467 draw_slider(X_D_POS_PWM_BTN, y, pin_d_state[pin_id]); 468 } 469 else 470 { 471 draw_digital_mode(X_D_POS_LEVEL_1, y, pin_d_mode[pin_id]); 472 473 if(pin_d_mode[pin_id] == PIN_MODE_OUTPUT) 474 draw_on_off(X_D_POS_LEVEL_2, y, pin_d_state[pin_id]) 475 else 476 { 477 if(pin_d_state[pin_id] == PIN_STATE_ON) 478 draw_state(X_D_POS_LEVEL_2, y, "ON"); 479 else 480 draw_state(X_D_POS_LEVEL_2, y, "OFF"); 481 } 482 483 if(pin_id == 3 || pin_id == 5 || pin_id == 6 || pin_id == 9 ) 484 draw_pwm_button(X_D_POS_PWM_BTN, y, "PWM") 485 } 486 } 487 488 for (var pin_id = 0; pin_id <= 5; pin_id++) 489 { 490 ctx.fillStyle = "DeepPink"; 491 ctx.beginPath(); 492 ctx.arc(pos_a_list[pin_id][0] + 0.5, pos_a_list[pin_id][1] + 0.5, 4, 0, 2 * Math.PI); 493 ctx.fill(); 494 495 var x, y; 496 497 x = canvas_width; 498 y = Y_A_END - pin_id * Y_GAP; 499 500 ctx.beginPath(); 501 ctx.lineTo(x + 0.5, y + 0.5); 502 ctx.lineTo(pos_a_list[pin_id][0] + 0.5, y + 0.5); 503 ctx.lineTo(pos_a_list[pin_id][0] + 0.5, pos_a_list[pin_id][1] + 0.5); 504 ctx.stroke(); 505 506 draw_pin(X_A_POS_LEVEL_0, y, "A" + pin_id.toString()); 507 draw_analog_mode(X_A_POS_LEVEL_1, y, pin_a_mode[pin_id]); 508 509 if(pin_a_mode[pin_id] == PIN_MODE_ANALOG) 510 draw_state(X_A_POS_LEVEL_2, y, pin_a_state[pin_id]); 511 else 512 { 513 draw_digital_mode(X_A_POS_LEVEL_2, y, pin_a_mode[pin_id]); 514 515 if(pin_a_mode[pin_id] == PIN_MODE_OUTPUT) 516 draw_on_off(X_A_POS_LEVEL_3, y, pin_a_state[pin_id]) 517 else 518 { 519 if(pin_a_state[pin_id] == PIN_STATE_ON) 520 draw_state(X_A_POS_LEVEL_3, y, "ON"); 521 else 522 draw_state(X_A_POS_LEVEL_3, y, "OFF"); 523 } 524 } 525 } 526} 527function process_event(event) 528{ 529 if(event.offsetX) 530 { 531 touch_x = event.offsetX; 532 touch_y = event.offsetY; 533 } 534 else if(event.layerX) 535 { 536 touch_x = event.layerX; 537 touch_y = event.layerY; 538 } 539 else 540 { 541 touch_x = Math.round(event.touches[0].pageX - event.touches[0].target.offsetLeft); 542 touch_y = Math.round(event.touches[0].pageY - event.touches[0].target.offsetTop); 543 } 544 545 var pin; 546 var cmd = CMD_NONE; 547 var state = 0; 548 549 var offset = (touch_y - Y_D_START) % Y_GAP; 550 var pin_id = Math.round((touch_y - Y_D_START - offset) / Y_GAP); 551 552 if((offset < BOX_HEIGHT / 2) || (offset > (Y_GAP - BOX_HEIGHT / 2) && offset < Y_GAP)) 553 { 554 if(offset > (Y_GAP - BOX_HEIGHT / 2) && offset < Y_GAP) 555 pin_id++; 556 557 if(touch_x < (canvas_width / 2)) 558 { 559 if(pin_id > 7) 560 pin_id--; 561 562 if(pin_id < 0 || pin_id > 13) 563 return; 564 565 if(pin_d_mode[pin_id] & PIN_MODE_FLAG_COMM) 566 return; 567 568 if(pin_d_mode[pin_id] != PIN_MODE_PWM) 569 { 570 if(event_type == "move") 571 return; 572 573 if( touch_x > (X_D_POS_LEVEL_1 - DIO_BOX_WIDTH / 2) && touch_x < (X_D_POS_LEVEL_1 + DIO_BOX_WIDTH / 2)) 574 { 575 pin_d_mode[pin_id] = (pin_d_mode[pin_id] + 1) % 2; 576 cmd = CMD_ARDUINO_SET_MODE; 577 state = pin_d_mode[pin_id]; 578 } 579 else 580 if( touch_x > (X_D_POS_LEVEL_2 - ONOFF_BOX_WIDTH / 2) && touch_x < (X_D_POS_LEVEL_2 + ONOFF_BOX_WIDTH / 2)) 581 { 582 if(pin_d_mode[pin_id] == PIN_MODE_OUTPUT) 583 { 584 pin_d_state[pin_id] = (pin_d_state[pin_id] + 1) % 2; 585 cmd = CMD_ARDUINO_SET_STATE; 586 state = pin_d_state[pin_id]; 587 } 588 } 589 else 590 if( touch_x > (X_D_POS_PWM_BTN - BOX_HEIGHT / 2) && touch_x < (X_D_POS_PWM_BTN + BOX_HEIGHT / 2)) 591 { 592 pin_d_mode[pin_id] = PIN_MODE_PWM; 593 pin_d_state[pin_id] = 0; 594 cmd = CMD_ARDUINO_SET_MODE; 595 state = pin_d_mode[pin_id]; 596 } 597 } 598 else 599 { 600 if( touch_x > (X_D_POS_LEVEL_1 - BOX_HEIGHT / 2) && touch_x < (X_D_POS_LEVEL_1 + BOX_HEIGHT / 2)) 601 { 602 if(event_type == "move") 603 return; 604 605 pin_d_mode[pin_id] = PIN_MODE_OUTPUT; 606 pin_d_state[pin_id] = 0; 607 cmd = CMD_ARDUINO_SET_MODE; 608 state = pin_d_mode[pin_id]; 609 } 610 else 611 { 612 var x_slider = X_D_POS_SLIDER - PWM_WIDTH / 2 + pin_d_state[pin_id] * PWM_WIDTH / 255; 613 if( touch_x > (x_slider - PWM_WIDTH / 2) && touch_x < (x_slider + PWM_WIDTH / 2)) 614 { 615 state = (touch_x - (X_D_POS_SLIDER - PWM_WIDTH / 2 )) / PWM_WIDTH * 255; 616 617 if(state >= 0 && state <= 255) 618 { 619 pin_d_state[pin_id] = Math.round(state); 620 cmd = CMD_ARDUINO_SET_STATE; 621 } 622 } 623 } 624 } 625 626 pin = "D" + pin_id; 627 } 628 else 629 { 630 if(event_type == "move") 631 return; 632 633 pin_id -= 5; 634 635 if(pin_id < 0 || pin_id > 5) 636 return; 637 638 pin_id = 5 - pin_id; 639 640 if( touch_x > (X_A_POS_LEVEL_1 - AN_BOX_WIDTH / 2) && touch_x < (X_A_POS_LEVEL_1 + AN_BOX_WIDTH / 2)) 641 { 642 if(pin_a_mode[pin_id] == PIN_MODE_ANALOG) 643 { 644 pin_a_mode[pin_id] = PIN_MODE_INPUT; 645 pin_a_state[pin_id] = PIN_STATE_OFF; 646 } 647 else 648 { 649 pin_a_mode[pin_id] = PIN_MODE_ANALOG; 650 pin_a_state[pin_id] = 0; 651 } 652 653 cmd = CMD_ARDUINO_SET_MODE; 654 state = pin_a_mode[pin_id]; 655 } 656 else 657 if( touch_x > (X_A_POS_LEVEL_2 - DIO_BOX_WIDTH / 2) && touch_x < (X_A_POS_LEVEL_2 + DIO_BOX_WIDTH / 2)) 658 { 659 if(pin_a_mode[pin_id] != PIN_MODE_ANALOG) 660 { 661 pin_a_mode[pin_id] = (pin_a_mode[pin_id] + 1) % 2; 662 cmd = CMD_ARDUINO_SET_MODE; 663 state = pin_a_mode[pin_id]; 664 } 665 } 666 else 667 if( touch_x > (X_A_POS_LEVEL_3 - ONOFF_BOX_WIDTH / 2) && touch_x < (X_A_POS_LEVEL_3 + ONOFF_BOX_WIDTH / 2)) 668 { 669 if(pin_a_mode[pin_id] == PIN_MODE_OUTPUT) 670 { 671 pin_a_state[pin_id] = (pin_a_state[pin_id] + 1) % 2; 672 cmd = CMD_ARDUINO_SET_STATE; 673 state = pin_a_state[pin_id]; 674 } 675 } 676 677 pin = "A" + pin_id; 678 } 679 } 680 681 if(cmd != CMD_NONE) 682 { 683 update_view(); 684 send_to_Arduino(pin, cmd, state); 685 } 686} 687function mouse_down() 688{ 689 //if(ws == null || authorized) 690 //return; 691 692 event.preventDefault(); 693 event_type = "down"; 694 process_event(event); 695} 696function mouse_up() 697{ 698 event.preventDefault(); 699 700 //if(ws != null && authorized == false) 701 //send_to_Arduino(CMD_AUTH, touch_list.toString()); 702 703 event_type = "up"; 704 update_view(); 705} 706function mouse_move() 707{ 708 event.preventDefault(); 709 710 event_type = "move"; 711 process_event(event); 712} 713 714function send_to_Arduino(pin, cmd, state) 715{ 716 if(ws.readyState == 1) 717 { 718 ws.send(pin + ":" + cmd + ":" + state + "\ \ 719"); 720 console.log("send data:" + pin + ":" + cmd + ":" + state); 721 } 722} 723 724window.onload = init; 725</script> 726</head> 727 728<body> 729 730<p> 731</p> 732<canvas id="canvas"></canvas> 733<h2> 734<p>WebSocket : <span id="ws_state">null</span></p> 735<button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button> 736</h2> 737 738</body> 739</html>
remote_io.php
php
This is the embeded web app code. It is uploaded to PHPoC Wifi Shield (or PHPoC Shield)
1<!DOCTYPE html> 2<html> 3<head> 4<title>Arduino - PHPoC Shield</title> 5<meta 6 name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7"> 7<meta 8 charset="utf-8"> 9<style> 10body { text-align: center; font-size: width/2pt; 11 } 12h1 { font-weight: bold; font-size: width/2pt; } 13h2 { font-weight: bold; 14 font-size: width/2pt; } 15button { font-weight: bold; font-size: width/2pt; } 16 17</style> 18<script> 19var 20 CMD_NONE = 0x00; 21var CMD_ARDUINO_SET_MODE = 0x01; 22var CMD_ARDUINO_SET_STATE = 23 0x02; 24var CMD_ARDUINO_GET_MODE = 0x03; 25var CMD_ARDUINO_GET_STATE = 0x04; 26 27var 28 CMD_WEB_UPDATE_STATE = 0x10; 29var CMD_WEB_UPDATE_MODE = 0x11; 30 31var PIN_MODE_FLAG_IO = 32 0x00; 33var PIN_MODE_FLAG_COMM = 0x10; // communication 34 35var PIN_MODE_INPUT = 36 0x00; 37var PIN_MODE_OUTPUT = 0x01; 38var PIN_MODE_ANALOG = 0x03; 39var PIN_MODE_PWM = 40 0x04; 41var PIN_MODE_SPI = 0x10; 42var PIN_MODE_I2C = 0x11; 43var PIN_MODE_UART = 44 0x12; 45 46var PIN_STATE_OFF = 0; 47var PIN_STATE_ON = 1; 48 49var canvas_width 50 = 450, canvas_height = 500; 51var img_width = 405, img_height = 333; 52var img_ratio 53 = 0.7; 54var arduino_img = new Image(); 55var pos_d0 = {x: 231, y: 5 }; 56var 57 pos_d13 = {x: 130, y: 79 }; 58var pos_a0 = {x: 380, y: 107 }; 59var pos_a5 = 60 {x: 343, y: 135 }; 61 62var pos_d_list = new Array(); 63var pos_a_list = new 64 Array(); 65 66var canvas; 67var ctx; 68var ws = null; 69 70var pin_d_mode 71 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 72var pin_a_mode = [3, 3, 3, 3, 3, 73 3]; 74 75var pin_d_state = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; 76var 77 pin_a_state = [0, 0, 0, 0, 0, 0]; 78 79var X_D_POS_LEVEL_0 = 25; 80var X_D_POS_LEVEL_1 81 = 100; 82var X_D_POS_LEVEL_2 = 190; 83var X_D_POS_PWM_BTN = 280; 84var X_D_POS_SLIDER = 85 280; 86var X_A_POS_LEVEL_0; 87var X_A_POS_LEVEL_1; 88var X_A_POS_LEVEL_2; 89var 90 X_A_POS_LEVEL_3; 91 92var Y_D_START, Y_D_END; 93var Y_A_START, Y_A_END; 94var 95 Y_GAP; 96 97var BOX_HEIGHT = 40; 98var AN_BOX_WIDTH = 70; 99var DIO_BOX_WIDTH = 100 70; 101var ONOFF_BOX_WIDTH = 80; 102var STATE_BOX_WIDTH = 70; 103var PWM_WIDTH 104 = 200; 105 106var click_state = 0; 107var mouse_xyra = {x:0, y:0, r:0.0, a:0.0}; 108 109arduino_img.src 110 = "arduino_2.jpg"; 111 112var buffer = ""; 113 114function init() 115{ 116 var 117 width = window.innerWidth; 118 var height = window.innerHeight; 119 120 //if(width 121 < height) 122 ratio = (width - 50) / canvas_width; 123 //else 124 //ratio 125 = (height - 50) / canvas_width; 126 127 canvas_width = Math.round(canvas_width*ratio); 128 canvas_height 129 = Math.round(canvas_height*ratio); 130 131 img_width = Math.round(img_width*ratio); 132 img_height 133 = Math.round(img_height*ratio); 134 135 img_width *= img_ratio; 136 img_height 137 *= img_ratio; 138 139 X_A_POS_LEVEL_0 = canvas_width - X_D_POS_LEVEL_0; 140 X_A_POS_LEVEL_1 141 = canvas_width - X_D_POS_LEVEL_1; 142 X_A_POS_LEVEL_2 = canvas_width - X_D_POS_LEVEL_2; 143 X_A_POS_LEVEL_3 144 = canvas_width - 280; 145 146 for (var pin_id = 0; pin_id <= 14; pin_id++) 147 { 148 149 if(pin_id == 8) 150 continue; 151 152 var x = pos_d0.x + ( pos_d13.x 153 - pos_d0.x)/ 14.0 * pin_id; 154 var y = pos_d0.y + ( pos_d13.y - pos_d0.y)/ 155 14.0 * pin_id;; 156 157 x = x * img_ratio * ratio + (canvas_width - img_width) 158 / 2 - 100; 159 y = y * img_ratio * ratio + (canvas_height - img_height); 160 161 pos_d_list.push(new 162 Array(Math.round(x), Math.round(y))); 163 } 164 165 for (var pin_id = 0; pin_id 166 <= 5; pin_id++) 167 { 168 var x = pos_a0.x + ( pos_a5.x - pos_a0.x)/ 5.0 169 * pin_id; 170 var y = pos_a0.y + ( pos_a5.y - pos_a0.y)/ 5.0 * pin_id;; 171 172 x 173 = x * img_ratio * ratio + (canvas_width - img_width) / 2 - 100; 174 y = y * img_ratio 175 * ratio + (canvas_height - img_height); 176 177 pos_a_list.push(new Array(Math.round(x), 178 Math.round(y))); 179 } 180 181 Y_D_START = 30; 182 Y_D_END = pos_d_list[13][1] 183 - 20; 184 Y_GAP = Math.round((Y_D_END - Y_D_START) / 14); 185 Y_A_START = 186 Y_D_START + 5 * Y_GAP; 187 Y_A_END = Y_D_START + 10 * Y_GAP;; 188 189 canvas 190 = document.getElementById("canvas"); 191 ctx = canvas.getContext("2d"); 192 193 canvas.width 194 = canvas_width; 195 canvas.height = canvas_height; 196 197 canvas.addEventListener("touchstart", 198 mouse_down); 199 canvas.addEventListener("touchend", mouse_up); 200 canvas.addEventListener("touchmove", 201 mouse_move); 202 canvas.addEventListener("mousedown", mouse_down); 203 canvas.addEventListener("mouseup", 204 mouse_up); 205 canvas.addEventListener("mousemove", mouse_move); 206 207 update_view(); 208} 209function 210 connect_onclick() 211{ 212 if(ws == null) 213 { 214 var ws_host_addr = "<?echo 215 _SERVER("HTTP_HOST")?>"; 216 if((navigator.platform.indexOf("Win") != -1) 217 && (ws_host_addr.charAt(0) == "[")) 218 { 219 // network resource identifier 220 to UNC path name conversion 221 ws_host_addr = ws_host_addr.replace(/[\\[\\]]/g, 222 ''); 223 ws_host_addr = ws_host_addr.replace(/:/g, "-"); 224 ws_host_addr 225 += ".ipv6-literal.net"; 226 } 227 228 ws = new WebSocket("ws://" + 229 ws_host_addr + "/arduino_io", "text.phpoc"); 230 document.getElementById("ws_state").innerHTML 231 = "CONNECTING"; 232 ws.onopen = ws_onopen; 233 ws.onclose = ws_onclose; 234 ws.onmessage 235 = ws_onmessage; 236 } 237 else 238 ws.close(); 239} 240function ws_onopen() 241{ 242 document.getElementById("ws_state").innerHTML 243 = "<font color='blue'>CONNECTED</font>"; 244 document.getElementById("bt_connect").innerHTML 245 = "Disconnect"; 246 247 setTimeout(function(){ 248 for(var pin = 0; pin 249 <= 13; pin ++) 250 { 251 send_to_Arduino("D" + pin, CMD_ARDUINO_GET_MODE, 252 0); 253 send_to_Arduino("D" + pin, CMD_ARDUINO_GET_STATE, 0); 254 } 255 256 for(var 257 pin = 0; pin <= 5; pin ++) 258 { 259 send_to_Arduino("A" + pin, CMD_ARDUINO_GET_MODE, 260 0); 261 send_to_Arduino("A" + pin, CMD_ARDUINO_GET_STATE, 0); 262 } 263 }, 264 100); 265} 266function ws_onclose() 267{ 268 document.getElementById("ws_state").innerHTML 269 = "<font color='gray'>CLOSED</font>"; 270 document.getElementById("bt_connect").innerHTML 271 = "Connect"; 272 ws.onopen = null; 273 ws.onclose = null; 274 ws.onmessage 275 = null; 276 ws = null; 277 update_view(); 278} 279function ws_onmessage(e_msg) 280{ 281 e_msg 282 = e_msg || window.event; // MessageEvent 283 284 buffer += e_msg.data; 285 buffer 286 = buffer.replace(/\ \ 287/g, "\ 288"); 289 buffer = buffer.replace(/\ /g, "\ 290"); 291 292 while(buffer.indexOf("\ 293") 294 == 0) 295 buffer = buffer.substr(1); 296 297 while(buffer.indexOf("\ 298") 299 >= 0) // because may update data come at the same time 300 { 301 var str = 302 buffer.substr(0, buffer.indexOf("\ 303")); 304 buffer = buffer.substr(buffer.indexOf("\ 305") 306 + 1); 307 308 var arr = str.split(":"); 309 var pin = arr[0]; 310 var 311 cmd = parseInt(arr[1]); 312 var state = arr[2]; 313 314 var pin_group 315 = pin.charAt(0); 316 var pin_number = pin.substr(1); 317 318 if(cmd == 319 CMD_WEB_UPDATE_MODE) 320 { 321 if(pin_group == "D") 322 pin_d_mode[pin_number] = 323 parseInt(state); 324 else 325 if(pin_group == "A") 326 pin_a_mode[pin_number] = 327 parseInt(state); 328 } 329 else 330 if(cmd == CMD_WEB_UPDATE_STATE) 331 { 332 if(pin_group 333 == "D") 334 { 335 if(pin_d_mode[pin_number] == PIN_MODE_INPUT || pin_d_mode[pin_number] 336 == PIN_MODE_OUTPUT) 337 state = parseInt(state); 338 339 pin_d_state[pin_number] = 340 state; 341 } 342 else 343 if(pin_group == "A") 344 { 345 if(pin_a_mode[pin_number] 346 == PIN_MODE_INPUT || pin_a_mode[pin_number] == PIN_MODE_OUTPUT) 347 state 348 = parseInt(state); 349 350 pin_a_state[pin_number] = state; 351 } 352 } 353 } 354 355 update_view(); 356} 357function 358 draw_pin(x, y, pin) 359{ 360 ctx.fillStyle = "#00979d"; 361 ctx.beginPath(); 362 ctx.arc(x, 363 y, 15, 0, 2 * Math.PI); 364 ctx.fill(); 365 366 ctx.fillStyle = "white"; 367 ctx.fillText(pin, 368 x, y); 369} 370function draw_analog_mode(x, y, mode) 371{ 372 ctx.fillStyle = "Gray"; 373 ctx.beginPath(); 374 ctx.arc(x 375 - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 376 ctx.arc(x 377 + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 378 ctx.fill(); 379 380 ctx.fillStyle 381 = "DeepPink"; 382 ctx.beginPath(); 383 if(mode == PIN_MODE_ANALOG) 384 ctx.arc(x 385 + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 386 else 387 ctx.arc(x 388 - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2* Math.PI); 389 390 ctx.fill(); 391 392 ctx.fillStyle 393 = "white"; 394 ctx.fillText("A", x + (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y); 395 ctx.fillText("D", 396 x - (AN_BOX_WIDTH - BOX_HEIGHT) / 2, y); 397} 398function draw_digital_mode(x, y, 399 mode) 400{ 401 ctx.fillStyle = "Gray"; 402 ctx.beginPath(); 403 ctx.arc(x - 404 (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 405 ctx.arc(x 406 + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 407 ctx.fill(); 408 409 ctx.fillStyle 410 = "red"; 411 ctx.beginPath(); 412 413 if(mode == PIN_MODE_OUTPUT) 414 ctx.arc(x 415 + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2* Math.PI); 416 else 417 ctx.arc(x 418 - (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 419 420 ctx.fill(); 421 422 ctx.fillStyle 423 = "white"; 424 ctx.fillText("DI", x - (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y); 425 ctx.fillText("DO", 426 x + (DIO_BOX_WIDTH - BOX_HEIGHT) / 2, y); 427} 428function draw_on_off(x, y, state) 429{ 430 ctx.fillStyle 431 = "Gray"; 432 ctx.beginPath(); 433 ctx.arc(x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) 434 / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 435 ctx.arc(x + (ONOFF_BOX_WIDTH 436 - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 437 ctx.fill(); 438 439 ctx.fillStyle 440 = "#1E90FF"; 441 ctx.beginPath(); 442 443 if(state == PIN_STATE_ON) 444 { 445 ctx.arc(x 446 + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2 - 5, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 447 * Math.PI); 448 ctx.arc(x + (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT 449 / 2, 1.5 * Math.PI, 0.5 * Math.PI); 450 } 451 else 452 { 453 ctx.arc(x - (ONOFF_BOX_WIDTH 454 - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 455 ctx.arc(x 456 - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2 + 5, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 457 * Math.PI); 458 } 459 460 ctx.fill(); 461 462 ctx.fillStyle = "white"; 463 ctx.fillText("OFF", 464 x - (ONOFF_BOX_WIDTH - BOX_HEIGHT) / 2, y); 465 ctx.fillText("ON", x + (ONOFF_BOX_WIDTH 466 - BOX_HEIGHT) / 2, y); 467} 468function draw_comm(x, y, state) 469{ 470 ctx.fillStyle 471 = "Gray"; 472 ctx.beginPath(); 473 ctx.arc(x - (STATE_BOX_WIDTH - BOX_HEIGHT) 474 / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 475 ctx.arc(x + (STATE_BOX_WIDTH 476 - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 477 ctx.closePath(); 478 ctx.fill(); 479 480 ctx.fillStyle 481 = "White"; 482 ctx.fillText(state, x, y); 483} 484function draw_state(x, y, state) 485{ 486 ctx.save(); 487 ctx.strokeStyle="#1E90FF"; 488 ctx.fillStyle 489 = "white"; 490 ctx.lineWidth = 6; 491 ctx.beginPath(); 492 ctx.arc(x - (STATE_BOX_WIDTH 493 - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 0.5 * Math.PI, 1.5 * Math.PI); 494 ctx.arc(x 495 + (STATE_BOX_WIDTH - BOX_HEIGHT) / 2, y, BOX_HEIGHT / 2, 1.5 * Math.PI, 0.5 * Math.PI); 496 ctx.closePath(); 497 ctx.fill(); 498 ctx.stroke(); 499 500 ctx.fillStyle 501 = "#1E90FF"; 502 ctx.fillText(state, x, y); 503 ctx.restore(); 504} 505function 506 draw_pwm_button(x, y, state) 507{ 508 if(state == "PWM") 509 ctx.fillStyle 510 = "#FFA500"; 511 else 512 ctx.fillStyle = "red"; 513 514 ctx.beginPath(); 515 ctx.arc(x, 516 y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 517 ctx.closePath(); 518 ctx.fill(); 519 520 ctx.fillStyle 521 = "White"; 522 ctx.fillText(state, x, y); 523} 524function draw_slider(x, y, 525 value) 526{ 527 ctx.save(); 528 ctx.strokeStyle="#1E90FF"; 529 ctx.lineWidth 530 = 12; 531 ctx.beginPath(); 532 ctx.lineTo(x - PWM_WIDTH / 2, y + 0.5); 533 ctx.lineTo(x 534 + PWM_WIDTH / 2, y + 0.5); 535 ctx.stroke(); 536 537 x = x - PWM_WIDTH / 2 + 538 value * PWM_WIDTH / 255; 539 ctx.fillStyle = "#FF4500"; 540 ctx.beginPath(); 541 ctx.arc(x 542 , y, BOX_HEIGHT / 2, 0, 2 * Math.PI); 543 ctx.fill(); 544 ctx.restore(); 545} 546function 547 update_view() 548{ 549 ctx.clearRect(0, 0, canvas_width, canvas_height); 550 ctx.drawImage(arduino_img, 551 (canvas_width - img_width) / 2 - 100, canvas_height - img_height, img_width, img_height); 552 553 ctx.lineWidth 554 = 3; 555 ctx.strokeStyle="gray"; 556 ctx.globalAlpha=1; 557 ctx.font="bold 558 16px Arial"; 559 ctx.textBaseline="middle"; 560 ctx.textAlign="center"; 561 562 for 563 (var pin_id = 0; pin_id <= 13; pin_id++) 564 { 565 ctx.fillStyle = "DeepPink"; 566 ctx.beginPath(); 567 ctx.arc(pos_d_list[pin_id][0] 568 + 0.5, pos_d_list[pin_id][1] + 0.5, 4, 0, 2 * Math.PI); 569 ctx.fill(); 570 571 var 572 x, y; 573 574 x = 0; 575 576 if(pin_id < 8) 577 y = Y_D_START 578 + pin_id * Y_GAP; 579 else 580 y = Y_D_START + (pin_id + 1) * Y_GAP; 581 582 ctx.beginPath(); 583 ctx.lineTo(x 584 + 0.5, y + 0.5); 585 ctx.lineTo(pos_d_list[pin_id][0] + 0.5, y + 0.5); 586 ctx.lineTo(pos_d_list[pin_id][0] 587 + 0.5, pos_d_list[pin_id][1] + 0.5); 588 ctx.stroke(); 589 590 draw_pin(X_D_POS_LEVEL_0, 591 y, "D" + pin_id.toString()); 592 593 if(pin_d_mode[pin_id] & PIN_MODE_FLAG_COMM) 594 { 595 if(pin_d_mode[pin_id] 596 == PIN_MODE_UART) 597 draw_comm(X_D_POS_LEVEL_1, y, "UART"); 598 else 599 if(pin_d_mode[pin_id] 600 == PIN_MODE_SPI) 601 draw_comm(X_D_POS_LEVEL_1, y, "SPI"); 602 else 603 if(pin_d_mode[pin_id] 604 == PIN_MODE_I2C) 605 draw_comm(X_D_POS_LEVEL_1, y, "I2C"); 606 607 draw_state(X_D_POS_LEVEL_2, 608 y, pin_d_state[pin_id]); 609 continue; 610 } 611 612 if(pin_d_mode[pin_id] 613 == PIN_MODE_PWM) 614 { 615 draw_pwm_button(X_D_POS_LEVEL_1, y, "I/O") 616 draw_slider(X_D_POS_PWM_BTN, 617 y, pin_d_state[pin_id]); 618 } 619 else 620 { 621 draw_digital_mode(X_D_POS_LEVEL_1, 622 y, pin_d_mode[pin_id]); 623 624 if(pin_d_mode[pin_id] == PIN_MODE_OUTPUT) 625 draw_on_off(X_D_POS_LEVEL_2, 626 y, pin_d_state[pin_id]) 627 else 628 { 629 if(pin_d_state[pin_id] 630 == PIN_STATE_ON) 631 draw_state(X_D_POS_LEVEL_2, y, "ON"); 632 else 633 draw_state(X_D_POS_LEVEL_2, 634 y, "OFF"); 635 } 636 637 if(pin_id == 3 || pin_id == 5 || pin_id 638 == 6 || pin_id == 9 ) 639 draw_pwm_button(X_D_POS_PWM_BTN, y, "PWM") 640 } 641 } 642 643 for 644 (var pin_id = 0; pin_id <= 5; pin_id++) 645 { 646 ctx.fillStyle = "DeepPink"; 647 ctx.beginPath(); 648 ctx.arc(pos_a_list[pin_id][0] 649 + 0.5, pos_a_list[pin_id][1] + 0.5, 4, 0, 2 * Math.PI); 650 ctx.fill(); 651 652 var 653 x, y; 654 655 x = canvas_width; 656 y = Y_A_END - pin_id * Y_GAP; 657 658 ctx.beginPath(); 659 ctx.lineTo(x 660 + 0.5, y + 0.5); 661 ctx.lineTo(pos_a_list[pin_id][0] + 0.5, y + 0.5); 662 ctx.lineTo(pos_a_list[pin_id][0] 663 + 0.5, pos_a_list[pin_id][1] + 0.5); 664 ctx.stroke(); 665 666 draw_pin(X_A_POS_LEVEL_0, 667 y, "A" + pin_id.toString()); 668 draw_analog_mode(X_A_POS_LEVEL_1, y, pin_a_mode[pin_id]); 669 670 if(pin_a_mode[pin_id] 671 == PIN_MODE_ANALOG) 672 draw_state(X_A_POS_LEVEL_2, y, pin_a_state[pin_id]); 673 else 674 { 675 draw_digital_mode(X_A_POS_LEVEL_2, 676 y, pin_a_mode[pin_id]); 677 678 if(pin_a_mode[pin_id] == PIN_MODE_OUTPUT) 679 draw_on_off(X_A_POS_LEVEL_3, 680 y, pin_a_state[pin_id]) 681 else 682 { 683 if(pin_a_state[pin_id] 684 == PIN_STATE_ON) 685 draw_state(X_A_POS_LEVEL_3, y, "ON"); 686 else 687 draw_state(X_A_POS_LEVEL_3, 688 y, "OFF"); 689 } 690 } 691 } 692} 693function process_event(event) 694{ 695 if(event.offsetX) 696 { 697 touch_x 698 = event.offsetX; 699 touch_y = event.offsetY; 700 } 701 else if(event.layerX) 702 { 703 touch_x 704 = event.layerX; 705 touch_y = event.layerY; 706 } 707 else 708 { 709 touch_x 710 = Math.round(event.touches[0].pageX - event.touches[0].target.offsetLeft); 711 touch_y 712 = Math.round(event.touches[0].pageY - event.touches[0].target.offsetTop); 713 } 714 715 var 716 pin; 717 var cmd = CMD_NONE; 718 var state = 0; 719 720 var offset = (touch_y 721 - Y_D_START) % Y_GAP; 722 var pin_id = Math.round((touch_y - Y_D_START - offset) 723 / Y_GAP); 724 725 if((offset < BOX_HEIGHT / 2) || (offset > (Y_GAP - BOX_HEIGHT 726 / 2) && offset < Y_GAP)) 727 { 728 if(offset > (Y_GAP - BOX_HEIGHT / 2) && offset 729 < Y_GAP) 730 pin_id++; 731 732 if(touch_x < (canvas_width / 2)) 733 { 734 if(pin_id 735 > 7) 736 pin_id--; 737 738 if(pin_id < 0 || pin_id > 13) 739 return; 740 741 if(pin_d_mode[pin_id] 742 & PIN_MODE_FLAG_COMM) 743 return; 744 745 if(pin_d_mode[pin_id] 746 != PIN_MODE_PWM) 747 { 748 if(event_type == "move") 749 return; 750 751 if( 752 touch_x > (X_D_POS_LEVEL_1 - DIO_BOX_WIDTH / 2) && touch_x < (X_D_POS_LEVEL_1 + 753 DIO_BOX_WIDTH / 2)) 754 { 755 pin_d_mode[pin_id] = (pin_d_mode[pin_id] 756 + 1) % 2; 757 cmd = CMD_ARDUINO_SET_MODE; 758 state = pin_d_mode[pin_id]; 759 } 760 else 761 if( 762 touch_x > (X_D_POS_LEVEL_2 - ONOFF_BOX_WIDTH / 2) && touch_x < (X_D_POS_LEVEL_2 763 + ONOFF_BOX_WIDTH / 2)) 764 { 765 if(pin_d_mode[pin_id] == PIN_MODE_OUTPUT) 766 { 767 pin_d_state[pin_id] 768 = (pin_d_state[pin_id] + 1) % 2; 769 cmd = CMD_ARDUINO_SET_STATE; 770 state 771 = pin_d_state[pin_id]; 772 } 773 } 774 else 775 if( 776 touch_x > (X_D_POS_PWM_BTN - BOX_HEIGHT / 2) && touch_x < (X_D_POS_PWM_BTN + BOX_HEIGHT 777 / 2)) 778 { 779 pin_d_mode[pin_id] = PIN_MODE_PWM; 780 pin_d_state[pin_id] 781 = 0; 782 cmd = CMD_ARDUINO_SET_MODE; 783 state = pin_d_mode[pin_id]; 784 } 785 } 786 else 787 { 788 if( 789 touch_x > (X_D_POS_LEVEL_1 - BOX_HEIGHT / 2) && touch_x < (X_D_POS_LEVEL_1 + BOX_HEIGHT 790 / 2)) 791 { 792 if(event_type == "move") 793 return; 794 795 pin_d_mode[pin_id] 796 = PIN_MODE_OUTPUT; 797 pin_d_state[pin_id] = 0; 798 cmd = CMD_ARDUINO_SET_MODE; 799 state 800 = pin_d_mode[pin_id]; 801 } 802 else 803 { 804 var 805 x_slider = X_D_POS_SLIDER - PWM_WIDTH / 2 + pin_d_state[pin_id] * PWM_WIDTH / 255; 806 if( 807 touch_x > (x_slider - PWM_WIDTH / 2) && touch_x < (x_slider + PWM_WIDTH / 2)) 808 { 809 state 810 = (touch_x - (X_D_POS_SLIDER - PWM_WIDTH / 2 )) / PWM_WIDTH * 255; 811 812 if(state 813 >= 0 && state <= 255) 814 { 815 pin_d_state[pin_id] = Math.round(state); 816 cmd 817 = CMD_ARDUINO_SET_STATE; 818 } 819 } 820 } 821 } 822 823 pin 824 = "D" + pin_id; 825 } 826 else 827 { 828 if(event_type == "move") 829 return; 830 831 pin_id 832 -= 5; 833 834 if(pin_id < 0 || pin_id > 5) 835 return; 836 837 pin_id 838 = 5 - pin_id; 839 840 if( touch_x > (X_A_POS_LEVEL_1 - AN_BOX_WIDTH / 841 2) && touch_x < (X_A_POS_LEVEL_1 + AN_BOX_WIDTH / 2)) 842 { 843 if(pin_a_mode[pin_id] 844 == PIN_MODE_ANALOG) 845 { 846 pin_a_mode[pin_id] = PIN_MODE_INPUT; 847 pin_a_state[pin_id] 848 = PIN_STATE_OFF; 849 } 850 else 851 { 852 pin_a_mode[pin_id] 853 = PIN_MODE_ANALOG; 854 pin_a_state[pin_id] = 0; 855 } 856 857 cmd 858 = CMD_ARDUINO_SET_MODE; 859 state = pin_a_mode[pin_id]; 860 } 861 else 862 if( 863 touch_x > (X_A_POS_LEVEL_2 - DIO_BOX_WIDTH / 2) && touch_x < (X_A_POS_LEVEL_2 + 864 DIO_BOX_WIDTH / 2)) 865 { 866 if(pin_a_mode[pin_id] != PIN_MODE_ANALOG) 867 { 868 pin_a_mode[pin_id] 869 = (pin_a_mode[pin_id] + 1) % 2; 870 cmd = CMD_ARDUINO_SET_MODE; 871 state 872 = pin_a_mode[pin_id]; 873 } 874 } 875 else 876 if( touch_x 877 > (X_A_POS_LEVEL_3 - ONOFF_BOX_WIDTH / 2) && touch_x < (X_A_POS_LEVEL_3 + ONOFF_BOX_WIDTH 878 / 2)) 879 { 880 if(pin_a_mode[pin_id] == PIN_MODE_OUTPUT) 881 { 882 pin_a_state[pin_id] 883 = (pin_a_state[pin_id] + 1) % 2; 884 cmd = CMD_ARDUINO_SET_STATE; 885 state 886 = pin_a_state[pin_id]; 887 } 888 } 889 890 pin = "A" + 891 pin_id; 892 } 893 } 894 895 if(cmd != CMD_NONE) 896 { 897 update_view(); 898 send_to_Arduino(pin, 899 cmd, state); 900 } 901} 902function mouse_down() 903{ 904 //if(ws == null || authorized) 905 //return; 906 907 event.preventDefault(); 908 event_type 909 = "down"; 910 process_event(event); 911} 912function mouse_up() 913{ 914 event.preventDefault(); 915 916 //if(ws 917 != null && authorized == false) 918 //send_to_Arduino(CMD_AUTH, touch_list.toString()); 919 920 event_type 921 = "up"; 922 update_view(); 923} 924function mouse_move() 925{ 926 event.preventDefault(); 927 928 event_type 929 = "move"; 930 process_event(event); 931} 932 933function send_to_Arduino(pin, 934 cmd, state) 935{ 936 if(ws.readyState == 1) 937 { 938 ws.send(pin + ":" + 939 cmd + ":" + state + "\ \ 940"); 941 console.log("send data:" + pin + ":" 942 + cmd + ":" + state); 943 } 944} 945 946window.onload = init; 947</script> 948</head> 949 950<body> 951 952<p> 953</p> 954<canvas 955 id="canvas"></canvas> 956<h2> 957<p>WebSocket : <span id="ws_state">null</span></p> 958<button 959 id="bt_connect" type="button" onclick="connect_onclick();">Connect</button> 960</h2> 961 962</body> 963</html>
ArduinoIOExample
arduino
This is an example of Arduino code for controlling/monitoring via the web app
1#include "SPI.h" 2#include "Phpoc.h" 3 4#define CMD_ARDUINO_SET_MODE 0x01 5#define CMD_ARDUINO_SET_STATE 0x02 6#define CMD_ARDUINO_GET_MODE 0x03 7#define CMD_ARDUINO_GET_STATE 0x04 8 9#define CMD_WEB_UPDATE_STATE 0x10 10#define CMD_WEB_UPDATE_MODE 0x11 11 12#define MODE_FLAG_IO 0x00 13#define MODE_FLAG_COMM 0x10 // communication 14 15#define MODE_INPUT 0x00 16#define MODE_OUTPUT 0x01 17#define MODE_ANALOG 0x03 18#define MODE_PWM 0x04 19#define MODE_SPI 0x10 20#define MODE_I2C 0x11 21#define MODE_UART 0x12 22 23 24PhpocServer server(80); 25 26/* 14 digital pin and 6 analog pin */ 27int pinModes[20] = {MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_INPUT, MODE_ANALOG, MODE_ANALOG, MODE_ANALOG, MODE_ANALOG, MODE_ANALOG, MODE_ANALOG}; 28int pinStates[20]; 29 30unsigned long updateInterval; 31unsigned long lastUpdateTime; 32char wbuf[20]; 33 34void sendToWeb(int pin, int cmd, float state) ; 35 36void setup() { 37 Serial.begin(9600); 38 while(!Serial) 39 ; 40 41 Phpoc.begin(PF_LOG_SPI | PF_LOG_NET); 42 43 server.beginWebSocket("arduino_io"); 44 45 Serial.print("WebSocket server address : "); 46 Serial.println(Phpoc.localIP()); 47 48 pinModes[0] = MODE_UART; 49 pinModes[1] = MODE_UART; 50 pinModes[10] = MODE_SPI; 51 pinModes[11] = MODE_SPI; 52 pinModes[12] = MODE_SPI; 53 pinModes[13] = MODE_SPI; 54 55 for(int pin = 0; pin < 20; pin++) { 56 if(pinModes[pin] == MODE_INPUT) 57 pinMode(pin, INPUT_PULLUP); 58 59 if(pinModes[pin] == MODE_ANALOG) 60 pinStates[pin] = analogRead(pin); 61 else 62 if(pinModes[pin] == MODE_INPUT || pinModes[pin] == MODE_OUTPUT ) 63 pinStates[pin] = digitalRead(pin); 64 } 65 66 updateInterval = 100; // 100 milllisecond 67 lastUpdateTime = 0; 68} 69 70void loop() { 71 // when the client sends the first byte, say hello: 72 PhpocClient client = server.available(); 73 74 if (client) { 75 String data = client.readLine(); 76 77 /* example of data: A5:1:0 in order pin:command:value */ 78 79 if(data) { 80 int firstConlon = data.indexOf(':'); 81 int secondConlon = data.indexOf(':', firstConlon + 1); 82 83 char group = data.charAt(0); /* A or D */ 84 int pin = data.substring(1, firstConlon).toInt(); 85 int cmd = data.substring(firstConlon + 1, secondConlon).toInt(); 86 int value = data.substring(secondConlon + 1).toInt(); 87 88 /* in Arduino Uno, pin A0 to A5 is mapped from pin 14 to 19 */ 89 if(group == 'A') 90 pin += 14; 91 92 if(cmd == CMD_ARDUINO_SET_MODE) { 93 if(group == 'A' && value == MODE_ANALOG) 94 pinMode(pin, MODE_INPUT); 95 else 96 if(value == MODE_INPUT) 97 pinMode(pin, INPUT_PULLUP); 98 else 99 pinMode(pin, value); 100 101 pinModes[pin] = value; 102 sendToWeb(pin, CMD_WEB_UPDATE_MODE, pinModes[pin]); 103 } 104 else 105 if(cmd == CMD_ARDUINO_SET_STATE) 106 { 107 if(pinModes[pin] == OUTPUT) 108 digitalWrite(pin, value); 109 else 110 if(pinModes[pin] == MODE_PWM) 111 analogWrite(pin, value); 112 113 pinStates[pin] = value; 114 //sendToWeb(pin, CMD_WEB_UPDATE_STATE, pinStates[pin]); 115 } 116 else 117 if(cmd == CMD_ARDUINO_GET_MODE) 118 sendToWeb(pin, CMD_WEB_UPDATE_MODE, pinModes[pin]); 119 else 120 if(cmd == CMD_ARDUINO_GET_STATE) 121 { 122 if(pinModes[pin] & MODE_FLAG_COMM) 123 { 124 if(pin == 0) 125 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("RX")); 126 else 127 if(pin == 1) 128 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("TX")); 129 else 130 if(pin == 10) 131 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("MOSI")); 132 else 133 if(pin == 11) 134 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("MISO")); 135 else 136 if(pin == 12) 137 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("SCK")); 138 else 139 if(pin == 13) 140 sendToWeb(pin, CMD_WEB_UPDATE_STATE, String("SS")); 141 } 142 else 143 sendToWeb(pin, CMD_WEB_UPDATE_STATE, pinStates[pin]); 144 } 145 else 146 Serial.println("unknown command"); 147 } 148 } 149 150 if ((millis() - lastUpdateTime) > updateInterval) { 151 for(int pin = 0; pin < 20; pin++) { 152 153 int newState; 154 155 if(pinModes[pin] == MODE_ANALOG) 156 { 157 newState = analogRead(pin); 158 if(abs(newState - pinStates[pin]) > 5) { 159 sendToWeb(pin, CMD_WEB_UPDATE_STATE, newState); 160 pinStates[pin] = newState; 161 } 162 } 163 else 164 if(pinModes[pin] == MODE_INPUT || pinModes[pin] == MODE_OUTPUT ) 165 { 166 newState = digitalRead(pin); 167 if(newState != pinStates[pin]) { 168 sendToWeb(pin, CMD_WEB_UPDATE_STATE, newState); 169 pinStates[pin] = newState; 170 } 171 } 172 } 173 174 lastUpdateTime = millis(); 175 } 176} 177 178void sendToWeb(int pin, int cmd, float state) { 179 String txtMsg; 180 181 if(pin < 14) 182 txtMsg = String("D") + String(pin) + ":"+ String(cmd) + ":" + String(state) + "\ \ 183"; 184 else 185 txtMsg = String("A") + String(pin - 14) + ":"+ String(cmd) + ":" + String(state) + "\ \ 186"; 187 188 txtMsg.toCharArray(wbuf, txtMsg.length() + 1); 189 server.write(wbuf, txtMsg.length()); 190} 191void sendToWeb(int pin, int cmd, String state) { 192 String txtMsg; 193 194 if(pin < 14) 195 txtMsg = String("D") + String(pin) + ":"+ String(cmd) + ":" + state + "\ \ 196"; 197 else 198 txtMsg = String("A") + String(pin - 14) + ":"+ String(cmd) + ":" + state + "\ \ 199"; 200 201 txtMsg.toCharArray(wbuf, txtMsg.length() + 1); 202 server.write(wbuf, txtMsg.length()); 203}
Comments
Only logged in users can leave comments