/* - od vrstice 40 naprej je nova koda za millis
*/
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 2; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
const int n = 100; // čas intervala v ms
const int timer = 250; // število intervalov (* čas intervala = čas aktivnosti)
const int rolete = 8; // število rolet
const int stolpci = 5; // število stanj na roleto (stara tipka, tipka, časovnik, smer, vklop)
const int releji = 2; // število relejev na roleto
const int arrayRolete [rolete][releji] {{30, 31}, {32, 33}, {34, 35}, {36, 37}, {38, 39}, {40, 41}, {42, 43}, {44, 45}}; // vsaka roleta ima 2 kontrolna pina za 2 releja, 1-smer, 2-vklop, za vsak rele nastavimo številko pina, ki se uporablja
// variables will change:
int gumb = 0; // variable for reading the pushbutton status
int gumbOld = 0; // variable for reading the pushbutton status
int cas = 0; // glavni timer
int smer = 0; // 3ST; 1 - gor, 0 - dol
int motor = 0; // SSR; 1 - premik, 0 - miruje
// nastavimo spremenjlivke za sprehod čez arraye
int t = 0; // števec za časovnik
int i = 0; // zaporedna številka rolete
int j = 0; // zaporedna številka stolpca
const int a = 0; // stara tipka - archive
const int b = 1; // tipka - button
const int c = 2; // časovnik - cas
const int d = 3; // smer - direction
const int e = 4; // vklop - engine
// tabela za rolete z stanji časovnikom in tipkami
int arrayRun [rolete][stolpci] = {0}; // vsaka roleta ima 5 stolpcev, tu vse sočasno nastavimo na 0 (kar ni definirano je 0)
// nastavimo funkcijo za premik
void moveRoletePrint (); // prototip funkcije
void moveRolete (); // prototip funkcije
/*****************************************************************************************************/
// nova koda za millis - do tu še ni bilo nič spremenjeno, stara koda je naprej od void setup{}
/*
unsigned long curr = 0;
unsigned long prev = 0;
int interval = 100;
curr = millis();
if( (curr - prev) > interval ){
prev = curr;
Serial.println("Beep!");
}
*/
// luči imamo 19 (8 spodaj, 11 zgoraj)
// rolet imamo 8 (2 spodaj, 6 zgoraj)
// gumbov imamo 49 (24 zgoraj, 13 spodaj in 12 na kontrolni plošči)
// Z gumbov in 2 funkciji (roleta long press, luč short press)
// TODO: sistem zapisa shift,mux in direktne vezave v gumbe
const int numBits = 8; // koliko bitni so shift registri
const int numChain = 2; // koliko shift registrov je vezanih skupaj
// nastavimo število shift registrov in koliko bitni so (2*8=16)
const int shiftBit = numBits*numChain;
const int shiftNo = 4;
const int pulseWidth = 10; // pulse width in microseconds
const int clockPin = 8; // CP
const int latchPin = 9; // PL
const int ArrayDataPin[shiftNo] = {10,11,12,13}; // Q7
// 3d array za staro/novo stanje shift registrov
const bool ArrayShiftState[shiftBit][shiftNo][2] = {0};
const int ukazi = 31;
// povezovalna tabela med stikalom in funkcijami:
// 0 ni ukaza
//* 1xx je pritličje
// - 100 master spodaj
// - 101 - dnevna 1 - TV
// - 102 - dnevna 2 - sedežna
// - 103 - jedilnica 1 - miza
// - 104 - jedilnica 2 - hladilnik
// - 105 - hodnik - spodaj
// - 106 - predsoba
// - 107 - kuhinja
// - 108 - WC
//** 2xx je nadstropje
// - 200 master zgoraj
// - 201 - spalnica
// - 202 - stopnišče (hodnik) - zgoraj
// - 203 - Gašper 1 - miza
// - 204 - Gašper 2 - postelja
// - 205 - Matevž 1 - miza
// - 206 - Matevž 2 - postelja
// - 207 - telovadnica 1 - J
// - 208 - telovadnica 2 - S
// - 209 - pralnica
// - 210 - kopalnica
// - 211 - podstrešje
//*** 3xx so rolete
// - 300 master rolete
// - 301 - roleta spalnica
// - 302 - roleta Gašper
// - 303 - roleta Matevž
// - 304 - roleta telovadnica J
// - 305 - roleta telovadnica S
// - 306 - roleta pralnica
// - 307 - roleta dnevna
// - 308 - roleta kuhinja
//**** 400 master vse luči
const int gumbi = 49
// TODO: prestaviti to tabeli v 2D, da lahko enako kot se berejo stikala iz SHIFT registrov
// tudi prirerajo vrednosti, prav tako za milis old in new mora biti 2D matrika
// - I in J se ne pišeta posebej v tabelo samo kot komentar
// - uskladiti "šifrant" z stanji in izhodi
// - naslednji korak je povezava akcije z izhodom
// - dodati časovnike na izhod
// vsak gumb ima določen vhod (shift register, PIN) in 2 funkciji 1-short, 2-long
// ista funkcija pomeni, da kratek in dolg press izvede enak ukaz
const int arrayGumbi [ukazi][4] {
/************************/
/* stikalna plošča - 12 */
/************************/
{0, 0, 0, 300}, // 0 - master rolete
{0, 1, 101, 101}, // 1 - dnevna 1
{0, 2, 102, 102}, // 2 - dnevna 2
{0, 3, 103, 103}, // 3 - jedilnica 1
{0, 4, 104, 104}, // 4 - jedilnica 2
{0, 5, 105, 105}, // 5 - hodnik
{0, 6, 106, 106}, // 6 - predsoba
{0, 7, 107, 107}, // 7 - kuhinja
{0, 8, 108, 108}, // 8 - WC
{0, 9, 0, 307}, // 9 - roleta dnevna
{0, 10, 0, 308}, // 10 - roleta kuhinja
{0, 11, 0, 100}, // 11 - master spodaj
/****************/
/* gumbi spodaj */
/****************/
// dnevna/jedilnica - 1x4
{1, 0, 101, 307}, // 12 - levo zgoraj - sedežna
{1, 1, 102, 307}, // 13 - levo spodaj - TV
{1, 2, 103, 307}, // 14 - desno zgoraj - jedilnica miza
{1, 3, 104, 307}, // 15 - desno spodaj - jdilnica hladilnik
// kuhinja/jedilnica - 1x3
{1, 4, 103, 308}, // 16 - levo zgoraj - jedilnica miza
{1, 5, 104, 308}, // 17 - levo spodaj - jedilnica hladilnik
{1, 6, 107, 308}, // 18 - desno - kuhinja
// hodnik/stopnišče - 2x1
{1, 7, 105, 100}, // 19 - desni - hodnik spodaj
{1, 8, 202, 200}, // 20 - levi - hodnik zgoraj
// hodnik - 2x1
{1, 9, 105, 105}, // 21 - desni - hodnik spodaj
{1, 10, 106, 106}, // 22 - levi - predsoba
// predsoba - 1x1 velik
{1, 11, 106, 400}, // 23 - vhod - predsoba
// WC - 1x1 velik
{1, 12, 108, 108}, // 24 - hodnik - WC
/****************/
/* gumbi zgoraj */
/****************/
// spalnica - 2x1 mali + 1x1 velik
{2, 0, 201, 301}, // 25 - Irena
{2, 1, 201, 301}, // 26 - Mitja
{2, 2, 201, 301}, // 27 - vhod
// Gašper - 3x2
{3, 0, 203, 302}, // 28 - vhod L - okno
{3, 1, 204, 302}, // 29 - vhod D - postelja
{3, 2, 203, 302}, // 30 - postelja D - okno
{3, 3, 204, 302}, // 31 - postelja L - postelja
{3, 4, 203, 302}, // 32 - miza L - postelja
{3, 5, 204, 302}, // 33 - miza D - okno
// Matevž - 3x2
{3, 6, 205, 303}, // 34 - vhod L - postelja
{3, 7, 206, 303}, // 35 - vhod D - okno
{3, 8, 205, 303}, // 36 - postelja D - okno
{3, 9, 206, 303}, // 37 - postelja L - postelja
{3, 10, 205, 303}, // 38 - miza L - postelja
{3, 11, 206, 303}, // 39 - miza D - okno
// telovadnica - 2x2 mali
{2, 3, 207, 304}, // 40 - telovadnicaJ L
{2, 4, 208, 305}, // 41 - telovadnicaJ D
{2, 5, 207, 304}, // 42 - telovadnicaS L
{2, 6, 208, 305}, // 43 - telovadnicaS D
// pralnica - 2x1 velik
{2, 7, 209, 306}, // 44 - telovadnica
{2, 8, 209, 306}, // 45 - hodnik
// kopalnica - 1x1 velik
{2, 9, 210, 210}, // 46 - kopalnica
// stopnišče - 2x1
{2, 10, 105, 100}, // 47 - stopnišče L
{2, 11, 202, 200} // 48 - stopnišče D
}; // vsak gumb ima določen vhod (pin/shift register/multiplexor), vrstni red in 2 funkciji 1-short, 2-long
unsigned long TrenutniCas; // shranimo millis na začetku zanke
// tabela za gumbe z stanji in tipkami
// (stara tipka, tipka, časovnik, smer, vklop)
int arrayButton [gumbi][5] = {0}; // vsako stikalo ima 5 stolpcev, tu vse sočasno nastavimo na 0 (kar ni definirano je 0)
unsigned long arrayButtonTimer [gumbi] = {0}; // časovnik damo posebej, ker ostlaih 4 spremenljivk ne potrebujemo v takšni dolžini
// v funkcijah prestavimo c na arrayButtonTimer in ne na arrayButton [i][c]
// prototipi funkcij
void readButton();
void setRelay();
void ReadAll165(); // prototip funkcije za branje vseh shift registrov
/****************************************************************************************************/
// funkcija za nastavitev ob zagonu
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
pinMode( clockPin, OUTPUT); // clock signal, idle LOW
digitalWrite( clockPin, LOW);
pinMode( latchPin, OUTPUT); // latch (copy input into registers), idle HIGH
digitalWrite( latchPin, HIGH);
// nastavimo vse tipke na vhod
//TODO - array za vhode tipk oz. multiplexer
// nastavimo vse releje na izhod
for (i = 0; i < rolete; i++) {
for (j = 0; j < releji; j++) {
pinMode(arrayRolete[i][j], OUTPUT);
/*if (j == 1) {
digitalWrite(arrayRolete[i][j], HIGH);
delay(400);
digitalWrite(arrayRolete[i][j], LOW);
delay(200);
} else {
digitalWrite(arrayRolete[i][j], LOW);
delay(400);
digitalWrite(arrayRolete[i][j], HIGH);
delay(200);
}*/
}
}
/*
motor = 1; // vklopimo master motor
smer = 1; // nastavimo master smer gor
// vklopimo motorje in odpremo rolete ob zagonu
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 1; // nastvimo smer na gor
arrayRun[i][e] = 1; // vklopimo motor
}
// gremo čez časovni interval
for (t = timer; t > 0; t--) {
// poženemo motorje
moveRolete();
delay(n); // počakaj interval
}
Serial.println("konec"); // izpis
motor = 0; // izklopimo master motor
smer = 0; // nastavimo master smer dol
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 0; // nastvimo smer na dol
arrayRun[i][e] = 0; // izklopimo motor
}
*/
}
// glavna zanka
void loop() {
// preberemo vse shift registre
ReadAll165();
// preberemo stanje master gumba
gumb = digitalRead(buttonPin);
// normaliziramo stanje gumba
if (gumb == HIGH) {
gumb = 1;
} else {
gumb = 0;
}
// TODO: preberemo stanje gumbov oz. multiplexorja
// če se je spremenilo stanje in je gumb pritisnjen potem izvedemo spremembo sicer teče timer
if (gumbOld != gumb && gumb == 1) {
////////////////////////////
if (motor == 0) {
// turn LED on:
digitalWrite(ledPin, HIGH);
Serial.println("premakni");
// vklopimo motorje
motor = 1;
for (i = 0; i < rolete; i++) {
arrayRun[i][e] = 1;
}
// nastavimo časovnike
cas = timer;
for (i = 0; i < rolete; i++) {
arrayRun[i][c] = timer;
}
} else {
// turn LED off:
digitalWrite(ledPin, LOW); // izklopimo luč
Serial.println("ustavi"); // izpis
// izklopimo motorje
motor = 0;
for (i = 0; i < rolete; i++) {
arrayRun[i][e] = 0;
}
// obrnemo smeri
if (smer == 0) {
smer = 1;
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 1;
}
} else {
smer = 0;
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 0;
}
}
// pobrišemo časovnike
cas = 0;
for (i = 0; i < rolete; i++) {
arrayRun[i][c] = 0;
}
}
} else {
// če je aktiven timer ga zmanjšamo za 1
if (cas > 1) {
cas--;
} else if (cas == 1) { // ko pride na 1 ugasnemo motor, obrnemo smer in ponastavimo timer na 0
// turn LED off:
digitalWrite(ledPin, LOW); // izklopimo luč
Serial.println("konec"); // izpis
// izklopimo motorje
motor = 0; // izklopimo motor
for (i = 0; i < rolete; i++) {
arrayRun[i][e] = 0;
}
// obrnemo smeri
if (smer == 0) {
smer = 1;
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 1;
}
} else {
smer = 0;
for (i = 0; i < rolete; i++) {
arrayRun[i][d] = 0;
}
}
cas = 0; // pobrišemo časovnike
for (i = 0; i < rolete; i++) {
arrayRun[i][c] = 0;
}
}
///////////////////////////
}
gumbOld = gumb; // zapišemo stanje ob branju za naslednji krog
// TODO: ponovimo za vse gumbe, kot za master
//izvedemo ukaze glede na vsebino tabele
moveRolete();
delay(n); // počakaj interval
}
// poženemo motorje z izpisi
void moveRoletePrint() {
// pogledamo zaporedno roleto
for (i = 0; i < rolete; i++) {
Serial.print("roleta: ");
Serial.print(i);
// pogledamo v katero smer se vozi
if (arrayRun[i][d] == 0) {
Serial.print(" - dol");
digitalWrite(arrayRolete[i][0], HIGH);
} else {
Serial.print(" - gor");
digitalWrite(arrayRolete[i][0], LOW);
}
// pogledamo ali se vozi ali muruje
if (arrayRun[i][e] == 0) {
Serial.print(" - čakam ");
digitalWrite(arrayRolete[i][1], LOW);
} else {
Serial.print(" - vozim ");
digitalWrite(arrayRolete[i][1], HIGH);
}
}
Serial.println(" ...");
}
// poženemo motorje brez izpisov
void moveRolete() {
// pogledamo zaporedno roleto
for (i = 0; i < rolete; i++) {
//Serial.print("roleta: ");
//Serial.print(i);
// pogledamo v katero smer se vozi
if (arrayRun[i][d] == 0) {
//Serial.print(" - dol");
digitalWrite(arrayRolete[i][0], LOW);
} else {
//Serial.print(" - gor");
digitalWrite(arrayRolete[i][0], HIGH);
}
// pogledamo ali se vozi ali muruje
if (arrayRun[i][e] == 0) {
//Serial.print(" - čakam");
digitalWrite(arrayRolete[i][1], LOW);
} else {
//Serial.print(" - vozim");
digitalWrite(arrayRolete[i][1], HIGH);
}
//Serial.println(" ...");
}
}
// preberemo vse shift registre naenkrat
void ReadAll165()
{
// pošljemo impulz na vse 74HC165, da shranimo stanje
digitalWrite( latchPin, LOW);
delayMicroseconds( pulseWidth);
digitalWrite( latchPin, HIGH);
// The first one that is read is the highest bit (input D7 of the 74HC165).
for( int i=shiftBit-1; i>=0; i--) // 16
{
for( int j=shiftNo-1; j>=0; j--) // 4
{
if( digitalRead(ArrayDataPin[j]) == HIGH)
{
ArrayShiftState[i][j][1] = 1;
} else {
ArrayShiftState[i][j][1] = 0;
}
}
// pošljemo impulz ure na vse shift registre, da dobimo naslednji podatek
digitalWrite( clockPin, HIGH);
delayMicroseconds( pulseWidth);
digitalWrite( clockPin, LOW);
}
}