nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Бүгүнкү макалада мен сиздер менен жаңы долбоор менен бөлүшкүм келет. Бул жолу айнек панели бар сенсордук өчүргүч. Аппарат компакттуу, 42x42 мм өлчөмүндө (стандарттык айнек панелдер 80x80 мм өлчөмдөрү бар). Бул аппараттын тарыхы көп убакыт мурун, болжол менен бир жыл мурун башталган.

nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Биринчи варианттар atmega328 микроконтроллеринде болгон, бирок аягында баары nRF52832 микроконтроллери менен аяктаган.

nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Аппараттын сенсордук бөлүгү TTP223 чиптеринде иштейт. Эки сенсор тең бир үзгүлтүккө ээ. TPS2477 чипиндеги күчөтүүчү конвертер аркылуу CR610981 батареясы менен иштейт | маалымат жадыбалы.

nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч
nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Аппарат талаа эффективдүү транзисторлорду колдонуу менен өчүрүү схемасын ишке ашырат. Баскычты баскандан кийин микроконтроллердин өзү кубаттуулукту башкарууну токтотуп, андан кийин баскычты тейлөө режимдеринде колдонсо болот (менин учурда бул башка түзмөктөр менен жупташтыруу, кубатты өчүрүү жана заводдук жөндөөлөргө кайтаруу).

Мамлекеттерди жана тейлөө режимдерин көрсөтүү үчүн 2 rgb LED бар. Сенсордук баскычтарга тийгенде чыкылдатууну жана тейлөө режимдеринин үн индикациясын симуляциялоо үчүн пьезоэмиттер да кошулган. Светодиоддор жана пьезоэмиттер колдонуучунун каалоосу боюнча күйгүзүлүшү жана өчүрүлүшү мүмкүн. Бул акылдуу үй контроллери аркылуу техникалык сенсорлорго буйруктарды жөнөтүү аркылуу ишке ашырылат; колдонуучу ошондой эле акылдуу үй контроллери аркылуу батареянын зарядын жана сигнал деңгээлин жөнөтүү аралыгын өзгөртө алат. Менин учурда ал МАЖОРДОМО.

Өтүү режиминдеги керектөө 7мА (250кбит, 10мс), уйкудагы керектөө 40μA, өчүк абалындагы керектөө 1мкАдан аз (= "бос" режимде күчөткүч конвертордун керектөөсү). Программалоо үчүн Rx, tx, swd туташтыргычы каралган. 2 кадам менен миниатюралык 3x1.27p туташтыргыч колдонулат. Программалоо үчүн атайын адаптер жасалган.

nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Ар дайымкыдай эле, аппараттын иштеши протоколго негизделген MySensors. Бул сенсордук өчүргүч ролик жалюзи башкаруу системасында колдонуу пландаштырылууда. Бирок, жалпысынан, колдонмо сиздин элестетүү менен гана чектелет. Мисалы, менин уулум (7 жашта) буга чейин коммутаторлордун версияларына 3 буйрук берген: ваннасы бар туалеттин жарыгын күйгүзүү жана өчүрүү (ал полдон төмөн орнотулат), жарыкты күйгүзүү. узун жана караңгы коридор ваннасы бар ажатканага, ал эми башкасы керебеттин жанына, желмогуздар качып кетүүсү үчүн бөлмөңүздөгү жарыкты тез күйгүзүү үчүн.

nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч
nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч
nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Иш салттуу түрдө SLA принтеринде басылып чыккан, аппарат миниатюралык, корпус кичинекей болуп чыкты, бул басып чыгаруу технологиясын колдонуу негиздүү.

Басып чыгарылган моделди көрүүnRF52832 боюнча айнек панели менен мини сенсордук өчүргүч
nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч
nRF52832 боюнча айнек панели менен мини сенсордук өчүргүч

Магниттер корпуска жана батарея бөлүкчөсүнүн капкагына чапталган.

Бул аппараттын сыноолору бар видеолор:



Кайталоону каалагандар үчүн:

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

stl ичинде иш файлдары - google drive

Gerber PCB файлдары - google drive

Бул өнүгүү, Arduinos жана Mysensors боюнча иштеп чыгууларыңыздагы кыйынчылыктар жөнүндө суроолоруңуз болсо, биздин телеграмма чатта ар дайым жардамга келет - https://t.me/mysensors_rus.

Source: www.habr.com

Комментарий кошуу