Mini interrupteur tactile avec panneau en verre sur nRF52832

Dans l'article d'aujourd'hui, je veux partager avec vous un nouveau projet. Cette fois, c'est un interrupteur tactile avec un panneau en verre. L'appareil est compact, dimensions 42x42mm (le panneau de verre standard a des dimensions 80x80mm). L'histoire de cet appareil a commencé il y a longtemps, il y a environ un an.



Les premières options étaient sur le microcontrôleur atmega328, mais finalement tout s'est terminé avec le microcontrôleur nRF52832.



La partie tactile de l'appareil fonctionne sur des puces TTP223. Les deux capteurs sont desservis par une interruption. Alimenté par une pile CR2477, via un convertisseur boost sur TPS610981 | Datashit .




Le dispositif met en œuvre un circuit de mise hors tension pour les transistors à effet de champ. Après avoir appuyé sur le bouton, le microcontrôleur lui-même intercepte la gestion de l'alimentation, puis le bouton peut être utilisé pour les modes de service (dans mon cas, il est couplé avec d'autres appareils, éteint l'alimentation et réinitialise les paramètres d'usine (réinitialisation d'usine)).


Il y a 2 LED rgb pour indiquer les états et les modes de service. Un émetteur piézo a également été ajouté pour simuler un clic lorsque vous touchez les boutons tactiles et l'indication sonore des modes de service. Les LED et l'émetteur piézo peuvent être allumés et éteints à la demande de l'utilisateur. Cela se fait via le contrôleur de la maison intelligente, en envoyant des commandes aux capteurs techniques, il est également possible de modifier les intervalles utilisateur pour envoyer la charge de la batterie et le niveau du signal via le contrôleur de la maison intelligente. Dans mon cas, c'est MAJORDOMO .


La consommation en mode transmission est de 7 mA (250 kbps, 10 ms), la consommation en veille est de 40 μA, la consommation hors ligne est inférieure à 1 μA (= consommation du convertisseur boost en mode veille). Sortie rx, tx, prise swd pour la programmation. Un connecteur miniature 2x3p est utilisé par incréments de 1,27. Un adaptateur spécial a été conçu pour la programmation.



Comme toujours, l'appareil est basé sur le protocole MySensors . Il est prévu que cet interrupteur tactile soit utilisé dans le système de commande des volets roulants. Mais en général, l'application n'est limitée que par votre imagination. Par exemple, déjà un fils (7 ans) a passé 3 commandes pour la version interrupteur: allumer et éteindre la lumière dans les toilettes avec une baignoire (elle sera montée pas très haut du sol), allumer la lumière dans un couloir long et sombre lorsque vous vous rendez aux toilettes avec une baignoire et une de plus chevet, pour allumer rapidement la lumière dans votre chambre afin que les monstres se dispersent.





Le boîtier était traditionnellement imprimé sur une imprimante SLA, l'appareil est petit, le boîtier est petit, l'utilisation de cette technologie d'impression est justifiée.


Voir le modèle imprimé



Les aimants sont collés dans le boîtier et le couvercle de la batterie.


Vidosiki avec des tests de cet appareil:





Pour ceux qui souhaitent répéter:


Code de programme de test de disjoncteur pour le système de commande de volet roulant pour Arduino IDE


Arduino Viring
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_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() { //delay(1000); pinMode(31, OUTPUT); digitalWrite(31, HIGH); delay(3000); pinMode(3, INPUT); pinMode(25, OUTPUT); pinMode(26, OUTPUT); pinMode(27, OUTPUT); pinMode(6, OUTPUT); pinMode(7, OUTPUT); pinMode(8, OUTPUT); pinMode(28, OUTPUT); // bizzer pinMode(2, INPUT); pinMode(9, INPUT); pinMode(10, INPUT); pinMode(29, INPUT); digitalWrite(28, LOW); // off bizzer digitalWrite(27, HIGH); digitalWrite(26, HIGH); digitalWrite(25, HIGH); digitalWrite(6, HIGH); digitalWrite(7, HIGH); digitalWrite(8, HIGH); } void before() { //digitalWrite(31, HIGH); NRF_POWER->DCDCEN = 1; //NRF_UART0->ENABLE = 0; analogReadResolution(12); disableNfc(); turnOffAdc(); //wait(2000); 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("Power on|off Node", "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; send(upMsg.set(switch_a)); //wait(200); digitalWrite(6, LOW); wait(10); playSound1(); wait(20); playSound2(); wait(50); } else { switch_a = 0; send(upMsg.set(switch_a)); //wait(200); digitalWrite(6, HIGH); wait(10); playSound2(); wait(20); playSound1(); wait(50); } //sleep_not_pasible = 1; //digitalWrite(25, HIGH); //wait(100); } 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; send(downMsg.set(switch_b)); //wait(200); digitalWrite(25, LOW); wait(10); playSound1(); wait(20); playSound2(); wait(50); } else { switch_b = 0; send(downMsg.set(switch_b)); //wait(200); digitalWrite(25, HIGH); wait(10); playSound2(); wait(20); playSound1(); wait(50); } //sleep_not_pasible = 1; //digitalWrite(6, HIGH); //wait(100); } if (digitalRead(9) == LOW && sens_flag1 == 1) { sens_flag1 = 0; //digitalWrite(6, HIGH); //playSound2(); //wait(50); } if (digitalRead(10) == LOW && sens_flag2 == 1) { sens_flag2 = 0; //digitalWrite(25, HIGH); //playSound2(); //wait(50); } 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) { //   myTone j = 500000 / j; //    j       k += millis(); //          while (k > millis()) { //  ,      digitalWrite(28, HIGH); delayMicroseconds(j); //    i   «1»   j digitalWrite(28, LOW ); delayMicroseconds(j); //    i   «0»   j } } void playSound0() { //wait(500); myTone(1300, 50); //     0,1    2048  wait(20); //  0,1  myTone(1300, 50); wait(50); } void playSound() { //wait(500); myTone(700, 30); //     0,1    2048  wait(10); //  0,1  myTone(700, 30); wait(10); myTone(700, 30); wait(50); //  0,1  //myTone(500, 30); //wait(500); } void playSound1() { //wait(500); myTone(200, 10); //     0,1    2048  wait(10); //  0,1  myTone(400, 5); wait(30); //  0,1  //myTone(500, 30); //wait(500); } void playSound2() { //wait(500); myTone(400, 10); //     0,1    2048  wait(10); //  0,1  myTone(200, 5); wait(30); //  0,1  //myTone(500, 30); //wait(500); } void readBatLev() { //NRF5_ESB_startListening(); wait(200); 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); wait(200); 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); } 

Dossiers en stl


Fichiers de circuits imprimés Gerber


Pour des questions sur ce développement, sur les difficultés de votre développement, l'Arduino et les Mysensors viendront toujours à la rescousse dans notre chat télégramme.

Source: https://habr.com/ru/post/fr453868/


All Articles