Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Այսօրվա հոդվածում ուզում եմ ձեզ հետ կիսվել նոր նախագծով։ Այս անգամ դա սենսորային անջատիչ է՝ ապակե վահանակով։ Սարքը կոմպակտ է՝ 42x42 մմ չափսերով (ստանդարտ ապակե վահանակներն ունեն 80x80 մմ չափսեր): Այս սարքի պատմությունը սկսվել է շատ վաղուց՝ մոտ մեկ տարի առաջ։

Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Առաջին տարբերակները atmega328 միկրոկոնտրոլերի վրա էին, բայց ի վերջո ամեն ինչ ավարտվեց nRF52832 միկրոկոնտրոլերով։

Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Սարքի սենսորային հատվածն աշխատում է TTP223 չիպերով։ Երկու սենսորներն էլ սպասարկվում են մեկ ընդհատումով: Սնուցվում է CR2477 մարտկոցով, TPS610981 չիպի վրա բարձրացնող փոխարկիչի միջոցով | Տվյալների թերթիկ.

Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա
Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Սարքը իրականացնում է հոսանքի անջատման միացում՝ օգտագործելով դաշտային տրանզիստորներ: Կոճակը սեղմելուց հետո միկրոկոնտրոլերն ինքն է ընդհատում հոսանքի կառավարումը, այնուհետև կոճակը կարող է օգտագործվել սպասարկման ռեժիմների համար (իմ դեպքում սա զուգավորում է այլ սարքերի հետ, անջատում է հոսանքը և վերականգնում գործարանային պարամետրերը):

Առկա է 2 rgb LED՝ վիճակները և սպասարկման ռեժիմները ցույց տալու համար: Ավելացվել է նաև պիեզո էմիտեր՝ սենսորային կոճակներին հպվելիս սեղմումը և սպասարկման ռեժիմների ձայնային ցուցիչը նմանեցնելու համար: LED-ները և պիեզո էմիտերը կարող են միացվել և անջատվել օգտագործողի հայեցողությամբ: Դա արվում է խելացի տան կարգավորիչի միջոցով՝ հրամաններ ուղարկելով տեխնիկական սենսորներին, օգտատերը կարող է նաև փոխել մարտկոցի լիցքավորման ուղարկման միջակայքերը և ազդանշանի մակարդակը նաև խելացի տան կարգավորիչի միջոցով: Իմ դեպքում դա է ՄԱԺՈՐԴՈՄՈ.

Հաղորդման ռեժիմում սպառումը 7 մԱ է (250 կբիթ, 10 մս), քնի ժամանակ՝ 40 մկԱ, անջատված վիճակում՝ 1 մԱ-ից պակաս (= «անգործուն» ռեժիմում խթանիչի սպառումը): Տրվում է Rx, tx, swd միակցիչ ծրագրավորման համար։ Օգտագործվում է մանրանկարչություն 2x3p միակցիչ՝ 1.27 բարձրությամբ: Ծրագրավորման համար պատրաստված է հատուկ ադապտեր։

Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Ինչպես միշտ, սարքի շահագործումը հիմնված է արձանագրության վրա MySensors. Այս սենսորային անջատիչը նախատեսվում է օգտագործել գլանափաթեթների կառավարման համակարգում։ Բայց ընդհանուր առմամբ, դիմումը սահմանափակվում է միայն ձեր երևակայությամբ: Օրինակ՝ որդիս (7 տարեկան) արդեն 3 պատվեր է կատարել անջատիչի տարբերակների համար՝ միացնել և անջատել լոգարանով զուգարանի լույսը (այն կտեղադրվի հատակից ցածր), միացնել լույսը երկար ու մութ միջանցք՝ լոգարանով զուգարան գնալիս, և մեկ ուրիշը՝ որպես անկողնու կողքին, սենյակի լույսն արագ միացնելու համար, որպեսզի հրեշները փախչեն:

Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա
Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա
Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Գործը ավանդաբար տպագրվել է SLA տպիչի վրա, սարքը մանրանկարչություն է, պատյանը փոքր է, այս տպագրական տեխնոլոգիայի կիրառումն արդարացված է։

Դիտեք տպագիր մոդելըՄինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա
Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա
Մինի սենսորային անջատիչ ապակե վահանակով nRF52832-ի վրա

Մագնիսները սոսնձված են գործի և մարտկոցի խցիկի կափարիչի մեջ:

Տեսանյութեր այս սարքի փորձարկումներով.



Նրանց համար, ովքեր ցանկանում են կրկնել.

Ստուգեք ծրագրի կոդը Arduino IDE-ի համար գլանափաթեթի կառավարման համակարգում անջատիչի համար

Arduino էլեկտրալարեր

int8_t timer_status = 0;
boolean sens_flag1 = 0;
boolean sens_flag2 = 0;
boolean switch_a = 0;
boolean switch_b = 0;
uint16_t temp;
float vcc;
int battery;
int old_battery;
uint32_t oldmillis;
uint32_t newmillis;
uint32_t interrupt_time;
uint32_t SLEEP_TIME = 7000;
uint32_t SLEEP_TIME_W;
uint32_t SLEEP_TIME_W2;
int NrfRSSI;
uint16_t NrfRSSI2;
boolean wait_off;
//#define MY_DEBUG
#define MY_DISABLED_SERIAL
#define MY_RADIO_NRF5_ESB
#define MY_PASSIVE_NODE
#define MY_NODE_ID 120
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define POWER_CHILD_ID 110
#define UP_POWER_SWITCH_ID 1
#define DOWN_POWER_SWITCH_ID 2
#define CHILD_ID_nRF52_RSSI_RX 3
#define BAT_COOF 0.0092957746478873
#define BAT_MIN 200
#define BAT_MAX 290
#include <MySensors.h>
MyMessage upMsg(UP_POWER_SWITCH_ID, V_STATUS);
MyMessage downMsg(DOWN_POWER_SWITCH_ID, V_STATUS);
MyMessage powerMsg(POWER_CHILD_ID, V_VAR1);
MyMessage msgRF52RssiReceiv(CHILD_ID_nRF52_RSSI_RX, V_VAR1);
void preHwInit() {
pinMode(31, OUTPUT); //power management pin
digitalWrite(31, HIGH);
delay(3000);
pinMode(3, INPUT); // on off mode button
pinMode(25, OUTPUT); // sens1 led
pinMode(26, OUTPUT); // sens1 led
pinMode(27, OUTPUT); // sens1 led
pinMode(6, OUTPUT); // sens21 led
pinMode(7, OUTPUT); // sens2 led
pinMode(8, OUTPUT); // sens2 led
pinMode(28, OUTPUT); // bizzer
pinMode(2, INPUT); // common interrupt for touch sensors
pinMode(9, INPUT); // touch sensors1
pinMode(10, INPUT); //touch sensors2
pinMode(29, INPUT); // battery
digitalWrite(28, LOW);
digitalWrite(27, HIGH);
digitalWrite(26, HIGH);
digitalWrite(25, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
}
void before()
{
NRF_POWER->DCDCEN = 1;
analogReadResolution(12);
disableNfc();
turnOffAdc();
digitalWrite(25, LOW);
digitalWrite(6, LOW);
wait(200);
digitalWrite(25, HIGH);
digitalWrite(6, HIGH);
wait(100);
playSound0();
wait(100);
digitalWrite(25, LOW);
digitalWrite(6, LOW);
wait(200);
digitalWrite(25, HIGH);
digitalWrite(6, HIGH);
wait(3000);
digitalWrite(27, LOW);
digitalWrite(8, LOW);
wait(200);
digitalWrite(27, HIGH);
digitalWrite(8, HIGH);
wait(400);
digitalWrite(6, LOW);
digitalWrite(25, LOW);
wait(200);
digitalWrite(6, HIGH);
digitalWrite(25, HIGH);
wait(400);
digitalWrite(26, LOW);
digitalWrite(7, LOW);
wait(200);
digitalWrite(26, HIGH);
digitalWrite(7, HIGH);
wait(1000);
digitalWrite(26, LOW);
digitalWrite(7, LOW);
}
void setup()
{
digitalWrite(26, HIGH);
digitalWrite(7, HIGH);
wait(50);
playSound();
wait(2000);
readBatLev();
wait(200);
SLEEP_TIME_W = SLEEP_TIME;
}
void presentation()
{
sendSketchInfo("EFEKTA ON|OFF NODE 2CH", "1.0");
wait(100);
present(POWER_CHILD_ID, S_CUSTOM, "BATTERY DATA");
wait(100);
present(UP_POWER_SWITCH_ID, S_BINARY, "UP SWITCH");
wait(100);
present(DOWN_POWER_SWITCH_ID, S_BINARY, "DOWN SWITCH");
}
void loop()
{
if (sens_flag1 == 0 && sens_flag2 == 0) {
if (switch_a == 0 && switch_b == 0) {
timer_status = sleep(digitalPinToInterrupt(2), RISING, digitalPinToInterrupt(3), RISING, 3600000, false);
wait_off = 1;
} else {
//oldmillis = millis();
timer_status = sleep(digitalPinToInterrupt(2), RISING, digitalPinToInterrupt(3), RISING, SLEEP_TIME_W, false);
wait_off = 0;
}
}
if (timer_status == 3) {
wait(100);
digitalWrite(27, LOW);
digitalWrite(8, LOW);
wait(2000);
digitalWrite(27, HIGH);
digitalWrite(8, HIGH);
wait(100);
digitalWrite(31, LOW);
}
if (timer_status == 2) {
if (digitalRead(9) == HIGH && sens_flag1 == 0 && switch_b == 0) {
sens_flag1 = 1;
if (switch_a == 0) {
oldmillis = millis();
SLEEP_TIME_W = SLEEP_TIME;
switch_a = 1;
digitalWrite(6, LOW);
wait(10);
playSound1();
wait(20);
playSound2();
wait(50);
send(upMsg.set(switch_a));
wait(200);
} else {
switch_a = 0;
digitalWrite(6, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(upMsg.set(switch_a));
wait(200);
}
}
if (digitalRead(10) == HIGH && sens_flag2 == 0 && switch_a == 0) {
sens_flag2 = 1;
if (switch_b == 0) {
oldmillis = millis();
SLEEP_TIME_W = SLEEP_TIME;
switch_b = 1;
digitalWrite(25, LOW);
wait(10);
playSound1();
wait(20);
playSound2();
wait(50);
send(downMsg.set(switch_b));
wait(200);
} else {
switch_b = 0;
digitalWrite(25, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(downMsg.set(switch_b));
wait(200);
}
}
if (digitalRead(9) == LOW && sens_flag1 == 1) {
sens_flag1 = 0;
}
if (digitalRead(10) == LOW && sens_flag2 == 1) {
sens_flag2 = 0;
}
if (switch_a == 1 || switch_b == 1) {
if (wait_off == 0) {
newmillis = millis();
wait(10);
SLEEP_TIME_W2 = SLEEP_TIME_W;
wait(10);
interrupt_time = newmillis - oldmillis;
wait(10);
SLEEP_TIME_W = SLEEP_TIME_W2 - interrupt_time;
wait(10);
Serial.print("WAS IN A SLEEP: ");
Serial.print(newmillis - oldmillis);
Serial.println(" MILLISECONDS");
if (SLEEP_TIME_W < 1000) {
if (switch_a == 1) {
switch_a = 0;
digitalWrite(6, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(upMsg.set(switch_a));
wait(200);
}
if (switch_b == 1) {
switch_b = 0;
digitalWrite(25, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(downMsg.set(switch_b));
wait(200);
}
SLEEP_TIME_W = SLEEP_TIME;
wait(50);
}
Serial.println(SLEEP_TIME);
Serial.println(SLEEP_TIME_W);
Serial.println(SLEEP_TIME_W2);
Serial.print("GO TO SLEEP FOR: ");
Serial.print(SLEEP_TIME_W);
Serial.println(" MILLISECONDS");
}
oldmillis = millis();
}
}
if (timer_status == -1) {
if (switch_a == 1 || switch_b == 1) {
if (switch_a == 1) {
switch_a = 0;
digitalWrite(6, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(upMsg.set(switch_a));
wait(200);
}
if (switch_b == 1) {
switch_b = 0;
digitalWrite(25, HIGH);
wait(10);
playSound2();
wait(20);
playSound1();
wait(50);
send(downMsg.set(switch_b));
wait(200);
}
} else {
readBatLev();
}
}
}
void disableNfc() {
NRF_NFCT->TASKS_DISABLE = 1;
NRF_NVMC->CONFIG = 1;
NRF_UICR->NFCPINS = 0;
NRF_NVMC->CONFIG = 0;
}
void turnOffAdc() {
if (NRF_SAADC->ENABLE) {
NRF_SAADC->TASKS_STOP = 1;
while (NRF_SAADC->EVENTS_STOPPED) {}
NRF_SAADC->ENABLE = 0;
while (NRF_SAADC->ENABLE) {}
}
}
void myTone(uint32_t j, uint32_t k) {
j = 500000 / j;
k += millis();
while (k > millis()) {
digitalWrite(28, HIGH); delayMicroseconds(j);
digitalWrite(28, LOW ); delayMicroseconds(j);
}
}
void playSound0() {
myTone(1300, 50);
wait(20);
myTone(1300, 50);
wait(50);
}
void playSound() {
myTone(700, 30); 
wait(10);
myTone(700, 30);
wait(10);
myTone(700, 30);
wait(50);
}
void playSound1() {
myTone(200, 10);
wait(10);
myTone(400, 5);
wait(30);
}
void playSound2() {
myTone(400, 10);
wait(10);
myTone(200, 5);
wait(30);
}
void readBatLev() {
temp = analogRead(29);
vcc = temp * 0.0033 * 100;
battery = map((int)vcc, BAT_MIN, BAT_MAX, 0, 100);
if (battery < 0) {
battery = 0;
}
if (battery > 100) {
battery = 100;
}
sendBatteryLevel(battery, 1);
wait(2000, C_INTERNAL, I_BATTERY_LEVEL);
send(powerMsg.set(temp));
wait(200);
NrfRSSI = transportGetReceivingRSSI();
NrfRSSI2 = map(NrfRSSI, -85, -40, 0, 100);
if (NrfRSSI2 < 0) {
NrfRSSI2 = 0;
}
if (NrfRSSI2 > 100) {
NrfRSSI2 = 100;
}
send(msgRF52RssiReceiv.set(NrfRSSI2));
wait(200);
}

Գործի ֆայլերը stl-ում - google drive

Gerber PCB ֆայլեր - google drive

Այս զարգացման վերաբերյալ հարցերի, Arduinos-ի և Mysensors-ի ձեր զարգացումների հետ կապված դժվարությունների համար միշտ օգնության կգա մեր հեռագրային չաթում. https://t.me/mysensors_rus.

Source: www.habr.com

Добавить комментарий