Raspberry Pi + Iskra JS + nodejs raspi-serial

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем Жиктор, 10 окт 2018.

  1. Жиктор

    Жиктор Нерд

    Всем санбона ботсвана!

    Дано:
    - Raspberry Pi какая-то из последних.
    - Iskra JS.

    Найти:
    Необходимо отправить команду включения лампочки напрямую из малины в искру через nodejs

    Мое решение:
    На малину я поставил операционную систему Raspbian (with desktop), подключил монитор, клавиатуру и мышь. Настроил вайфай. Поставил nodejs, npm, git, pm2. Загрузил helloworld проект на nodejs. Проверил работоспособность: со своего основного компьютера вижу сайт, который запускается на малине. Отлично.
    Затем я загрузил Espruino Web IDE, подключил проводом Искру к Малине через usb. Всё приконнектилось. Команды отрабатывают (рис 1.)
    [​IMG]

    Как видно на изображении подключение идёт через порт /dev/ttyACM0.
    Я запускаю две команды LED1.write(1) и LED1.write(0) соответственно для включения/отключения лампочки.

    Далее, я добавил в свой хеллоуворлд проект пакеты raspi и raspi-serial. По ссылке есть инструкция по использованию.
    Добавил файл led.js и роутинг под него, вот код:
    Код (Javascript):
    'use strict';
    var express = require('express');
    var router = express.Router();

    const raspi = require('raspi').init;
    const Serial = require('raspi-serial').Serial;

    router.get('/', function (req, res) {
        var kk = req.query.p;
        console.log(kk);

        var serial = new Serial('/dev/ttyacm0/');
        serial.open(() => {
            serial.write('LED1.write(1);');
            console.log('LED1.write('+kk+');');
        });
     
        res.send(kk ? 'led on' : 'led off');
    });

    module.exports = router;
    Собственно, я подключаюсь к тому самому порту, через который работала и Web IDE, и пытаюсь выполнить лишь одну команду serial.write('LED1.write(1);');
    Код отрабатывает без ошибок (первый раз), но лампочка не загорается. Второй раз выпадает ошибка, что порт уже открыт и нельзя его открыть еще раз. То есть я как-то неправильно работаю с этой библиотекой.

    Подскажите, пожалуйста, был ли у кого-то подобный опыт? Быть может есть где-то другие инструкции?

    UPD:
    Подсказали, что закрывать надо так же внутри анонимной функции, переменная serial будет видна
    Код (Javascript):
    var serial = new Serial('/dev/ttyacm0/');
        serial.open(() => {
            serial.write('LED1.write(1);');
            serial.close();
        });
    Остается главный вопрос, как правильно использовать serial.write('LED1.write(1);'); чтоб работало
     

    Вложения:

    • gURQt3obI4c.jpg
      gURQt3obI4c.jpg
      Размер файла:
      108,6 КБ
      Просмотров:
      31
    Последнее редактирование: 10 окт 2018
  2. не надо порт открывать при каждом запросе, не закрывая
    либо закрывайте, либо откройте один раз и держите открытым
     
    sys, arkadyf и Mitrandir нравится это.
  3. Жиктор

    Жиктор Нерд

    Доброго дня!
    Спасибо за участие.
    Я не уверен как правильно это делать. Попробую вечером в файле index.js (где стартует сервер) добавить эти строчки:
    Код (Javascript):

    const Serial = require('raspi-serial').Serial;
    //...
    var serial =new Serial('/dev/ttyacm0/');
    serial.open();
    Но в файле led.js (который описывал в первом посте, со своим роутингом)
    мне так же необходимо будет импортировать библиотеку и создать объект
    Код (Javascript):

    const Serial = require('raspi-serial').Serial;
    var serial =new Serial('/dev/ttyacm0/');
    serial.write('LED1.write(1);');
     
    Так как будет создаваться новый объект через new, то я не уверен, что нода корректно будет работать с таким кодом. Но я попробую вечером.

    В любом случае, это не решает проблему, лампочка не загорается на строчке serial.write('LED1.write(1);'); и я не знаю, как это написать правильно.

    И я не понимаю как правильно закрыть. Из-за асинхронности яваскрипта, если написать
    Код (Javascript):
    var serial = new Serial('/dev/ttyacm0/');
        serial.open(() => {
            serial.write('LED1.write(1);');
        });
        serial.close();
    В таком случае порт вначале откроется, затем сразу закроется, а после этого зайдет в функцию колбек и свалится с ошибкой
     
  4. Ну надо наверно закрывать после отправки текста, а не совсем сразу.
     
  5. sys

    sys Злобный Буратино

    Код (Javascript):
    var serial = new Serial('/dev/ttyACM0');
     
    Жиктор нравится это.
  6. Жиктор

    Жиктор Нерд

    Привет, в смысле, в конце не нужно обратный слеш ставить, в этом и была загвоздка? И шрифт, чувствительный к регистру (про шрифт не уверен, переменная serial у меня заполнялась)? Попробую вечером, отпишусь.
    Спасибо
     
  7. sys

    sys Злобный Буратино

    и слеш в конце не нужен и в Linux регистр имеет значение...
    Ради эксперимента запустите Espruino IDE, подключите Искру и из линуксового терминала в командной строке bash введите:
    Код (Bash):
    echo "print('kuku')" > /dev/ttyACM0
    Видите реакцию в консоле IDE? а теперь сравните с:
    Код (Bash):
    echo "print('kuku')" > /dev/ttyacm0
     
    Жиктор нравится это.
  8. Жиктор

    Жиктор Нерд

    Hi!
    Write from rpi )
    console.log(serial)
    Код (Javascript):
    Serial {
      _events: {},
      _eventsCount: 0,
      _maxListeners: undefined,
      _alive: true,
      _pins: [ 15, 16 ],
      _portId: '/dev/ttyAMA0',
      _options:
       { portId: '/dev/ttyAMA0',
         baudRate: 9600,
         dataBits: 8,
         stopBits: 1,
         parity: 'none' } }
     
    When i write
    Код (Javascript):
    var serial = new Serial('/dev/ttyACM0');
    portId set to /dev/ttyAMA0', when I write
    Код (Javascript):
    var serial = new Serial('/dev/ttyacm0');
    portId set to /dev/ttyAMA0',
    wtf?

    Код (Bash):
    echo "LED1.write(1)" > /dev/ttyACM0
    echo "LED1.write(false)" > /dev/ttyACM0
    Work fine! Thanks for this!
     
  9. sys

    sys Злобный Буратино

    не знаю, наверно модуль с интеллектуальной подстановкой :)
    в итоге-то всё заработало как надо?
     
  10. Жиктор

    Жиктор Нерд

    Привет!
    Через библиотеку raspi-serial ничерта не работает. Я ему пишу один порт (ACM0), он мне выводит, что подключился к другому (AMA0). Еще и указывает _pins:[15,16]. Я вначале грешил на единственный подключенный прибор - кулер. Но я его вырубил, перезагрузился, всё равно так подключается.
    Ну и, собственно, не работает.
    У меня пока не было времени, я попробую посмотреть как напрямую из node js кидать команды в командную строку. Если так получится, то будет хорошо, мне лишь бы работало.
    Если не получится, я возьму дополнительные провода и соединю по UART через пины, но мне бы хотелось, конечно, без дополнительных проводов.

    С командами из консоли тоже, конечно, интересная история. LED1.write(1) включает лампочку, LED1.write(true) - не включает лампочку, LED1.write(0) - не работает, LED1.write(false) выключает лампочку.
     
  11. А вы с чего вообще решили, что порт указывается первым аргументом к конструктору? Вы просто подключаетесь к порту по умолчанию, что бы вы там ни вводили.
     
    Последнее редактирование: 17 окт 2018
    sys и Жиктор нравится это.
  12. Жиктор

    Жиктор Нерд

    Вы правы, это всё объясняет. Почитал внимательнее документацию, надо в options пихать.
    Просто в примере вообще ничего не было указано, я передал параметром и обрадовался, что всё функционирует. Я был невнимателен, спасибо
     
    sys нравится это.
  13. Жиктор

    Жиктор Нерд

    Привет всем, кто следит за обновлениями

    Я подключился к нужному порту так:
    Код (Javascript):

    var serial =new Serial({ portId : '/dev/ttyACM0' });
    serial.open(()=>{
            serial.write('LED1.write(1);');
       });
     
    При выполнении никаких ошибок (закрывать порт тоже не обязательно). Но не пашет.
    Если я подключаюсь к этому же порту через Espruino Web IDE, то тогда мой вышеописанный код отсылает данные в консоль этой IDE. То есть не выполняет, а прописывает в консоли.
    Остается нажать Enter. Следующий запуск кода дописывает в консоль в конец предыдущей записи.
    Я не знаю как правильно выполнить эти данные. Как бы нажать программно Enter.

    Я пробовал дописывать обработчик на Искре:
    Код (Javascript):

     USB.on("data", function(data) {
        //eval(data)();
        LED1.write(data);
     });
     
    Отправлял и куски кода и просто 1, 0, true, false, никакой реакции.
     
  14. sys

    sys Злобный Буратино

    Почитайте про обмен данными с платой через USB http://forum.amperka.ru/threads/f-a-q-ЧаВо-Прежде-чем-задать-вопрос-на-форуме.12591/#post-125368
    Может поможет ;)
     
    Жиктор нравится это.
  15. Жиктор

    Жиктор Нерд

    Привет!
    Специально обученный человек забрал заказ, в котором были провода мама-папа, в субботу я настроил передачу через стандартный распберевский '/dev/ttyAMA0' (пины 15 и 16) и Serial3 (пины 0 и 1) на искре.
    Ссылка как надо, именно это я и спрашивал в самом начале, так у меня получается три лишних провода прокинуто. Думаю, что можно отмечать как решено, хотя пока я поживу с лишними проводами. Может быть когда-нибудь вернусь к этой теме и прокину через usb )
    Спасибо, sys!