Just want to share what I've been working on lately which, of course, involves the awesome Moteino.
Basically, it is a door lock that is controlled by Moteino but im working on getting a webserver running on Raberry Pi using this guide http://lowpowerlab.com/blog/2013/10/07/raspberrypi-home-automation-gateway-setup/ so that I can securely control it on internet. Im thinking of having a nfc tag on the door that I can scan with my phone and trigger the unlocking.
Anyone that have any tips for switch I can use and how I can attach it ?
Lock and unlock switch. By pressing the switch less than 1 sec and more than 30 ms (debounce time) does the door unlock. By pressing it for more than 1 sec lock's it if the door is closed. http://www.youtube.com/watch?v=aoEl4oNLPY8 (http://www.youtube.com/watch?v=aoEl4oNLPY8) demo
The way I unlock it from the outside now is by using a flat screwdriver not so wery secure I now but I needed a backup plan in case somthing should go wrong whit the hardware or software.
I'm gonna put the Moteino inside the black box and cut some of the wire so it's not so long.
The key is attached to the servo whit Sugru.
Now I connected a FTDI ( this one http://www.tinyosshop.com/index.php?route=product/product&product_id=600) between my computer and rasberry pi. Im gona use it to test the web control on the rasberry pi.
Made the wiring nicer/cleaner yesterday.
I have installed ATXRaspi today and it works great. Im done whit setting up the server on the Raspberry pi and im gona edit the webpage to my needs next.
Cool, great progress!
Tank you :D Here is a new demo http://www.youtube.com/watch?v=hu2nT3eSSW4 still working on getting every thing to work togeter (Moteino door lock and light control <--> Moteino gateway <--> Raspberry pi <---> Tasker on Android)
This project is starting to be wery big. Good that I don't have work so I can use all my time on this project. I have free to 14 mars then I go to military :D Things I want to add to this prosject is 8x8x8 led cube, mailbox notification and sound. I have a stereo that is always on but it is connected to my computer so will use a relay to switch to Raspberry pi when I want to. The relay is gona be connected to GPIO of the raspberry pi im using one relay for left speaker and one for right speaker. So that means that i also can have only on realy on.Then sound from my computer goes to one speaker and raspberry pi to the outer speaker.
Is it anyone that nows how to use GPIO pins whit node.js? Im thinking of using rpi-gpio https://npmjs.org/package/rpi-gpio (https://npmjs.org/package/rpi-gpio) or wiring-pi https://github.com/eugeneware/wiring-pi (https://github.com/eugeneware/wiring-pi) . But I have to be running as root or with sudo else the Raspberry Pi will not let me output to the GPIO. When I try to run gateway.js whit sudo "sudo node gateway.js &" I get "sudo: node: command not found".
Take a look at: http://wiringpi.com/
The link you shared is probably a forked repository from the original.
You could run the node process as sudo, and that should get past the error you're getting.
Yes got it working! :)
Added this to shutdowncheck:
gpio export 28 output
gpio export 30 output
npm install wiring-pi
then I could control the relay this way:
var wpi = require('wiring-pi');
wpi.wiringPiSetupSys();
wpi.digitalWrite(28, wpi.HIGH);
wpi.digitalWrite(30, wpi.HIGH);
Mailbox
sudo apt-get install libasound2-dev
npm install lame
npm install speaker
npm install wiring-pi
this is the command I use to kill gateway.js ps aux | grep "gateway.js" | grep -v grep | awk '{print $2}' | xargs kill -9
I have some problem whit the code the mp3 file is only playing 1,5 time when it should be playing 5 times. Anyone that gets why? http://www.youtube.com/watch?v=d3zGCdISbkk
var lame = require('lame'), Speaker = require('speaker'), fs = require('fs'), var wpi = require('wiring-pi');
wpi.wiringPiSetupSys();
playSong('alarm.mp3',5, 10000);
function playSong(song,repeat,timout) {
writeHigh();
console.log("MUSIC START");
var $stream = fs.createReadStream(song).pipe(new lame.Decoder).pipe(new Speaker);
var i = 0;
function repeat()
{
$stream = fs.createReadStream(song).pipe(new lame.Decoder).pipe(new Speaker);
i++;
}
$stream.on('error', function(err){
// handle playback error
console.log(err);
writeLow();
});
setTimeout(function() {
$stream.end();
writeLow();
}, timout);
$stream.on('close', function()
{
if (i < repeat)
{
console.log("MUSIC REPEAT");
repeat();
}
else
{
writeLow();
}
});
}
function writeHigh(){
console.log("RELAY ON");
wpi.digitalWrite(28, wpi.HIGH);
wpi.digitalWrite(30, wpi.HIGH);
}
function writeLow(){
console.log("RELAY OFF");
wpi.digitalWrite(28, wpi.LOW);
wpi.digitalWrite(30, wpi.LOW);
}
Now do I have a way of controlling my cube whit node.js. But I having bad experience whit it. If i use sleep do i block execution of all javascript! node.js server processes seem to freeze up for a long time (seconds) from time to time and I had to restart raspberry pi serveral times. Since the cube is only on when my pc is on will I write a udp server in c# where I write effects and send it to the cube. I followed this guide for making the cube http://www.instructables.com/id/Led-Cube-8x8x8/ .
var serialport = require("serialport");
var serialcube = new serialport.SerialPort("/dev/ttyUSB0", { baudrate : 38400, parser: serialport.parsers.readline("\n") });
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[length-1 - i] = createArray.apply(this, args);
}
return arr;
}
var data = createArray(8, 8);
fill(0x00);
function myFunction()
{
setvoxel(0, 0, 0);
cube_push();
}
function setvoxel(x, y, z)
{
if (inrange(x,y,z))
data[z][y] |= (1 << x);
}
function clrvoxel(x, y, z)
{
if (inrange(x,y,z))
data[z][y] &= ~(1 << x);
}
function fill (pattern)
{
var z;
var y;
for (z=0;z<8;z++)
{
for (y=0;y<8;y++)
{
data[z][y] = pattern;
}
}
}
function inrange(x, y, z)
{
if (x >= 0 && x < 8 && y >= 0 && y < 8 && z >= 0 && z < 8)
{
return true;
} else
{
// One of the coordinates was outside the cube.
return false;
}
}
function cube_push()
{
var i = 0;
var buffer = new Array();
buffer[i] = 0xff;
i += 1;
buffer[i] = 0x0;
i += 1;
for (var x = 0; x < 8; x++)
{
for (var y = 0; y < 8; y++)
{
buffer[i++] = data[y][x];
if (data[y][x] == 0xff)
{
buffer[i++] = data[y][x];
}
}
}
serialcube.write(buffer, 0, i);
}
Today have im been working whit getting tasker to work whit node.js.
I started whit downloaded lib folder from https://github.com/Wisembly/elephant.io to /var/www/default
sudo apt-get install php5-curl
sudo nano /etc/php5/fpm/php.ini
Added extension=curl.so after Dynamic Extensions.
Saved and restarted php: sudo service php5-fpm restart
Created a new php file client.php and added this code:
<?php
require( __DIR__ . '/lib/ElephantIO/Client.php');
use ElephantIO\Client as ElephantIOClient;
$elephant = new ElephantIOClient('http://localhost:8080', 'socket.io', 1, false, true, true);
$elephant->init();
$elephant->emit('DORSTS', 'got status?');
$elephant->close();
?>Then set Tasker to run a shell script like this:
curl https://username:
[email protected]/client.php --insecure
The key here is the "--insecure" flag which tells cURL to ignore the SSL certificate warning.
Then i used Trigger to write to nfc tag that triggers the task when I scan it whit my phone. Demo http://www.youtube.com/watch?v=gBh8OC36KYs
Created a blog http://yrielectro.com/ about this project.
I have connected gpio pins to the buttons on the 8x8x8 led cube so that I can start rs232 mode, reset and start animations on the cube from internet.
nano shutdowncheck
gpio export 2 output
gpio export 29 output
gpio export 31 output
gpio -g write 29 1
gpio -g write 31 1
gpio -g write 2 1
http://www.youtube.com/watch?v=ocUBnr-OMKc (http://www.youtube.com/watch?v=ocUBnr-OMKc)
curl https://username:
[email protected]/client.php?cmd=MAIN_BTN --insecure
-------------------------------------------------------
BUTTON || Port || Pin nr || GPIO pin ||
-------------------------------------------------------
MAIN_BTN || PINB4 || 5 || 29 ||
RS232_BTN || PIND5 || 19 || 31 ||
RESET_BTN || RESET || 9 || 2 ||
-------------------------------------------------------
<?php
require( __DIR__ . '/lib/ElephantIO/Client.php');
use ElephantIO\Client as ElephantIOClient;
$elephant = new ElephantIOClient('http://localhost:8080', 'socket.io', 1, false, true, true);
$elephant->init();
$elephant->emit($_GET["cmd"], $_GET["cmd"]);
$elephant->close();
?> socket.on('MAIN_BTN', function (data) {
console.log(data.toString());
Pressbutton('RESET_BTN', 100);
setTimeout(function() {
Pressbutton('MAIN_BTN', 100);
}, 200);
});
socket.on('RS232_BTN', function (data) {
console.log(data.toString());
Pressbutton('RESET_BTN', 100);
setTimeout(function() {
Pressbutton('RS232_BTN', 100);
}, 200);
});
socket.on('RESET_BTN', function (data) {
console.log(data.toString());
Pressbutton('RESET_BTN', 100);
});
function Pressbutton(btname, delay)
{
switch (btname)
{
case 'MAIN_BTN':
wpi.digitalWrite(29, wpi.LOW);
break;
case 'RS232_BTN':
wpi.digitalWrite(31, wpi.LOW);
break;
case 'RESET_BTN':
wpi.digitalWrite(2, wpi.LOW);
break;
}
setTimeout(function() {
wpi.digitalWrite(29, wpi.HIGH);
wpi.digitalWrite(31, wpi.HIGH);
wpi.digitalWrite(2, wpi.HIGH);
}, delay);
}
Have made some progress now. Have added
- Wake on lan
- SMS notification using wavecom modem
- Projector power on/off
- and much more..
demo: www.youtube.com/watch?v=sXgScbBoOZ4
That's some serious progress! Keep it coming!
New demo http://www.youtube.com/watch?v=_esg_ueAh-g
- have added rgb led
- Autovoice voice recognition that trigger task in tasker
- Pushover notifications send from node.js
- SpeakMe pro reads notifications from pushover
Goran, nice work. If you would be able to put all the info together in a writeup on your blog, with perhaps a more complete video, I would be glad to post it on the LowPowerLab blog. It looks like a great project so it would make a great entry on the hackaday.com website as well, but they do like to see a nice writeup with details and good pictures...
Tank you! Im gone make a writeup soon but I have some parts that I wants to finish first.
- Control safe whit Moteino
- Control blueray player whit serial port on the raspberry pi
- remote shutdown compute C# r
- 8x8x8 led cube animation when received mail C#
- voice recognition computer c#
Awesome, take your time, there's no rush.
If your automation consists of multiple parts you might want to break it into multiple writeups so users have an easier time digesting it all.
Hi,
I want to make a update on what im have been working on.
- Updated on a old project this one https://www.youtube.com/watch?v=f9J_L2zKlW0 have made some modifications so its more space inside the box and I can unlock the door remotly whit this using Moteino of cource. https://www.youtube.com/watch?v=MUId0ozRu00
- New video https://www.youtube.com/watch?v=vDKNd2Ck0O4
- Built myself a ShapeOko CNC machine
- Control safe whit Moteino
- Control blueray player whit serial port on the raspberry pi
- voice recognition computer c#
Quite impressive, excellent work!
Tank you ! ;) By the way doo you have any experience using the SoftwareSerial Libary and RFM12B Libary together ? Im tring to connect RFID Reader ID-12LA tx line to pin 9 on the Moteino it works when i don't include the RFM12B libary... Maybe both libary uses the same Interrupts?
#include <SoftwareSerial.h>
#include <RFM12B.h>
#define SERIAL_BAUD 115200
#define NETWORKID 100
#define NODEID 1 // network ID used for this unit
#define DOORNODEID 3
#define SAFENODEID 4
// The RFID module's TX pin needs to be connected to the Arduino.
#define rxPin 9
#define txPin 7
#define MAX_ID 20
//char input[RF12_MAXDATA];
#define KEY "ABCDABCDABCDABCD"
RFM12B radio;
byte readSerialLine(char* input, char endOfLineChar=10, byte maxLength=64, uint16_t timeout=50);
// Create a software serial object for the connection to the RFID module
SoftwareSerial rfid = SoftwareSerial( rxPin, txPin );
// note, retype rather than copy and paste or you get a funny extra character
const char * allowedTags [] =
{
"4500BE8CC3B4", // 1 - Gøran Yri
"8E40736E6073", // 2 - Dick
"A609CA0E4311", // 3 - Harry
"A3EC57520837", // 4 - visitor
NULL // end of table marker
};
// List of names to associate with the matching tag IDs
char* tagName[] = {
"DORUNL", // Tag 1
"DORLOC", // Tag 2
"NAME 3", // Tag 3
};
// Check the number of tags defined
int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]);
void setup()
{
radio.Initialize(NODEID, RF12_433MHZ, NETWORKID);
radio.Encrypt((uint8_t*)KEY);
Serial.begin(SERIAL_BAUD);
Serial.println("Listening...");
rfid.begin(9600); // Serial port for connection to RFID module
}
#define MAX_ID 20
char cur_id [MAX_ID] = "";
int len = 0;
byte recvCount = 0;
byte ackCount=0;
byte inputLen=0;
char input[64];
void loop()
{
//process any serial input
inputLen = readSerialLine(input);
if (inputLen >= 6)
{
if (input[0]=='D' && input[1]=='O' && input[2]=='R' && input[3]=='U' && input[4]=='N' && input[5]=='L')
{
Serial.print("UNL ... ");
if (radio.sendWithRetry(DOORNODEID, "UNL", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='D' && input[1]=='O' && input[2]=='R' && input[3]=='L' && input[4]=='O' && input[5]=='C')
{
Serial.print("LOC ... ");
if (radio.sendWithRetry(DOORNODEID, "LOC", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='D' && input[1]=='O' && input[2]=='R' && input[3]=='S' && input[4]=='T' && input[5]=='S')
{
Serial.print("STS ... ");
if (radio.sendWithRetry(DOORNODEID, "STS", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='D' && input[1]=='O' && input[2]=='R' && input[3]=='N' && input[4]=='A' && input[5]=='T')
{
Serial.print("NAT ... ");
if (radio.sendWithRetry(DOORNODEID, "NAT", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='D' && input[1]=='O' && input[2]=='R' && input[3]=='M' && input[4]=='O' && input[5]=='R')
{
Serial.print("MOR ... ");
if (radio.sendWithRetry(DOORNODEID, "MOR", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='L' && input[1]=='E' && input[2]=='D' && input[3]=='S' && input[4]=='T' && input[5]=='S')
{
Serial.print("LEDSTS ... ");
if (radio.sendWithRetry(DOORNODEID, "LEDSTS", 6))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='L' && input[1]=='E' && input[2]=='D' && input[3]=='T' && input[4]=='O' && input[5]=='G')
{
Serial.print("Toggle led ... ");
if (radio.sendWithRetry(DOORNODEID, "LEDTOG", 6))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='S' && input[1]=='A' && input[2]=='F' && input[3]=='O' && input[4]=='P' && input[5]=='N')
{
Serial.print("OPEN SAFE ... ");
if (radio.sendWithRetry(SAFENODEID, "SAFOPN", 6))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='S' && input[1]=='A' && input[2]=='F' && input[3]=='S' && input[4]=='T' && input[5]=='S')
{
Serial.print("GETTING SAFE STATUS ... ");
if (radio.sendWithRetry(SAFENODEID, "STS", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='S' && input[1]=='A' && input[2]=='F' && input[3]=='O' && input[4]=='N' && input[5]=='N')
{
Serial.print("TURNING ALL LIGHT ON ... ");
if (radio.sendWithRetry(SAFENODEID, "ON", 2))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
if (input[0]=='S' && input[1]=='A' && input[2]=='F' && input[3]=='O' && input[4]=='F' && input[5]=='F')
{
Serial.print("TURNING ALL LIGHT OFF ... ");
if (radio.sendWithRetry(SAFENODEID, "OFF", 3))
Serial.println("ok ... ");
else Serial.println("nothing ... ");
}
}
if (radio.ReceiveComplete())
{
if (radio.CRCPass())
{
digitalWrite(9,1);
Serial.print('[');Serial.print(radio.GetSender(), DEC);Serial.print("] ");
for (byte i = 0; i < *radio.DataLen; i++)
Serial.print((char)radio.Data[i]);
//Serial.print(" [RSSI:");Serial.print(radio.RSSI);Serial.print("]");
//Serial.print(" [RSSI:-105");Serial.print("]");
if (radio.ACKRequested())
{
radio.SendACK();
Serial.print(" [ACK-sent]");
}
delay(5);
digitalWrite(9,0);
}
else Serial.print(" [BAD-CRC]");
Serial.println();
}
char inByte;
int tagId = 0;
if (rfid.available() > 0) {
// get incoming byte:
inByte = rfid.read();
switch (inByte)
{
case 2: // start of text
len = 0;
break;
case 3: // end of text
cur_id [len] = 0;
Serial.println (cur_id);
// Search the tag database for this particular tag
tagId = findTag(cur_id);
// Only fire the strike plate if this tag was found in the database
if( tagId > 0 )
{
Serial.print("Authorized tag ID ");
Serial.print(tagId);
Serial.print(": unlocking for ");
Serial.println(tagName[tagId - 1]); // Get the name for this tag from the database
char buff[10];
sprintf(buff, tagName[tagId - 1]);
byte len = strlen(buff);
radio.sendWithRetry(DOORNODEID, buff, len);
} else {
Serial.println("Tag not authorized");
}
Serial.println(); // Blank separator line in output
Serial.flush ();
len = 0;
break;
case 10: // newline
case 13: // carriage return
break;
default:
if (len >= (MAX_ID - 1))
break;
cur_id [len++] = inByte;
break;
} // end of switch
} // end of incoming data
} // end of loop
/**
* Search for a specific tag in the database
*/
int findTag(char tagValue[MAX_ID] ) {
for (int thisCard = 0; thisCard < numberOfTags; thisCard++) {
// Check if the tag value matches this row in the tag database
if(strcmp(tagValue, allowedTags[thisCard]) == 0)
{
// The row in the database starts at 0, so add 1 to the result so
// that the card ID starts from 1 instead (0 represents "no match")
return(thisCard + 1);
}
}
// If we don't find the tag return a tag ID of 0 to show there was no match
return(0);
}
// reads a line feed (\n) terminated line from the serial stream
// returns # of bytes read, up to 255
// timeout in ms, will timeout and return after so long
byte readSerialLine(char* input, char endOfLineChar, byte maxLength, uint16_t timeout)
{
byte inputLen = 0;
Serial.setTimeout(timeout);
inputLen = Serial.readBytesUntil(endOfLineChar, input, maxLength);
input[inputLen]=0;//null-terminate it
Serial.setTimeout(0);
//Serial.println();
return inputLen;
}
Yes I have used software serial with RFM12B before, no issues at 57600baud. But if you are heavy on the interrupts side you might have to slow down the baud rate. The pins for software serial should not interfere with the RFM interrupt.
My code worked but I had forgot to set the correct baud rate on the serial terminal :-[
I have made a new video have also made new intro let me now what you think about it. https://www.youtube.com/watch?v=WCttYWJN5mQ
Tomorrow do I go to military so have updated my blog and posted my code :) I have learned a lot the past two months ! http://yrielectro.com/ (http://yrielectro.com/) http://yrielectro.com/homeautomation.zip (http://yrielectro.com/homeautomation.zip)
Thanks for sharing your project and enjoy your military service, if that is possible :)