Книга набора «Йодо» и исходный код проектов

Электронная версия инструкции из набора Йодо. Самая актуальная информация по примерам, помощь и подсказки именно здесь!

Электронная версия

Эксперименты

1. Лампа

Светодиод сделаем, который всегда горит. Микроконтроллер использовать, чтобы просто свет включить — это перебор. Но ведь учишься ты!

Light.js
var myCoolLamp = require('@amperka/led').connect(P1);
myCoolLamp.turnOn();

2. Маячок

Мигающий светодиод сделаем. Можешь показывать им, что живо устройство или действия ждёт.

Beacon.js
var led = require('@amperka/led').connect(P1);
led.blink(0.1, 0.9);

3. Кнопочный выключатель

Свтеа переключатель давай сделаем. Клик — свет включится, клик — выключится.

Switch.js
var led = require('@amperka/led')
  .connect(P1);
 
var button = require('@amperka/button')
  .connect(P3);
 
function myCoolButtonHandler() {
  led.toggle();
}
 
button.on('press', myCoolButtonHandler);

4. Телеграф

Звуковых сообщений простых передатчик сделаем мы. Телеграмму поможет передать он.

Telegraph.js
var buzzer = require('@amperka/buzzer')
  .connect(P5);
 
var button = require('@amperka/button')
  .connect(P3);
 
button.on('press', function() {
  buzzer.turnOn();
});
 
button.on('release', function() {
  buzzer.turnOff();
});

5. Диммер

Силы света регулятор сделаем мы. Ручку крути, чтобы сторону выбирать свою: тёмную или светлую.

Dimmer.js
var pot = require('@amperka/pot')
  .connect(A0);
var led = require('@amperka/led')
  .connect(P1)
  .turnOn();
 
function updateBrightness() { 
  var val = pot.read();
  led.brightness(val);
}
 
setInterval(updateBrightness, 10);

6. Автоматический диммер

Разум диммеру дадим. Пусть тем ярче свет горит, чем окружающий мир темнее.

AutoDimmer.js
var led = require('@amperka/led') 
  .connect(P1)
  .turnOn();
 
var sensor = require('@amperka/light-sensor') 
  .connect(A2);
 
setInterval(function() {
  var luxes = sensor.read('lx'); 
  var level = 1 - luxes / 50; led.brightness(level);
}, 10);

7. Умное освещение

Энергию сбережём давай. Свет во тьме включаться и на рассвете гаснуть заставим. Границу света и тьмы потенциометр задаст.

SmartLight.js
var led = require('@amperka/led') 
  .connect(P1);
 
var pot = require('@amperka/pot') 
  .connect(A0);
 
var sensor = require('@amperka/light-sensor') 
  .connect(A2);
 
setInterval(function() {
  var threshold = pot.read() * 100; var luxes = sensor.read('lx');
  if (luxes < threshold) {
    led.turnOn(); 
  } else {
    led.turnOff(); 
  }
}, 10);

8. Элементарный синтезатор

Музыкой заняться пора. С космическим звучанием и одной ручкой синтезатор построим.

BasicSynth.js
var buzzer = require('@amperka/buzzer')
  .connect(P5) 
  .turnOn();
 
var pot = require('@amperka/pot') 
  .connect(A0);
 
setInterval(function() {
  var freq = 20 + 4000 * pot.read(); 
  buzzer.frequency(freq);
}, 10);

9. Терменвокс

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

Thereminvox.js
var buzzer = require('@amperka/buzzer') 
  .connect(P5)
  .turnOn();
 
var sensor = require('@amperka/light-sensor') 
  .connect(A2);
 
var button = require('@amperka/button') 
  .connect(P3);
 
button.on('press', function() { 
  buzzer.toggle();
});
 
setInterval(function() { 
  buzzer.frequency(20 * sensor.read('lx'));
}, 10);

10. Пантограф

Механикой самое время заняться. Манипулятор соберём, что ручки потенциометра движение повторяет.

Pantograph.js
var servo = require('@amperka/servo') 
  .connect(P13);
 
var pot = require('@amperka/pot') 
  .connect(A0);
 
setInterval(function() {
  var angle = 180 * pot.read(); 
  servo.write(angle);
}, 20);

11. Переезд

Кораблей движением управлять нужно нам. Палку-управлялку сделаем, что шлагбаумом дикари зовут, со звуком и светом для надёжности пущей. Кнопку нажми, чтобы проезд закрыть. Снова нажми, чтобы открыть.

Crossing.js
var trigger = require('@amperka/button') 
  .connect(P2);
 
var buzzer = require('@amperka/buzzer') 
  .connect(P5)
  .frequency(50);
 
var light = require('@amperka/led') 
  .connect(P1);
 
var barrier = require('@amperka/servo') 
  .connect(P13)
  .write(90);
 
var closed = false;
 
trigger.on('press', function() { 
  closed = !closed;
  if (closed) {
    buzzer.beep(1, 0.5); 
    light.blink(1, 0.5); 
    barrier.write(0);
  } else { 
    buzzer.turnOff(); 
    light.turnOff(); 
    barrier.write(90);
  } 
});

12. Консольный люксометр

Устройство соберём, что на компьютер силу света посылает. За её величиной в виде числа сможем следить мы.

ConsoleLightmeter.js
var sensor = require('@amperka/light-sensor') 
  .connect(A2);
 
setInterval(function() {
  var lx = sensor.read('lx').toFixed(0);
  var time = getTime().toFixed(0); 
  console.log(time, 'sec', '->', lx, 'luxes');
}, 1000);

13. Экранный люксометр

Предыдущее устройство улучшим. Доступным родной язык станет нам. Издалека за показаниями следить возможно будет.

ScreenLightmeter.js
var sensor = require('@amperka/light-sensor')
  .connect(A2);
 
setInterval(function() {
  var lx = sensor.read('lx').toFixed(0); 
  USB.write(lx+' lx'+'\r\n');
}, 200);

14. HTML-термометр

Великий термометр сделаем, что символами крупными температуру выводит. Serial Projector знакомый используй, чтобы результат наблюдать.

HTML-Thermometer.js
var thermometer = require('@amperka/thermometer')
  .connect(A4);
 
setInterval(function() {
  var celsius = thermometer.read('C'); 
  USB.write('<div style="font-size: 0.5em">'+'temperature'+'</div>'+celsius.toFixed(1)+'\r\n');
}, 1000);

15. Ультразвуковая линейка

Расстояние измеряющий прибор сделаем мы. В Serial Projector смотри, чтобы точную дистанцию знать.

UltrasonicRuler.js
var sonic = require('@amperka/ultrasonic') 
  .connect({trigPin: P10, echoPin: P11});
 
setInterval(function() { 
  sonic.ping(function(err, val) {
    if (err) { 
      USB.write(err.msg+'\r\n');
    } else {
      USB.write(val.toFixed(0)+' mm'+'\r\n'); 
    }
  }, 'mm');
}, 100);

16. Парктроник

Для манёвров точных парктроник сделай. Непрерывный звук будет, когда препятствие близко. Прерывистый сигнал издаст он, если ещё до столкновения время есть.

Parktronic.js
var sonic = require('@amperka/ultrasonic') 
  .connect({trigPin: P10, echoPin: P11});
 
var buzzer = require('@amperka/buzzer') 
  .connect(P5)
  .frequency(440);
 
setInterval(function() { 
  sonic.ping(function(err, val) {
    if (val < 5) { 
      buzzer.turnOn();
    } else if (val < 20) { 
      buzzer.beep(0.1, 0.1);
    } else if (val < 50) { 
      buzzer.beep(0.2, 0.2);
    } else {
      buzzer.turnOff(); 
    }
  }, 'cm');
}, 100);

17. Сканер ИК-пультов

Пульта инфракрасный свет научу видеть. Код кнопки нажатой в консоль устройство выведет. Любой пульт подойдет ему. Приём сигнала светодиод покажет.

IR-Scanner.js
var ir = require('@amperka/ir-receiver')
  .connect(P7);
 
var light = require('@amperka/led') 
  .connect(P1);
 
ir.on('receive', function(code, repeat) { 
  if (!repeat) {
    console.log('*******'); 
  }
 
  console.log('0x' + code.toString(16));
  light.toggle();
});

18. ИК-выключатель света

Светом с пульта управлять будем. Кнопкой, которая свет переключает, та станет, что первой после включения платы нажмёшь.

IR-LigthSwitch.js
var ir = require('@amperka/ir-receiver')
  .connect(P7);
 
var light = require('@amperka/led')
  .connect(P1);
 
var powerCode = null;
 
ir.on('receive', function(code, repeat) { 
  if (repeat) {
    return; 
  }
 
  if (powerCode === null) {
    powerCode = code; 
  }
 
  if (code === powerCode) {
    light.toggle(); 
  }
});

19. Пульт киномана

USB-устройство построим, которое клавиатурой притворяется. Видеоплеером VLC с инфракрасного пульта сможешь управлять ты.

CinephilesMate.js
var ir = require('@amperka/ir-receiver') 
  .connect(P7);
 
var kb = require('@amperka/usb-keyboard');
 
var rewindCode = 0xfd20df; 
var forwardCode = 0xfd609f; 
var playCode = 0xfda05f;
 
ir.on('receive', function(code, repeat) { 
  if (code === playCode) {
    if (!repeat) {
      kb.tap(kb.KEY.SPACE); 
    }
  } else if (code === rewindCode) { 
    kb.tap([kb.MODIFY.CTRL, kb.KEY.LEFT]);
  } else if (code === forwardCode) {
    kb.tap([kb.MODIFY.CTRL, kb.KEY.RIGHT]); 
  }
});

20. Генератор паролей

Устройство сделаем, что из 16 символов пароли совершенно случайные придумывает. Кнопку надолго зажми, чтобы новый пароль задумать. Кратко кнопку нажми, чтобы у курсора пароль текущий ввести.

PasscodeGen.js
var button = require('@amperka/button') 
  .connect(P3, {holdTime: 0.5});
 
var buzzer = require('@amperka/buzzer') 
  .connect(P5);
 
var kb = require('@amperka/usb-keyboard'); 
var random = require('@amperka/hw-random'); 
var password = '';
 
function generatePassword() { 
  password = '';
  while (password.length < 16) {
    var code = random.int(33, 126);
    password += String.fromCharCode(code); 
  }
}
 
button.on('hold', function() { 
  generatePassword(); 
  console.log(password); 
  buzzer.beep(0.1);
});
 
button.on('click', function () { 
  kb.type(password);
}); 
 
generatePassword();

21. Excel-робот

Клавиатурного робота напишем, который каждые 5 секунд в новую строку Excel освещённость и температуру вбивает. Запись чтобы начать, Excel запусти и в ячейку А2 курсор поставь. Чтобы запись прекратить, ещё раз кнопку нажми. На ночь робота оставь. По записанным данным график построй. Изменение данных в динамике увидишь ты.

ExcelRobot.js
var lightSensor = require('@amperka/light-sensor') 
  .connect(A2);
 
var thermometer = require('@amperka/thermometer') 
  .connect(A4);
 
var button = require('@amperka/button') 
  .connect(P3);
 
var kb = require('@amperka/usb-keyboard'); 
 
var timer = require('@amperka/timer')
  .create(5);
 
button.on('press', function() { 
  if (timer.isRunning()) {
    timer.stop(); 
  } else {
    timer.tick().run(); }
});
 
timer.on('tick', function() {
  var time = getTime();
  var lx = lightSensor.read('lx'); 
  var c = thermometer.read('C');
 
  kb.type(time.toFixed(0) + '\t' + 
          lx.toFixed(0) + '\t' +
          c.toFixed(0) + '\n');
});

22. Умный шлагбаум

Из проекта 11 переезд улучшим, самостоятельным сделаем его. Сам проезд закроется, если препятствие увидит. Обратно откроется он, как только на 4 секунды пустоту увидит.

SmartBarrier.js
var sonic = require('@amperka/ultrasonic') 
  .connect({trigPin: P10, echoPin: P11});
 
var buzzer = require('@amperka/buzzer') 
  .connect(P5)
  .frequency(50);
 
var light = require('@amperka/led') 
  .connect(P1);
 
var barrier = require('@amperka/servo') 
  .connect(P13)
  .write(90);
 
var hysteresis = require('@amperka/hysteresis') 
  .create({high: 0.5, highLag: 4, low: 0.5, lowLag: 0});
 
setInterval(function() { 
  sonic.ping(function(err, val) {
    if (err) return;
    hysteresis.push(val); 
  }, 'm');
}, 100);
 
hysteresis.on('low', function(val) { 
  buzzer.beep(1, 0.5); 
  light.blink(1, 0.5); 
  barrier.write(0);
});
 
hysteresis.on('high', function(val) { 
  buzzer.turnOff();
  light.turnOff();
  barrier.write(90);
});

23. Тревожная кнопка

Тёмные силы отпугнуть чтобы, звонкую сирену собери. Кнопку нажми, чтобы тревогу включить. Ещё раз нажми, чтобы прекратить.

AlarmButton.js
var button = require('@amperka/button') 
  .connect(P2);
 
var buzzer = require('@amperka/buzzer') 
  .connect(P5);
 
var light = require('@amperka/led') 
  .connect(P1);
 
var animation = require('@amperka/animation') 
  .create({
    from: 0,
    to: 1,
    loop: true, 
    updateInterval: 0.01
});
 
var armed = false;
 
animation.on('update', function(val) { 
  light.brightness(val); 
  buzzer.frequency(1000 + 4000 * val);
});
 
button.on('press', function() { 
  armed = !armed; 
  buzzer.toggle(armed); 
  light.toggle(armed);
  if (armed) { 
    animation.play();
  } else {
    animation.stop(); 
  }
});

24. Театральный свет

Для представлений свет сделай, который плавно гаснет и мягко нарастает.

TheatreLight.js
var light = require('@amperka/led') 
  .connect(P1)
  .turnOn()
  .brightness(0);
 
var button = require('@amperka/button') 
  .connect(P3);
 
var anim = require('@amperka/animation') 
  .create()
  .reverse();
 
anim.on('update', function(val) { 
  light.brightness(val);
});
 
button.on('press', function() { 
  anim.reverse().play();
});

25. Настольный радар

Роботу голову соберём. Дальномер крутиться будет, чтоб перед собой пространство понять. В виде круговой диаграммы через Serial Projector работу наблюдай.

TableRadar.js
var ultrasonic = require('@amperka/ultrasonic') 
  .connect({trigPin: P10, echoPin: P11});
 
var servo = require('@amperka/servo') 
  .connect(P13);
 
var canvas = { 
  width: 800, 
  height: 500, 
  radius: 300, 
  margin: 150
};
 
var sectors = { 
  count: 18, 
  current: 0, 
  direction: 1
};
 
sectors.values = new Array(sectors.count);
 
function dumpSvg() {
  var svg = [];
  svg.push('<svg width="' + canvas.width + 'px' +
  '" height="' + canvas.height + 'px'); 
  svg.push('" xmlns="http://www.w3.org/2000/svg">');
 
  var cx = canvas.width / 2;
  var cy = canvas.height - canvas.margin; 
  var astep = Math.PI / sectors.count;
 
  for (var i = 0; i < sectors.count; ++i) { 
    var fill = 'black';
    var stroke = 'green';
    var r = sectors.values[i];
    if (!r || r > canvas.radius) {  
      fill = 'none';
      stroke = 'white';
      r = canvas.radius;
    }
 
    if (i === sectors.current) {
      stroke = 'yellow'; 
    }
 
    var a1 = astep * i - Math.PI / 2; 
    var a2 = a1 + astep;
 
    var x1 = cx + r * Math.sin(a1); 
    var y1 = cy - r * Math.cos(a1); 
    var x2 = cx + r * Math.sin(a2); 
    var y2 = cy - r * Math.cos(a2);
 
    x1 = x1.toFixed(0); 
    y1 = y1.toFixed(0); 
    x2 = x2.toFixed(0); 
    y2 = y2.toFixed(0);
 
    svg.push('<path d="');
    svg.push('M' + cx + ' ' + cy + ' '); 
    svg.push('L' + x1 + ' ' + y1 + ' '); 
    svg.push('A'+r +' '+r +' 0,0,1, '+
             x2 + ' ' + y2 + ' '); 
    svg.push('Z');
    svg.push('" stroke="' + stroke +
             '"  fill="' +  fill + '" />');
  }
 
  svg.push('</svg>');
  svg.push('\r\n');
  USB.write(svg.join('')); 
}
 
setInterval(function() { 
  ultrasonic.ping(function(err, val) {
    sectors.values[sectors.current] = val; 
    sectors.current += sectors.direction;
    if (sectors.current === sectors.count - 1 ||
        sectors.current === 0) { 
      sectors.direction = -sectors.direction;
    }
 
    servo.write(sectors.current *180 / sectors.count);
    dumpSvg(); 
  }, 'mm');
}, 300);

А что же дальше?

Прошел все задания? Молодец! Теперь ты смело можешь испытать свои силы и фантазию в реализации собственных проектов. А если ты уже слышал об «Интернете вещей» и хочешь узнать, что это такое, попробуй наше дополнение к набору «Йодо». Ещё одно продолжение — «Автополив» — познакомит тебя с системой автополива растений, а расширение «Робоняша» поможет собрать няшного мобильного робота. Всё только начинается!