IoT_lover
Published © GPL3+

Arduino - Drawing Route for Car on the Office's Map

Sending documents for your-coworker by putting it on a car, and draw a path from you to your co-worker on web-based map.

IntermediateFull instructions provided6,741

Things used in this project

Story

Read more

Schematics

step_car_JnZCNgI2aB.jpg

Code

Arduino Code

Arduino
#include <Sppc.h>

SppcStepper step(14);


void step_test(void)
{
  Serial.println(step.getPID());
  Serial.println(step.getName());

  step.setMode(32);
  step.setSpeed(200000);
  step.setAccel(500000, 500000);
  step.stepMove(10000);
  step.stepMove(-10000);
  step.stepMove(10000);
  step.stepMove(-10000);
}

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

  Sppc.begin(PF_LOG_SPI | PF_LOG_NET);
  Expansion.begin();

  step.setMode(32);
  step.setSpeed(5000);
  step.setAccel(50000, 50000);
  step.setEioMode(0, 1);
  step.stepGoto(100000000);
}

void loop() {
   if(step.getState() == 1) {
       Serial.println("lock");
       delay(1000);
       step.setEioMode(0, 0);
   }
   else if(step.getState() == 0) {
       step.setEioMode(0, 1);
       step.stepGoto(100000000);
   }
}

Web User Interface (remote_car.php)

PHP
<!DOCTYPE html>
<html>
<head>
<title>Arduino - PHPoC Shield - Step Motor</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style>
body {
	text-align: center;
	background-color: #00979D;
}
#canvas {
	margin-right: auto;
	margin-left: auto; 
	position: relative;
}
canvas {
	position: absolute; 
	left: 0px;
	top: 0px;
	overflow-touchImageY: auto;
	overflow-touchImageX: hidden;
	-webkit-overflow-scrolling: touch; /* nice webkit native scroll */
}
#layer1 { z-index: 2; }
#layer2 {
	z-index: 1;
	background: url(map.png) no-repeat; 
	background-size: contain; 
	border: 1px solid #000;
}
</style>
<script>
var RESOLUTION = 100;
var IMAGE_WIDTH = 1140, IMAGE_HEIGHT = 1562;

var ws = null;
var layer1 = null, layer2 = null;
var canvas = null;
var ctx1 = null, ctx2 = null;

var canvasWidth, canvasHeight;
var touchImageX, touchImageY; //position of car on map's image coordinate (pixel)
var touchState = 0;

function init() {
	//initial position
	touchImageX = 16 * IMAGE_WIDTH / 25.0;
	touchImageY = 22 * IMAGE_HEIGHT / 34.0;

	canvas = document.getElementById("canvas");

	layer1 = document.getElementById("layer1");
	layer2 = document.getElementById("layer2");

	layer1.addEventListener("touchstart", mouse_down);
	layer1.addEventListener("touchend", mouse_up);
	layer1.addEventListener("touchmove", mouse_move);
	layer1.addEventListener("mousedown", mouse_down);
	layer1.addEventListener("mouseup", mouse_up);
	layer1.addEventListener("mousemove", mouse_move);

	ctx1 = layer1.getContext("2d");
	ctx2 = layer2.getContext("2d");

	canvas_resize();
}
function ws_onmessage(e_msg) {
	var arr = JSON.parse(e_msg.data);
	var carPosStepX			= arr[0];
	var carPosStepY			= arr[1];

	var carPosPixelX = Math.round(carPosStepX * canvasWidth / MAX_X);
	var carPosPixelY = -Math.round(carPosStepY * canvasHeight / MAX_Y);

	ctx1.clearRect(0, 0, canvasWidth, -canvasHeight);
	ctx1.beginPath();
	ctx1.arc(carPosPixelX, carPosPixelY, 7, 0, 2*Math.PI);
	ctx1.fill();
}
function ws_onopen() {
	document.getElementById("ws_state").innerHTML = "OPEN";
	document.getElementById("wc_conn").innerHTML = "Disconnect";
}
function ws_onclose() {
	document.getElementById("ws_state").innerHTML = "CLOSED";
	document.getElementById("wc_conn").innerHTML = "Connect";
	ws.onopen = null;
	ws.onclose = null;
	ws.onmessage = null;
	ws = null;
}
function wc_onclick() {
	if(ws == null) {
		ws = new WebSocket("ws://<?echo _SERVER("HTTP_HOST")?>/remote_car", "text.phpoc");
		document.getElementById("ws_state").innerHTML = "CONNECTING";

		ws.onopen = ws_onopen;
		ws.onclose = ws_onclose;
		ws.onmessage = ws_onmessage;  
	} else {
		ws.close();
	}
}
function event_handler(event, type) {
	var touchScreenX, touchScreenY; //position in canvas coordinate (in pixel).

	if(event.targetTouches) {
		if(event.targetTouches.length > 1)
			return;

		var targetTouches = event.targetTouches;

		touchScreenX = targetTouches[0].pageX - canvas.offsetLeft;
		touchScreenY = targetTouches[0].pageY - canvas.offsetTop - canvasHeight;
	} else {
		touchScreenX = event.offsetX;
		touchScreenY = event.offsetY - canvasHeight;
	}

	// convert from screen coordinate to map's image coordinate
	var newTouchImageX = Math.round(touchScreenX / canvasWidth * IMAGE_WIDTH);
	var newTouchImageY = Math.round((-touchScreenY) / canvasHeight * IMAGE_HEIGHT); 

	if(type == "MOVE") {
		var deltaX = newTouchImageX - touchImageX;
		var deltaY = newTouchImageY - touchImageY;
		var dist = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));

		if(dist < RESOLUTION)
			return;
	}

	touchImageX = newTouchImageX;
	touchImageY = newTouchImageY;

	if(ws != null && ws.readyState == 1) {
		ws.send(touchImageX + "," + touchImageY + "\r\n"); 
		console.log(touchImageX + "," + touchImageY); 

		ctx2.lineTo(touchScreenX, touchScreenY);
		ctx2.stroke();
	}
}
function mouse_down() {
	event.preventDefault();
	event_handler(event, "DOWN");
	touchState = 1;
}
function mouse_up() {
	event.preventDefault();
	touchState = 0;
}
function mouse_move() {
	event.preventDefault();
	if(touchState == 1)
		event_handler(event, "MOVE");
}
function canvas_clear() {
	ctx1.clearRect(0, 0, canvasWidth, -canvasHeight);
	ctx2.clearRect(0, 0, canvasWidth, -canvasHeight);
}
function canvas_resize() {
	var width = window.innerWidth;
	var height = window.innerHeight;
	canvasHeight = height - 100;
	canvasWidth = Math.round(canvasHeight / IMAGE_HEIGHT * IMAGE_WIDTH);

	canvas.style.width = canvasWidth + "px";
	canvas.style.height = canvasHeight + "px";
	layer1.width = canvasWidth;
	layer1.height = canvasHeight;
	layer2.width = canvasWidth;
	layer2.height = canvasHeight;

	ctx1.translate(0, canvasHeight);
	ctx1.lineWidth = 5;
	ctx1.fillStyle = "green";
	ctx2.translate(0, canvasHeight);
	ctx2.lineWidth = 5;
	ctx2.strokeStyle = "blue";

	var touchScreenX = Math.round(touchImageX * canvasWidth / IMAGE_WIDTH);
	var touchScreenY = Math.round((-touchImageY) * canvasHeight / IMAGE_HEIGHT);

	ctx1.beginPath();
	ctx1.arc(touchScreenX, touchScreenY, 3, 0, 2*Math.PI);
	ctx1.fill();
	ctx2.beginPath();
	ctx2.lineTo(touchScreenX, touchScreenY);
}

window.onload = init;
</script>
</head>

<body onresize="canvas_resize()">
<div id="canvas">
	<canvas id="layer1"></canvas>
	<canvas id="layer2"></canvas>
</div>
<p>WebSocket : <span id="ws_state">null</span></p>
<button id="wc_conn" type="button" onclick="wc_onclick();">Connect</button>
<button type="button" onclick="canvas_clear();">Clear</button>
</body>
</html>

Credits

IoT_lover

IoT_lover

10 projects • 190 followers

Comments