- PVSM.RU - https://www.pvsm.ru -

Управление виртуальной 3D моделью через микроконтроллер на JavaScript

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

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 [1] но даже этой «оптимизации» не хватает чтоб записать в память весь код, уже не говоря о минификации самого 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 = "<div class='body'></div><script src='https://clck.ru/D8D4S'></script><script>start({x:"+pos.x+",y:"+pos.y+",z:"+pos.z+"},"+config.socket_port+")</script>";

	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 [1].

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

image

Результат.

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

image

image

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

Поки чмоки.

Автор: Александр

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/277285

Ссылки в тексте:

[1] 3D-Quarter-the-Espruino: https://github.com/JsusDev/3D-Quarter-the-Espruino

[2] Источник: https://geektimes.ru/post/299779/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox