Из этой статьи мы с вами узнаем, как собрать последовательный контролер и с помощью него запустить игру на компьютере. Эта самоделка будет интересно, прежде всего, начинающим Ардуиноведам.
Инструменты и материалы:-Arduino Nano;-Макетная плата;-Провод;-Резистор 10 кОм;-Кнопка выключения;-Переменный резистор;-Потенциометр;-Светодиодная лента с 3 светодиодами;
-Клей;
-Лазерный резак;-Паяльные принадлежности;
-Картон;
-Малярный скотч;
Шаг первый: подготовка деталей
Сначала нужно подготовить комплектующие.
На кнопке есть три контакта. Для данной сборки нужны всего два. К контакту N0 нужно припаять один провод, а к контакту COM два. Один из этих проводов припаивается через резистор.
К ползунковому резистору нужно припаять три провода к разным контактным площадкам.
В схеме используется неопиксельная светодиодная лента. На ленте есть три контактные площадки. К этим площадкам нужно припаять провода.
У потенциометра есть тоже три контактные площадки, к которым припаиваются провода.Шаг второй: схема
Дальше нужно произвести монтаж деталей согласно схемы. Мастер использовал аналоговый входной контакт 0 для потенциометра, аналоговый входной контакт 1 для ползунка, цифровой контакт 9 для светодиодной ленты и цифровой контакт 8 для кнопки.Шаг третий: корпус
Для проектирования корпуса мастер использовал программу MakerCase. Файлы для резки деталей можно скачать ниже.
serial_game_box.svgШаг четвертый: сборка
Дальше собирает корпус. Для фиксации деталей частично использует клей, частично малярный скотч.Шаг пятый: программирование
Сначала нужно загрузить код для взаимодействия комплектующих и Ардуино. Для светодиодной ленты так же нужно установить библиотеку Adafruit NeoPixel.
Код можно скачать ниже.
serialgamecode.ino
Дальше нужно загрузить код для игры. Мастер приводит код, но любой пользователь может загрузить свой код,для своей игры.
Мастер скачал код отсюда. Когда эта программа запускается с Arduino, она генерирует стартовый код для приема последовательного вывода от Arduino в p5.js.
Приведенный ниже код определяет логику игры и написан на p5.js.


//input your port on line 12, OR delete this and copy the starter code from the P5.serialcontrol application
let serial;
let latestData = "waiting for data";
let potent = 0;
let slider = 0;
let button = 0;
let score = 0;
var x1 = 70;
var y1 = 10;
let plants = [];
let rainmeters = [];
let rain = [];
let MAXRAIN = 100;
let currentRainCount = 0;
let needFill = false;
let gameover = false;
var angle = 0;
var speed = 0;
function setup() {
createCanvas(windowWidth, windowHeight);
for(let i = 0; i < 3; i++){
let px = random(0,400);
let rainmeter = new RainMeter(px,700,99,10);
let plant = new Plant(px,700, 50, rainmeter);
plants.push(plant);
}
serial = new p5.SerialPort();
serial.list();
serial.open('COM13');
serial.on('connected', serverConnected);
serial.on('list', gotList);
serial.on('data', gotData);
serial.on('error', gotError);
serial.on('open', gotOpen);
serial.on('close', gotClose);
serial.write('f');
}
function serverConnected() {
print("Connected to Server");
}
function gotList(thelist) {
print("List of Serial Ports:");
for (let i = 0; i < thelist.length; i++) {
print(i + " " + thelist[i]);
}
}
function gotOpen() {
print("Serial Port is Open");
}
function gotClose(){
print("Serial Port is Closed");
latestData = "Serial Port is Closed";
}
function gotError(theerror) {
print(theerror);
}
//Where data comes in and we can do something with it
//Data comes in as a String
function gotData() {
let currentString = serial.readLine();
if(currentString.length > 0){
//splits string at delimeter
let sensorArray = split(currentString, ",");
//Set variables to appropriate index of array and convert string to number
slider = Number(sensorArray[0]);
potent = Number(sensorArray[1]);
button = Number(sensorArray[2]);
}
}
function draw() {
background("Moccasin");
if(!gameover){
for(let i = 0; i < 3; i++){
plants[i].show();
plants[i].rainmeter.show();
plants[i].rainmeter.deplete();
}
textSize(20);
text('Score: '+score, 600, 30);
if(potent <= 10){
fill("red");
text('Fill: OFF',600,50);
}
else if(potent > 10 && potent <= 100){
text('Fill: '+potent+"%",600,50);
}
else{
fill("green");
text('Fill: FULL',600,60);
}
let rainmeter = new RainMeter();
fill("lightblue");
ellipse(x1,10,100,30);
fill("blue");
ellipse(700,700,300,30);
x1 = slider;
if(button == 1 && !needFill && potent <= 10){
let raindrop = new RainDrop(x1,y1);
rain.push(raindrop);
currentRainCount += 1;
if(currentRainCount == 50){
serial.write('h');
}
if(currentRainCount == 80){
serial.write('c');
}
}
if(currentRainCount >= MAXRAIN){
needFill = true;
serial.write('x');
}
for(let i = 0; i < rain.length; i++){
rain[i].show();
rain[i].move();
}
for(let i = 0; i < plants.length; i++){
plants[i].checkHit();
}
//Hover cloud over the lake to refill
if(slider >= 610 && potent >= 100){
needFill = false;
currentRainCount = 0;
serial.write('f');
}
}
else{
fill("red");
textSize(30);
text('A tree has dried out.',250,200);
textSize(50);
text('Game Over',250,250);
fill("blue");
textSize(30);
text('Final score: '+score, 250,400);
}
}
function keyTyped(){
if(key === 'r' || key === 'x'){
serial.write(key);
}
}
class Plant{
constructor(x,y,r,rainmeter){
this.x = x;
this.y = y;
this.r = r;
this.rainmeter = rainmeter;
this.stars = 0;
}
show(){
fill("brown");
rect(this.x-9,this.y-20,20,20);
rect(this.x-9,this.y,20,20);
fill("green");
ellipse(this.x,this.y-70,this.r * 2);
}
checkHit(){
for(let i = 0; i < rain.length; i++){
let distance = dist(rain[i].x, rain[i].y, this.x, this.y)
if(distance <= this.r){
let addScore = this.rainmeter.water();
if(addScore){
score += 1;
}
rain.shift();
}
}
}
}
class RainDrop{
constructor(x,y){
this.x = random(x1-30,x1+30);
this.y = y;
}
show(){
fill("blue");
rect(this.x,this.y,20,20);
}
move(){
this.y = this.y + 10;
}
}
class RainMeter{
constructor(x,y,bx,by){
this.x = x;
this.y = y;
this.bx = bx;
this.by = by;
}
show(){
fill("white");
rect(this.x-50,this.y-150,100,10);
fill("blue");
rect(this.x-50,this.y-150,this.bx,this.by);
}
deplete(){
if(this.bx > 0){
this.bx = this.bx - 0.1;
}
else{
gameover = true;
}
}
water(){
if(this.bx < 100){
this.bx = this.bx + 1;
return false;
}
return true;
}
}
Для наброска кода p5 также требуется дополнительный файл с именем p5.serialport.js:
/*! p5.serialport.js v0.0.1 2015-07-23 */
/**
* @module p5.serialport
* @submodule p5.serialport
* @for p5.serialport
* @main
*/
/**
* p5.serialport
* Shawn Van Every (Shawn.Van.Every@nyu.edu)
* ITP/NYU
* LGPL
*
* https://github.com/vanevery/p5.serialport
*
*/
(function(root, factory) {
if (typeof define === 'function' && define.amd)
define('p5.serialport', ['p5'], function(p5) {
(factory(p5));
});
else if (typeof exports === 'object')
factory(require('../p5'));
else
factory(root['p5']);
}(this, function(p5) {
// =============================================================================
// p5.SerialPort
// =============================================================================
/**
* Base class for a serial port. Creates an instance of the serial library and prints "hostname":"serverPort" in the console.
*
* @class p5.SerialPort
* @constructor
* @param {String} [hostname] Name of the host. Defaults to 'localhost'.
* @param {Number} [serverPort] Port number. Defaults to 8081.
* @example
* var portName = '/dev/cu.usbmodem1411'; //enter your portName
*
*function setup() {
* createCanvas(400, 300);
* serial = new p5.SerialPort()
* serial.open(portName);
*}
*/
p5.SerialPort = function(_hostname, _serverport) {
var self = this;
this.bufferSize = 1; // How much to buffer before sending data event
this.serialBuffer = [];
//this.maxBufferSize = 1024;
this.serialConnected = false;
this.serialport = null;
this.serialoptions = null;
this.emitQueue = [];
this.clientData = {};
this.serialportList = [];
if (typeof _hostname === 'string') {
this.hostname = _hostname;
} else {
this.hostname = "localhost";
}
if (typeof _serverport === 'number') {
this.serverport = _serverport;
} else {
this.serverport = 8081;
}
try {
this.socket = new WebSocket("ws://" + this.hostname + ":" + this.serverport);
console.log(("ws://" + this.hostname + ":" + this.serverport));
} catch (err) {
if (typeof self.errorCallback !== "undefined") {
self.errorCallback("Couldn't connect to the server, is it running?");
}
}
this.socket.onopen = function(event) {
console.log('opened socket');
serialConnected = true;
if (typeof self.connectedCallback !== "undefined") {
self.connectedCallback();
}
if (self.emitQueue.length > 0) {
for (var i = 0; i < self.emitQueue.length; i ++){
self.emit(self.emitQueue[i]);
}
self.emitQueue = [];
}
};
this.socket.onmessage = function(event) {
var messageObject = JSON.parse(event.data);
// MESSAGE ROUTING
if (typeof messageObject.method !== "undefined") {
if (messageObject.method == 'echo') {
} else if (messageObject.method === "openserial") {
if (typeof self.openCallback !== "undefined") {
self.openCallback();
}
} else if (messageObject.method === "data") {
// Add to buffer, assuming this comes in byte by byte
self.serialBuffer.push(messageObject.data);
if (typeof self.dataCallback !== "undefined") {
// Hand it to sketch
if (self.serialBuffer.length >= self.bufferSize) {
self.dataCallback();
}
}
if (typeof self.rawDataCallback !== "undefined") {
self.rawDataCallback(messageObject.data);
}
} else if (messageObject.method === 'list') {
self.serialportList = messageObject.data;
if (typeof self.listCallback !== "undefined") {
self.listCallback(messageObject.data);
}
} else if (messageObject.method === "close") {
if (typeof self.closeCallback !== "undefined") {
self.closeCallback();
}
} else if (messageObject.method === "write") {
// Success Callback?
} else if (messageObject.method === "error") {
//console.log(messageObject.data);
if (typeof self.errorCallback !== "undefined") {
self.errorCallback(messageObject.data);
}
} else {
// Got message from server without known method
console.log("Unknown Method: " + messageObject);
}
} else {
console.log("Method Undefined: " + messageObject);
}
};
this.socket.onclose = function(event) {
if (typeof self.closeCallback !== "undefined") {
self.closeCallback();
}
};
this.socket.onerror = function(event) {
if (typeof self.errorCallback !== "undefined") {
self.errorCallback();
}
};
};
/**
*
* @method emit
* @private
* @return
* @example
*
*/
p5.SerialPort.prototype.emit = function(data) {
if (this.socket.readyState == WebSocket.OPEN) {
this.socket.send(JSON.stringify(data));
} else {
this.emitQueue.push(data);
}
};
/**
* Tells you whether p5 is connected to the serial port.
*
* @method isConnected
* @return {Boolean} true or false
* @example
* var serial; // variable to hold an instance of the serialport library
* var portName = '/dev/cu.usbmodem1411';
*
* function setup() {
* createCanvas(400, 300);
* serial = new p5.SerialPort();
* serial.open(portName);
* println(serial.isConnected());
* }
*/
p5.SerialPort.prototype.isConnected = function() {
if (self.serialConnected) { return true; }
else { return false; }
};
/**
* Lists serial ports available to the server.
* Synchronously returns cached list, asynchronously returns updated list via callback.
* Must be called within the p5 setup() function.
* Doesn't work with the p5 editor's "Run in Browser" mode.
*
* @method list
* @return {Array} array of available serial ports
* @example
* function setup() {
* createCanvas(windowWidth, windowHeight);
* serial = new p5.SerialPort();
* serial.list();
* serial.open("/dev/cu.usbmodem1411");
* }
*
* For full example: Link
* @example
* function printList(portList) {
* // portList is an array of serial port names
* for (var i = 0; i < portList.length; i++) {
* // Display the list the console:
* println(i + " " + portList[i]);
* }
* }
*/
p5.SerialPort.prototype.list = function(cb) {
if (typeof cb === 'function') {
this.listCallback = cb;
}
this.emit({
method: 'list',
data: {}
});
return this.serialportList;
};
/**
* Opens the serial port to enable data flow.
* Use the {[serialOptions]} parameter to set the baudrate if it's different from the p5 default, 9600.
*
* @method open
* @param {String} serialPort Name of the serial port, something like '/dev/cu.usbmodem1411'
* @param {Object} [serialOptions] Object with optional options as {key: value} pairs.
* Options include 'baudrate'.
* @param {Function} [serialCallback] Callback function when open completes
* @example
* // Change this to the name of your arduino's serial port
* serial.open("/dev/cu.usbmodem1411");
*
* @example
* // All of the following are valid:
*serial.open(portName);
*serial.open(portName, {}, onOpen);
*serial.open(portName, {baudrate: 9600}, onOpen)
*
*function onOpen() {
* print('opened the serial port!');
*}
*/
p5.SerialPort.prototype.open = function(_serialport, _serialoptions, cb) {
if (typeof cb === 'function') {
this.openCallback = cb;
}
this.serialport = _serialport;
if (typeof _serialoptions === 'object') {
this.serialoptions = _serialoptions;
} else {
//console.log("typeof _serialoptions " + typeof _serialoptions + " setting to {}");
this.serialoptions = {};
}
// If our socket is connected, we'll do this now,
// otherwise it will happen in the socket.onopen callback
this.emit({
method: 'openserial',
data: {
serialport: this.serialport,
serialoptions: this.serialoptions
}
});
};
/**
* Sends a byte to a webSocket server which sends the same byte out through a serial port.
* @method write
* @param {String, Number, Array} Data Writes bytes, chars, ints, bytes[], and strings to the serial port.
* @example
* You can use this with the included Arduino example called PhysicalPixel.
* Works with P5 editor as the socket/serial server, version 0.5.5 or later.
* Written 2 Oct 2015 by Tom Igoe. For full example: Link
*
* function mouseReleased() {
* serial.write(outMessage);
* if (outMessage === 'H') {
* outMessage = 'L';
* } else {
* outMessage = 'H';
* }
*}
*
* For full example: Link
* @example
* function mouseDragged() {
* // map the mouseY to a range from 0 to 255:
* outByte = int(map(mouseY, 0, height, 0, 255));
* // send it out the serial port:
* serial.write(outByte);
*}
*/
p5.SerialPort.prototype.write = function(data) {
//Writes bytes, chars, ints, bytes[], Strings to the serial port
var toWrite = null;
if (typeof data == "number") {
// This is the only one I am treating differently, the rest of the clauses are meaningless
toWrite = [data];
} else if (typeof data == "string") {
toWrite = data;
} else if (Array.isArray(data)) {
toWrite = data;
} else {
toWrite = data;
}
this.emit({
method: 'write',
data: toWrite
});
};
/**
* Returns a number between 0 and 255 for the next byte that's waiting in the buffer.
* Returns -1 if there is no byte, although this should be avoided by first checking available() to see if data is available.
*
* @method read
* @return {Number} Value of the byte waiting in the buffer. Returns -1 if there is no byte.
* @example
* function serialEvent() {
* inByte = int(serial.read());
*byteCount++;
*}
*
* @example
* function serialEvent() {
* // read a byte from the serial port:
*var inByte = serial.read();
*// store it in a global variable:
*inData = inByte;
*}
*/
p5.SerialPort.prototype.read = function() {
if (this.serialBuffer.length > 0) {
return this.serialBuffer.shift();
} else {
return -1;
}
};
/**
* Returns the next byte in the buffer as a char.
*
* @method readChar
* @return {String} Value of the Unicode-code unit character byte waiting in the buffer, converted from bytes. Returns -1 or 0xffff if there is no byte.
* @example
* var inData;
*
*function setup() {
* // callback for when new data arrives
* serial.on('data', serialEvent);
*
*function serialEvent() {
* // read a char from the serial port:
* inData = serial.readChar();
*}
*/
p5.SerialPort.prototype.readChar = function() {
if (this.serialBuffer.length > 0) {
/*var currentByte = this.serialBuffer.shift();
console.log("p5.serialport.js: " + currentByte);
var currentChar = String.fromCharCode(currentByte);
console.log("p5.serialport.js: " + currentChar);
return currentChar;
*/
return String.fromCharCode(this.serialBuffer.shift());
} else {
return -1;
}
};
/**
* Returns a number between 0 and 255 for the next byte that's waiting in the buffer, and then clears the buffer of data. Returns -1 if there is no byte, although this should be avoided by first checking available() to see if data is available.
* @method readBytes
* @return {Number} Value of the byte waiting in the buffer. Returns -1 if there is no byte.
* @example
* var inData;
*
*function setup() {
* // callback for when new data arrives
* serial.on('data', serialEvent);
*
*function serialEvent() {
* // read bytes from the serial port:
* inData = serial.readBytes();
*}
*/
p5.SerialPort.prototype.readBytes = function() {
if (this.serialBuffer.length > 0) {
var returnBuffer = this.serialBuffer.slice();
// Clear the array
this.serialBuffer.length = 0;
return returnBuffer;
} else {
return -1;
}
};
/**
* Returns all of the data available, up to and including a particular character.
* If the character isn't in the buffer, 'null' is returned.
* The version without the byteBuffer parameter returns a byte array of all data up to and including the interesting byte.
* This is not efficient, but is easy to use.
*
* The version with the byteBuffer parameter is more efficient in terms of time and memory.
* It grabs the data in the buffer and puts it into the byte array passed in and returns an integer value for the number of bytes read.
* If the byte buffer is not large enough, -1 is returned and an error is printed to the message area.
* If nothing is in the buffer, 0 is returned.
*
* @method readBytesUntil
* @param {[byteBuffer]}
* @return {[Number]} [Number of bytes read]
* @example
*// All of the following are valid:
*charToFind.charCodeAt();
*charToFind.charCodeAt(0);
*charToFind.charCodeAt(0, );
*/
p5.SerialPort.prototype.readBytesUntil = function(charToFind) {
console.log("Looking for: " + charToFind.charCodeAt(0));
var index = this.serialBuffer.indexOf(charToFind.charCodeAt(0));
if (index !== -1) {
// What to return
var returnBuffer = this.serialBuffer.slice(0, index + 1);
// Clear out what was returned
this.serialBuffer = this.serialBuffer.slice(index, this.serialBuffer.length + index);
return returnBuffer;
} else {
return -1;
}
};
/**
* Returns all the data from the buffer as a String.
* This method assumes the incoming characters are ASCII.
* If you want to transfer Unicode data: first, convert the String to a byte stream in the representation of your choice (i.e. UTF8 or two-byte Unicode data).
* Then, send it as a byte array.
*
* @method readString
* @return
* @example
*
*
*
*
*/
p5.SerialPort.prototype.readString = function() {
//var returnBuffer = this.serialBuffer;
var stringBuffer = [];
//console.log("serialBuffer Length: " + this.serialBuffer.length);
for (var i = 0; i < this.serialBuffer.length; i++) {
//console.log("push: " + String.fromCharCode(this.serialBuffer[i]));
stringBuffer.push(String.fromCharCode(this.serialBuffer[i]));
}
// Clear the buffer
this.serialBuffer.length = 0;
return stringBuffer.join("");
};
/**
* Returns all of the data available as an ASCII-encoded string.
*
* @method readStringUntil
* @param {String} stringToFind String to read until.
* @return {String} ASCII-encoded string until and not including the stringToFind.
* @example
*
* For full example: Link
*
* var serial1 = new p5.SerialPort();
* var serial2 = new p5.SerialPort();
* var input1 = '';
* var input2 = '';
*
* function serialEvent(){
* data = serial1.readStringUntil('rn');
*if (data.length > 0){
*input1 = data;
*}
* }
*
* function serial2Event() {
* var data = serial2.readStringUntil('rn');
*if (data.length > 0){
*input2 = data;
*}
* }
*/
p5.SerialPort.prototype.readStringUntil = function(stringToFind) {
var stringBuffer = [];
//console.log("serialBuffer Length: " + this.serialBuffer.length);
for (var i = 0; i < this.serialBuffer.length; i++) {
//console.log("push: " + String.fromCharCode(this.serialBuffer[i]));
stringBuffer.push(String.fromCharCode(this.serialBuffer[i]));
}
stringBuffer = stringBuffer.join("");
//console.log("stringBuffer: " + stringBuffer);
var returnString = "";
var foundIndex = stringBuffer.indexOf(stringToFind);
//console.log("found index: " + foundIndex);
if (foundIndex > -1) {
returnString = stringBuffer.substr(0, foundIndex);
this.serialBuffer = this.serialBuffer.slice(foundIndex + stringToFind.length);
}
//console.log("Sending: " + returnString);
return returnString;
};
/**
* Returns all of the data available as an ASCII-encoded string until a line break is encountered.
*
* @method readLine
* @return {String} ASCII-encoded string
* @example
*
* You can use this with the included Arduino example called AnalogReadSerial.
* Works with P5 editor as the socket/serial server, version 0.5.5 or later.
* Written 2 Oct 2015 by Tom Igoe. For full example: Link
*
* function gotData() {
* var currentString = serial.readLine(); // read the incoming data
* trim(currentString); // trim off trailing whitespace
*
* if (!currentString) return; { // if the incoming string is empty, do no more
* console.log(currentString);
* }
*
* if (!isNaN(currentString)) { // make sure the string is a number (i.e. NOT Not a Number (NaN))
* textXpos = currentString; // save the currentString to use for the text position in draw()
* }
*}
*/
p5.SerialPort.prototype.readLine = function() {
return this.readStringUntil("rn");
};
/**
* Returns the number of bytes available.
*
* @method available
* @return {Number} The length of the serial buffer array, in terms of number of bytes in the buffer.
* @example
*function draw() {
*// black background, white text:
*background(0);
*fill(255);
*// display the incoming serial data as a string:
*var displayString = "inByte: " + inByte + "t Byte count: " + byteCount;
*displayString += " available: " + serial.available();
*text(displayString, 30, 60);
*}
* */
p5.SerialPort.prototype.available = function() {
return this.serialBuffer.length;
};
/**
* Returns the last byte of data from the buffer.
*
* @method last
* @return {Number}
* @example
*
* */
p5.SerialPort.prototype.last = function() {
//Returns last byte received
var last = this.serialBuffer.pop();
this.serialBuffer.length = 0;
return last;
};
/**
* Returns the last byte of data from the buffer as a char.
*
* @method lastChar
* @example
*
* */
p5.SerialPort.prototype.lastChar = function() {
return String.fromCharCode(this.last());
};
/**
* Clears the underlying serial buffer.
*
* @method clear
* @example
*/
p5.SerialPort.prototype.clear = function() {
//Empty the buffer, removes all the data stored there.
this.serialBuffer.length = 0;
};
/**
* Stops data communication on this port.
* Use to shut the connection when you're finished with the Serial.
*
* @method stop
* @example
*
*/
p5.SerialPort.prototype.stop = function() {
};
/**
* Tell server to close the serial port. This functions the same way as serial.on('close', portClose).
*
* @method close
* @param {String} name of callback
* @example
*
*var inData;
*
*function setup() {
* serial.open(portOpen);
* serial.close(portClose);
*}
*
* function portOpen() {
* println('The serial port is open.');
*}
*
*function portClose() {
* println('The serial port closed.');
*}
*/
p5.SerialPort.prototype.close = function(cb) {
//
if (typeof cb === 'function') {
this.closeCallback = cb;
}
this.emit({
method: 'close',
data: {}
});
};
/**
* Register clients that connect to the serial server.
*
* This is for use with the p5 Serial Control application so the application
* can access and render the names of clients who have connected. Note that
* calling this method does not log the list of registered clients. To do that,
* you'd use:
* serial.on('registerClient', logClientData)
*
* The example demonstates the registerClient method, as well as how you'd log
* the list of clients.
*
* @method registerClient
* @example
*
* function setup() {
* // Create a new p5 Serial Port object
* serial = new p5.SerialPort();
* // List the available ports
* serial.list();
* // On port open, call the gotOpen callback
* serial.on('open', gotOpen);
* // Register the clients that have connected to the server
* serial.registerClient();
* // After registerClient method is done, call the logClientData callback
* serial.on('registerClient', logClientData)
* }
*
* // Callback to log the client data
* function logClientData(data) {
* console.log("Client data: ", data)
* }
*
* // Callback to log a message when the port is opened
* function gotOpen() {
* console.log("Serial port is open.")
* }
*/
// p5.SerialPort.prototype.registerClient = function(cb) {
// if (typeof cb === 'function') {
// this.registerCallback = cb;
// }
// this.emit({
// method: 'registerClient',
// data: {}
// });
// return this.clientData;
// };
/**
* // Register callback methods from sketch
*
*/
p5.SerialPort.prototype.onData = function(_callback) {
this.on('data',_callback);
};
p5.SerialPort.prototype.onOpen = function(_callback) {
this.on('open',_callback);
};
p5.SerialPort.prototype.onClose = function(_callback) {
this.on('close',_callback);
};
p5.SerialPort.prototype.onError = function(_callback) {
this.on('error',_callback);
};
p5.SerialPort.prototype.onList = function(_callback) {
this.on('list',_callback);
};
p5.SerialPort.prototype.onConnected = function(_callback) {
this.on('connected',_callback);
};
p5.SerialPort.prototype.onRawData = function(_callback) {
this.on('rawdata',_callback);
};
// Version 2
p5.SerialPort.prototype.on = function(_event, _callback) {
if (_event == 'open') {
this.openCallback = _callback;
} else if (_event == 'data') {
this.dataCallback = _callback;
} else if (_event == 'close') {
this.closeCallback = _callback;
} else if (_event == 'error') {
this.errorCallback = _callback;
} else if (_event == 'list') {
this.listCallback = _callback;
} else if (_event == 'connected') {
this.connectedCallback = _callback;
} else if (_event == 'rawdata') {
this.rawDataCallback = _callback;
}
};
}));
После установки кода можно подключить Ардуино к компьютеру и протестировать игру. Сама игра несложная и интуитивно понятная. Нужно из облака "напоить" дерево. Облако, в свою очередь, можно наполнить водой из озера.



