Vibrobot Made with obniz

The Vibrobot can be now operated from anywhere in the world.

A Vibrobot is a robot to which brushes are attached instead of tires, and when vibrates the brushes, it proceeds in a specific direction due to the asymmetry of the coat.

This robot can go straight ahead, turn right, and turn left by PWM controlling two vibration motors and operating the left and right brushes respectively. In addition, a distance sensor is mounted on the front and you can confirm in real time on the screen of the smartphone whether there is an obstacle ahead.

Materials

Steps

Connect parts to an obniz like the table and the image below. Then, put two Vibration Motors at the toothbrush heads and put the GP2Y0A21YK0F(IR distance sensor) at the front of the toothbrush heads.

obniz parts
0 [GP2Y0A21YK0F] Vcc
1 [GP2Y0A21YK0F] GND
2 [GP2Y0A21YK0F] signal
4 [Vibration Motor1] GND
5 [Vibration Motor1] Vcc
6 [Vibration Motor2] GND
7 [Vibration Motor2] Vcc

After that, supply power to the obniz and run the program below. You can control the Vibrobot on this manipulation screen.

Operation Method

Depending on the distance to the obstacle ahead, the color of the area on the screen changes. It gets green when the obstacle is far, and it gets red when the obstacle is near. In Manual mode, you can freely control the robot to go straight ahead, turn right and left by adjusting the strength of left and right vibrations with the slider in the Control area on ​​the screen. It may be interesting to control the robot from where you can’t see it but seeing only the color of the screen. If you set Power to Low, Middle, or High, it will be in Auto mode, usually continue going straight ahead and automatically turn right when approaching to an obstacle, which allows it to keep moving semipermanently.

When you make this, it is necessary to form a habit such that the tips of the brushes turn diagonally backward. You can also manipulate many obniz at the same time from one smartphone, so if you make a lot of such robots and move them at the same time, they may work interestingly with each other.

Program

<!-- HTML Example -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <script src="https://unpkg.com/obniz@2.0.2/obniz.js"></script>
    <style type="text/css">
        html,
        css {
            touch-action: none;
        }

        input.controller {
            margin-top: 25%;
            -webkit-transform: rotate(270deg);
            -moz-transform: rotate(270deg);
            -o-transform: rotate(270deg);
            transform: rotate(270deg);
            -webkit-border-radius: 24px;
            -moz-border-radius: 24px;
            border-radius: 24px;
        }

        input.controller {
            -webkit-appearance: none;
            width: 90%;
            background: #eee;
            box-shadow: 0 0 10px #666;
            border-radius: 10px;
        }

        input.controller::-webkit-slider-thumb {
            -webkit-appearance: none;
            background: #333;
            width: 50px;
            height: 50px;
            border-radius: 50%;
        }

        input.controller::-webkit-slider-thumb:hover {
            background: #999;
        }

        input.controller::-webkit-slider-thumb:active {
            background: #fefefe;
        }

        .box {
            display: table-cell;
        }
    </style>
</head>

<body>
    <div id="obniz-debug"></div>
    <h3>Info</h3>
    <div id="mode-print"></div>
    <div id="dist-print"></div>
    <div id="print" style="height:100px;"></div>

    <h3>Control</h3>
    <p class="switch">
        Power:
        <br />
        <label>
            <input type="radio" name="power" id="" value=0 onchange="changemode(this.value)">Manual</label>
        <label>
            <input type="radio" name="power" value="60" onchange="changemode(this.value)">Low</label>
        <label>
            <input type="radio" name="power" value="80" onchange="changemode(this.value)">Middle</label>
        <label>
            <input type="radio" name="power" value="100" onchange="changemode(this.value)">High</label>
    </p>

    <div class="sliders">
        <div class="box">
            <label for="slider_pwm1">Left</label>
            <input id="slider_pwm1" type="range" class="controller" min="0" max="100" value="0" />
        </div>
        <div class="box">
            <label for="slider_pwm2">Right</label>
            <input id="slider_pwm2" type="range" class="controller" min="0" max="100" value="0" />
        </div>
    </div>

    <script>
        var obniz = new Obniz("OBNIZ_ID_HERE");
        var mode = 0, pwm, pwm2;
        var power = 0;

        obniz.onconnect = async function () {
            var sensor = obniz.wired("GP2Y0A21YK0F", { vcc: 0, gnd: 1, signal: 2 })
            sensor.start(function (distance) {
                $("#dist-print").text("distance: " + distance + " mm");

                var color_scale = d3.scaleLinear()
                    .domain([0, 200, 400])
                    .range(['red', 'yellow', 'lime'])
                    ;
                changeBoxColor(color_scale(distance));

                if (mode == 1) {
                    if (distance < 150) {
                        $("#mode-print").text("RIGHT");
                        console.log("near");
                        pwm.duty(100);
                        pwm2.duty(0);
                    } else {
                        $("#mode-print").text("GO");
                        console.log("far");
                        pwm.duty(power);
                        pwm2.duty(power);
                    }
                } else {
                    $("#mode-print").text("");
                }
            })

            pwm = obniz.getFreePwm();
            pwm.start({ io: 7 });
            pwm.freq(20);
            obniz.io6.output(false);

            $("#slider_pwm1").on('input', function () {
                pwm.duty($("#slider_pwm1").val())
            });

            pwm2 = obniz.getFreePwm();
            pwm2.start({ io: 5 });
            pwm2.freq(20);
            obniz.io4.output(false);

            $("#slider_pwm2").on('input', function () {
                pwm2.duty($("#slider_pwm2").val())
            });
        };

        obniz.onclose = async function () {
            $("#slider").off('input');
            $("#slider_pwm").off('input');
            $("#slider_pwm2").off('input');
        };

        function changemode(_power) {
            power = _power;
            if (_power != 0) {
                mode = 1;
                $("#slider_pwm1").prop('disabled', true);;
                $("#slider_pwm2").prop('disabled', true);;
            } else {
                mode = 0;
                $("#slider_pwm1").prop('disabled', false);
                $("#slider_pwm2").prop('disabled', false);
                pwm.duty(0);
                pwm2.duty(0);
            }
        }

        function changeBoxColor(newColor) {
            document.getElementById('print').style.backgroundColor = newColor;
        }
    </script>
</body>

</html>
 

 

 

Recommended