Se afișează postările cu eticheta cod. Afișați toate postările
Se afișează postările cu eticheta cod. Afișați toate postările

luni, 18 noiembrie 2013

Arduino si o tastatura cu 12 butoane (II)

   Fata de articolul precedent, in care am facut un sistem de acces cu cod, cu timp de acces pana se apasa o tasta sau temporizat, fara sau cu posibilitate de schimbare a parolei, acum o sa conectez si un afisaj LCD1602 (cu 16 coloane si 2 randuri).
   Deoarece pentru tastatura folosesc 7 intrari digitale (D1..D7), iar pentru LED-ul multicolor inca 3 (D9, D10, D11) + o iesire pentru electromagnet (D13), nu am suficiente iesiri digitale pentru afisajul LCD... imi trebuie 6... asa ca o sa folosesc cele 6 intrari analogice A0..A5 ca iesiri digitale D14..D19, dupa cum am gasit in cartea "30 Arduino Projects for the Evil Genius" scrisa de Simon Monk si in articolul How to add 6 extra pins to your Arduino with no extra hardware
 
   Schema de conectare, din bucatele este:
O poza cu montajul:
   Schema completa este:
   Un sketch care are implementata si partea de afisare si acces functie de parola, iar inchiderea se face apasand tasta '#'. Schimbarea parolei se face cand zavorul este decuplat (acces permis) dupa apasarea tastei '*' (stocarea datelor se face in memoria interna EEPROM a microcontrolerului ATmega). LED-ul multicolor se aprinde in rosu, cand yala este incuiata, verde cand este descuiata si "palpaie" in albastru cand se apasa oricare tasta.
   Am facut 2 filmulete in care sunt toate starile si prezint modul de functionare:
   Sketch-ul pentru ce am prezentat mai inainte este:  
// original schematic and schetch from http://www.arduinoevilgenius.com/
// adapted schematic by niq_ro ( http://www.tehnic.go.ro/ )
// sketch door lock ver.3.1 (16.11.2013) use sketch door lock ver.2.0 (02.03.2013)
#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   |
---------------------

*/

void setup()
{
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

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 3.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()
{

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);
}
else
{
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, LOW);
}
}

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);
}
   Am modificat sketch-ul pentru a avea acces temporizat (doar 5 secunde dupa introducerea corecta a codului), dupa cum se vede in filmuletul Arduino - door lock ver.3.4 (code stored in EEPROM) with 1602 LCD - acces for 5 seconds
   Sketch-ul modificat este:

// original schematic and schetch from http://www.arduinoevilgenius.com/
// adapted schematic by niq_ro ( http://www.tehnic.go.ro/ )
// sketch door lock ver.3.4 (17.11.2013) use sketch door lock ver.2.0 (02.03.2013)
#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   |
---------------------
*/

void setup()
{
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);

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 3.4");
delay(1000);
lcd.clear();

lcd.setCursor(1, 0);
lcd.print("apasa tasta '#'");
lcd.setCursor(2, 1);
lcd.print("pentru stergere");
delay(1000);
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 == '#' )   // 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, HIGH);
}
else
{
digitalWrite(redPin, LOW);
digitalWrite(greenPin, HIGH);
digitalWrite(solenoidPin, LOW);

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, HIGH);
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);
}
   

marți, 1 octombrie 2013

Prezentare "frumoasa" sketch/program in articol (II)

   In precedentul articol am prezentat cum afisez frumos un cod/program/sketch, apoi cum fac un text de dimensiuni mari sa fie afisat intr-o fereastra mica.
   Deoarece nu vreau sa instalez programe si alte "ajutoare", am mai cautat si am ajuns la concluzia ca am cautat prea departe, in sensul ca inclusiv programul Arduino IDE are facilitatea de a copia codul si a-l transforma in cod HTML, sketch-ul aratand intuitiuv (cu anumite culori, de exemplu):

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int led = 13;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
}

// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}

   Acest tip de prezentare nu elimina problema textelor lungi, asa ca e vreu ceva de genul:
/*
original sketch made by niq_ro ( http://www.tehnic.go.ro )
Santuhalm, Romania, 30.7.2013
revised (1.3.3) sketch in 25.8.2013, Craiova

*/
int u1 = 0; // initial voltage value from sensor;
float u = 0.00; // initial calculated voltage value; 
int i1 = 0; // initial current value;
float i = 0.00; // initial calculated current value;
int t1 = 0; // initial temperature value;
float t = 0.00; // initial calculated temperature value; 

int voltagePin = A4; // divider from measuread voltge is put at analog input no.4
int currentPin = A3; // output from ACS712 is put at analog input no.3
int temperaturePin = A5; // output from LM335 is put at analog input no.5


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

// initialize the library with the numbers of the interface pins
// LiquidCrystal lcd(RS, EN, D4, D5, D6, D7);
LiquidCrystal lcd(3, 4, 5, 6, 7, 8);


void setup() {                
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(1, 0);
  lcd.print("indicator panou");
  lcd.setCursor(1, 1);
  lcd.print("ramura negativa");
  delay(2000);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("versiune 1.3.3");
  lcd.setCursor(4, 1);
  lcd.print("by niq_ro");
  delay(2000);
 // lcd.clear();
 
}


void loop() {
  
float u2 = 0; 
float i2 = 0;
float t2 = 0;
  for (int x=1; x <= 5; x++)
  {
// calculate the value  
u1 = analogRead(voltagePin); // read value from voltage divider;
u = 105*u1/1023.0; // calculated value for input voltage;
u2 = u2 + u;

i1 = analogRead(currentPin); // read value from current sensor (ACS712);
i = 10.0*(5.0*i1/1023.0-2.5); // calculated value for input current using ACS712-20;
i2 = i2 + i;

t1 = analogRead(temperaturePin); // read value from temperature sensor (LM335);
t = 100.0*(5.0*t1/1023.0-2.980)+25.0;
t2 = t2 + t;

delay (200);
  }   

u = u2/5.0; // average and corrected voltage
i = i2/5.0 + 0.05; // average and corrected current
t = t2/5.0 - 8.0 ; // average and corrected temperature
 
// Print a message to the LCD.
  lcd.clear();
  
  // show the voltage value
  if (u >= 100.0) 
  {
    lcd.setCursor(0, 0);
    lcd.print("-");
    lcd.print(u,1);
    lcd.print("V");
  }
  else
  if (u >= 10.0) 
    {
    lcd.setCursor(1, 0);
    lcd.print("-");
    lcd.print(u,1);
    lcd.print("V");
    }
  else  
  if (u > 0.0) 
  { lcd.setCursor(2, 0);
    lcd.print("-");
    lcd.print(u,1);
    lcd.print("V");
  }  
    else
   { lcd.setCursor(3, 0);
    lcd.print(u,1);
    lcd.print("V");
   } 
  // show the current value
  if (i >= 10.0) 
    {
    lcd.setCursor(1, 1);
    lcd.print("+");
    lcd.print(i,1);
    lcd.print("A");
    }
  else  
  if (i > 0.0) 
  { lcd.setCursor(2, 1);
    lcd.print("+");
    lcd.print(i,1);
    lcd.print("A");
  }
  else
  if (i < -10.0) 
  { lcd.setCursor(1, 1);
    lcd.print(i,1);
    lcd.print("A");
  }
  else
  if (i < 0.0) 
  { lcd.setCursor(2, 1);
    lcd.print(i,1);
    lcd.print("A");
  }  
    else
  {  lcd.setCursor(3, 1);
    lcd.print(i,1);
    lcd.print("A");
  }
 
   // show the power value
float p=i*u;
  if (p < 0.0) p = -p;
  if (p >= 1000.0)
  {
  lcd.setCursor(11, 0);
  }
  else
  if (p >= 100.0)
  {
  lcd.setCursor(12, 0);
  }
  else
  if (p >= 10.0)
  {
  lcd.setCursor(13, 0);
  }
  else lcd.setCursor(14, 0);
  lcd.print(p,0);
  lcd.print("W");


   // show the temperature value
 if (t >= 100.0) 
    {
    lcd.setCursor(8, 1);
    lcd.print("+");
    lcd.print(t,1);
    lcd.write(0b11011111);
    lcd.print("C");
    }
  else  
  if (t >= 10.0) 
  { lcd.setCursor(9, 1);
    lcd.print("+");
    lcd.print(t,1);
    lcd.write(0b11011111);
    lcd.print("C");
  }
  else
  if (t >= 0.0) 
  { lcd.setCursor(10, 1);
    lcd.print("+");
    lcd.print(t,1);
    lcd.write(0b11011111);
    lcd.print("C");
  }
  else
  if (t < -10.0) 
  { lcd.setCursor(9, 1);
    lcd.print("+");
    lcd.print(t,1);
    lcd.write(0b11011111);
    lcd.print("C");
  }
  else
  { lcd.setCursor(10, 1);
    lcd.print(t,1);
    lcd.write(0b11011111);
    lcd.print("C");
  }  
delay(1000);
}

   Toata smecheria este in adaugarea urmatorului text, in sursa paginii (html):
 <pre style="background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: 200px; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;"><code style="color: black; word-wrap: normal;">  
inaintea textului selectat si copiat ca HTML din Arduino IDE,
iar la final trebuie pus:
 </code>/<pre>  
 </p>  

   Un alt exemplu de sketch:
/*.............................................................
Sending Multiple Variables Using VirtualWire. Receiver
Author: Rodrigo Mompo Redoli
For http://controlrobotics.rodrigomompo.com
adapted sketch by niq_ro (Nicu FLORICA) from http://nicuflorica.blogspot.com
..............................................................*/
#include <VirtualWire.h>
#include <Time.h>  
// Sensors 
int Sensor1Data;
int Sensor2Data;
int Sensor3Data;
int Sensor4Data;
  
char StringReceived[22]; 
// other  
int led = 13; //pin for LED
int j=1; // count the messages
  
void setup() {
  // set the time for record time and value
   setTime(0,0,0,25,9,13); // set time to Saturday 8:29:00am Jan 1 2011

pinMode(led, OUTPUT); 

  // VirtualWire 
    // Initialise the IO and ISR
    // Required for DR3100

    // Bits per sec
    vw_setup(2000);
    vw_set_rx_pin(11);  
      
    // Start the receiver PLL running
    vw_rx_start();       

Serial.begin(9600);
Serial.println("Receptorul lui niq_ro e pregatit sa primeasca mesaje..."); 

  
} // END void setup
  
void loop(){
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
      
//Taking the data from the control base
    if (vw_get_message(buf, &buflen)) 
    {
      digitalWrite(led, HIGH);
Serial.print("Pachet date nr. "); // print a message
Serial.print(j); // number of message
Serial.print(": ");
 int i;
        // Message with a good checksum received, dump it. 
        for (i = 0; i < buflen; i++)
 {            
          // Fill Sensor1CharMsg Char array with corresponding 
          // chars from buffer.   
          StringReceived[i] = char(buf[i]);
     //     Serial.print(StringReceived[i]);
 }
  
      sscanf(StringReceived, "%d,%d,%d,%d,%d,%d",&Sensor1Data, &Sensor2Data,&Sensor3Data,&Sensor4Data); // Converts a string to an array
//Serial.print();
  if (hour()<10) Serial.print("0");
  Serial.print(hour());
  Serial.print(":");
  if (minute()<10) Serial.print("0");
  Serial.print(minute());
  Serial.print(":");
  if (second()<10) Serial.print("0");
  Serial.print(second());
Serial.print(" - ");
digitalWrite(led, LOW);        
Serial.print(Sensor1Data);
Serial.print(", ");
Serial.print(Sensor2Data);
Serial.print(", ");
Serial.print(Sensor3Data);
Serial.print(" & ");
Serial.println(Sensor4Data);
        // Turn off light to and await next message 
j=j++; // count the message         
    }
  
 memset( StringReceived, 0, sizeof( StringReceived));// This line is for reset the StringReceived
}