Includerea MOC3063 în ansamblul releului pentru a controla sarcina electronică bazată pe ATTiny13, cumpărarea controlerului și controlul triacului prin opto-cuplaj

Recent, dispozitivele avansează în mod activ.inteligente acasă, inclusiv, și pe această resursă. Una dintre principalele probleme legate de comutarea sarcinilor de putere în astfel de dispozitive este păstrarea controlului obișnuit (prin apăsare sau altul). Dispozitivul din revizuire este conceput pentru a rezolva această problemă oferind posibilitatea de a controla atît de la "componenta inteligentă" a casei, cît și de mijloacele convenționale, de exemplu un comutator. În plus, acest dispozitiv poate ușor șipunerea în siguranță a controlului luminii prin intermediul comutatoarelor multiple. Sau combinați diferite modalități de gestionare. Artizanat, lipire, cod și teste - toate sub tăiere ... (atenție: o mulțime de fotografii și clipuri video).
Despre controlerul Attiny85 în sine se scrie foarte mult,inclusiv pe această resursă. Revizuirea cazului de utilizare cu instrucțiuni detaliate privind conectarea controlerului poate fi găsită aici. Controlerul are 8 pini: 2 dintre acestea sunt destinate conectării sursei de alimentare, 1 - la semnalul de resetare (resetare), deci doar 5 pini rămân pentru sarcinile "utile", dar în multe cazuri acest lucru este suficient. controler:

Microcontrolerul ATtiny85 are următoarele caracteristici:
- pentru codul de program este prevăzută o memorie de 8 KB;
- pentru codul executabil (RAM, SRAM, RAM) 512B este rezervat;
- memorie de date (EEPROM) 512 B
- prezența a 6 pini digitali, în realitate este mai bine să folosiți 5 (lasând 1 sub RESET);
- două ieșiri PWM și 4 ADC (rezoluție 10 biți);
- frecvența de la 1 la 20 MHz.
ATtiny85 este oferit în pachete: MLF (WQFN) 20M1 20dip8, PDIP 8P3 8, SOIC (208mil) 8S2 8.
În funcție de modificare, sursa de alimentare poate fi de la 1,8 la 5,5 V.
Această examinare se concentrează pe versiunea din pachetul SOIC. Pachetul a sosit în 3 săptămâni (piesa a fost urmărită).
Adesea folosesc relee în meșteșugurile mele.pe elementele de solidaritate, în special, a fost triacul care a fost folosit pentru a crea aparatul de sudare cu puncte, mai multe detalii aici. Dar, dacă folosiți un releu solid (și orice alt tip) în combinație cu un sistem de control complex, apar următoarele probleme:
- local, un astfel de releu poate fi controlat numai în 2 versiuni: fie prin nodul central, fie nodul central va fi în întuneric cu privire la starea curentă a releului;
- în cazul reluării nodului central - starea releului se modifică la cea inițială (sau starea curentă trebuie salvată):
- dar, cel mai important, dacă vroiai să facischimbarea nodului central sau înlocuirea lui (într-un caz foarte rău, acesta se poate rupe) - de fapt, releul devine incontrolabil, ceea ce înseamnă, de exemplu, incapacitatea de a activa lumina sau altceva.
Cel de-al doilea moment ma determinat să trec la astaDezvoltarea este o situație destul de tipică de folosire a comutatoarelor cu buclă. Datorită costului ridicat al cablului de alimentare și este nevoie de multe pentru a organiza lumina în câteva puncte, pe lângă faptul că o cantitate mare de cablu cu o tensiune de 220 volți nu contribuie la securitate, mi se pare rezonabil să comutam sarcina electrică cu un fir subțire (de exemplu telefon) 5 volți. Dispozitivul din recenzie va rezolva această problemă.
Dacă aceste două probleme sunt combinate, atuncioportunitatea utilizării unui astfel de dispozitiv este dificil de supraestimat. Sunt conștient că există experți care, folosind numai 15 tranzistori și câteva elemente montate, vor declara cu mândrie că au făcut-o fără un controlor, rezolvând problema hardware-ului (aproape similar cu acesta). Spun imediat: prețul controlerului este atât de scăzut încât nu are sens să discutăm, în plus, soluția este foarte flexibilă, făcând schimbări nu necesită un fier de lipit. În acest tinky sa dovedit a fi controlori foarte fiabili și stabili, printre altele, nimic nu împiedică să aibă o anumită rezervă de astfel de relee "puțin inteligente" - pentru a elimina complet toate situațiile anormale.
Schema simplă a dispozitivului:

R1, R2, R3 - sunt setate opționaltragerea la înălțime a pinilor corespunzători ai controlerului. R4 trage panoul RESET la putere, împiedicând reluarea spontană a controlerului. Sarcina este conectată la ieșirea controlerului PB3, această ieșire este trasă la masă de către rezistorul R6, pentru a evita situațiile anormale de a activa triacul. R5 limitează curentul optocoshistorului MOC3063. MOC3063, R7 (0,5 W), R8 (0,5 W) și T1 - formează un circuit tipic de comutare al triacului. Circuitul RC de amortizare (amortizare) constă în C1 și R9 (1W), prezența sa fiind deosebit de critică în sarcina inductivă. Am folosit BTA16 ca un triac, puteți pune atât mai puțin și mai puternic (în pachetul TO220), în funcție de sarcina comutată. De asemenea, dacă este necesar, puteți instala radiatorul pe triac, l-am amplasat specific pe margine.
Plăcile cu circuite imprimate au dovedit:

Placa este fabricată în China, dimensiunile sunt compacte (se va potrivi complet în cutie sau în cutia de joncțiune), în special această placă a fost făcută în dirtypcbs.com, profitând de panelizare (în viitorul apropiat, mă aștept la o taxă a unui alt producător pentru $ 2 - pe acțiune


După asamblare, dispozitivul arată astfel:

Acesta este un eșantion experimental, deci puțin rănit, nu acordați atenție aspectului.

Bineînțeles, în loc de pini de testare, puteți imediatlipiți cablajul, economisind astfel spațiu. Dacă cablurile de semnal se apropie de rețeaua electrică și nu utilizați cabluri ecranate, atunci ar trebui să aveți grijă de protecția împotriva interferențelor.
Primul lucru pe care l-am descarcat a fost un utilitar de incarcare:
void setup () {
pinMode (3, OUTPUT);
}
void loop () {
digitalWrite (3, HIGH);
întârziere (1000);
digitalWrite (3, LOW);
întârziere (1000);
}

Am folosit arduino nano ca programator:

După ce a fost conectată alimentarea cu panza și servită pe un dispozitiv nou:

Videoclip de lucru (folosit, modificat în funcție de dorințe, stați de aici):
Cele mai simple funcții sunt testate, cu toate acestea, dacă aveți nevoie de un bliț de 220 volți, puteți utiliza dispozitivul în această formă :).
Apoi simulează o situație în care avem nevoiemulte (bine, până la 4) comută pentru o singură încărcare și nu vrem să tragem fire groase de la 220 volți. Pentru aceasta, toate intrările gratuite ale dispozitivului nostru trebuie să conecteze întrerupătoarele cu același tip de comportament și să scrie programul corespunzător:
// ieșire pentru încărcare
const uint8_t load_pin = 3;
// condiție de încărcare
bool load_on = false;
// structură care descrie un întrerupător separat
typedef struct {
uint8_t pin; // pin
bool state; // state
nesemnate lung ButtonTimerDebounce; // timpul pentru a porni comutarea (pentru protecția împotriva tulburărilor)
} btn_t;
// serie de comutatoare
btn_t btn [] = {
{1, 0, 0},
{0, 0, 0},
{2, 0, 0},
{4, 0, 0},
};
// numărul elementelor din matrice - vom calcula mai târziu
uint8_t num_btn = 0;
// numărul de milisecunde de la începutul controlerului (pentru protecție împotriva tulburărilor)
nesemnate lungi CurrentTime = 0;
// timpul de gardă în ms
const nesemnate int DebounceTime = 100;
// funcția de determinare a numărului de elemente dintr-o matrice cu elemente de tip arbitrar
șablon în linie size_t arraySize (const T (& arr) [n]) {
return n;
}
void setup () {
// configurați știftul de încărcare
pinMode (încărcare_pin, OUTPUT);
digitalWrite (încărcare_pin, LOW);
// numără numărul de comutatoare
num_btn = arraySize (btn);
// configurați toate comutatoarele
pentru (uint8_t i = 0; i <num_btn; i ++) {
pinMode (btn [i] .pin, INPUT);
pinMode (btn [i] .pin, INPUT_PULLUP);
btn [i] .state = digitalRead (btn [i] .pin); // starea curentă a comutatorului este considerată inițială
}
}
void loop () {
CurrentTime = milis ();
// ignorați toate comutatoarele
pentru (uint8_t i = 0; i <num_btn; i ++) {
// Dacă starea comutatorului este diferită de cea curentă
dacă btn [i] .state! = digitalRead (btn [i] .pin)) {
// Dacă suntem la începutul eliminării sarcinii, setați ora de referință
dacă (btn [i] .ButtonTimerDebounce == 0) btn [i] .ButtonTimerDebounce = CurrentTime;
// Dacă a existat un comutator, luând în considerație bâlbâitul
dacă ((btn ​​[i] .ButtonTimerDebounce + (nesemnată lungă) DebounceTime) <CurrentTime) {
// Modificați starea încărcării
btn [i] .state =! btn [i] .state;
load_on =! load_on;
dacă (load_on) {
digitalWrite (load_pin, HIGH);
} altceva {
digitalWrite (încărcare_pin, LOW);
}
// resetați timpul de numărătoare inversă
btn [i] .ButtonTimerDebunț = 0;
}
} altceva {
// resetați timpul de numărătoare inversă pentru o alarmă falsă - comutatorul nu a schimbat starea pentru un anumit timp
btn [i] .ButtonTimerDebunț = 0;
}
}
}

Ca simulator de switch-uri am decis să folosesc aceste butoane cu o schimbare de stare:

Pentru a nu lipi, am decis să fac cablareconectați butoanele la panoul de paie (ele sunt totuși utile pentru mine). Deoarece cablajul folosit scroi Scroi 2x0.5. Puneți pe izolator și fixați terminalul criptat:

Din spate:

rezultat:

Am pus pe izolator:

Celălalt capăt al știftului pentru panoul de paie:

Sârmă este gros pentru astfel de vârfuri, prin urmareComponentele de înclinare, precum și muchiile înguste și laterale înșurubă firul în sine, deși cel larg ar trebui să se sapă în izolație, dar totul se menține foarte strâns - nu am reușit să spargă terminalul de la fir cu mâinile. Excesul de strângere strânsă:

Dacă cineva este interesat, atunci am revizuit procesul de strângere și de îndoire aici.
S-au dovedit aceste tranzacții:

Apoi le-a lovit pe butoane și a mutat izolația:

Testul butoanelor cheltuite dintr-o dată toate (3 bucăți făcute) în modul de pro-apeluri apăsate alternativ:

Suport final:

Teste video:
Logica muncii este aceeași cu cea a lui(flip). Acest cod are nevoie de puțină memorie, iar ATTiny13 se va descurca bine în locul celui de-al 85-lea tinkle, deoarece acestea sunt similare în cazul cazului și le-am asigurat interschimbabilitatea pe tablă. Astfel, în loc de cablurile scumpe și groase, liniile subțiri de telefon pot fi utilizate cu succes, iar tensiunea este sigură, în plus, prin uciderea și scurtcircuitarea firului, numai un singur switch poate fi distrus, restul va continua să funcționeze.
Să trecem la cea mai dificilă parte - interacțiuneaa relațiilor noastre "puțin inteligente" cu alți frați mai inteligenți. Pentru teste, și în practică, soluția cu portul serial este destul de viabilă. ATtiny85 nu are un port serial hardware, dar software-ul funcționează bine. Scrieți codul:
#include "SoftwareSerial.h" const uint8_t Rx = 0;
const uint8_t Tx = 2;
SoftwareSerial TinySerial (Rx, Tx);
const uint8_t load_pin = 3;
bool load_on = false;
typedef struct {
uint8_t pin;
bool state;
nesemnate lung ButtonTimerDebounce;
}
btn_t;
btn_t btn [] = {
{1, 0, 0},
{4, 0, 0},
};
uint8_t num_btn = 0;
nesemnate lungi CurrentTime = 0;
const nesemnate int DebounceTime = 100;
șablon în linie size_t arraySize (const T (& arr) [n]) {
return n;
}
void setup () {
pinMode (încărcare_pin, OUTPUT);
digitalWrite (încărcare_pin, LOW);
pinMode (Rx, INPUT);
pinMode (Tx, OUTPUT);
TinySerial.begin (9600);
TinySerial.write (101);
num_btn = arraySize (btn);
pentru (uint8_t i = 0; i <num_btn; i ++) {
pinMode (btn [i] .pin, INPUT);
pinMode (btn [i] .pin, INPUT_PULLUP);
btn [i] .state = digitalRead (btn [i] .pin);
}
}
void loop () {
CurrentTime = milis ();
dacă (TinySerial.available ()) {
uint8_t recived = TinySerial.read ();
dacă (recived == 152) {
change_power (true);
}
altfel dacă (recived == 151) {
change_power (false);
}
altfel dacă (recived == 153) {
if (load_on) {
TinySerial.write (202);
}
altfel {
TinySerial.write (201);
}
}
}
pentru (uint8_t i = 0; i <num_btn; i ++) {
if (btn [i] .state! = digitalRead (btn [i] .pin)) {
if (btn [i] .ButtonTimerDebounce == 0) btn [i] .ButtonTimerDebounce = CurrentTime;
if ((btn ​​[i] .ButtonTimerDebounce + (nesemnat de mult) DebounceTime) <CurrentTime) {
btn [i] .state =! btn [i] .state;
if (load_on) {
change_power (false);
} altfel {
change_power (true);
}
btn [i] .ButtonTimerDebounce = 0;
}
} altfel {
btn [i] .ButtonTimerDebounce = 0;
}
}
}
void change_power (bool val) {
if (val) {
digitalWrite (load_pin, HIGH);
load_on = true;
TinySerial.write (102);
}
altfel {
digitalWrite (încărcare_pin, LOW);
load_on = false;
TinySerial.write (101);
}
}

Nu o să comentez linie cu rând, din moment ce eisimilar cu cel precedent. Permiteți-mi să explic, am folosit mai multe coduri pentru interacțiunea dispozitivului. La încărcare, tinka îl informează pe fratele mai mare că încărcătura este oprită. Apoi poate accepta și procesa comenzile de solicitare a stării de pornire, oprire și încărcare. Procedura de modificare a stării de încărcare a fost luată ca o funcție separată, deoarece codul a fost adăugat puțin acolo, iar numărul de puncte de apel posibile a fost modificat. Tot același nano arduino va acționa ca un frate mai mare (deși poate fi orice: un computer (inclusiv zmeura pi), un alt controler etc.). Codul Arduino este mai simplu:
#include "SoftwareSerial.h" const uint8_t Rx = 12;
const uint8_t Tx = 11;
SoftwareSerial TinySerial (Rx, Tx);
const uint8_t led_pin = 13;
const uint8_t bt_pin = 14;
bool load_on = false;
bool ButtonOn = false;
nesemnate lungi CurrentTime = 0;
unsigned long ButtonTimerDebounce = 0;
const unsigned int DebounceTime = 50;
void setup () {
pinMode (led_pin, OUTPUT);
digitalWrite (led_pin, LOW);
pinMode (bt_pin, INPUT);
pinMode (bt_pin, INPUT_PULLUP);
pinMode (Rx, INPUT);
pinMode (Tx, OUTPUT);
TinySerial.begin (9600);
TinySerial.write (153);
Serial.begin (9600);
întârziere (15);
dacă (TinySerial.available ()) {
uint8_t recived = TinySerial.read ();
if (recived == 202) {
change_led (adevărat);
}
altfel dacă (recived == 201) {
change_led (false);
}
}
}
void loop () {
CurrentTime = milis ();
dacă (TinySerial.available ()) {
uint8_t recived = TinySerial.read ();
if (recived == 102) {
change_led (adevărat);
} altceva dacă (recepționat == 101) {
change_led (false);
}
}
if (Serial.available ()) {
uint8_t recived = Serial.read ();
TinySerial.write (recived);
}
if (digitalRead (bt_pin) == LOW &&! ButtonOn) {
ButtonOn = true;
if (ButtonTimerDebounce == 0) ButtonTimerDebounce = CurrentTime;
if (ButtonTimerDebounce + (nesemnat de mult) DebounceTime <CurrentTime) {
if (load_on) {
TinySerial.write (151);
} altfel {
TinySerial.write (152);
}
ButtonTimerDebounce = 0;
}
} else if (ButtonOn && digitalRead (bt_pin) == HIGH) {
ButtonOn = false;
}
}
void change_led (bool val) {
if (val) {
digitalWrite (led_pin, HIGH);
load_on = true;
Serial.println ("încărcare");
} altceva {
digitalWrite (led_pin, LOW);
load_on = false;
Serial.println ("încărcare");
}
}

După încărcare, se citește starea încărcării șiafișat prin LED. De asemenea, informații despre modificarea stării încărcării în sine sunt primite (prin comutatoare locale). Am conectat un buton la arduino, al cărui handler trimite o comandă pentru a schimba starea de încărcare într-un mod tăcut. afișajul se modifică numai atunci când o modificare de stare este confirmată. Stand final:

Video care ilustrează funcționarea acestei opțiuni:
Butonul conectat la arduino, am lungEste folosit pentru teste și a supraviețuit destul de mult, deci nu funcționează întotdeauna, dar sensul este clar. În acest caz, eliminarea unui dispozitiv mai inteligent (aici arduno nano) nu afectează funcționarea locală a dispozitivului, de care aveam nevoie. Avantajele circuitului anterior sunt păstrate, singurul număr de întrerupătoare este redus. Pentru cei cărora nu le plac firele, permiteți-mi să vă reamintesc despre modulele radio concepute pentru a extinde interfața Serial UART pe radio, recenzia mea despre acest subiect este aici.
Astfel, dispozitivul și-a arătat performanțele și, cred, îmi va fi foarte util în rezolvarea țării și nu numai a sarcinilor. Dacă sunt necesare mai multe concluzii, atunci acest lucru este posibil și:
1 - folosiți un alt controler, cu mai multe picioare, (de exemplu, ATTiny 2313);
2 - aplicați expansorul portului cu autobuzul i2c(de exemplu: PCF8574 pentru 8 porturi sau MCP23017 pentru 16 porturi), care este prezent în acest controler. Economisirea stării de încărcare la oprirea alimentării nu este dificil de implementat, dar prefer lumina oprită atunci când refac electricitatea din mai multe motive.
Dacă este interesant, vă voi povesti mai multe despre meseriile mele noi.
Mulțumim celor care au citit până la sfârșit! Sper că această recenzie uriașă a unui dispozitiv atât de simplu nu te-a plictisit! An Nou fericit tuturor!
PS.
Placă modificată:

Consiliul de protecție:

Consiliul de la revizuire cu sursa de alimentare:

Fișier care se deschide în Layout Sprint descărcați aici.
Fișiere de gerbera gata pregătite pentru a comanda o eșarfă modificată din descărcarea de recenzie aici.