Công tắc cảm ứng mini mặt kính trên nRF52832

Trong bài viết hôm nay tôi muốn chia sẻ với các bạn một dự án mới. Lần này là một công tắc cảm ứng với mặt kính. Thiết bị có kích thước nhỏ gọn, kích thước 42x42mm (tấm kính tiêu chuẩn có kích thước 80x80mm). Lịch sử của thiết bị này đã bắt đầu từ lâu, khoảng một năm trước.

Công tắc cảm ứng mini mặt kính trên nRF52832

Các lựa chọn đầu tiên là về vi điều khiển atmega328, nhưng cuối cùng tất cả đều kết thúc với vi điều khiển nRF52832.

Công tắc cảm ứng mini mặt kính trên nRF52832

Phần cảm ứng của máy chạy trên chip TTP223. Cả hai cảm biến được phục vụ bởi một ngắt. Được cung cấp năng lượng bởi pin CR2477, thông qua bộ chuyển đổi tăng tốc trên chip TPS610981 | bảng dữliệu.

Công tắc cảm ứng mini mặt kính trên nRF52832
Công tắc cảm ứng mini mặt kính trên nRF52832

Thiết bị thực hiện mạch tắt nguồn bằng cách sử dụng bóng bán dẫn hiệu ứng trường. Sau khi nhấn nút, bộ vi điều khiển sẽ tự chặn điều khiển nguồn và sau đó nút này có thể được sử dụng cho các chế độ dịch vụ (trong trường hợp của tôi, đây là ghép nối với các thiết bị khác, tắt nguồn và đặt lại về cài đặt gốc).

Có 2 đèn LED rgb để biểu thị trạng thái và chế độ dịch vụ. Một bộ phát áp điện cũng đã được thêm vào để mô phỏng tiếng click khi chạm vào các nút cảm ứng và chỉ báo âm thanh của các chế độ dịch vụ. Đèn LED và bộ phát Piezo có thể được bật và tắt theo ý muốn của người dùng. Điều này được thực hiện thông qua bộ điều khiển nhà thông minh bằng cách gửi lệnh đến các cảm biến kỹ thuật; người dùng cũng có thể thay đổi khoảng thời gian gửi mức sạc pin và mức tín hiệu thông qua bộ điều khiển nhà thông minh. Trong trường hợp của tôi nó là MAJORDOMO.

Mức tiêu thụ ở chế độ truyền là 7mA (250kbit, 10ms), mức tiêu thụ khi ngủ là 40µA, mức tiêu thụ ở trạng thái tắt nhỏ hơn 1µA (= mức tiêu thụ của bộ chuyển đổi tăng tốc ở chế độ “không hoạt động”). Đầu nối Rx, tx, swd để lập trình được cung cấp. Một đầu nối 2x3p thu nhỏ có bước 1.27 được sử dụng. Một bộ chuyển đổi đặc biệt được tạo ra để lập trình.

Công tắc cảm ứng mini mặt kính trên nRF52832

Như mọi khi, hoạt động của thiết bị dựa trên giao thức Cảm biến của tôi. Công tắc cảm ứng này dự kiến ​​sẽ được sử dụng trong hệ thống điều khiển rèm cuốn. Nhưng nhìn chung, ứng dụng chỉ bị giới hạn bởi trí tưởng tượng của bạn. Ví dụ, con trai tôi (7 tuổi) đã thực hiện 3 lệnh cho các phiên bản công tắc: bật tắt đèn trong nhà vệ sinh có bồn tắm (nó sẽ được gắn thấp so với sàn nhà), bật đèn trong một bồn cầu. hành lang dài và tối khi đi đến nhà vệ sinh có bồn tắm và một hành lang khác làm đầu giường để bật nhanh đèn trong phòng để lũ quái vật bỏ chạy.

Công tắc cảm ứng mini mặt kính trên nRF52832
Công tắc cảm ứng mini mặt kính trên nRF52832
Công tắc cảm ứng mini mặt kính trên nRF52832

Vỏ máy theo truyền thống được in trên máy in SLA, thiết bị thu nhỏ, vỏ máy nhỏ, việc sử dụng công nghệ in này là hợp lý.

Xem mẫu inCông tắc cảm ứng mini mặt kính trên nRF52832
Công tắc cảm ứng mini mặt kính trên nRF52832
Công tắc cảm ứng mini mặt kính trên nRF52832

Nam châm được dán vào vỏ và nắp ngăn chứa pin.

Video thử nghiệm thiết bị này:



Dành cho những ai muốn lặp lại:

Kiểm tra mã chương trình cho một công tắc trong hệ thống điều khiển rèm cuốn cho Arduino IDE

Dây 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);
}

Hồ sơ vụ án trong stl - Google Drive

Tập tin PCB của Gerber - Google Drive

Đối với các câu hỏi về sự phát triển này, về những khó khăn trong quá trình phát triển của bạn trên Arduinos và Mysensors, chúng tôi sẽ luôn giải đáp trong cuộc trò chuyện qua điện tín của chúng tôi - https://t.me/mysensors_rus.

Nguồn: www.habr.com

Thêm một lời nhận xét