مفتاح لمس صغير مع لوحة زجاجية على nRF52832

في مقال اليوم أريد أن أشارككم مشروعًا جديدًا. هذه المرة هو مفتاح اللمس مع لوحة زجاجية. الجهاز صغير الحجم بقياس 42 × 42 ملم (الألواح الزجاجية القياسية لها أبعاد 80 × 80 ملم). بدأ تاريخ هذا الجهاز منذ وقت طويل، منذ حوالي عام.

مفتاح لمس صغير مع لوحة زجاجية على nRF52832

كانت الخيارات الأولى على متحكم atmega328، ولكن في النهاية انتهى كل شيء مع متحكم nRF52832.

مفتاح لمس صغير مع لوحة زجاجية على nRF52832

يعمل الجزء اللمسي من الجهاز على شرائح TTP223. يتم خدمة كلا المستشعرين من خلال مقاطعة واحدة. مدعوم ببطارية CR2477، عبر محول تعزيز على شريحة TPS610981 | ورقة البيانات.

مفتاح لمس صغير مع لوحة زجاجية على nRF52832
مفتاح لمس صغير مع لوحة زجاجية على nRF52832

ينفذ الجهاز دائرة انقطاع التيار الكهربائي باستخدام ترانزستورات التأثير الميداني. بعد الضغط على الزر، يعترض المتحكم الدقيق نفسه التحكم في الطاقة ومن ثم يمكن استخدام الزر في أوضاع الخدمة (في حالتي، يكون هذا هو الاقتران بأجهزة أخرى، وإيقاف تشغيل الطاقة وإعادة ضبط إعدادات المصنع).

يوجد 2 مصباح LED RGB للإشارة إلى الحالات وأوضاع الخدمة. تمت إضافة باعث بيزو أيضًا لمحاكاة النقرة عند لمس أزرار اللمس والإشارة الصوتية لأوضاع الخدمة. يمكن تشغيل وإيقاف تشغيل مصابيح 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

اردوينو الأسلاك

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 - محرك جوجل

ملفات جربر ثنائي الفينيل متعدد الكلور - محرك جوجل

للأسئلة حول هذا التطوير، حول الصعوبات في تطويراتك على Arduinos وMysensors، ستأتي دائمًا للإنقاذ في دردشة Telegram الخاصة بنا - https://t.me/mysensors_rus.

المصدر: www.habr.com

إضافة تعليق