Hari ini saya ingin membagikan salah satu proyek Arduino saya. Suatu ketika, belum lama ini, di suatu tempat di Internet, saya mengetahui tentang Arduino. Saya bergabung dengan bisnis ini dengan cukup cepat, tingkat entri di sana tidak tinggi. Setelah beberapa waktu, setelah mengumpulkan banyak sensor, sensor untuk rumah pintar mulai membuat diriku berpikir bahwa entah bagaimana itu semua keluar dari pikiran.
Modul, kotak polos besar, banyak kabel dan lem panas :). Melihat kotak saya dengan sensor suhu dan, misalnya, pada sensor suhu Xiaomi yang sama, saya menyadari bahwa saya ingin itu terlihat seperti Xiaomi, tetapi pada saat yang sama Anda dapat memprogram ulang seperti milik saya dalam kotak berukuran 10cm x 6cm dengan kabel dan perekat hotmelt. Dan mungkin kemudian awal proyek Arduino DIY saya di papan PCB diletakkan.
Pada artikel hari ini, kita akan berbicara tentang sensor suhu dan kelembaban berdasarkan pada prosesor atmega328p-mu. Ini adalah versi "lebih kecil" (analog absolut) dari prosesor atmega328p-au (Arduino Uno, Pro Mini, Nano) yang dikenal oleh semua pengembang Arduino. Jika seseorang telah membaca artikel saya sebelumnya, mereka tahu bahwa saya lebih suka Mysensors. Apa ini Ini adalah perpustakaan yang sangat sederhana dan dirancang dengan baik dan, yang penting, dijelaskan dengan baik untuk Arduino IDE (dan tidak hanya) untuk membuat jaringan radio IOT pada frekuensi 2,4 GHz, 915, 868, 433 MHz, serta jaringan kabel pada antarmuka 485, mungkin tidak semua disebutkan. Protokol terus berkembang, sesuatu ditambahkan setiap saat.
Hal pertama yang dilakukan adalah sensor itu sendiri pada papan PCB. Saya melakukannya tanpa melihat kasingnya, menurut prinsipnya, yang utama adalah membuat sensor, dan entah bagaimana saya akan mencetak kasingnya ... ya, jangan lakukan itu :). Faktanya, sensor itu sendiri adalah Arduinka Pro Mini yang sama, modul radio nRF24l01, sensor suhu dan kelembaban SHT20, hanya tanpa kabel dan lem panas. Dari "bells and whistles," ini adalah SPI flash drive eksternal untuk melakukan flashing di udara (bootloader DualOptibut diperlukan untuk operasi, kemudian saya berhenti meletakkannya (flash drive) pada paket rangkaian, karena tidak ada firmware di udara dan setengah baterai) dan "crypto mic" ATSHA204A, jadi untuk berbicara, untuk penuh perangkat keras kit (di Mysensors, untuk mengaktifkan tanda tangan, enkripsi, dll., Anda hanya perlu menentukan #def yang diperlukan di awal sketsa).

Papan itu sendiri dibuat dalam program Diptrace, setelah menonton tutorial video di YouTube, pada awalnya itu tampak seperti sesuatu yang "neraka", tetapi dalam kenyataannya ternyata tidak begitu sulit. Saya memesan papan di Cina di jlcpcb.com, 2 dolar, warna apa pun, dan setelah 2 minggu Anda sudah mendapatkan 10 buah "kreasi Anda sendiri" di tangan Anda :).


Langkah selanjutnya adalah pengembangan tubuh. Oh, ternyata ini masalah yang sama. Secara umum, saya tidak mencari cara yang mudah, saya memutuskan untuk menguasai Solid Works. Ternyata, ini sama sekali tidak seperti dengan Deeptrace. Meskipun demikian, saya merekomendasikan editor ini untuk belajar. Proses pembelajaran berlangsung selama sebulan dengan santai menonton video pelajaran di YouTube dan mengulangi pelajaran di editor. Dalam proses mengembangkan kasing, menjadi jelas bahwa membuat papan perangkat tanpa memperhitungkan parameter kasing masa depan adalah keputusan yang buruk, dari seri kami memasukkan tongkat ke roda kami sendiri. Sebagai hasil dari versi papan, tiga keluar, dengan mempertimbangkan pemasangan papan dalam kasus ini, dan saya pikir ini bukan pilihan terakhir.
Pada awal pengembangan bangunan, idenya adalah untuk mencetaknya pada printer 3D FDM, tetapi semakin jauh ke dalam hutan semakin jelas bahwa tidak dapat mereproduksi semua Daftar Keinginan saya. Pada saat pemahaman ini datang, saya sudah belajar tentang teknologi pencetakan 3D lainnya - SLA. Tanpa berpikir dua kali dan terkesan dengan kualitas cetak, Wishlist pada Ali -
ANYCUBIC Photon dikeluarkan. (Tautan ana Ali, bukan iklan, bukan afiliasi, ... hanya tautan).
Saya akan menulis segera, sekarang, berdasarkan pengalaman saya pada saat penulisan ini, ... oh, hal yang keren ini adalah hal yang keren !!! Kasing yang dirancang dalam editor tentu saja dan dicetak bukan pertama kalinya dan ada banyak perbaikan. Yah, mungkin bukan sebaliknya. Hasilnya, saya mendapatkan hasil yang saya inginkan. Cukup miniatur perangkat, casing DIY yang bagus dengan detail, tombol, font, semuanya seperti yang ada di kepala. Sebuah magnet ditambahkan ke penutup belakang, sekarang dapat dengan mudah dipasang di permukaan besi.








Ini adalah upaya untuk mencetak model yang sama pada printer FDM:


Karena perangkatnya ternyata kecil, tapi masih arduinka, saya bingung dengan output konektor miniatur untuk pemrograman. Dan karenanya, adaptor kecil dibuat untuk konektor untuk koneksi yang nyaman dengan programmer dan konverter TTL.

Semuanya dibeli di Ali (ya, tidak hanya modul arduino penuh)
SMD tantalum kapasitor 4.7uF - 4.7uF | 10v | 10% - C1
Kapasitor keramik SMD 100nF | Y5V - 100nF | 50v | + 80-20% - C2, C3, C4, C5, C6, C7
LED - LED SIDE - D1
Pin Header Female - 2x3P | 6pin | 1.27mm - J1, J2
SMD resistor 20K Ohm - 20K | 5% - R1
SMD resistor 4.7K Ohm - 4.7K | 5% - R2, R3, R4
SMD resistor 470K Ohm - 470 | 1% - R5
SMD resistor 1M Ohm - 1M | 1% - R6
SMD resistor 18K Ohm - 18K | 5% - R7
SMD resistor 10K Ohm - 10K | 5% - R8
Tombol sisi SMD 4-pin - SW1, SW2
512-Kbit, Memori Flash Seri 1.65V SPI - AT25DF512C-SSHN-B - U1
Mini NRF24L01 + 2.4GHz 1.27MM RF - nRF24l01 1.27 SMD - U2
ATMEGA328P-MU QFN32 - U3
AUTHENTICATION CRYPTO, 1 WIRE - ATSHA204A-STUCZ-T - U4
Sensor Kelembaban dan Suhu IC - SHT20 - U5
PEMEGANG BATERAI UNTUK CR2477-1 - L-KLS5-CR2477-1 - U6
Kode programnya cukup sederhana. Contoh perpustakaan DFRobot digunakan untuk bekerja dengan sensor SHT20. Pada prinsipnya, setiap sketsa, untuk sensor apa pun dapat diubah menjadi sketsa untuk bekerja di jaringan Mysensors dalam 5 menit.
Daftar kode#include <Wire.h>
#include "DFRobot_SHT20.h"
DFRobot_SHT20 sht20;
#define MY_DEBUG
#define MY_RADIO_RF24
#define MY_PASSIVE_NODE
#define MY_NODE_ID 200
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC
#define MY_TRANSPORT_UPLINK_CHECK_DISABLED
#define TEMP_SENS_ID 1
#define HUM_SENS_ID 2
#define SETTING_LED_SENS_ID 100
#define DELAY_TIME_SENS_ID 101
#define BATTARY_SEND_SENS_ID 102
#define BATTARY_DATA_SENS_ID 103
#define BAT_COOF 3.04
#define BAT_MIN 195
#define BAT_MAX 295
#define ON 1
#define OFF 0
float humd;
float temp;
float oldhumd;
float oldtemp;
float tempThreshold = 0.5;
float humThreshold = 10.0;
static uint32_t lightMillis;
static uint32_t previousMillis;
uint32_t send_batteryTime;
uint32_t w_battetyTime = 0;
static uint8_t led_pin = 4;
static uint8_t mode_pin = 2;
uint32_t delayTime;
int8_t battery;
int8_t old_battery;
uint8_t set_led;
boolean sleep_mode;
boolean configMode = 0;
int8_t timer_status = 0;
bool flag_mode_button = 0;
bool sleep_flag = 0;
bool listen_flag = 0;
#include <MySensors.h>
MyMessage msg_temp(TEMP_SENS_ID, V_TEMP);
MyMessage msg_hum(HUM_SENS_ID, V_HUM);
MyMessage msg_setting_led(SETTING_LED_SENS_ID, V_VAR1);
MyMessage msg_delay_time(DELAY_TIME_SENS_ID, V_VAR1);
MyMessage msg_battary_send(BATTARY_SEND_SENS_ID, V_VAR1);
MyMessage powerMsg(BATTARY_DATA_SENS_ID, V_VAR1);
void preHwInit()
{
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, OFF);
pinMode(mode_pin, INPUT_PULLUP);
}
void before()
{
set_led = loadState(100);
if (set_led > 1) {
set_led = 1;
saveState(100, set_led);
}
delayTime = loadState(101);
if (delayTime > 60) {
delayTime = 3;
saveState(101, delayTime);
}
send_batteryTime = loadState(102);
if (send_batteryTime > 48) {
send_batteryTime = 6;
saveState(102, send_batteryTime);
}
digitalWrite(led_pin, ON);
}
void presentation()
{
sendSketchInfo("Temp & Hum Sensor CR2477", "1.0");
wait(100);
present(TEMP_SENS_ID, S_TEMP, "TEMPERATURE DATA");
wait(100);
present(HUM_SENS_ID, S_HUM, "HUMIDITY DATA");
wait(100);
present(SETTING_LED_SENS_ID, S_CUSTOM, "LED MODE");
wait(100);
present(DELAY_TIME_SENS_ID, S_CUSTOM, "DELAY TIME/MIN");
wait(100);
present(BATTARY_SEND_SENS_ID, S_CUSTOM, "BATTERY SEND TIME/H");
wait(100);
present(BATTARY_DATA_SENS_ID, S_CUSTOM, "BATTERY DATA");
}
void setup()
{
digitalWrite(led_pin, OFF);
wait(500);
digitalWrite(led_pin, ON);
wait(75);
digitalWrite(led_pin, OFF);
wait(50);
digitalWrite(led_pin, ON);
wait(75);
digitalWrite(led_pin, OFF);
wait(50);
digitalWrite(led_pin, ON);
wait(75);
digitalWrite(led_pin, OFF);
TRANSPORT_DEBUG(PSTR("MyS: OPERATING MODE\n"));
wait(100);
readBatLev();
wait(100);
sht20.initSHT20();
wait(100);
send_data();
wait(100);
send(msg_delay_time.set(delayTime));
wait(100);
send(msg_setting_led.set(set_led));
wait(100);
send(msg_battary_send.set(send_batteryTime));
}
void loop()
{
if (configMode == 0) {
if (sleep_flag == 0) {
timer_status = sleep(digitalPinToInterrupt(mode_pin), FALLING, delayTime * 60 * 1000, false);
sleep_flag = 1;
}
if (timer_status == -1) {
w_battetyTime = w_battetyTime + (delayTime * 60 * 1000);
if (w_battetyTime >= send_batteryTime * 60 * 60 * 1000) {
readBatLev();
w_battetyTime = 0;
}
send_data();
sleep_flag = 0;
}
if (timer_status == 0) {
if (digitalRead(2) == LOW && flag_mode_button == 0)
{
flag_mode_button = 1;
previousMillis = millis();
wait(50);
}
if (digitalRead(2) == LOW && flag_mode_button == 1) {
if ((millis() - previousMillis > 0) && (millis() - previousMillis <= 2000)) {
if (millis() - lightMillis > 50) {
lightMillis = millis();
digitalWrite(led_pin, !digitalRead(led_pin));
}
}
if ((millis() - previousMillis > 2000) && (millis() - previousMillis <= 2500)) {
digitalWrite(led_pin, OFF);
}
if ((millis() - previousMillis > 2500) && (millis() - previousMillis <= 4500)) {
if (millis() - lightMillis > 25) {
lightMillis = millis();
digitalWrite(led_pin, !digitalRead(led_pin));
}
}
if (millis() - previousMillis > 4500) {
digitalWrite(led_pin, OFF);
}
}
if (digitalRead(2) == HIGH && flag_mode_button == 1)
{
if ((millis() - previousMillis > 0) && (millis() - previousMillis <= 2000)) {
configMode = !configMode;
flag_mode_button = 0;
TRANSPORT_DEBUG(PSTR("MyS: CONFIGURATION MODE\n"));
sleep_flag = 0;
digitalWrite(led_pin, OFF);
}
if ((millis() - previousMillis > 2000) && (millis() - previousMillis <= 2500)) {
flag_mode_button = 0;
sleep_flag = 0;
}
if ((millis() - previousMillis > 2500) && (millis() - previousMillis <= 4500))
{
flag_mode_button = 0;
sleep_flag = 0;
digitalWrite(led_pin, OFF);
}
if (millis() - previousMillis > 4500) {
flag_mode_button = 0;
sleep_flag = 0;
wait(50);
}
}
}
} else {
if (listen_flag == 0) {
RF24_startListening();
listen_flag = 1;
}
if (millis() - lightMillis > 1000) {
lightMillis = millis();
digitalWrite(led_pin, !digitalRead(led_pin));
}
if (digitalRead(2) == LOW && flag_mode_button == 0)
{
flag_mode_button = 1;
wait(50);
}
if (digitalRead(2) == LOW && flag_mode_button == 1) {
}
if (digitalRead(2) == HIGH && flag_mode_button == 1)
{
configMode = !configMode;
listen_flag = 0;
flag_mode_button = 0;
TRANSPORT_DEBUG(PSTR("MyS: OPERATING MODE\n"));
digitalWrite(led_pin, OFF);
wait(50);
}
}
}
void receive(const MyMessage & message)
{
if (message.sensor == SETTING_LED_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getByte() <= 1) {
set_led = message.getBool();
saveState(100, set_led);
send(msg_setting_led.set(set_led));
if (set_led == 0) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED: OFF\n"));
}
if (set_led == 1) {
TRANSPORT_DEBUG(PSTR("MyS: STATUS LED: ON\n"));
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
}
}
}
}
if (message.sensor == DELAY_TIME_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getULong() <= 60 && message.getULong() != 0) {
delayTime = message.getULong();
saveState(101, delayTime);
send(msg_delay_time.set(delayTime));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW INTERVAL TEMP&HUM SEND VALUE IS SET: %d MIN.\n"), delayTime);
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
} else if (message.getULong() > 60) {
delayTime = 60;
saveState(101, delayTime);
send(msg_delay_time.set(delayTime));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW INTERVAL TEMP&HUM SEND VALUE IS SET: %d MIN.\n"), delayTime);
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
} else if (message.getULong() == 0) {
delayTime = 1;
saveState(101, delayTime);
send(msg_delay_time.set(delayTime));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW INTERVAL TEMP&HUM SEND VALUE IS SET: %d MIN.\n"), delayTime);
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
}
}
}
if (message.sensor == BATTARY_SEND_SENS_ID) {
if (message.type == V_VAR1) {
if (message.getULong() <= 168) {
send_batteryTime = message.getULong();
saveState(102, send_batteryTime);
send(msg_battary_send.set(send_batteryTime));
TRANSPORT_DEBUG(PSTR("MyS: THE NEW INTERVAL BATTERY SEND IS SET: %d HOUR\n"), send_batteryTime);
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
}
}
}
}
void send_data()
{
humd = sht20.readHumidity();
temp = sht20.readTemperature();
int t_humd = (int)humd;
int t_temp = (int)temp;
if (abs(temp - oldtemp) >= tempThreshold) {
send(msg_temp.set(temp, 1));
oldtemp = temp;
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
}
wait(100);
if (abs(humd - oldhumd) >= humThreshold) {
send(msg_hum.set(humd, 1));
oldhumd = humd;
if (set_led == 1) {
digitalWrite(led_pin, ON);
wait(50);
digitalWrite(led_pin, OFF);
}
}
TRANSPORT_DEBUG(PSTR("MyS: DATA - TEMPERATURE: %d, HUMIDITY %d\n"), t_temp, t_humd);
}
void readBatLev() {
ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX0);
wait(100);
RF24_startListening();
wait(200);
ADCSRA |= _BV(ADSC);
while (bit_is_set(ADCSRA, ADSC));
uint8_t low = ADCL;
uint8_t high = ADCH;
long temp = (high << 8) | low;
float vcc = temp * 1.1 / 1023 * BAT_COOF * 100;
battery = map((int)vcc, BAT_MIN, BAT_MAX, 0, 100);
if (battery < 0) {
battery = 0;
}
if (battery > 100) {
battery = 100;
}
TRANSPORT_DEBUG(PSTR("MyS: BATTERY LEVEL: %d, PREVIUS BATTERY LEVEL: %d\n"), battery, old_battery);
TRANSPORT_DEBUG(PSTR("MyS: BATTERY LEVEL ADC: %d\n"), temp);
wait(100);
sendBatteryLevel(battery);
wait(100);
send(powerMsg.set(temp));
TRANSPORT_DEBUG(PSTR("MyS: SEND BATTERY LEVEL\n"));
}
:
:
( ), Mysensors( Mysensors )

. , , , 3d
www.openhardware.io. , Mysensors β
t.me/mysensors_rus.