今天,我想分享我的Arduino项目之一。 很久以前,在互联网上的某个地方,我发现了有关Arduino的信息。 我加入这项业务的速度相当快,入门水平并不高。 一段时间后,已经收集了一堆传感器,用于智能家居的传感器开始让我自己以为这是完全不合时宜的。
模块,大的普通盒子,一堆电线和热胶:)。 看着装有温度传感器的盒子,例如同一小米的温度传感器,我意识到我希望它看起来像小米,但与此同时,您可以像我的小盒子一样在一个10cm x 6cm的盒子中用电线和热熔粘合剂对其进行重新编程。 然后可能是我在PCB板上进行DIY arduino项目的开始。
在今天的文章中,我们将讨论基于atmega328p-mu处理器的温度和湿度传感器。 这是所有arduino开发人员都知道的atmega328p-au处理器(Arduino Uno,Pro Mini,Nano)的“较小”版本(绝对模拟)。 如果有人以前阅读过我的文章,他们知道我更喜欢Mysensors。 这是什么 这是一个非常简单且经过精心设计的,而且重要的是,描述良好的Arduino IDE库(不仅如此),用于创建频率为2.4 GHz,915、868、433 MHz的IOT无线电网络以及485接口上的有线网络,也许没有全部提及协议在不断发展,一直在增加一些东西。
要做的第一件事是PCB板上的传感器本身。 根据原理,我这样做是在不考虑外壳的情况下进行的,主要是制造一个传感器,然后我将以某种方式打印外壳……是的,不要那样做:)。 实际上,传感器本身就是Arduinka Pro Mini,nRF24l01无线电模块,SHT20温湿度传感器,只是没有电线和热胶。 在“铃铛和哨子”中,这是一个用于空中闪烁的外部SPI闪存驱动器(需要DualOptibut引导程序才能运行,后来我停止将它们(闪存驱动器)放在电路板上,因为没有固件在空中,只有一半电池)和“加密麦克风” ATSHA204A,可以说是完整的硬件套件(在Mysensors中,用于激活签名,加密等,您只需要在草图的开头指定必要的#def即可)。

在观看了YouTube上的视频教程后,该板本身是由Diptrace程序制作的,起初看起来有些“怪诞”,但实际上并没有那么困难。 我在jlcpcb.com上在中国订购了木板,2美元,任何颜色,两周后,您已经可以得到10件“您自己的作品” :)。


下一步是身体的发展。 哦,原来是同样的问题。 通常,我没有寻找简单的方法,所以我决定精通Solid Works。 事实证明,这与Deeptrace根本不一样。 尽管如此,我还是推荐这位编辑进行研究。 学习过程持续了一个月,可以在YouTube上悠闲地观看视频课程,然后在编辑器中重复该课程。 在开发表壳的过程中,很明显,在不考虑未来表壳参数的情况下制作设备板是一个错误的决定,从这一系列中,我们将操纵杆插入了自己的轮子。 由于这些板的版本不同,考虑到该板的安装情况,总共推出了三块板,我认为这不是最后的选择。
在建筑物开发之初,其想法是在FDM 3D打印机上进行打印,但是越深入森林,就越清楚它无法复制我的所有心愿单。 到了理解的时候,我已经了解了另一种3D打印技术-SLA。 不用三思而后行,就对打印质量印象深刻,就发布了《 Ali-
ANYCUBIC Photon》上的愿望清单。 (链接ANA Ali,不是广告,不是会员,...只是链接)。
根据撰写本文时的经验,我现在就写,哦,这很酷! 当然,这种情况是在编辑器中设计的,并且不是第一次打印,并且有了很多改进。 好吧,可能不是这样。 结果,我得到了想要的结果。 非常微型的设备,一个很好的DIY盒,具有非常精确的细节,按钮,字体以及所有在头部中表示的东西。 后盖上增加了一块磁铁,现在可以轻松地将其安装在铁表面上。








这些是在FDM打印机上打印相同型号的尝试:


由于该设备虽然很小,但仍然很困难,所以我对用于编程的微型连接器的输出感到困惑。 因此,为连接器制作了一个小型适配器,以方便与编程器和TTL转换器连接。

一切都在Ali上购买(是的,不仅有完整的arduino模块)
贴片钽电容器4.7uF-4.7uF | 10v | 10%-C1
贴片陶瓷电容器100nF | Y5V-100nF | 50v | + 80-20%-C2,C3,C4,C5,C6,C7
LED-LED侧面-D1
排针母头-2x3P | 6pin | 1.27毫米-J1,J2
贴片电阻20K Ohm-20K | 5%-R1
贴片电阻4.7K Ohm-4.7K | 5%-R2,R3,R4
贴片电阻470K Ohm-470 | 1%-R5
贴片电阻1M Ohm-1M | 1%-R6
贴片电阻18K Ohm-18K | 5%-R7
贴片电阻10K Ohm-10K | 5%-R8
4针SMD侧面按钮-SW1,SW2
512Kbit,1.65V SPI串行闪存-AT25DF512C-SSHN-B-U1
迷你NRF24L01 + 2.4GHz 1.27MM射频-nRF24l01 1.27 SMD-U2
ATMEGA328P-MU QFN32-U3
加密认证,1线-ATSHA204A-STUCZ-T-U4
湿度和温度传感器IC-SHT20-U5
CR2477-1的电池座-L-KLS5-CR2477-1-U6
程序代码非常简单。 DFRobot库的示例用于SHT20传感器。 原则上,任何传感器的任何草图都可以在5分钟内转换为在Mysensors网络中工作的草图。
代码清单#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.