步驟1:您需要做什么
物理的:
Arduino(此項目使用了UNO,但進行了一些調整,幾乎所有開發板都可以使用)
LED(盡可能多地控制)
按鈕(至少三個)
TIP41或TIP42(至少一個)
繼電器(至少一個)
光敏電阻(至少一個)
溫度傳感器(在這個項目中,我使用了TMP36,但是很多可以很好地工作)
非物理
Arduin o IDE
Johnny-five JS
套接字。 io
p5.js
bootstrap
我們需要設置Arduino使其與該項目正常工作,我們將看看如何
第2步:準備Arduino
您可能知道,Arduino可以處理您上傳的草圖為此,通常您需要在Arduino IDE上編寫代碼,進行編譯,然后將其上傳到板上,但是使用Instructable,您將在實時代碼上運行,并且板上有兩種獲取和發布數據的方式,因此我們需要進行設置
打開您的Arduino IDE和一個名為StandardFirmata的示例,將其上傳到您的開發板就可以了!您的Arduino已準備好通過JavaScript與您的計算機進行交互。
我們將首先在服務器端工作,使所有環境都可以在Arduino與瀏覽器之間進行交互,因此,讓我們繼續下一步并進行配置
第3步:從服務器準備就緒
首先,我們需要從項目專用的文件夾開始,因此,在您的命令行中為此:
mkdir myRockingProject && cd myRockingProject #name it as you want
npm init #to work with node
mkdir public #here we will put the client (browser) stuff
您可以下載我附加的package.json文件,將其放在項目文件夾中,然后在命令行中運行:
npm install
然后,創建一個名為server.js的文件,我們將所有服務器端內容放在這里,這是我們要使用的主要文件,因為這是node.js與Arduino之間的所有通信。
如果您使用npm init創建了自己的package.json,我們將需要添加使我們在環境中運行良好的節點模塊,所以讓我們運行:
npm install --save express johnny-five socket.io
這將安裝并讓您使用提到的模塊(表達j5和socket.io),您將能夠來查看您的package.json文件的更改,包括以下內容:
“dependencies”: {
“express”: “^4.13.4”,
“johnny-five”: “^0.9.43”,
“socket.io”: “^1.4.5”
}
注意:我們目前不會使用socket.io,但我們已安裝它以在發生時做好準備時間到了。
現在,在我們的server.js文件中,我們將調用要使用的模塊,首先我們需要使用express,這將使我們將客戶端調用路由到文件并與服務器和服務器進行交互,因此讓我們創建服務器:
var express = require(‘express’); // Calling the module
var app = express(), // Creating an express ‘app’
server = app.listen(3000); // Telling the server to listen on port 3000 (localhost:3000)
app.use(express.static(‘public’)); // We tell our app (express, to serve the static files located on the ‘public’ folder
我們的服務器已準備就緒,可以監聽客戶端請求并向其提供信息,但是我們仍然沒有任何服務
下一步是設置Arduino-服務器通信,我們將首先在服務器上對其進行設置,因此,在約翰尼五圖書館,一個功能強大的JavaScript-Arduino橋,可以直接使用JavaScript控制板,我們將設置實現自動化所需的一切!
在我們正在使用的同一文件中(server.js )我們將編寫其他代碼正確地在arduino IDE上寫,所以讓我們編寫以下代碼:
// Setting up johnny-five
var five = require(“johnny-five”),
arduino = five.Board();
//////////////////////////////// VARIABLES ////////////////////////////////
var living_room_light = false, other_rooms_light = false, fan = false, backyard_light = false; // Helpers
var living_room_button, other_rooms_light_button, backyard_light_button; // Buttons pins
var living_room_light_pin_led, other_rooms_light_pin_led, fan_pin, dimmable_led; // LEDs pins
var backyard_light_pin; // Relay pin
var photoresistor; // Light sensor
var temperature; // Tmp sensor
//////////////////////////////// BOARD ////////////////////////////////
arduino.on(“ready”, function() {
//////////////////////////////// DIMMABLE LED ////////////////////////////////
dimmable_led = five.Led(6);
//////////////////////////////// LIVING ROOM ////////////////////////////////
//Initialize pushbutton for living room at digital input 2
living_room_button = five.Button(2);
// Pin 13 is used to set living room light, analog input A0 is used to check light intensity from a photoresistor
photoresistor = new five.Sensor(“A0”);
living_room_light_pin_led = new five.Led(13);
living_room_light_pin_led.off();
// Check if photoresistor gets less than a half of light available and change living room light if applicable
photoresistor.on(‘change’, function() {
if(this.scaleTo([0, 100]) 《 60){
living_room_light = !living_room_light;
living_room_light_pin_led.on();
console.log(‘photoresistor-change’);
}
});
// Changes living room light when pushbutton is pushed
living_room_button.on(“release”, function () {
living_room_light = !living_room_light;
living_room_light_pin_led.toggle();
console.log(‘living-room-light-pushbutton’);
});
//////////////////////////////// OTHER ROOMS ////////////////////////////////
// All rooms excepting the living room are simultaneously light powered on manually
other_rooms_light_button = five.Button(4);
// Light is powered via pin 12, LEDs connected in parallel
other_rooms_light_pin_led = new five.Led(12);
// Change light state whenever ‘other_lights_button’ is pressed then released
other_rooms_light_button.on(“release”, function () {
other_rooms_light = !other_rooms_light;
other_rooms_light_pin_led.toggle();
console.log(‘other-rooms-change’);
});
//////////////////////////////// FAN CONTROLLING WITH TEMPERATURE MEASURING ////////////////////////////////
// Temperature will be measured with a TMP36 sensor
temperature = new five.Thermometer({
controller: “TMP36”,
pin: “A1”,
freq: 2000
});
// TIP42 transistor is attached to pin 5
fan_pin = new five.Pin(5);
// Whenever temperature provided by LM35 sensor is greater than 22° C the fan input changes its value to ‘high’ and when temperature is less or equal to 22° C it goes ‘low’
temperature.on(“data”, function () {
console.log(‘temperature: ’ + this.celsius.toFixed(2));
if(this.celsius 》 24.00) {
if(fan) {
fan_pin.high();
fan = !fan;
console.log(“Temperature is: ”+this.celsius.toFixed(2)+“, fan is on”);
}
}
else if(this.celsius 《 24.00) {
if(!fan) {
fan_pin.low();
fan = !fan;
console.log(“Temperature is: ”+this.celsius.toFixed(2)+“, fan is off”);
}
}
});
//////////////////////////////// BACKYARD LIGHT ////////////////////////////////
backyard_light_button = new five.Button(8);
// Relay to toggle the backyard light is attached to pin 9
backyard_light_pin = new five.Pin(9);
// Check any pushbutton event to toggle the light
backyard_light_button.on(“release”, function() {
backyard_light = !backyard_light;
if(backyard_light) {
backyard_light_pin.high();
console.log(“Backyard light is on”);
}
else {
backyard_light_pin.low();
console.log(“Backyard light is off”);
}
});
});
到目前為止,我們已經準備好通過服務器與arduino進行交互,我們可以構建電路,運行代碼它會起作用,但是這樣做的樂趣在哪里?在任何地方,電路都很棒,但是無論如何,這可指導的目的是使用Web用戶界面與arduino進行交互,因此讓我們繼續下一步并創建我們的UI。
步驟4 :客戶端(瀏覽器)
我們現在將使用/public文件夾,在此處,我們將添加應用程序的索引和使其動態化的JS文件,所以我們開始吧:
首先,在/lib文件夾中創建一個名為“ assets”的文件夾,并在其中另外創建兩個名為“ lib”和“ styles”的文件夾,并放入bootstrap,jquery和p5文件,這些將幫助我們實現目標,引導程序看起來更平滑,p5和jquery添加自定義功能以及圖表來跟蹤房屋溫度。
然后,在主文件夾(/public)中創建一個文件名為 index.html ,您可以根據需要檢查我的并將其粘貼,并在完成可指導的自定義操作后為您自定義并玩得開心!
這是我的index.html
在擁有索引文件之后,還需要兩個java腳本文件,其中一個使用jquery控制界面,另一個創建實時顯示溫度的圖表。另外,我們現在將開始使用socket.io。
Socket.io是一個功能強大的JS庫,用于構建實時Web應用程序,我們將利用它并利用它從Arduino發出事件。 -server到客戶端,反之亦然,您可以在此處查看socket.io文檔,并且還有許多有關如何使用它的示例。讓我們繼續前面提到的文件。
一個文件將稱為script.js,并且需要包含以下內容:
$(function() {
var socket = io.connect(“http://localhost:3000”);
// Slider with jQuery UI
$( “#slider-range-max” ).slider({
range: “max”,
min: 0,
max: 255,
value: 0,
slide: function( event, ui ) {
// Assign the slider value to the dimmable-led input
$( “#amount” ).val( ui.value );
// Send the event to the server with the name and value of it
socket.emit(‘dimmable-led’, ui.value);
console.log(“Slider value: ” + ui.value);
}
});
$( “#amount” ).val( $( “#slider-range-max” ).slider( “value” ) );
// Both this and the next ( $(“#other-rooms-btn”).click() ) change the calling action button state and emit the event via socket
$(“#living-room-btn”).click(function() {
changeBtnState(“#living-room-btn”, “#living-room-light”);
socket.emit(‘living-room-light’, $(“#living-room-light”).val());
console.log($(“#living-room-btn”).val());
});
$(“#other-rooms-btn”).click(function() {
changeBtnState(“#other-rooms-btn”, “#other-rooms-light”);
socket.emit(‘other-rooms-lights’, $(“#other-rooms-light”).val());
console.log($(“#other-rooms-btn”).val());
});
// Checks for events sent from arduino to change the living room or every other rooms because of a pushbutton or photoresistor
socket.on(‘living-room-light-pushbutton’, function() { changeBtnState(“#living-room-btn”, “#living-room-light”) });
socket.on(‘backyard-light-change’, function(value) {
if(value) {
if($(“#backyard-light”).val() == “Off”) {
$(“#backyard-light”).val(“On”);
}
}
else if($(“#backyard-light”).val() == “On”) {
$(“#backyard-light”).val(“Off”);
}
});
///// I need to change this to handle the photoresistor only once per state /////
socket.on(‘photoresistor-change’, function() { changeBtnState(“#living-room-btn”, “#living-room-light”) });
socket.on(‘other-rooms-change’, function() { changeBtnState(“#other-rooms-btn”, “#other-rooms-light”) })
// One function to rule them all, well, the UI buttons.。.
// btn: the button id to change ------ input: the input id to change
function changeBtnState(btn, input) {
var btnClass = $(btn).attr(‘class’);
var text, state, newBtnClass, oldBtnClass;
if(btnClass === “btn btn-success”) {
oldBtnClass = ‘btn-success’;
newBtnClass = ‘btn-danger’;
text = ‘off’;
state = “On”;
} else if(btnClass === “btn btn-danger”) {
oldBtnClass = ‘btn-danger’;
newBtnClass = ‘btn-success’;
text = ‘on’;
state = “Off”;
}
$(btn).removeClass(oldBtnClass);
$(btn).addClass(newBtnClass);
$(btn).text(“Turn ” + text);
console.log(btn + “ is ” + state);
$(input).val(state);
}
});
在這里,我們正在處理UI事件(單擊和一個滑塊),然后它們通過套接字發出消息,這些消息將在服務器上接收并根據它們執行Arduino工作。
在另一個文件中,我們將其命名為“ temperature_canvas_sketch”借助p5.js(一個基于Processing lang的出色的JS庫)顯示從溫度傳感器獲得的數據。因此,在我們的temperature_canvas_sketch.js文件中,添加以下內容:
var chartpoints = []; chartpoints.push({x: 0, y: 0});
var socket = io.connect(“http://localhost:3000”);
// Creating a canvas where the chart will be displayed and matching the connection with the socket
function setup() {
cnv = createCanvas(displayWidth / 2, displayHeight / 5);
cnv.parent(“termo-container”);
// Gets a change whenever the temperature sensor changes and sets it to its element
socket.on(‘temperature’, function(temperature) {
$(“#termometer”).val(temperature + “°C”);
createPoint(temperature);
});
}
// Handle chart points to display
function draw() {
background(255);
noFill();
stroke(0);
// Here we draw the last temperature value from the chartpoints array where it is supposed to be
//// Starts draw of point
beginShape();
for (var i=0; i 《 chartpoints.length; i++) {
var P = chartpoints[i];
vertex(P.x, height - P.y);
text(P.y, P.x, height - P.y);
//if (P.x《0)chartpoints.pop(i);
P.x--;
}
endShape();
//// Ends draw of point
}
// This function is called whenever the tmp36 sends a new value to the client
function createPoint(temp) {
//var t = random(0, height-20);
// Creates a new point with x -》 live width of the canvas & y -》 the temperature value from arduino
var P = new Points(width, temp);
chartpoints.push(P);
}
// Custom class of points that will be drawed
var Points = function()
{
var x;
var y;
var constructor = function Points(x, y)
{
this.x = x;
this.y = y;
};
return constructor;
}();
這將用來繪制帶有發送數據的圖表,在這種情況下,是顯示房屋的實時溫度。
但是現在我們在客戶端而不是服務器上有了套接字,我們需要回到那里并添加它們以使其正常工作,所以繼續。
步驟5:使用服務器和Arduino事件處理的套接字
現在我們在客戶端擁有套接字事件處理程序/發射器,我們需要使其在服務器端工作,請記住,我們已經在第二步中安裝了socket.io模塊,因此我們只需要對其進行設置,就可以在server.js文件中添加以下幾行:
var socket = require(‘socket.io’);
// Creating a socket
var io = socket(server);
// Retrieving client info via socket when a new connection (only one for this project) is established
io.sockets.on(‘connection’, function(socket) {
// Get dimmable light value from the UI and send it to the arduino
socket.on(‘dimmable-led’, function(value) {
console.log(‘Dimmable LED value is now: ’ + value);
dimmable_led.brightness(value);
});
// Living room and other rooms lights can be controlled via UI
socket.on(‘living-room-light’, function(state) {
console.log(‘Living room light is: ’ + state);
living_room_light_pin_led.toggle();
});
socket.on(‘other-rooms-lights’, function(val) {
other_rooms_light_pin_led.toggle();
});
});
我們現在正在處理來自客戶端的事件,檢索消息并使arduino對它們作出反應,使LED變暗,并打開/關閉客廳和其他房間的燈光。
在此之后,我們需要從ardu獲取數據/更改時,向客戶端發出事件以更改UI ino,因此在我們的arduino代碼中,我們將需要添加和更改某些行。
在客廳代碼中:
photoresistor.on(‘change’, function() {
if(this.scaleTo([0, 100]) 《 60){
living_room_light = !living_room_light;
living_room_light_pin_led.on();
io.sockets.emit(‘photoresistor-change’); // this is new
console.log(‘photoresistor-change’);
}
});
living_room_button.on(“release”, function () {
living_room_light = !living_room_light;
living_room_light_pin_led.toggle();
io.sockets.emit(‘living-room-light-pushbutton’, null); //this is new
console.log(‘living-room-light-pushbutton’);
});
On其他房間代碼:
other_rooms_light_button.on(“release”, function () {
other_rooms_light = !other_rooms_light;
other_rooms_light_pin_led.toggle();
io.sockets.emit(‘other-rooms-change’);
console.log(‘other-rooms-change’);
});
在溫度測量代碼上,只需在.on(“ data”,。..)函數的回調的開頭添加以下行:
io.sockets.emit(‘temperature’, this.celsius.toFixed(2));
在后院的燈光代碼上:
backyard_light_button.on(“release”, function() {
backyard_light = !backyard_light;
if(backyard_light) {
backyard_light_pin.high();
console.log(“Backyard light is on”);
io.sockets.emit(‘backyard-light-change’, 1); //this is new
}
else {
backyard_light_pin.low();
console.log(“Backyard light is off”);
io.sockets.emit(‘backyard-light-change’, 0); //this is new
}
});
就是這樣,我們的代碼必須現在可以正常工作,轉到您的命令行并運行服務器
node server
,然后在瀏覽器中轉到http://localhost:3000,您應該看到一個UI,如圖所示,該UI能夠通過該UI與Arduino交互,反之亦然。
我附加了自己的script.js文件,因此您可以看一下。
步驟6:最終爭論
我希望這對所有人來說都是很容易理解的,并且您會成功并運用自己。我必須說,所有顯示的代碼都是針對我的特定案例使用的,并且該項目最初是作為學校主題項目完成的,但是無論如何,我都試圖將其應用于自己的房子(祝我好運)。隨意(并且希望您會)根據需要更改代碼,如果有任何疑問或疑問,可以在下面發表評論或與我聯系以獲取更多信息。
將來的步驟可以由您完成像這樣:
添加傳感器或繼電器來控制更多東西,例如打開電視,冰箱,在敲門或敲鐘之前就知道門口是否有人
將Arduino連接到樹莓派以使本地服務器一直運行
借助一些Node.js框架在手機上創建應用
濕度傳感器告訴您植物是否被水化
-
自動化
+關注
關注
29文章
5592瀏覽量
79386 -
javascript
+關注
關注
0文章
519瀏覽量
53887 -
Arduino
+關注
關注
188文章
6471瀏覽量
187293
發布評論請先 登錄
相關推薦
評論