joi, 12 decembrie 2013

Afisaje LED cu 7 segmente si.. Arduino (III)

   La solicitarea lui Jay (cu care am legat o buna prietenie datorita lui Arduino), fata de articolele precedente, cel din iunie - Afisaje LED cu 7 segmente si.. Arduino si cel din iulie - Afisaje LED cu 7 segmente si.. Arduino (II), acum o sa conectez la o placa Arduino doar afisajul multiplexat cu 4 cifre cu anod comun si un modul de ceas real, despre care am scris in articolele din mai -  Ceas de timp real (RTC) cu DS1307 si Arduino si din iunie - Ceas de timp real (RTC) cu DS1307 si Arduino (partea a 2-a) rezultandu-mi un ceas, doar un ceas in care saafisez orele si minutele.. atat.
   Schema de conectare este foarte simpla:
   Schema interna a afisajului folosit de mine, KW4-563ASA este:

   Pentru a usurinta inlocuirii afisajului cu altul similar (dar alta configuratie a pinilor) prezint urmatorul tabel:
   Am facut un filmulet cu varianta in care secundarul este "animat", numit just a clock with Arduino and 7-segment display + RTC:
iar sketch-ul, care nu e optim din punct de vedere al programarii, dar "merge" foarte bine:
/*
 6-13-2011
 Spark Fun Electronics 2011
 Nathan Seidle

 This code is public domain but you buy me a beer if you use this and we meet 
 someday (Beerware license).

 4 digit 7 segment display:
 http://www.sparkfun.com/products/9483
 Datasheet: 
 http://www.sparkfun.com/datasheets/Components/LED/7-Segment/YSD-439AR6B-35.pdf

 This is an example of how to drive a 7 segment LED display from an ATmega
 without the use of current limiting resistors. This technique is very common 
 but requires some knowledge of electronics - you do run the risk of dumping 
 too much current through the segments and burning out parts of the display. 
 If you use the stock code you should be ok, but be careful editing the 
 brightness values.

 This code should work with all colors (red, blue, yellow, green) but the 
 brightness will vary from one color to the next because the forward voltage 
 drop of each color is different. This code was written and calibrated for the 
 red color.

 This code will work with most Arduinos but you may want to re-route some of 
 the pins.

 7 segments
 4 digits
 1 colon
 =
 12 pins required for full control 

 */
// modified connexion by niq_ro from http://nicuflorica.blogspot.com
// for my Luckylight KW4-563ASA
// dataseet: http://www.tme.eu/ro/Document/dfc2efde2e22005fd28615e298ea2655/KW4-563XSA.pdf

int digit1 = 11; //PWM Display pin 12 (digit1 is common anonds A1 from right side)
int digit2 = 10; //PWM Display pin 9 (digit2 is  common A2)
int digit3 = 9; //PWM Display pin 8 (digit3 is common anods A3)
int digit4 = 6; //PWM Display pin 6 (digit4 is common anods, from left side)

//Pin mapping from Arduino to the ATmega DIP28 if you need it
//http://www.arduino.cc/en/Hacking/PinMapping
int segA = 2; //Display pin 11
int segB = 3; //Display pin 7
int segC = 4; //Display pin 4
int segD = 5; //Display pin 2
int segE = 12; //Display pin 1
int segF = 7; //Display pin 10
int segG = 8; //Display pin 5
int segDP = 13; // Display pin 3

/*
#include "DHT.h"
#define DHTPIN A2     // what pin we're connected to
#define DHTTYPE DHT11   // DHT 11 
DHT dht(DHTPIN, DHTTYPE);
*/

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
// original sketck from http://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/
// add part with SQW=1Hz from http://tronixstuff.wordpress.com/2010/10/20/tutorial-arduino-and-the-i2c-bus/


void setup() {

 //  Serial.begin(57600);
  Wire.begin();
  RTC.begin();
// RTC.adjust(DateTime(__DATE__, __TIME__));
// if you need set clock... just remove // from line above this

// part code for flashing LED
Wire.beginTransmission(0x68);
Wire.write(0x07); // move pointer to SQW address
// Wire.write(0x00); // turns the SQW pin off
 Wire.write(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave at 1Hz
// Wire.write(0x13); // sends 0x13 (hex) 00010011 (binary) 32kHz

Wire.endTransmission();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  
  
// dht.begin();

  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);
  pinMode(segDP, OUTPUT);

  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
  
//  pinMode(13, OUTPUT);

 Serial.begin(9600);
 Serial.println("test for niq_ro");
}

void loop() {
digitalWrite(segDP, HIGH);
  DateTime now = RTC.now();
  int timp = now.hour()*100+now.minute();
//   int timp = (now.minute(), DEC);
//   displayNumber(12); // this is number to diplay
//   int timp = 1234;
  Serial.print(now.hour(), DEC);
  Serial.print(":");
  Serial.print(now.minute(), DEC);
  Serial.print(" -> ");
  Serial.print(timp);
  Serial.println(" !");

/*  
   int h = dht.readHumidity();
   int t = dht.readTemperature();

   for(int i = 1000 ; i >0  ; i--) {
     displayNumber(t); // this is number to diplay
   }
   
   for(int i = 1000 ; i >0  ; i--) {
     displayNumber1(h); // this is number to diplay
   }
 */
   
   for(int i = 400 ; i >0  ; i--) {
     if (timp > 1000) displayNumber01(timp); 
     else displayNumber02(timp); 
   } 

   for(int i = 400 ; i >0  ; i--) {
     if (timp > 1000) displayNumber03(timp); 
     else displayNumber04(timp); 
   } 

  
}


//Given a number, we display 10:22
//After running through the 4 numbers, the display is left turned off

//Display brightness
//Each digit is on for a certain amount of microseconds
//Then it is off until we have reached a total of 20ms for the function call
//Let's assume each digit is on for 1000us
//Each digit is on for 1ms, there are 4 digits, so the display is off for 16ms.
//That's a ratio of 1ms to 16ms or 6.25% on time (PWM).
//Let's define a variable called brightness that varies from:
//5000 blindingly bright (15.7mA current draw per digit)
//2000 shockingly bright (11.4mA current draw per digit)
//1000 pretty bright (5.9mA)
//500 normal (3mA)
//200 dim but readable (1.4mA)
//50 dim but readable (0.56mA)
//5 dim but readable (0.31mA)
//1 dim but readable in dark (0.28mA)

void displayNumber(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW


  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
      digitalWrite(digit1, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      lightNumber(11); // display degree symbol
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      lightNumber(12); // display C letter
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    }
     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber1(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW


  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
      digitalWrite(digit1, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      lightNumber(toDisplay % 10);
      toDisplay /= 10;
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      lightNumber(10); // display degree symbol
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      lightNumber(13); // display C letter
      delayMicroseconds(DISPLAY_BRIGHTNESS); 
      break;
    }
     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber01(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     digitalWrite(digit1, DIGIT_ON);
     digitalWrite(segDP, HIGH);
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, LOW);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber02(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     lightNumber(10); 
     digitalWrite(segDP, HIGH);
     break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, LOW);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber03(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     digitalWrite(digit1, DIGIT_ON);
     digitalWrite(segDP, HIGH);
      break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 

void displayNumber04(int toDisplay) {
#define DISPLAY_BRIGHTNESS  500

#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
     lightNumber(10); 
     digitalWrite(segDP, HIGH);
     break;
   case 2:
      digitalWrite(digit2, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_ON);
      digitalWrite(segDP, HIGH);
      break;
    }
    lightNumber(toDisplay % 10);
    toDisplay /= 10;
    delayMicroseconds(DISPLAY_BRIGHTNESS); 

     //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_OFF);
    digitalWrite(digit2, DIGIT_OFF);
    digitalWrite(digit3, DIGIT_OFF);
    digitalWrite(digit4, DIGIT_OFF);
}
} 


//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  LOW
#define SEGMENT_OFF HIGH

  switch (numberToDisplay){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  // all segment are ON
  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  
  // degree symbol made by niq_ro
  case 11:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  // C letter made by niq_ro
  case 12:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  
  // H letter made by niq_ro
  case 13:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;
  }
}
   ... cat atat, momentan.

marți, 26 noiembrie 2013

Comanda periferice de la calculator pe portul serial folosind Arduino

   O aplicatie de efect este aceea in care se comanda un motor, un ventilator, un proiector, o usa de acces prin introducerea unor cifre sau cuvinte de la tastatura calculatorului.
   Aceasta se poate baza pe comanda Serial.read() a limbajului placii de dezvoltare Arduino.
   Pe net se gasesc cateva articole despre acest tip de comanda, din care amintesc:
- USING ARDUINO TO CONTROL A LED USING THE SERIAL PORT
   Am incercat si eu sa fac asta, rezultandu-mi filmuletul control a LED using Arduino thru keyboard, apoi control a LED using Arduino thru keyboard (II)
   Niste poze din timpul experimentelor:
   Un exemplu de skech simplu este: 
// sketch write by niq_ro from http://www.tehnic.go.ro
// and http://nicuflorica.blogspot.com/
// version 1.0

int motorPin = 13;
void setup()
{
pinMode(motorPin, OUTPUT);
digitalWrite(motorPin, LOW);
Serial.begin(9600);
Serial.println("Apasa 1 pentru a aprinde LED-ul si 2 sa-l stingi!!!");
}

void loop()
{
if (Serial.available())
{
int ch = Serial.read();
Serial.print(ch);

if (ch==49)
{
digitalWrite(motorPin, HIGH);
Serial.println(" Aprind LED-ul");
}
if (ch==50)
{
digitalWrite(motorPin, LOW);
Serial.println(" Sting LED-ul");
}
Serial.println("Apasa 1 pentru a aprinde LED-ul si 2 sa-l stingi!!!");
}
}

   Am modificat sketch-ul si am primit o aplicatie, cu care pot comanda pe langa LED-ul de pe placa (cel de la pinul D13) inca 3 LED-uri, dintr-ul LED multicolor, cum am prezentat in filmuletele control a few LEDs with Arduino and own software (I), respectiv control a few LEDs with Arduino and own software (II)
   Led-urile se pot inlocui cu optocuploare, relee, etc si se pot comanda si echipamente alimentate la retea... dar asta alta data...

vineri, 22 noiembrie 2013

Arduino, un servomotor si o tastatura cu 12 butoane

   In prezentul articol o sa prezint un modul de acces cu parola, cu inchidere manuala sau temporizata, in care elementul de executie e un servomotor.
   Acest articol se bazeaza pe informatiile, schemele si programioarele (sketch-urile) din articolele anterioare:
- Arduino si o tastatura cu 12 butoane
- Arduino si o tastatura cu 12 butoane (II)
- Arduino si un servomotor
   In prima faza am conectat tastatura, afisajul si servomotorul:
schema de conectare fiind:
   Am realizat 2 filmulete:
- Arduino - door lock with code - ver.4.0, cu timp de acces nelimitat, inchidere prin apasarea tastei '#':
- Arduino - door lock with code - ver.4.1, cu timp de acces limitat la 5 secunde:
   Sketch-ul pentru prima versiune este:
// original schematic and schetch from http://www.arduinoevilgenius.com/
// adapted schematic by niq_ro ( http://www.tehnic.go.ro/ )
// sketch door lock ver.4.0 (19.11.2013) use sketch door lock ver.2.0 (02.03.2013)
// http://nicuflorica.blogspot.com
#include <Keypad.h>
#include <EEPROM.h>
char* secretCode = "2255";
int position = 0;
int position2 = 0;
boolean locked = true;
const byte rows = 4;
const byte cols = 3;
char keys[rows][cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[rows] = {2, 7, 6, 4};
byte colPins[cols] = {3, 1, 5};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
int redPin = 11;
int greenPin = 9;
int bluePin = 10;
int solenoidPin = 13;

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

/*
---------------------
| Arduino | LCD1602 |
---------------------
| D14(A0) |    RS   |
---------------------
| D15(A1) |    E    |
---------------------
| D16(A2) |    D4   |
---------------------
| D14(A3) |    D5   |
---------------------
| D14(A4) |    D6   |
---------------------
| D14(A5) |    D7   |
---------------------

*/

#include <Servo.h>
Servo servoMain; // Define our Servo


void setup()
{
/*pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
*/
//pinMode(9, OUTPUT);
servoMain.attach(9); // servo on digital pin 9
//servoMain.write(0);   // Turn Servo Left to 0 degrees
lcd.begin(16, 2);
// print my logo
lcd.setCursor(0, 0);
lcd.print("www.tehnic.go.ro");
lcd.setCursor(0, 1);
lcd.print("   by niq_ro");
delay(5000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("acces permis la");
lcd.setCursor(2, 1);
lcd.print("introducere");
delay(1000);
lcd.clear();

lcd.setCursor(2, 0);
lcd.print("parola corecta");
lcd.setCursor(2, 1);
lcd.print("versiune 4 .0");
delay(1000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("apasa tasta '#'");
lcd.setCursor(0, 1);
lcd.print("pentru stergere");
delay(5000);
lcd.clear();


//eraseCode(); // a first test for initial code at "2255";
delay(1000);
loadCode(); // load the code from EEPROM

flash();
updateOutputs();

// print a new message
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("introdu parola");
lcd.setCursor(0, 1);

}
void loop()
{

//servoMain.write(0);   // Turn Servo Left to 0 degrees
char key = keypad.getKey();
if (key)
{
position2 ++;
//digitalWrite(bluePin, HIGH);
delay(30);
//digitalWrite(bluePin, LOW);
lcd.print("?");
}
if (key == '*' && ! locked)
{
// unlocked and * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
}
if (key == '#')
{
locked = true;
position = 0;
position2= 0;
updateOutputs();
//digitalWrite(bluePin, HIGH);
//delay(300);
//digitalWrite(bluePin, LOW);

lcd.clear();
lcd.setCursor(1, 0);
lcd.print("yala incuiata");
lcd.setCursor(0, 1);
delay(1000);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("introdu parola");
lcd.setCursor(0, 1);

//lcd.clear();

}
if (key == secretCode[position])
{
position ++;
}
if (position == 4 & position2 == 4)
{
locked = false;
//digitalWrite(bluePin, HIGH);
delay(300);
//digitalWrite(bluePin, LOW);
updateOutputs();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola corecta..");
lcd.setCursor(2, 1);
lcd.print("acces permis");
}
delay(100);

}

void updateOutputs()
{
if (locked)
{
//digitalWrite(redPin, HIGH);
//digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, HIGH);
servoMain.write(90);  // Turn Servo back to center position (90 degrees)
}
else
{
//digitalWrite(redPin, LOW);
//digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, LOW);
servoMain.write(0);   // Turn Servo Left to 0 degrees
}
}

void getNewCode()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola noua este");
lcd.setCursor(6, 1);
lcd.print("");

flash();
for (int i = 0; i < 4; i++ )
{
char key;
key = keypad.getKey();
while (key == 0)
{
key = keypad.getKey();
}
flash();
secretCode[i] = key;
lcd.print(key);
}
saveCode();
flash();flash();

}


void loadCode()
{
if (EEPROM.read(0) == 7)
{
secretCode[0] = EEPROM.read(1);
secretCode[1] = EEPROM.read(2);
secretCode[2] = EEPROM.read(3);
secretCode[3] = EEPROM.read(4);
}
}

void saveCode()
{
EEPROM.write(1, secretCode[0]);
EEPROM.write(2, secretCode[1]);
EEPROM.write(3, secretCode[2]);
EEPROM.write(4, secretCode[3]);
EEPROM.write(0, 7);
}


void eraseCode() // code is "2255"
{
EEPROM.write(1, 2);
EEPROM.write(2, 2);
EEPROM.write(3, 5);
EEPROM.write(4, 5);
EEPROM.write(0, 2);
}


void flash()
{
/*digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(100);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
*/
delay(100);
}
    Sketch-ul pentru a 2-a versiune este:
// original schematic and schetch from http://www.arduinoevilgenius.com/
// adapted schematic by niq_ro ( http://www.tehnic.go.ro/ )
// sketch door lock ver.4.1 (19.11.2013) use sketch door lock ver.2.0 (02.03.2013)
// http://nicuflorica.blogspot.com
#include <Keypad.h>
#include <EEPROM.h>
char* secretCode = "2255";
int position = 0;
int position2 = 0;
boolean locked = true;
const byte rows = 4;
const byte cols = 3;
char keys[rows][cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[rows] = {2, 7, 6, 4};
byte colPins[cols] = {3, 1, 5};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);
/*
int redPin = 11;
int greenPin = 9;
int bluePin = 10;
*/
int solenoidPin = 13;

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

/*
---------------------
| Arduino | LCD1602 |
---------------------
| D14(A0) |    RS   |
---------------------
| D15(A1) |    E    |
---------------------
| D16(A2) |    D4   |
---------------------
| D14(A3) |    D5   |
---------------------
| D14(A4) |    D6   |
---------------------
| D14(A5) |    D7   |
---------------------
*/


#include <Servo.h>
Servo servoMain; // Define our Servo


void setup()
{
  /*
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
*/
pinMode(solenoidPin, OUTPUT);
servoMain.attach(9); // servo on digital pin 9

lcd.begin(16, 2);
// print my logo
lcd.setCursor(0, 0);
lcd.print("www.tehnic.go.ro");
lcd.setCursor(0, 1);
lcd.print("   by niq_ro");
delay(5000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("acces permis la");
lcd.setCursor(2, 1);
lcd.print("introducere");
delay(1000);
lcd.clear();

lcd.setCursor(1, 0);
lcd.print("parola corecta");
lcd.setCursor(2, 1);
lcd.print("versiune 4.1");
delay(1000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("apasa tasta '#'");
lcd.setCursor(0, 1);
lcd.print("pentru stergere");
delay(2000);
lcd.clear();



//eraseCode(); // a first test for initial code at "2255";
delay(1000);
loadCode(); // load the code from EEPROM

flash();
updateOutputs();
afisaj();

}
void loop()
{
/*
 servoMain.write(0);   // Turn Servo Left (to 0 degrees)
 delay(500);          // Wait 1 second  
*/

char key = keypad.getKey();
if (key)
{
position2 ++;
// digitalWrite(bluePin, HIGH);
delay(30);
// digitalWrite(bluePin, LOW);
lcd.print("?");
}


if (key == '*' && ! locked)
{
// unlocked and * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
afisaj();
}
// if (key == '#' && ! locked)   // manual locked when push '#'
if (key == '#' )   // manual locked when push '#'
{
locked = true;
position = 0;
position2= 0;
updateOutputs();
// digitalWrite(bluePin, HIGH);
//delay(300);
// digitalWrite(bluePin, LOW);
afisaj();
}

if (key == secretCode[position])
{
position ++;
}
if (position == 4 & position2 == 4)
{
locked = false;
// digitalWrite(bluePin, HIGH);
delay(300);
// digitalWrite(bluePin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola corecta..");
lcd.setCursor(0, 1);
lcd.print("acces permis 5s");
updateOutputs();
afisaj();
}
}


void updateOutputs()
{
if (locked)
{
//digitalWrite(redPin, HIGH);
//digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
servoMain.write(90);  // Turn Servo back to center position (90 degrees)
}
else
{
//digitalWrite(redPin, LOW);
//digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, HIGH);
servoMain.write(0);  // Turn Servo back to left position (0 degrees)

delay (50);
for (int i=0; i <= 100; i++)
{
char key;
key = keypad.getKey();
if (key == '*')
{
// unlocked and * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
}
delay (50);
}
//digitalWrite(redPin, HIGH);
//digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
servoMain.write(90);  // Turn Servo back to center position (90 degrees)
locked = true;
position = 0;
position2= 0;
}
}


void getNewCode()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola noua este");
lcd.setCursor(6, 1);
lcd.print("");

flash();
for (int i = 0; i < 4; i++ )
{
char key;
key = keypad.getKey();
while (key == 0)
{
key = keypad.getKey();
}
flash();
secretCode[i] = key;
lcd.print(key);
}
saveCode();
flash();flash();
//delay(400);
//afisaj();
}


void loadCode()
{
if (EEPROM.read(0) == 7)
{
secretCode[0] = EEPROM.read(1);
secretCode[1] = EEPROM.read(2);
secretCode[2] = EEPROM.read(3);
secretCode[3] = EEPROM.read(4);
}
}

void saveCode()
{
EEPROM.write(1, secretCode[0]);
EEPROM.write(2, secretCode[1]);
EEPROM.write(3, secretCode[2]);
EEPROM.write(4, secretCode[3]);
EEPROM.write(0, 7);
}


void eraseCode() // code is "2255"
{
EEPROM.write(1, 2);
EEPROM.write(2, 2);
EEPROM.write(3, 5);
EEPROM.write(4, 5);
EEPROM.write(0, 2);
}


void flash()
{
//digitalWrite(redPin, HIGH);
//digitalWrite(greenPin, LOW);
delay(100);
//digitalWrite(redPin, LOW);
//digitalWrite(greenPin, HIGH);
delay(100);
}

void afisaj()
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("yala incuiata");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("introdu parola");
lcd.setCursor(0, 1);
}

   Ulterior am conectat si LED-ul multicolor, care imi indica starea (rosu la inchis, verde la deschis si albastru la apasare tasta):
 
   Am facut un filmulet, numit Arduino - door lock with code - ver.4.2
iar sketch-ul pentru aceasta varianta este:
// original schematic and schetch from http://www.arduinoevilgenius.com/
// adapted schematic by niq_ro ( http://www.tehnic.go.ro/ )
// sketch door lock ver.4.2 (20.11.2013) use sketch door lock ver.2.0 (02.03.2013)
// http://nicuflorica.blogspot.com

#include <Keypad.h>
#include <EEPROM.h>
char* secretCode = "2255";
int position = 0;
int position2 = 0;
boolean locked = true;
const byte rows = 4;
const byte cols = 3;
char keys[rows][cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[rows] = {2, 7, 6, 4};
byte colPins[cols] = {3, 1, 5};

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols);

int solenoidPin = 13;
int redPin = 12;
int bluePin = 11;
int greenPin = 10;
int servoPin = 9;

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(14, 15, 16, 17, 18, 19);

/*
---------------------
| Arduino | LCD1602 |
---------------------
| D14(A0) |    RS   |
---------------------
| D15(A1) |    E    |
---------------------
| D16(A2) |    D4   |
---------------------
| D14(A3) |    D5   |
---------------------
| D14(A4) |    D6   |
---------------------
| D14(A5) |    D7   |
---------------------
*/


#include <Servo.h>
Servo servoMain; // Define our Servo


void setup()
{

pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

pinMode(solenoidPin, OUTPUT);
servoMain.attach(servoPin); 

lcd.begin(16, 2);
// print my logo
lcd.setCursor(0, 0);
lcd.print("www.tehnic.go.ro");
lcd.setCursor(0, 1);
lcd.print("   by niq_ro");
delay(5000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("acces permis la");
lcd.setCursor(2, 1);
lcd.print("introducere");
delay(1000);
lcd.clear();

lcd.setCursor(1, 0);
lcd.print("parola corecta");
lcd.setCursor(2, 1);
lcd.print("versiune 4.2");
delay(1000);
lcd.clear();

lcd.setCursor(0, 0);
lcd.print("apasa tasta '#'");
lcd.setCursor(0, 1);
lcd.print("pentru stergere");
delay(2000);
lcd.clear();



//eraseCode(); // a first test for initial code at "2255";
delay(1000);
loadCode(); // load the code from EEPROM

flash();
updateOutputs();
afisaj();

}
void loop()
{

char key = keypad.getKey();
if (key)
{
position2 ++;
digitalWrite(bluePin, HIGH);
delay(30);
digitalWrite(bluePin, LOW);
lcd.print("?");
}


if (key == '*' && ! locked)
{
// unlocked and * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
afisaj();
}
// if (key == '#' && ! locked)   // manual locked when push '#'
if (key == '#' )   // manual locked when push '#'
{
locked = true;
position = 0;
position2= 0;
updateOutputs();
digitalWrite(bluePin, HIGH);
delay(300);
digitalWrite(bluePin, LOW);
afisaj();
}

if (key == secretCode[position])
{
position ++;
}
if (position == 4 & position2 == 4)
{
locked = false;
digitalWrite(bluePin, HIGH);
delay(300);
digitalWrite(bluePin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola corecta..");
lcd.setCursor(0, 1);
lcd.print("acces permis 5s");
updateOutputs();
afisaj();
}
}


void updateOutputs()
{
if (locked)
{
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
servoMain.write(90);  // Turn Servo back to center position (90 degrees)
}
else
{
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, HIGH);
servoMain.write(0);  // Turn Servo back to left position (0 degrees)

delay (50);
for (int i=0; i <= 100; i++)
{
char key;
key = keypad.getKey();
if (key == '*')
{
// unlocked and * pressed so change code
position = 0;
position2 = 0;
getNewCode();
updateOutputs();
}
delay (50);
}
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
digitalWrite(solenoidPin, LOW);
servoMain.write(90);  // Turn Servo back to center position (90 degrees)
locked = true;
position = 0;
position2= 0;
}
}


void getNewCode()
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("parola noua este");
lcd.setCursor(6, 1);
lcd.print("");

flash();
for (int i = 0; i < 4; i++ )
{
char key;
key = keypad.getKey();
while (key == 0)
{
key = keypad.getKey();
}
flash();
secretCode[i] = key;
lcd.print(key);
}
saveCode();
flash();flash();
//delay(400);
//afisaj();
}


void loadCode()
{
if (EEPROM.read(0) == 7)
{
secretCode[0] = EEPROM.read(1);
secretCode[1] = EEPROM.read(2);
secretCode[2] = EEPROM.read(3);
secretCode[3] = EEPROM.read(4);
}
}

void saveCode()
{
EEPROM.write(1, secretCode[0]);
EEPROM.write(2, secretCode[1]);
EEPROM.write(3, secretCode[2]);
EEPROM.write(4, secretCode[3]);
EEPROM.write(0, 7);
}


void eraseCode() // code is "2255"
{
EEPROM.write(1, 2);
EEPROM.write(2, 2);
EEPROM.write(3, 5);
EEPROM.write(4, 5);
EEPROM.write(0, 2);
}


void flash()
{
digitalWrite(redPin, HIGH);
digitalWrite(greenPin, LOW);
delay(100);
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
delay(100);
}

void afisaj()
{
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("yala incuiata");
lcd.setCursor(0, 1);
delay(500);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("introdu parola");
lcd.setCursor(0, 1);
}