Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Šiandienos straipsnyje noriu pasidalinti su jumis nauju projektu. Šį kartą tai jutiklinis jungiklis su stiklo skydeliu. Įrenginys kompaktiškas, 42x42mm išmatavimai (standartinių stiklo plokščių matmenys 80x80mm). Šio įrenginio istorija prasidėjo seniai, maždaug prieš metus.

Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Pirmieji variantai buvo antmega328 mikrovaldiklio, bet galiausiai viskas baigėsi nRF52832 mikrovaldikliu.

Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Jutiklinė įrenginio dalis veikia TTP223 lustais. Abu jutikliai aptarnaujami vienu pertraukimu. Maitinamas iš CR2477 baterijos, per TPS610981 lusto padidinimo keitiklį | duomenų lapas.

Mini jutiklinis jungiklis su stiklo skydeliu nRF52832
Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Įrenginys įgyvendina maitinimo išjungimo grandinę, naudodamas lauko tranzistorius. Paspaudus mygtuką, mikrovaldiklis pats perima galios valdymą ir tada mygtukas gali būti naudojamas aptarnavimo režimams (mano atveju tai yra poravimas su kitais įrenginiais, maitinimo išjungimas ir gamyklinių nustatymų atstatymas).

Būsenoms ir aptarnavimo režimams rodyti yra 2 rgb šviesos diodai. Taip pat buvo pridėtas pjezo emiteris, kuris imituoja paspaudimą palietus jutiklinius mygtukus ir garso signalą apie aptarnavimo režimus. Šviesos diodai ir pjezo spinduliuotė gali būti įjungiami ir išjungiami vartotojo nuožiūra. Tai atliekama per išmaniojo namo valdiklį, siunčiant komandas techniniams jutikliams, taip pat per išmaniojo namo valdiklį vartotojas gali keisti baterijos įkrovos siuntimo ir signalo lygio siuntimo intervalus. Mano atveju tai MAJORDOMO.

Sąnaudos perdavimo režimu yra 7 mA (250 kbit, 10 ms), suvartojimas miego režimu yra 40 µA, suvartojimas išjungtoje būsenoje yra mažesnis nei 1 µA (= padidinimo keitiklio suvartojimas „tuščiosios eigos“ režimu). Suteikiama Rx, tx, swd jungtis programavimui. Naudojama miniatiūrinė 2x3p jungtis, kurios žingsnis yra 1.27. Programavimui pagamintas specialus adapteris.

Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Kaip visada, įrenginio veikimas pagrįstas protokolu Mano jutikliai. Šį jutiklinį jungiklį planuojama naudoti roletų valdymo sistemoje. Tačiau apskritai taikymą riboja tik jūsų vaizduotė. Pavyzdžiui, mano sūnus (7 m.) jau padarė 3 užsakymus jungiklių versijoms: įjungti ir išjungti šviesą tualete su vonia (ji bus montuojama žemai nuo grindų), įjungti šviesą ilgas ir tamsus koridorius keliaujant į tualetą su vonia, o kitas – prie lovos, kad greitai įjungtumėte savo kambaryje šviesą, kad pabaisos pabėgtų.

Mini jutiklinis jungiklis su stiklo skydeliu nRF52832
Mini jutiklinis jungiklis su stiklo skydeliu nRF52832
Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Korpusas tradiciškai buvo spausdinamas SLA spausdintuvu, įrenginys miniatiūrinis, korpusas pasirodė mažas, šios spausdinimo technologijos naudojimas yra pagrįstas.

Žiūrėti spausdintą modelįMini jutiklinis jungiklis su stiklo skydeliu nRF52832
Mini jutiklinis jungiklis su stiklo skydeliu nRF52832
Mini jutiklinis jungiklis su stiklo skydeliu nRF52832

Magnetai įklijuoti į korpusą ir akumuliatoriaus skyriaus dangtelį.

Vaizdo įrašai su šio įrenginio bandymais:



Tiems, kurie nori pakartoti:

Išbandyti Arduino IDE roletų valdymo sistemos jungiklio programos kodą

Arduino laidai

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);
}

Bylos failai stl - Google diskas

Gerber PCB failai - Google diskas

Jei turite klausimų apie šią plėtrą, apie sunkumus, susijusius su jūsų „Arduinos“ ir „Mysensors“ plėtra, visada padės mūsų telegramos pokalbyje - https://t.me/mysensors_rus.

Šaltinis: www.habr.com

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