Вопрос амперке, логика работы библиотеки @amperka/proximity

Тема в разделе "Iskra JS, Espruino, Йодо", создана пользователем Konkery, 22 фев 2017.

  1. Konkery

    Konkery Гик

    Доброго времени суток !
    Стал прикручивать модуль "Датчик приближения и освещённости" и столкнулся со странным поведением.
    В моем коде посредством вызова setInterval(...) каждые 250 мс читаю значение освещенности и в ней же
    расстояние, итог получаю только то значение которое пытаюсь считать первым.
    Изменил код так, что чтение освещенности произвожу в отдельном вызове setInterval(...), чтение расстояния
    произвожу в физически другом setInterval(...). Интервалы вызова и первого и второго setInterval(...)
    установлены в 250 мс, результат - не работает. Т.е. снова получаю значение только того что вызвал первым.
    Решил "растащить" по времени первый и второй вызовы setInterval(...). Пока не развел не менее чем в
    полтора-два раза, обращение к модулю возвращало только одно значение, обычно то которое
    считывалось по коду программы первым. Время выставил у "первого" setInterval(...) - 400 мс, у "второго" -
    800 мс. В итоге меня это окончательно запутало.
    В результате я решил 100% воспроизвести пример с вашего сайта как аппаратно так и софтверно. Сказано сделано, один в один повторил схему, результат - не работает, т.е. вообще не возвращает результат. Для справки результат выводит в терминал через console.log(...).
    Результат который удалось достичь, считывание и освещенности и расстояния до препятствия у меня заработало только при использовании двух экземпляров setInterval(...) сильно разнесенных по времени, что меня не устраивает.
    Пока патался и так и сяк завести модуль, попутно возникли вопросы, прошу прояснить:
    1. Вывод прерывания который есть в модуле ( в примере на вашем сайте его сажают на P4) - какова его роль в логике работы модуля ?
    Из документации на Troyka модуль:
    Troyka контакты
    Контакты питания:

    • земля (G) — соедините с землёй микроконтроллера;
    • питание (V) — соедините с питанием микроконтроллера;
    • прерывание (Q) — пин прерывания. Датчик приближения способен генерировать прерывания при возникновения событий во время исполнения программы. Подключите к одному из пинов микроконтроллера, поддерживающих прерывания. Если вы не используете прерывания в вашей программе, подключать не обязательно.
    В документации сказано у вас сказано, что если "...вы не используете..." то этот пин можно игнорировать. Честно говоря не понятка как я могу его использовать, ведь в библиотеки нет никаких методов его инициализации. В процессе проверки как работает код с вашего примера, я отсоединил данный пин от P4 и программа сразу перестал выводить значения, после подключения вывод показаний с датчика возобновился, таким образом получается что он очень даже используется причем не конечным программным кодом, а самой библиотекой;
    Из документации на микросхему VL6180 следует что вывод можно програмно настроить на одно из нескольких типов событий, прошу дать пояснения на что именно он настроен, и можно ли в дальнейшем работать без него.
    2. Можно ли работать с данным модулем в режиме "свободного" считывания ? т.е. не по прерываниям, а считывать значения освещенности и дистанции в моменты когда это нужно мне в моем коде ?
    3. Можно ли подряд, последовательно в синхронном режиме считать значение освещенности и значение дистанции ? Или нужно выдерживать некие тайминги или учитывать иные аспекты ? Заранее спасибо !
     
  2. Morgan

    Morgan Гик

    А можно код?
     
  3. Konkery

    Konkery Гик

    Для однозначности привожу код из примера с которым экспериментировал:

    Код (Javascript):
    // настраиваем I2C1 для работы модуля
    I2C1.setup({sda: SDA, scl: SCL, bitrate: 400000});
    // подключаем модуль к I2C1 и пину прерывания
    var prox = require('@amperka/proximity').connect({
      i2c: I2C1,
      irqPin: P4
    });
    // каждые 10 миллисекунд измеряем расстояние
    function getRange() {
      prox.range(function(error, value) {
        if (error) {
          print(error.msg);
        } else {
          print('distance:', value, 'mm');
        }
        setTimeout(getRange, 10);
      });
    }
    // каждые 10 миллисекунд измеряем освещенность
    function getAmbient() {
      prox.ambient(function(error, value) {
        if (error) {
          print(error.msg);
        } else {
          print('illuminance:', value, 'lux');
        }
        setTimeout(getAmbient, 10);
      });
    }
     
  4. Konkery

    Konkery Гик

    Ниже тоже тестовый код который у меня работал вроде устойчиво но в котором четко видна разница во времени:

    Код (Javascript):
    // настраиваем I2C1 для работы модуля
    I2C1.setup({sda: SDA, scl: SCL, bitrate: 100000});
    // подключаем модуль к I2C1 и пину прерывания
    var prox = require('@amperka/proximity').connect({
      i2c: I2C1,
      irqPin: P4
    });

    setInterval( function()
    {
      prox.ambient(function(error1, value1)
               {
                if (error1) {console.log("error_1!");}
                else {console.log(value1 +" lx");}
                });
    },600);
     
    setInterval(function()
    {
      prox.range(function(error2, value2)
                {
                  if (error2)
                    {
                      console.log("error_2!");
                    } else
                    {
                      console.log(value2 +" mm");
                    }
                  });
    }, 900);
     
  5. Konkery

    Konkery Гик

    замечу что код на основе setTimeout(...) не работал вовсе !
     
  6. Konkery

    Konkery Гик

    скорость на шине I2C уменьшал до 50 000, изменений не заметил
     
  7. Konkery

    Konkery Гик

    Так какой нибудь ответ будет ?
     
  8. ИгорьК

    ИгорьК Гуру

    Предложу вариант ответа. Если Вы хотите делать что-то точно - изучайте AVR.
    Если программировать быстро, логично, много, в несколько потоков - не выбрасывайте Iskra JS. Я их вчера три штуки по праздничным ценам забрал.

    Это мой вариант. Могу ошибаться.
     
  9. Konkery

    Konkery Гик

    Вы сами поняли что сказали ? лично я, нет)
     
  10. ИгорьК

    ИгорьК Гуру

    Теперь что касается Вашего кода. Чтобы растащить запросы между собой, я бы предложил связать запросы через callback, то есть первый запрос вызывает запуск таймера на второй. Попробуйте сделать.
     
  11. ИгорьК

    ИгорьК Гуру

    Это не так важно :) Со временем, значит :)
    Про три платы понятно? Остальное потом :)
     
    Последнее редактирование: 1 мар 2017
  12. ИгорьК

    ИгорьК Гуру

    Например. Пробуйте менять переменную interval до приемлемого значения:
    Код (Javascript):
    var interval = 500;
    // настраиваем I2C1 для работы модуля
    I2C1.setup({sda: SDA, scl: SCL, bitrate: 100000});
    // подключаем модуль к I2C1 и пину прерывания
    var prox = require('@amperka/proximity').connect({
        i2c: I2C1, irqPin: P4
    });
    function ask() {
        setTimeout(function() {
            prox.range(function(error2, value2) {
                    if (error2) {
                    console.log("error_2!");
                }
                else {
                    console.log(value2 +" mm");
                }
            });
        }, interval);
    }
    setInterval( function() {
        prox.ambient(function(error1, value1) {
            ask()
            if (error1) {console.log("error_1!");}
            else {console.log(value1 +" lx");}
        });
    },interval);
     
    Последнее редактирование: 1 мар 2017
  13. Morgan

    Morgan Гик

    Привет!

    Обновили пример на вики: http://wiki.amperka.ru/js:proximity
    После загрузки рекомендуется сбросить питание, датчик плохо реагирует на софтверный ресет.
     
    Konkery и arkadyf нравится это.