Zaslal: út duben 10 2018, 21:19 Předmět: Pomoc s programem - arduino uno
Zdravím vás, chtěl jsem si udělat elektronicky zabezpečovací systém a nevím si rady s jednou věcí. Potřeboval jsem pro začátek program s funkcí.
Zapnu arduino, nic se neděje.
Když na klávesnici zmáčknu #, má se na displej napsat "zamceno" a budova se má "uzamčít", takže pokaždé, když by se otevřely dveře a zaznamenal to magnetický senzor, má se na 10s rozeznít sirénka a to je vše. Pokud by se znovu otevřely, znovu by se měla rozeznít sirénka, až do té doby, než by se zadal kód, který by to zrušil a zase by se nic nedělo, i kdyby se otevíraly dveře..
Program jsem napsal s dvěma podmínkami if v sobě.. první, že pokud zmáčknu #, má se zapnout senzor a pokud jím neprotéká proud, má se zapnout sirénka.. bohužel mi to funguje tak, že jakmile zmáčknu "#", napíše se uzamčít, pak se na 10s zapne sirénka a vypne.. a já si nevím rady co s tím(tu část s tím odemčením budovy na kód nemám naprogramovanou, ale snad to jde i bez toho, ne? )
byte rowPins[ROWS] = {
8,7,6,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
9,3,2}; //connect to the column pinouts of the keypad
Keypad klavesnice( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
int magnet = 10;
int sirena = 0;
void setup()
{
digitalWrite(magnet, HIGH);// zapne se magneticky senzor
pinMode(magnet, INPUT);
pinMode(sirena, OUTPUT);
lcd.begin();// initialize the lcd
lcd.backlight();
}
void loop()
{
char stisknutyznak = klavesnice.getKey();// vytvoří proměnnou, do které uloží znak stisknuté klávesy
if (stisknutyznak == '#') //když se stiskne křížek, objeví se na display zamčeno
{
lcd.setCursor (4,0);
lcd.print("Zamceno");
delay(5000) ;
lcd.clear(); // po 5ti sekundách se nápis "zamčeno" smaže
if(digitalRead(magnet) == HIGH) //pokud neprochazi proud, sirena je zapnutá
{
digitalWrite(sirena,LOW);
}
else {
digitalWrite(sirena, HIGH);// sirena se zapne na 10 sekund
delay(10000);
digitalWrite(sirena,LOW);
Podmienky vyzerajú byť dobre. Ale nechápem, prečo na jeden pin zapíšeš výstup do Hi a vzápätí z neho spravíš vstup, nemôže to robiť problém, že tam ostane Out Hi?
digitalWrite(magnet, HIGH);// zapne se magneticky senzor
pinMode(magnet, INPUT);
edit - moja blbosť, bude to pre pullup. Ale zvykne sa to naopak. Najskôr nastaviť ako output a potom write. Ale to asi nebude mať vplyv.
Naposledy upravil passion dne st duben 11 2018, 5:48, celkově upraveno 1 krát.
Ty podmínky nemohou být vnořené v sobě. Udělej si pomocnou proměnnou "zamceno" tu nastavuj do 1 nebo 0 podle toho co bude stisknuto. V další podmínce testuj jestli platí současně zamceno=1 a rezepnutý kontakt. Pak spust sirénu. Vyhni se používání delay. Pokud běží delay procesor nic jiného nedělá takže nevypneš ani tu sirénu dokud nedoběhne těch 10s.
Jasně že může mít dvě podmínky vnořený do sebe - ale pokud to má smysl! Takhle by musel vyškolit zloděje aby před vloupáním stiskl na klávesnici křížek, jinak to k té druhé podmínce která testuje kontakt vůbec nedojde.
dělám to na základě programu, který mi funguje jak má, jen se ho snažím napasovat na tu podmínku se stisknutým křížkem.
Pochopte.. jsem doma, tak je mi jedno jestli se otvírají dveře.. odejdu pryč, stisknu křížek, tím pádem se to aktivuje a když někdo cizí otevře dveře, aniž by třeba předtím zadal nějaké heslo, tak se rozhouká sirénka.
Pošlu ten samostatný kód na dveře, který funguje
const int magnet = 10;
const int sirena = 0;
int status;
void setup() {
tak pro zajímavost... už mi to funguje a opravdu jsem místo toho druhého 'if' musel použít 'else if'.. mohl by mi prosím někdo přesně vysvětlit, jaký je mezi tím problém? já z netu tak nějak pochopil, že musí být splněny obě podmínky současně, když tam dám to else if, ale myslel jsem si, že to vyřeší ty závorky
Ale funguje. V prvom programe máš prehodenú úroveň v podmienke:
if(digitalRead(magnet) == HIGH) //pokud neprochazi proud, sirena je zapnutá
{
digitalWrite(sirena,LOW);
}
else {
digitalWrite(sirena, HIGH);// sirena se zapne na 10 sekund
delay(10000);
digitalWrite(sirena,LOW);
}
Ak je magnet Hi - siréna bude Lo
Inak siréna Hi
V druhom programe to máš opačne:
if(digitalRead(magnet) == LOW){
digitalWrite(sirena, LOW);
}
else{
digitalWrite(sirena, HIGH);
delay (5000);
digitalWrite(sirena, LOW);
}
Ak je magnet Lo - siréna bude Lo
Ina siréna Hi
Edit - ak máš problém pochopiť postup v podmienkach, nakresli si to do vývojového diagramu.
Z toho, co říkáš by to fungovalo, akorát opačně.. při zavřených dvěřích by sirénka jela, při otevřených ne... ale v tom to není, to bych poznal, že je akorát toto přehozené.
byte rowPins[ROWS] = {
8,7,6,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
9,3,2}; //connect to the column pinouts of the keypad
Keypad klavesnice( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
int magnet = 10;
int sirena = 0;
void setup()
{
pinMode(magnet, INPUT);
pinMode(sirena, OUTPUT);
lcd.begin();// initialize the lcd
lcd.backlight();
}
void loop()
{
char stisknutyznak = klavesnice.getKey();// vytvoří proměnnou, do které uloží znak stisknuté klávesy
if (stisknutyznak == '#') //když se stiskne křížek, objeví se na display zamčeno
{
lcd.setCursor (4,0);
lcd.print("Zamceno");
digitalWrite(magnet, HIGH);// a zapne se magneticky senzor
delay(1000) ;
lcd.clear(); // po 5ti sekundách se nápis "zamčeno" smaže
Tak daj do angličtiny a pochopíš:
if = Ak
else = inak
Tým else ukončíš kladnú odpoveď v prvej podmienke, a druhým if začneš druhú podmienku. Ale stále ju máš vnorenú v zápornej odpovedi v prvej podmienke. Else môžeš aj nemusíš použiť - ak nepotrebuješ riešiť zápornú odpoveď podmienky
edit - tým write magnet nezapínaš magnet! Ten pin si v setup nastavil ako vstup. Tým, že na vstup zapíšeš Hi, zapneš interný pullup rezistor!
Ešte niečo - pre prehľadnosť kódu nemusíš pri jednom príkaze za if ani za else písať zložené zátvorky (ale môžeš). Ak ich nepoužiješ, podmienka v if sa končí tým jedným príkazom. Ak ich použiješ, podmienku ukončíš až opačnou zátvorkou. Ty si v tom prvom príspevku neukončil prvú podmienku opačnou zátvorkou a do nej si ako písal kolega, vnoril druhú podmienku.
Skús to takto pre pochopenie, pullup zapni už v setup, ak je to potrebné:
if (stisknutyznak == '#') //když se stiskne křížek, objeví se na display zamčeno
{
lcd.setCursor (4,0);
lcd.print("Zamceno");
delay(1000) ;
lcd.clear(); // po 1 sekunde se nápis "zamčeno" smaže
}
if(digitalRead(magnet) == HIGH)
{
digitalWrite(sirena, HIGH);
delay(3000);
digitalWrite(sirena,LOW);
}
else digitalWrite(sirena, LOW);
Ta poslední varianta o které píšeš že funguje také není příliš šťastná. Zkus co ti to udělá když ti tlačítko na kterém je křížek odejde a zůstane trvale sepnuté.
Proč to neuděláš přes tu pomocnou proměnnou jak jsem psal?
//-------- tady nastavuješ co bylo stisknuto -------
if (stisknutyznak == '#') //když se stiskne křížek, objeví se na display zamčeno
{
zamceno=1;
lcd.setCursor (4,0);
lcd.print("Zamceno");
}
if (stisknutyznak == '*') //když se stiskne hvězdička, objeví se na display odemčeno
{
zamceno=0;
lcd.setCursor (4,0);
lcd.print("Odemceno");
}
// a tady testuješ jestli je zamčeno a ZÁROVEŇ došlo k narušení
If zamceno==1 and (digitalRead(magnet) == HIGH)
{
// tady zapneš sirénu
}
děkuji moc.. udělal jsem to tak.. funguje to a je to fakt dobrý nápad!
teď ale mám další problém.. chci k tomu přidat to, že po zapojení se bude na displeji na 4 řádku ukazovat aktuální datum a čas.. vzal jsem zase program, který už mám hotový a umí to a přidal ho k tomu programu.. a jediné co teď funguje je, že se zobrazí ten čas a zamykání nefuguje... postupně jsem přidával části kodů a zjistil jsem, že neplechu dělá tento příkaz, ale nechápu proč.. věděl by někdo?
Co to přesně znamená že dělá neplechu? Zkus sem dát celý kód, z toho jednoho řádku není zřejmé proč by to nemělo fungovat. Dnes už se k tomu nedostanu ale zítra se na to podívám.
Vzal jsem program na to otevírání dveří co jsme tu řešili a postupně do něj dopisoval proměnné a části kódu z toho RTC, který mi funguje a vždy po jednom řádku jsem to zkovnertoval a zjišťoval, jestli to funguje. a po napsání toho řádku to přestalo fungovat, takže očekávám že chyba je v něm. Kód přikládám, děkuji moc.
kód:
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS1307.h>
#define Password_Lenght 5 //délka hesla 5
LiquidCrystal_I2C lcd(0x27,20,4);
char Data[Password_Lenght]; // 6 is the number of chars it can hold + the null char = 7
char Master[Password_Lenght] = "1";
byte data_count = 0, master_count = 0;
bool Pass_is_good;
char stisknutyznak;
int rtc[68];
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] = {
8,7,6,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
9,3,2}; //connect to the column pinouts of the keypad
Keypad klavesnice( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //initialize an instance of class NewKeypad
int zamceno;
int magnet = 10;
int sirena = 0;
void setup()
{
pinMode(magnet, INPUT);
pinMode(sirena, OUTPUT);
lcd.begin();// initialize the lcd
lcd.backlight();
lcd.setCursor(4,0); // nastaví kurzor na pozici
RTC.set(DS1307_DATE,11); // nastaví den v měsíci
RTC.set(DS1307_MTH,4); // nastaví měsíc
RTC.set(DS1307_YR,18); // nastaví rok
RTC.set(DS1307_MIN,11); // nastaví minuty
RTC.set(DS1307_HR,10); // nastaví hodiny
RTC.start(); // spustí čas
}
void loop()
{
char stisknutyznak = klavesnice.getKey();// vytvoří proměnnou, do které uloží znak stisknuté klávesy
RTC.get(rtc,true);
// připraví pole znaků pro čas
char cas[9];
// zapíše do pole znaků cas hodnoty z rtc
lcd.setCursor(3,3); // nastaví kurzor na pozici
lcd.print(cas); // vypíše cas na displej
if (stisknutyznak == '#') //když se stiskne křížek, objeví se na display zamčeno
{
zamceno=1;
lcd.setCursor (4,0);
lcd.print("Zamceno");
digitalWrite(magnet, HIGH);// a zapne se magneticky senzor
delay(1000) ;
lcd.clear(); // po 5ti sekundách se nápis "zamčeno" smaže
Časy uváděny v GMT + 1 hodina Jdi na stránku 1, 2, 3Další
Strana 1 z 3
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.