[Из песочницы] Управление виртуальной 3D моделью через микроконтроллер на JavaScript

Добрый день, хочется представить очередное свое произведение рукотворчества, свою подделку »3D-Quarter-the-Espruino» и рассказать о проблемах с которыми я столкнулся в процессе изготовления устройства.

image

Видео


Первая трудность с которой я столкнулся была совсем неочевидной я даже не думал о том что у Espruino всего один аналоговый пин, так как для моего устройства потребуется минимум два таких пина, но я не растерялся и придумал костыль.

image

Я решил что можно решить эту проблему путем последовательного переключения между переменными резисторами путем использования транзисторов.

image

Но как бы не так, транзисторы не справились с этой задачей (ибо нужна Гальваническая развязка), да и как оказалось их у меня почти не осталось для опытов.

На помощь пришла оптопара никогда до этого я ее не использовал, оказался очень даже практичный компонент.

image

Теперь схема выглядит так.

image

Теперь немного JavaScript кода, увы Espruino не поддерживает ES6.

эта функция собирает в массив информацию с единственного аналогового пина в массив, после того как 3 позиции в массиве заполнены он формируется в объект и передается в callback.

function Listener(obj, callback) {

        var indexPin = 0, dataPins = []; 
        
        setInterval(function () {

                if (indexPin == 1) {
                        digitalWrite(obj.pin3, 0); 
                        // переключаемся между пинами отключая один 
                        digitalWrite(obj.pin1, 1);
                         // и включая следующий
                }
                
                if (indexPin == 2) {
                        digitalWrite(obj.pin1, 0);
                        digitalWrite(obj.pin2, 1);
                }

                if (indexPin == 3) {
                        digitalWrite(obj.pin2, 0);
                        digitalWrite(obj.pin3, 1);  
                }

                if (indexPin > 2) { indexPin = 0; }
            
                indexPin++;

                dataPins.push(analogRead(0).toFixed(3)); 
                // считываем пин и ограничиваем дробное до 3 чисел после точки 
                // (чтобы не трясло)

                if (dataPins.length > 2) {

                        callback({
                                y: dataPins[0],
                                x: dataPins[1],
                                z: dataPins[2]
                        });

                        dataPins = [];
    
                }
        }, obj.speed); // скорость считывания пина

}


следующая проблема с которой я столкнулся была более тривиальной это — ограниченная память микроконтроллера.

Изначально я хотел вообще хранить часть кода на ПК и запуская сервер на Node.JS хостить страничку, а на Esp только цеплять веб сокеты Страничка подгружается с GitHub, но даже этой «оптимизации» не хватает чтоб записать в память весь код, уже не говоря о минификации самого JavaScript кода. поэтому устройство может работать только после загрузки в него кода и до того пока не будет отключено.

image

Код готовый к записи:


function Listener(obj, callback) {
        
        var indexPin = 0, dataPins = [];

        setInterval(function () {

                if (indexPin == 1) {
                        digitalWrite(obj.pin3, 0);
                        digitalWrite(obj.pin1, 1);
                }
                
                if (indexPin == 2) {
                        digitalWrite(obj.pin1, 0);
                        digitalWrite(obj.pin2, 1);
                }
            
                if (indexPin == 3) {
                        digitalWrite(obj.pin2, 0);
                        digitalWrite(obj.pin3, 1);  
                }

                if (indexPin > 2) { indexPin = 0; }

                indexPin++;

                dataPins.push(analogRead(0).toFixed(3));

                if (dataPins.length > 2) {

                        callback({
                                y: dataPins[0],
                                x: dataPins[1],
                                z: dataPins[2]
                        });

                        dataPins = [];

                }

        }, obj.speed);

}

function Connect(obj, callback) {

        const wifi = require("Wifi");

        wifi.connect(obj.ssid, { password: obj.password },function(err) {

                if(err){return;}

                wifi.getIP(function(res) {

                        console.log(res.ip);

                        callback();

                });

        });

}

function Server(port, callback) {

        const Http = require("http");

        Http.createServer(callback).listen(port);

}

function WebSocket(port, callback) {

        const WS = require("ws");

        const server = WS.createServer();

        server.listen(port);

        server.on("websocket", callback);

}

function HTML_Page(config, req, res) {

        const pos = config.correction_position;

        const HTML = "
"; res.writeHead(200, {'Content-type':'text/html'}); res.end(HTML); } function init (config) { Connect(config.wifi, function () { digitalWrite(2,0); console.log("Connect wifi: "+config.wifi.ssid); Server(config.server_port, function (req, res) { HTML_Page(config, req, res); }); Listener(config.listen_pin, function (data) { Data = data; }); WebSocket(config.socket_port,function (Ws) { Ws.on('message', function () { Ws.send(JSON.stringify(Data)); }); }); }); } /* * функция в которую передаются все * необходимые настройки для старта программы */ init({ wifi: { ssid: "Имя точки доступа", password: " Пароль точки доступа" }, socket_port: 8000, server_port: 80, listen_pin: { pin1: 13, pin2: 12, pin3: 15, speed: 30 }, correction_position: { x: 0.3, y: 0.025, z: -0.03 } // объект для коррекции позиции модели });


Минифицированный код можно найти на GitHub.

Вот так выглядит схема готового устройства.

image

Результат.


И еще парочка фото.

image

image

Я собирал из тех компонентов которые у меня были, а оптопару вообще мне пришлось долго искать. И они вовсе не самые оптимальные для этого устройства, поэтому не буду указывать точные названия компонентов их будет очень просто подобрать.

Поки чмоки.

© Geektimes