Внимание.
У меня впаяна ESP-07 вместо оригинальной ESP-12E (различаются они количеством пинов)
Первая трудность с которой я столкнулся была совсем неочевидной я даже не думал о том что у Espruino всего один аналоговый пин (вход), так как для моего устройства потребуется минимум два таких пина, но я не растерялся и придумал костыль.
Я решил что можно решить эту проблему путем последовательного переключения между переменными резисторами путем использования транзисторов.
Но как бы не так, транзисторы не справились с этой задачей (ибо нужна Гальваническая развязка), да и как оказалось их у меня почти не осталось для опытов.
На помощь пришла оптопара никогда до этого я ее не использовал, оказался очень даже практичный компонент.
Теперь схема выглядит так.
Теперь немного 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); // скорость считывания пина
}
следующая проблема с которой я столкнулся была более тривиальной это — ограниченная память микроконтроллера.
Код готовый к записи:
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.
Вот так выглядит схема готового устройства.
Результат.
И еще парочка фото.
Я собирал из тех компонентов которые у меня были, а оптопару вообще мне пришлось долго искать. И они вовсе не самые оптимальные для этого устройства, поэтому не буду указывать точные названия компонентов их будет очень просто подобрать.
Поки чмоки.
Комментарии (11)
Garbus
09.04.2018 03:48А еще для «карманно-колхозного» варианта можно было обойтись тремя диодами. Просто считывающий импульс подавать на сам резистор, а не держать постоянно запитанным.
Но вообще подобные штуки лучше хоть как-то дополнять фильтрами, а то так и будет проявляться «дрожание» управляющего сигнала.
TxN
09.04.2018 09:40Как раз только вчера вытащил из закромов еспшку с намерением сделать ArduBoy с аналоговым джойстиком, а тут оказывается такая засада (совсем из головы вылетело, что в 8266 всего один аналоговый вход), а тут как раз готовое решение, спасибо.
Хотя есть еще вариант со внешним АЦП, может его проще будет использовать, чем делить один вход на два канала.dmitryrf
09.04.2018 14:22Можно взять простой аналоговый мультиплексор:
www.aliexpress.com/item/CJMCU-4051-74HC4051-8-Channel-Mux-Analog-Multiplexer-Selector-Module/32784934785.html
smart_alex
09.04.2018 09:57Управление виртуальной 3D моделью через микроконтроллер на JavaScript есть в стандартной поставке АМС для десятка платформ от Mega до ESP32. Всё хранится внутри контроллера и никакие сторонние хранилища не нужны. После выключения питания тоже ничего не пропадает.
Причём одна из моделей отображает состояние реальных объектов в реальном же времени.
https://geektimes.ru/post/274326/
dmsav
09.04.2018 11:58Очень классно. Очень понравились гифки: наглядно, просто и красиво. Могли бы сказать пожалуйста, в какой программе делали?
И для чего именно делали такое устройство? Демонстрационная установка?JsusDev Автор
09.04.2018 12:21Анимацию рисовал сам в программе sothink swf quicker (но советую adobe premiere pro)
делал устройство потому что было желание посмотреть как это будет работать с через websocket микроконтроллеров, сама страничка с моделью сделана еще в 2016 году и в оригинале управляется мышкой. С пином действительно получилось очень неожиданно и практически из за этого родилось желание написать статью к тому же я давно этого хотел.dmsav
09.04.2018 12:39Получилось да интересно. Как раз сейчас стоит задача, обратная вашей: с одного аналогового пина Arduino нужно задавать несколько аналоговых сигналов. Рассматриваю похожее решение вот.
IgorKKK
"у Espruino всего один аналоговый пин"
Прочитает доверчивый человек и сильно расстроится. Поверит и никогда не обратится к столь хорошей оболочке.
Полагаю, речь идет о ESP-8266 под управлением Espruino — самом неподходящем железе для этой системы. Потому как у всех остальных железяк много аналоговых ног.
JsusDev Автор
Действительно аналоговый пин один в моем случае с (esp07), принял ваш комментарий к сведенью, внес правки.