LowPowerLab Forum

Hardware support => Projects => Topic started by: goryri on January 17, 2014, 07:49:51 AM

Title: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 17, 2014, 07:49:51 AM
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.
Title: Re: Montino + Raspberry pi controlled door lock
Post by: goryri on January 17, 2014, 08:24:12 AM
Anyone that have any tips for switch I can use and how I can attach it ?
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 17, 2014, 05:30:50 PM
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
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 18, 2014, 04:10:35 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 18, 2014, 04:21:51 AM
I'm gonna put the Moteino inside the black box and cut some of the wire so it's not so long.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 18, 2014, 04:34:47 AM
The key is attached to the servo whit Sugru.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 18, 2014, 05:29:48 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 21, 2014, 02:19:09 AM
Made the wiring nicer/cleaner yesterday.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 21, 2014, 04:50:04 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on January 21, 2014, 11:19:27 AM
Cool, great progress!
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 22, 2014, 04:03:50 PM
Tank you  :D Here is a new demo
still working on getting every thing to work togeter (Moteino door lock and light control <--> Moteino gateway <--> Raspberry pi <---> Tasker on Android)
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 23, 2014, 07:10:02 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 24, 2014, 06:50:07 AM
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".
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on January 24, 2014, 08:03:28 AM
Take a look at: http://wiringpi.com/
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on January 24, 2014, 08:55:39 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 25, 2014, 02:42:20 PM
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);
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 25, 2014, 04:17:53 PM
Mailbox
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 26, 2014, 05:48:25 AM
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?
Code: [Select]

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);
}
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 26, 2014, 10:27:19 AM
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/ .
Code: [Select]
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);
}
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 27, 2014, 08:44:15 AM
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:

Code: [Select]
<?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:password@domain.com/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
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 27, 2014, 05:56:13 PM
Created a blog http://yrielectro.com/ about this project.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on January 28, 2014, 11:01:53 AM
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:password@domain.com/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              ||
-------------------------------------------------------

Code: [Select]
<?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();
?>
Code: [Select]
  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);
}
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on February 06, 2014, 02:47:26 PM
Have made some progress now. Have added
demo: www.youtube.com/watch?v=sXgScbBoOZ4
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on February 07, 2014, 08:44:58 AM
That's some serious progress! Keep it coming!
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on February 11, 2014, 11:57:50 AM
New demo
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on February 11, 2014, 12:43:17 PM
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...
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on February 11, 2014, 02:28:20 PM
Tank you! Im gone make a writeup soon but I have some parts that I wants to finish first.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on February 11, 2014, 02:52:02 PM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on March 07, 2014, 05:14:16 AM
Hi,
I want to make a update on what im have been working on.

Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on March 07, 2014, 11:35:45 AM
Quite impressive, excellent work!
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on March 07, 2014, 03:28:44 PM
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?

Code: [Select]
#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;
}
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on March 10, 2014, 09:02:11 AM
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.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on March 10, 2014, 04:13:46 PM
My code worked but I had forgot to set the correct baud rate on the serial terminal  :-[
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on March 15, 2014, 05:52:42 AM
I have made a new video have also made new intro let me now what you think about it.
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: goryri on March 17, 2014, 06:02:04 PM
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)
Title: Re: Moteino + Raspberry pi controlled door lock
Post by: Felix on March 17, 2014, 07:37:01 PM
Thanks for sharing your project and enjoy your military service, if that is possible :)