====== Книга набора «Йодо» и исходный код проектов ====== Электронная версия инструкции из набора [[amp>product/yodo?utm_source=announce&utm_campaign=yodo&utm_medium=wiki|Йодо]]. Самая актуальная информация по примерам, помощь и подсказки именно здесь! {{ :yodo:yodo-book-cover.png?nolink |}} ===== Электронная версия ===== * {{https://storage.googleapis.com/media.amperka.com/products/yodo/media/yodo-amperka-prepress-09.pdf|Книга}} в формате .pdf ===== Эксперименты ===== ==== 1. Лампа ==== Светодиод сделаем, который всегда горит. Микроконтроллер использовать, чтобы просто свет включить — это перебор. Но ведь учишься ты! var myCoolLamp = require('@amperka/led').connect(P1); myCoolLamp.turnOn(); {{ :yodo:yodo-lessons-1.png?nolink |}} ==== 2. Маячок ==== Мигающий светодиод сделаем. Можешь показывать им, что живо устройство или действия ждёт. var led = require('@amperka/led').connect(P1); led.blink(0.1, 0.9); {{ :yodo:yodo-lessons-2.png?nolink |}} ==== 3. Кнопочный выключатель ==== Свтеа переключатель давай сделаем. Клик — свет включится, клик — выключится. var led = require('@amperka/led') .connect(P1); var button = require('@amperka/button') .connect(P3); function myCoolButtonHandler() { led.toggle(); } button.on('press', myCoolButtonHandler); {{ :yodo:yodo-lessons-3.png?nolink |}} ==== 4. Телеграф ==== Звуковых сообщений простых передатчик сделаем мы. Телеграмму поможет передать он. 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(); }); {{ :yodo:yodo-lessons-4.png?nolink |}} ==== 5. Диммер ==== Силы света регулятор сделаем мы. Ручку крути, чтобы сторону выбирать свою: тёмную или светлую. 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); {{ :yodo:yodo-lessons-5.png?nolink |}} ==== 6. Автоматический диммер ==== Разум диммеру дадим. Пусть тем ярче свет горит, чем окружающий мир темнее. 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); {{ :yodo:yodo-lessons-6.png?nolink |}} ==== 7. Умное освещение ==== Энергию сбережём давай. Свет во тьме включаться и на рассвете гаснуть заставим. Границу света и тьмы потенциометр задаст. 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); {{ :yodo:yodo-lessons-7.png?nolink |}} ==== 8. Элементарный синтезатор ==== Музыкой заняться пора. С космическим звучанием и одной ручкой синтезатор построим. 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); {{ :yodo:yodo-lessons-8.png?nolink |}} ==== 9. Терменвокс ==== В игру изящества добавим. К датчику ладонь приближай и отдаляй, чтобы ноту задать. 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); {{ :yodo:yodo-lessons-9-1.png?nolink |}} ==== 10. Пантограф ==== Механикой самое время заняться. Манипулятор соберём, что ручки потенциометра движение повторяет. 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); {{ :yodo:yodo-lessons-10.png?nolink |}} ==== 11. Переезд ==== Кораблей движением управлять нужно нам. Палку-управлялку сделаем, что шлагбаумом дикари зовут, со звуком и светом для надёжности пущей. Кнопку нажми, чтобы проезд закрыть. Снова нажми, чтобы открыть. 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); } }); {{ :yodo:yodo-lessons-11.png?nolink |}} ==== 12. Консольный люксометр ==== Устройство соберём, что на компьютер силу света посылает. За её величиной в виде числа сможем следить мы. 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); {{ :yodo:yodo-lessons-12.png?nolink |}} ==== 13. Экранный люксометр ==== Предыдущее устройство улучшим. Доступным родной язык станет нам. Издалека за показаниями следить возможно будет. var sensor = require('@amperka/light-sensor') .connect(A2); setInterval(function() { var lx = sensor.read('lx').toFixed(0); USB.write(lx+' lx'+'\r\n'); }, 200); {{ :yodo:yodo-lessons-13.png?nolink |}} ==== 14. HTML-термометр ==== Великий термометр сделаем, что символами крупными температуру выводит. Serial Projector знакомый используй, чтобы результат наблюдать. var thermometer = require('@amperka/thermometer') .connect(A4); setInterval(function() { var celsius = thermometer.read('C'); USB.write('
'+'temperature'+'
'+celsius.toFixed(1)+'\r\n'); }, 1000);
{{ :yodo:yodo-lessons-14.png?nolink |}} ==== 15. Ультразвуковая линейка ==== Расстояние измеряющий прибор сделаем мы. В Serial Projector смотри, чтобы точную дистанцию знать. 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); {{ :yodo:yodo-lessons-15.png?nolink |}} ==== 16. Парктроник ==== Для манёвров точных парктроник сделай. Непрерывный звук будет, когда препятствие близко. Прерывистый сигнал издаст он, если ещё до столкновения время есть. 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); {{ :yodo:yodo-lessons-16.png?nolink |}} ==== 17. Сканер ИК-пультов ==== Пульта инфракрасный свет научу видеть. Код кнопки нажатой в консоль устройство выведет. Любой пульт подойдет ему. Приём сигнала светодиод покажет. 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(); }); {{ :yodo:yodo-lessons-17.png?nolink |}} ==== 18. ИК-выключатель света==== Светом с пульта управлять будем. Кнопкой, которая свет переключает, та станет, что первой после включения платы нажмёшь. 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(); } }); {{ :yodo:yodo-lessons-18.png?nolink |}} ==== 19. Пульт киномана ==== USB-устройство построим, которое клавиатурой притворяется. Видеоплеером VLC с инфракрасного пульта сможешь управлять ты. 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]); } }); {{ :yodo:yodo-lessons-19.png?nolink |}} ==== 20. Генератор паролей ==== Устройство сделаем, что из 16 символов пароли совершенно случайные придумывает. Кнопку надолго зажми, чтобы новый пароль задумать. Кратко кнопку нажми, чтобы у курсора пароль текущий ввести. 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(); {{ :yodo:yodo-lessons-20.png?nolink |}} ==== 21. Excel-робот ==== Клавиатурного робота напишем, который каждые 5 секунд в новую строку Excel освещённость и температуру вбивает. Запись чтобы начать, Excel запусти и в ячейку А2 курсор поставь. Чтобы запись прекратить, ещё раз кнопку нажми. На ночь робота оставь. По записанным данным график построй. Изменение данных в динамике увидишь ты. 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'); }); {{ :yodo:yodo-lessons-21.png?nolink |}} ==== 22. Умный шлагбаум ==== Из проекта 11 переезд улучшим, самостоятельным сделаем его. Сам проезд закроется, если препятствие увидит. Обратно откроется он, как только на 4 секунды пустоту увидит. 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); }); {{ :yodo:yodo-lessons-22.png?nolink |}} ==== 23. Тревожная кнопка ==== Тёмные силы отпугнуть чтобы, звонкую сирену собери. Кнопку нажми, чтобы тревогу включить. Ещё раз нажми, чтобы прекратить. 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(); } }); {{ :yodo:yodo-lessons-23.png?nolink |}} ==== 24. Театральный свет ==== Для представлений свет сделай, который плавно гаснет и мягко нарастает. 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(); }); {{ :yodo:yodo-lessons-24.png?nolink |}} ==== 25. Настольный радар ==== Роботу голову соберём. Дальномер крутиться будет, чтоб перед собой пространство понять. В виде круговой диаграммы через Serial Projector работу наблюдай. 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(''); 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(''); } svg.push(''); 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); {{ :yodo:yodo-lessons-25.png?nolink |}} {{ :yodo:yodo-lessons-26.png?nolink |}} ==== А что же дальше? ==== Прошел все задания? Молодец! Теперь ты смело можешь испытать свои силы и фантазию в реализации собственных проектов. А если ты уже слышал об «Интернете вещей» и хочешь узнать, что это такое, попробуй наше [[amp>product/yodo-iot?utm_source=announce&utm_campaign=yodo&utm_medium=wiki | дополнение к набору «Йодо»]]. Ещё одно продолжение — [[amp>product/yodo-automatic-watering?utm_source=announce&utm_campaign=yodo&utm_medium=wiki | «Автополив»]] — познакомит тебя с системой автополива растений, а расширение [[amp>product/yodo-to-robonjasha?utm_source=announce&utm_campaign=yodo&utm_medium=wiki | «Робоняша»]] поможет собрать няшного мобильного робота. Всё только начинается!