Mini touch switch na may glass panel sa nRF52832

Sa artikulo ngayon nais kong ibahagi sa iyo ang isang bagong proyekto. Sa pagkakataong ito ito ay isang touch switch na may glass panel. Ang aparato ay compact, na may sukat na 42x42mm (karaniwang mga panel ng salamin ay may mga sukat na 80x80mm). Ang kasaysayan ng device na ito ay nagsimula nang matagal na ang nakalipas, mga isang taon na ang nakalipas.

Mini touch switch na may glass panel sa nRF52832

Ang mga unang pagpipilian ay nasa atmega328 microcontroller, ngunit sa huli ang lahat ay natapos sa nRF52832 microcontroller.

Mini touch switch na may glass panel sa nRF52832

Ang touch na bahagi ng device ay tumatakbo sa TTP223 chips. Ang parehong mga sensor ay pinaglilingkuran ng isang interrupt. Pinapatakbo ng CR2477 na baterya, sa pamamagitan ng boost converter sa TPS610981 chip | Datasheet.

Mini touch switch na may glass panel sa nRF52832
Mini touch switch na may glass panel sa nRF52832

Ang device ay nagpapatupad ng power-off circuit gamit ang field-effect transistors. Pagkatapos ng pagpindot sa pindutan, ang microcontroller mismo ay humarang sa kontrol ng kuryente at pagkatapos ay ang pindutan ay maaaring gamitin para sa mga mode ng serbisyo (sa aking kaso, ito ay pagpapares sa iba pang mga aparato, pinapatay ang kapangyarihan at pag-reset sa mga setting ng pabrika).

Mayroong 2 rgb LED para sa pagtukoy ng mga estado at mga mode ng serbisyo. Nagdagdag din ng piezo emitter upang gayahin ang isang pag-click kapag hinahawakan ang mga pindutan ng pagpindot at indikasyon ng tunog ng mga mode ng serbisyo. Ang mga LED at piezo emitter ay maaaring i-on at i-off sa pagpapasya ng gumagamit. Ginagawa ito sa pamamagitan ng smart home controller sa pamamagitan ng pagpapadala ng mga command sa mga teknikal na sensor; maaari ding baguhin ng user ang mga pagitan para sa pagpapadala ng charge ng baterya at antas ng signal sa pamamagitan din ng smart home controller. Sa aking kaso ito ay MAJORDOMO.

Ang pagkonsumo sa transmit mode ay 7mA (250kbit, 10ms), ang pagkonsumo sa pagtulog ay 40Β΅A, ang pagkonsumo sa off state ay mas mababa sa 1Β΅A (=consumption ng boost converter sa "idle" mode). Ang Rx, tx, swd connector para sa programming ay ibinigay. Ginagamit ang isang miniature na 2x3p connector na may pitch na 1.27. Ang isang espesyal na adaptor ay ginawa para sa programming.

Mini touch switch na may glass panel sa nRF52832

Gaya ng nakasanayan, ang pagpapatakbo ng device ay nakabatay sa protocol MySensors. Ang touch switch na ito ay binalak na gamitin sa roller blind control system. Ngunit sa pangkalahatan, ang application ay limitado lamang sa pamamagitan ng iyong imahinasyon. Halimbawa, ang aking anak na lalaki (7 taong gulang) ay nakagawa na ng 3 mga order para sa mga bersyon ng switch: upang i-on at patayin ang ilaw sa isang banyo na may bathtub (ito ay mai-mount nang mababa mula sa sahig), upang i-on ang ilaw sa isang mahaba at madilim na koridor kapag naglalakbay sa isang banyo na may bathtub, at isa pa bilang tabi ng kama, para sa mabilis na pagbukas ng ilaw sa iyong silid upang tumakas ang mga halimaw.

Mini touch switch na may glass panel sa nRF52832
Mini touch switch na may glass panel sa nRF52832
Mini touch switch na may glass panel sa nRF52832

Ang kaso ay tradisyonal na naka-print sa isang SLA printer, ang aparato ay maliit, ang kaso ay naging maliit, ang paggamit ng teknolohiyang ito sa pag-print ay nabigyang-katwiran.

Tingnan ang naka-print na modeloMini touch switch na may glass panel sa nRF52832
Mini touch switch na may glass panel sa nRF52832
Mini touch switch na may glass panel sa nRF52832

Ang mga magnet ay nakadikit sa case at sa takip ng kompartamento ng baterya.

Mga video na may mga pagsubok sa device na ito:



Para sa mga gustong ulitin:

Subukan ang program code para sa switch sa roller blind control system para sa Arduino IDE

Arduino Wiring

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

Mga case file sa stl - google drive

Gerber PCB file - google drive

Para sa mga tanong tungkol sa pag-unlad na ito, tungkol sa mga paghihirap sa iyong mga pag-unlad sa Arduinos at Mysensors ay palaging darating sa pagsagip sa aming telegram chat - https://t.me/mysensors_rus.

Pinagmulan: www.habr.com

Magdagdag ng komento