» »

Arduino žaluzije

Arduino žaluzije

sumoborac ::

Pred kratkim smo dobili žaluzije na elektro motorčke in sem po dolgem casu si vzel 2h casa in sam skupaj spacal kodo. Zadeva generalno dela OK a se mi zdi, da je nekje bug saj se parkrat dnevno zgodi, da se zaluzije za trenutek sprozijo in potem ugasnejo brez da bi kdo kje kaj pritisnil. Zadeva je zvezana zelo "osnovno":
Stikalo gor / sredina / dol - Sredina je povezana na Nulo, gor in dol pa na Arduino (pull-down pine)
Motorcek je priklopljen preko vmesnega releja (5V vklaplja 240V). Pred relejem je se SolidStateSwich, ki vklopi 240V na releju z zamikom (zato da ne "zakuri" releja v poziciji).

Koda:
int signalGor[] = {
  39, // pisarna
  43, // balkon desno
  41, // balkon vrata
  45, // kuhinja desno
  47, // kuhinja levo
  49, // dnevna soba desno
  51, // dnevna soba sredina
  53 // dnevna soba levo
};
//signalDol = signalGor - 1

String imena[] = {
  "pisarna",
  "balkon desno",
  "balkon vrata",
  "kuhinja desno",
  "kuhinja levo",
  "dnevna soba desno",
  "dnevna soba sredina",
  "dnevna soba levo"
};

int napetost[] = {
  27, // pisarna
  22, // balkon
  23, // balkonska vrata
  25, // kuhinja desno
  24, // kuhinja levo
  28, // dnevna soba desno
  26, // dnevna soba sredina
  29 // dnevna soba levo
};

int motorSmer[] = {
  34, // pisarna
  38, // balkon
  37, // balkonska vrata
  35, // kuhinja desno
  32, // kuhinja levo
  31, // dnevna soba desno
  33, // dnevna soba sredina
  30 // dnevna soba levo
};

int motorGor[] = {
  HIGH, // pisarna
  HIGH, // balkon
  HIGH, // balkonska vrata
  HIGH, // kuhinja desno
  HIGH, // kuhinja levo
  HIGH, // dnevna soba desno
  HIGH, // dnevna soba sredina
  LOW // dnevna soba levo
};

const int CAS_DELOVANJA_VELIKI = 60000;
const int CAS_DELOVANJA_SREDNJI = 5000;
const int CAS_DELOVANJA_MALI = 2000;

unsigned long casDelovanje[] = {
  65000, // pisarna
  65000, // balkon
  65000, // balkonska vrata
  65000, // kuhinja desno
  65000, // kuhinja levo
  65000, // dnevna soba desno
  65000, // dnevna soba sredina
  65000 // dnevna soba levo
};

const int CAS_PRITISKA = 50; // 30 millis
const int SMER_GOR = 1;
const int SMER_DOL = 2;
const int SMER_STOP = 0;
const int COUNT = 8;

unsigned int stanje[8];
unsigned int stanjeZaluzij[8];
unsigned long casZaluzij[8];
unsigned long timers[16];


// Debug usage only
unsigned long lastDisplay = 0;
unsigned long casPritiska[16];
String output[8];


void setup() {
    Serial.begin(9600);
    
    for (int i = 0; i < COUNT; i++) {
        pinMode(signalGor[i], INPUT_PULLUP);
        pinMode(signalGor[i] - 1, INPUT_PULLUP);

        pinMode(napetost[i], OUTPUT);
        digitalWrite(napetost[i], LOW);

        pinMode(motorSmer[i], OUTPUT);
        digitalWrite(motorSmer[i], HIGH);

        
        stanje[i] = SMER_STOP;
        stanjeZaluzij[i] = SMER_STOP;
        timers[i*2] = 0;
        timers[i*2 + 1] = 0;
        casZaluzij[i] = 0;
        
        casPritiska[i*2] = 0;
        casPritiska[i*2+1] = 0;
        output[i] = "S => ";
    }
    stopZaluzije();
}

void loop() {
    //preberemo stanja vseh pritiskov
    readButtons();
    processButtons();
}

void processButtons() {
    for (int i = 0; i < COUNT; i++) {
        // gumb pritisnjen
        if (stanje[i] == SMER_GOR) {
            if (stanjeZaluzij[i] == SMER_DOL) {
                izklopiLokacijo(i);
                delay(500); // Delay enabling back for 500ms per instructions of motor
                continue;
            }

            if (stanjeZaluzij[i] == SMER_STOP) {
                vklopiLokacijo(i, stanje[i]);
                addOutput(i, "vklop - " + String(stanje[i]));
                continue;
            }
        }

        if (stanje[i] == SMER_DOL) {
            if (stanjeZaluzij[i] == SMER_GOR) {
                izklopiLokacijo(i);
                delay(500); // Delay enabling back for 500ms per instructions of motor
                continue;
            }

            if (stanjeZaluzij[i] == SMER_STOP) {
                vklopiLokacijo(i, stanje[i]);
                addOutput(i, "vklop - " + String(stanje[i]));
                continue;
            }
        }

        if (casZaluzij[i] > 0 && (casZaluzij[i] + casDelovanje[i]) < millis()) {
            stanje[i] = SMER_STOP;
            addOutput(i, "times: " + String(casZaluzij[i]) + " + " + String(casDelovanje[i]) + " < " + String(millis()));
        }

        if (stanje[i] == SMER_STOP && stanjeZaluzij[i] != SMER_STOP) {
            izklopiLokacijo(i);
            addOutput(i, "stop");
            continue;
        }
      
    }
  
}

void stopZaluzije() {
    for (int i = 0; i < COUNT; i++) {
        izklopiLokacijo(i);
    }
}

void izklopiLokacijo(int lokacija) {
  
  int pinSSR = napetost[lokacija];
  int pinSmer = motorSmer[lokacija];

  stanjeZaluzij[lokacija] = SMER_STOP;
  casZaluzij[lokacija] = 0;

  // izklopimo napajanje
  digitalWrite(pinSSR, LOW);
  delay(8);
  //resetiramo relay
  digitalWrite(pinSmer, HIGH);
}


void vklopiLokacijo(int lokacija, int smerPomika) {
  int pinSSR = napetost[lokacija];
  int pinSmer = motorSmer[lokacija];

  stanjeZaluzij[lokacija] = smerPomika;
  casZaluzij[lokacija] = millis();

  //nastavimo relay
  digitalWrite(pinSmer, smerPomika == SMER_GOR ? motorGor[lokacija] : !motorGor[lokacija]);
  delay(16);
  //vklopimo napajanje
  digitalWrite(pinSSR, HIGH);
}

void readButtons()
{
    for (int i = 0; i < COUNT; i++) {
        bool stanjeGor = digitalRead(signalGor[i]);
        delay(2);
        bool stanjeDol = digitalRead(signalGor[i] - 1);

        int key = i*2;
        if (!stanjeGor && timers[key] == 0) {
            casPritiska[key] = timers[key] = millis();
        }
        if (stanjeGor && timers[key] > 0 && (timers[key] + CAS_PRITISKA) < millis()) {
            stanje[i] = stanje[i] == SMER_GOR ? SMER_STOP : SMER_GOR;
            int cas = millis() - casPritiska[key];
            addOutput(i, "UP PRESSED + (" + String(cas) + ")");
            casPritiska[key] = timers[key] = 0; // resetiramo vrednost 
        }

        key = (i*2) + 1;
        if (!stanjeDol && timers[key] == 0) {
            casPritiska[key] = timers[key] = millis();  
        }
        if (stanjeDol && timers[key] > 0 && (timers[key] + CAS_PRITISKA) < millis()) {
            stanje[i] = stanje[i] == SMER_DOL ? SMER_STOP : SMER_DOL;
            int cas = millis() - casPritiska[key];
            addOutput(i, "DOWN PRESSED + (" + String(cas) + ")");
            casPritiska[key] = timers[key] = 0; // resetiramo vrednost
        } 
        delay(5);
    }
}

void addOutput(int i, String message) {
    if (output[i].length() > 200 && i != COUNT) {output[i] = "S => ";}
    output[i] = output[i] + " | " + message;
    if (i == COUNT) { output[i] = output[i] + "\n"; }
}


Predvidevam, da mi nekje nek variable overflowa ampak ga ne uspem vidt. Anyone?
Prid sm al pa tm ostan...

Highlag ::

Lahko ti samo rele dela motnje v napajanju, pa se procesor čudno obnaša..
(nisem gledal kode) Poizkusi rele s kakšnim solid state relejem zamenjat, ki ima detekcijo ničle, ker delajo precej manj motenj...
Never trust a computer you can't throw out a window

sumoborac ::

Pred samim relejem je SolidState switch, ki poskrbi, da se napetost na motorjih ne pokaze dokler sam rele ne skoci cez (0.Xs zamika). Rele se prozi iz strani arduina in je locen pin od SSRja, tako da v kodi prizgem 2 razlicna pina zato da se zaluzije aktivirajo.
Prid sm al pa tm ostan...

Randomness ::

Seveda ti overflowa. RTFM

TheBlueOne ::

Randomness je izjavil:

Seveda ti overflowa. RTFM


Ampak ne dnevno, ca. 50 dni pise.

@OP Sicer ze nekaj casa nisem kaj delal z Arduinom pa vseeno, upornike si dodal pri Pull down? Ce nimas uporanikov in raje kvazi stabiliziras s casom, se slej kot prej zgodi, da je kaksen fantomski signal.

Zgodovina sprememb…

Randomness ::

Ampak ne dnevno, ca. 50 dni pise.
Si prebral do konca? Tudi odstavek "Notes and Warnings"?

techfreak :) ::

Ce je mozno, imej nekaj ur gor priklopljen racunalnik, pa spremljaj kaj se na serijskem izhodu izpisuje. Lahko dodas se kaksen dodaten debug message.

TheBlueOne ::

@Randomness Potem ni problem overflow. Za overflow, ce bi drugace bilo vse OK, bi dodal samo rollover event, da so funkcije deaktivirane toliko zadnjih sekund, kot je maksimalen uporabljen cas v programu.

Jaz sem imel podoben problem kot OP, ko sem zacel eksperimentirati z Arduinom, ampak je bilo krivo pomanjkanje ne-dodanih upornikov. Ko na hitro preletim kodo mi deluje kakor da je poskusal ta problem resit z dolzino signala, kar problem vecinoma resi, ne pa 100%(igra verjetnosti). Sicer nisem gledal tocno, kaj je potrebno, da se zadeve premaknejo ampak si mislim, da je en pogoj, da je prisoten vhodni signal? Potem fantomski pomiki ne bi smeli biti mogoci, tudi ce casi ne pasejo skupaj. Bi pa moral malo bolj natancno skozi kodo, za kar pa sem morda prelen. :D:))

Zgodovina sprememb…

KraitPay ::

1. Si preprican da kaksnih od vhodov (tipka gor, tipka dol) ni na "floating" potencialu?
2. Si prepričan da ti 5V vklaplja rele in ne "0V"? -> Dodaj nam shemo. Malo me muči tisti SSR, kakšen SSR je to, dodaj podatkovni list releja, SSRja in žaluzij.
3. Vsak kabel deluje kot antena, če uporabljaš kakšne analogne vhode, se pripravi na motne pinov, ki so zraven ADCja.
4. Kot so že nekateri napisali, uporabi pull-up upore na tipkah vzporedno z kondenzatorjem.

sumoborac ::

TheBlueOne je izjavil:


@OP Sicer ze nekaj casa nisem kaj delal z Arduinom pa vseeno, upornike si dodal pri Pull down? Ce nimas uporanikov in raje kvazi stabiliziras s casom, se slej kot prej zgodi, da je kaksen fantomski signal.


Ne, nisem, po mojem razumevanju ima Arduino ze pullDown interni upornik, ki bi moral poskrbeti za to. Ni zadosti?


1. Si preprican da kaksnih od vhodov (tipka gor, tipka dol) ni na "floating" potencialu?
2. Si prepričan da ti 5V vklaplja rele in ne "0V"? -> Dodaj nam shemo. Malo me muči tisti SSR, kakšen SSR je to, dodaj podatkovni list releja, SSRja in žaluzij.
3. Vsak kabel deluje kot antena, če uporabljaš kakšne analogne vhode, se pripravi na motne pinov, ki so zraven ADCja.
4. Kot so že nekateri napisali, uporabi pull-up upore na tipkah vzporedno z kondenzatorjem.


1. Z enim stikalom sem imel tezavo, ampak se je kazalo kot non-stop premikanje. Sem ga odklopil.
2. Tale rele: https://www.amazon.de/gp/product/B00PIM... in tale SSR https://www.amazon.de/gp/product/B07DR9...
3. Ja, bi znalo biti povezano z tem. 5V kablovje tece vzporedno z 240V kabli za priziganje luci. Sem opazil da je del "duhcev" povezan z tem - clovek prizge luc pa se sprozi zaluzija. Kako omejiti te motnje oz jih zaznati in jih "preskociti"? Bi pomagalo, da prevezem zadevo na 240V in postavim pred arduino opto-izolator?
4. Ce uporabljam pullDown, kako naj potem postavim pull-up upore? In kam kondenzator?

Ce je mozno, imej nekaj ur gor priklopljen racunalnik, pa spremljaj kaj se na serijskem izhodu izpisuje. Lahko dodas se kaksen dodaten debug message.

Sem. Dlje od tega, da zaznam "signal tipke" ko ga ni, nisem prisel. Vrednosti sprejemljivk vse zgledajo OK (kar pa vseeno ne izkljuci buga kje :D )
Prid sm al pa tm ostan...

TheBlueOne ::

sumoborac je izjavil:


Ne, nisem, po mojem razumevanju ima Arduino ze pullDown interni upornik, ki bi moral poskrbeti za to. Ni zadosti?



Ne, ne verjetno ne bo zadosti. Ce se ne motim jih ne potrebujes, ce je izhod, ce pa je vhod pa jih potrebujes.

Bo kar to tvoj problem, ti verjetno ni treba gledati naprej. Vec tukaj:

https://www.instructables.com/id/Unders...

Zgodovina sprememb…

KraitPay ::

Povečaj še deboucing time za branje vhodnih spremenljivk. 2mS je občutno premalo, je pa odvisno od kvalitete stikal.

Moten na kablu se ne moreš znebiti, lahko ga samo zmanjšaš. Npr uporaba perice v kombinaciji z EMC kablom. Sekanje tokokrogov na 90°. Zadostna razdalja med signalnimi in napajalnimi linijami, ustrezno ničenje sistema.

Če uporabiš 230V in optokopler, bi stvar morala delovati v teoriji. V praksi pa se potem pojavijo razne zanke in neuzrezno ničenje, pa si zopet na začetku. Če upoštevaš zgornja navodila bi stvar morala funkcionirati.

Za kaj resnega ti predlagam uporabo PLCja, sploh če bi rad nekaj sestavil in se potem nikoli več s tem ukvarjal.

Zgodovina sprememb…

  • spremenil: KraitPay ()

TheBlueOne ::

KraitPay je izjavil:

Povečaj še deboucing time za branje vhodnih spremenljivk. 2mS je občutno premalo, je pa odvisno od kvalitete stikal.


Ko sem jaz dodal upornike sem imel 100% kakovost, prej pa sicer tendira v pravo smer ampak ni idealno. Je ze boljse, da stima osnova/hardware.

beni ::

Kako določaš trenutni položaj rolete (dvignjena - spuščena - koliko % je spuščena) ?
Pojma nimam ...

TheBlueOne ::

Praviloma imas koncna stikala za odprto in zaprto, polozaj v % pa priblizno preko casovnika. Za sencila s kaksnimi koracnimi motorji ali pa recimo enkoderji se nisem slisal. Bi verjetno bilo prekomplicirano.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Pametno stanovanje (strani: 1 2 3 450 51 52 53 )

Oddelek: Elektrotehnika in elektronika
2646481907 (572) Lonsarg
»

Arduino kot časovni rele

Oddelek: Pomoč in nasveti
81605 (1191) davor92
»

Pomoč C++

Oddelek: Pomoč in nasveti
71350 (1069) samo111
»

Arduino in luči (strani: 1 2 )

Oddelek: Elektrotehnika in elektronika
9812045 (9671) FX6300B
»

Arduino "leteče luči"

Oddelek: Elektrotehnika in elektronika
132994 (1871) zrataj4201

Več podobnih tem