[HTML5/WS/CANVAS] Controlling a servo motor

[HTML5/WS/CANVAS] Controlling a servo motor

Postby admin » Wed Nov 04, 2015 4:51 pm

We will go through an example of controlling a Tower Pro SG92R micro servo motor with HTML5 Canvas by using a PHPoC Blue.

Image

Diagram

Image

Source Codes
1. task0.php

Code: Select all

<?php

if(_SERVER("REQUEST_METHOD"))
    exit; // avoid php execution via http request

include "/lib/sd_340.php";
include "/lib/sn_tcp_ws.php";

define("PWM_PERIOD", 20000); // 20000us (20ms)
define("WIDTH_MIN", 600);
define("WIDTH_MAX", 2450);

ht_pwm_setup(0, (WIDTH_MIN + WIDTH_MAX) / 2, PWM_PERIOD, "us");
ws_setup(0, "ht_pwm_servo", "csv.phpoc");

$rwbuf = "";
 
while(1)
{
    if(ws_state(0) == TCP_CONNECTED)
    {
        $rlen = ws_read_line(0, $rwbuf);

        if($rlen)
        {
            $angle = -(int)$rwbuf + 90;

            if($angle < 0)
                $angle = 0;

            if($angle > 180)
                $angle = 180;

            $width = WIDTH_MIN + (int)round((WIDTH_MAX - WIDTH_MIN) * $angle / 180.0);

            if(($width >= WIDTH_MIN) && ($width <= WIDTH_MAX))
                ht_pwm_width(0, $width, PWM_PERIOD);
        }
    }
}
 
?>



2. index.php

Code: Select all

<!DOCTYPE html>
<html>
<head>
<title>PHPoC / <?echo system("uname -i")?></title>
<meta name="viewport" content="width=device-width, initial-scale=0.7">
<style>
body { text-align: center; }
canvas { background-color: #f0f0f0; }
</style>
<script>
var canvas_width = 401, canvas_height = 466;
var pivot_x = 200, pivot_y = 200;
var bracket_radius = 160, bracket_angle = 0;
var bracket_img = new Image();
var click_state = 0;
var last_angle = 0;
var mouse_xyra = {x:0, y:0, r:0.0, a:0.0};
var ws;

bracket_img.src = "servo_bracket.png";

function init()
{
    var servo = document.getElementById("servo");

    servo.width = canvas_width;
    servo.height = canvas_height;
    servo.style.backgroundImage = "url('/servo_body.png')";

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

    var ctx = servo.getContext("2d");

    ctx.translate(pivot_x, pivot_y);

    rotate_bracket(0);

    ws = new WebSocket("ws://<?echo _SERVER("HTTP_HOST")?>/ht_pwm_servo", "csv.phpoc");
    document.getElementById("ws_state").innerHTML = "CONNECTING";

    ws.onopen  = function(){ document.getElementById("ws_state").innerHTML = "OPEN" };
    ws.onclose = function(){ document.getElementById("ws_state").innerHTML = "CLOSED"};
    ws.onerror = function(){ alert("websocket error " + this.url) };

    ws.onmessage = ws_onmessage;
}
function ws_onmessage(e_msg)
{
    e_msg = e_msg || window.event; // MessageEvent

    alert("msg : " + e_msg.data);
}
function rotate_bracket(angle)
{
    var servo = document.getElementById("servo");
    var ctx = servo.getContext("2d");

    ctx.clearRect(-pivot_x, -pivot_y, canvas_width, canvas_height);
    ctx.rotate(angle / 180 * Math.PI);

    ctx.drawImage(bracket_img, -pivot_x, -pivot_y);

    ctx.rotate(-angle / 180 * Math.PI);
}
function check_range_xyra(event, 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) - pivot_x;
        y = pivot_y - (touches[0].pageY - touches[0].target.offsetTop);
        min_r = 60;
        max_r = pivot_x;
        width = 40;
    }
    else
    {
        x = event.offsetX - pivot_x;
        y = pivot_y - event.offsetY;
        min_r = 60;
        max_r = bracket_radius;
        width = 20;
    }

    /* cartesian to polar coordinate conversion */
    r = Math.sqrt(x * x + y * y);
    a = Math.atan2(y, x);

    mouse_xyra.x = x;
    mouse_xyra.y = y;
    mouse_xyra.r = r;
    mouse_xyra.a = a;

    radian = bracket_angle / 180 * Math.PI;

    /* rotate coordinate */
    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 mouse_down()
{
    if(event.touches && (event.touches.length > 1))
        click_state = event.touches.length;

    if(click_state > 1)
        return;

    if(check_range_xyra(event, mouse_xyra))
    {
        click_state = 1;
        last_angle = mouse_xyra.a / Math.PI * 180.0;
    }
}
function mouse_up()
{
    click_state = 0;
}
function mouse_move()
{
    var angle;

    if(event.touches && (event.touches.length > 1))
        click_state = event.touches.length;

    if(click_state > 1)
        return;

    if(!click_state)
        return;

    if(!check_range_xyra(event, mouse_xyra))
    {
        click_state = 0;
        return;
    }

    angle = mouse_xyra.a / Math.PI * 180.0;

    if((Math.abs(angle) > 90) && (angle * last_angle < 0))
    {
        if(last_angle > 0)
            last_angle = -180;
        else
            last_angle = 180;
    }

    bracket_angle += (last_angle - angle);
    last_angle = angle;

    if(bracket_angle > 90)
        bracket_angle = 90;

    if(bracket_angle < -90)
        bracket_angle = -90;

    rotate_bracket(bracket_angle);

    if(ws.readyState == 1)
        ws.send(Math.floor(bracket_angle) + "\r\n");

    debug = document.getElementById("debug");
    debug.innerHTML = Math.floor(bracket_angle);

    event.preventDefault();
}
window.onload = init;
</script>
</head>

<body>

<h2>
HT / Tower Pro SG92R Micro Servo<br>

<br>

<canvas id="servo"></canvas>

<p>
WebSocket : <span id="ws_state">null</span><br>
Angle : <span id="debug">0</span>
</p>
</h2>

</body>
</html>


Please download a PSP (PHPoC Support Package) of libraries and examples from PHPoC, and upload it in the PHPoC Blue.




Video

phpBB [video]
admin
Site Admin
 
Posts: 166
Joined: Mon Jan 20, 2014 4:40 pm

Re: [HTML5/WS/CANVAS] Controlling a servo motor

Postby juanjogonzalez » Thu Mar 09, 2017 11:00 am

When i'm trying execute this example (from smartphone), I get the following error:

websocket error ws://192.168.0.1/ht_pwm_servo

Load the files to P4S-342 in mmap HT0
Browser smartphone: firefox
Url Example: http://192.168.0.1

But, when execute the example from phpoc debugger, no problem with websocket, but the canvas don't work

Some idea?
juanjogonzalez
 
Posts: 2
Joined: Thu Mar 09, 2017 9:54 am

Re: [HTML5/WS/CANVAS] Controlling a servo motor

Postby Khanh » Thu Mar 09, 2017 2:21 pm

To run any examples which use websocket, you need to run code in debugger (server side). If not, websocket server in PHPoC is not run. Therefore, websocket client in your web browser can not connect to websocket server.

For the problem that the canvas don't work, The reason is websocket in Firefox may be disable. You can find it by google "firefox websocket".
Please try it on other browser.
Khanh
 
Posts: 72
Joined: Fri Mar 11, 2016 10:57 am

Re: [HTML5/WS/CANVAS] Controlling a servo motor

Postby juanjogonzalez » Fri Mar 10, 2017 12:23 am

The problem was the browser, I tried with google chrome and it works perfect, thank you very much.

Best regards,
Juanjo
juanjogonzalez
 
Posts: 2
Joined: Thu Mar 09, 2017 9:54 am

Re: [HTML5/WS/CANVAS] Controlling a servo motor

Postby Khanh » Fri Mar 10, 2017 9:01 am

You're welcome!
Khanh
 
Posts: 72
Joined: Fri Mar 11, 2016 10:57 am


Return to Example

Who is online

Users browsing this forum: No registered users and 1 guest

cron