5 yıl boyunca üniversitemizde kağıt kurslar "eskileri al ve bir araya getir" ilkesine göre yapıldı. Bu yaklaşım bana rutin olarak uymuyordu, bu yüzden hemen donanımdaki dersi seçtim. Arduino mikrodenetleyicisi, öğrenme kolaylığı nedeniyle dersin kalbi olarak önerildi. Kursun türünü belirledikten sonra, bir soru daha vardı: tam olarak ne yapılmalı. Mikrodenetleyicileri programlama konusunda tecrübem olmadığı için hemen Google'ı açtım ve mevcut projeleri incelemeye başladım. Pek çok proje var, bazıları oldukça basit, bazıları ustaca (örneğin 3B tarayıcı), ancak büyük çoğunluğunun pratik bir uygulaması yoktu. Ve tam olarak neyin rafta yatıp orada toz toplamayacağını istedim. Arduino dünyasına yarım saatlik bir geziden sonra, evdeki hava istasyonları konusuyla ilgileniyordum ve projeleri uygulamak çok zor görünmüyordu (temelde yeni başlayanlara rüşvet veriyordu).
Dönem ödevi konusu bu şekilde seçildi ve zamanla sorunlar ana hatlarıyla belirtilmemiş gibi görünüyordu.
Bileşen seçimi
Farklı projelere baktığımda Nano'nun hatta Pro Mini'nin benim için yeterli olacağını fark ettim ama yine de Arduino için programlama yapmak istediğimi ve gelecekte daha fazla projeyi hayata geçireceğimi umarak Arduino Uno'yu seçtim. Daha önce ellerimde hiç lehim havyası tutmamıştım, bu yüzden daha kolay geliştirme için Sensor Shield v4'ü de satın almaya karar verdim.Daha fazla detay
Kart, sensörlerin, modüllerin, servo motorların, Seri ve I2C arayüzlerinin hızlı bir şekilde bağlanmasını kolaylaştırır ve ayrıca Duemilanova / Uno form faktörünün kontrolörünün tüm bağlantı noktalarını görüntüler (mega serisine de bağlanabilir, ancak kısıtlamalar ve ardından gelen sonuçlarla). Diğer kalkanları kendi başına destekler.
Meteorolojik veriler için kaynak olarak aşağıdaki sensörleri seçtim:
Sensörlere karar verdim. Ama sensörlerden gelen verilerle ne yapılmalı. Sergilemeye karar verdim. Renkli bir resim istedim, bu yüzden tek renkli çözümleri hemen attım. Birkaç dakikalık aramanın ardından 1,8 inç ST7735 TFT ekran seçildi.
Daha fazla detay
Ekran, iletişim için 4 telli bir SPI protokolü kullandığından ve kendi piksel adreslenebilir çerçeve arabelleğine sahip olduğundan, her türlü mikro denetleyici ile kullanılabilir. 1,8 inç ekran 128x160 renkli piksellere sahiptir. Ayrıca microSD hafıza kartı için bir yuva vardır, böylece bir microSD kartın FAT16 / FAT32 dosya sisteminden tam renkli bitmap'leri kolayca yükleyebilirsiniz.
Özellikler:
- Diyagonal ekran - 1,8 inç, çözünürlük 128x160 piksel, 18 bit renk (262,144 renk)
- Video belleği arabelleğinin yerleşik piksel adreslemesine sahip denetleyici
- Dahili microSD yuvası - 2'den fazla dijital hat kullanır
- 3.3 ve 5V ile uyumlu
- Boyutlar: 34 mm x 56 mm x 6.5 m
Arduino denetleyici programlama
Hava durumu istasyonunun bileşenlerine karar verdikten sonra, kontrolörü programlamaya başlayalım. Arduino IDE, Arduino'yu flaşlamak için kullanıldı. Ayrıca Adafruit'un kütüphanelerini kullandı.Taslağa geçmeden önce işlevselliği ele alalım:
- Sensörlerden her 10 saniyede bir okuma alınır ve sadece önceki ölçüme göre değiştirilen göstergeler ekranda güncellenir.
- COM bağlantı noktası üzerinden uygulanan veri aktarımı
Eskiz
#Dahil etmek
Davayı bir araya getirme zamanı
Kurs çalışmasının ana koşulu, prezentabl formda çalışan bir prototipti. Bu nedenle, bir dava satın almak zorunda kaldım ve bir dosyayla donanmış olarak, hava istasyonunu herhangi bir şekilde çantaya sokmak zorunda kaldım.Yerel bir elektronik mağazasından konut satın alındı.
Konut
(Fotoğrafta durum biraz farklı. Şeffaf kapağım var)
Ardından, bir dosya kullanarak sensörlerin çıkışını yapmak ve güç sağlamak için delikler açıldı. Sensörleri dışarı çıkarmaya karar verdim, çünkü sistemi kılıfsız test ederken ekranın arkasının çok ısındığını ve bunun kasanın içindeki sıcaklığı etkileyeceğini fark ettim.
Sensörler ve güç için delikli muhafaza
Bacakları 2 sensöre lehimlemek zorunda olduğum ve bunlardan birinin üzerindeki izi yaktığım için, kaderi kışkırtmamaya ve telleri sensörlere lehimlememeye karar verdim (başka bir şey üzerinde çalışacağım) ve bağlantının az çok güvenilir olması için geri sarmaya karar verdim elektrik bandı.
Muhafazaya "itmeden" önce sistem
Kasa Arduino'dan çok daha büyük olduğu için (daha küçük olanı yoktu), kartın kasanın içinde dolaşmaması için bir destek bulmam gerekiyordu. Ayrıca, kasanın içini gizlemek için paralondan bir figür ve içinde ekran için bir dikdörtgen kesildi. Elimde süper yapıştırıcı yoktu, bu yüzden çift taraflı bant üzerine oturmak zorunda kaldım.
Wonder Yuda balina balığı
Kapağı kapatıyoruz, güç kaynağını bağlıyoruz ve bekliyoruz.
Binadaki bitmiş hava durumu istasyonu
Sonuçları ekranda görüntüledikten sonra, nem ölçümünde hoş olmayan bir hata ortaya çıkardık: DHT22 kesinlikle% 99.90 rakamını veriyor (% 1.00 için oldukça nadirdir). Sorunun ne olduğunu anlamaya başlarız. İlk yaptığımız şey, değerlerin COM portuna çıkışına bakmaktır. İyi hissettiriyor. Kasanın birkaç kez yeniden doldurulmasından, demontajından ve montajından sonra, Google'da bir cevap aramak için düşünce aklıma geliyor. Beklendiği gibi, Rus Google etkili bir şey söylemedi. Tamam. İngilizce aramaya başladık ve forumlardan birinde benzer bir sorunu olan erkeklerle karşılaşıyoruz. Tartışmanın ilk dört sayfası pratik bir şey vermiyor, ancak beşinci sayfada sorumuzun cevabını buluyoruz:
Nem sensörleri, yanlış gazlardan veya yüksek nemli IIRC'ye çok uzun süre maruz kalmadan kolayca etkilenebilir. Veri sayfasında sensörün nasıl "sıfırlanacağı" ile ilgili bir prosedür vardır, deneyebilirsiniz.
Tek soru DHT22'ye ne zaman ve nasıl zarar vermeyi başardığımdı. Ama ders almanın zamanı gelmişti ve bu yüzden bu sorunun çözümünü daha sonraya bıraktım.
Sonsöz
Kurs başarılı oldu. Meteoroloji istasyonu, üniversitedeki tüm kuyruklar kapanana kadar süresiz olarak ertelendi. Ancak, tahmin ettiğimden daha erken meteoroloji istasyonuna dönmek zorunda kaldık. Öyle oldu ki, Kasım ayı ortasında iş yerimi değiştirdim ve yeni ekipte Arduino platformu ve benzerleriyle ilgilenen insanlarla tanıştım. Bu nedenle, bu platforma olan ilgim, soğumaya zamanım olmadığı için tekrar alevlendi. Hava istasyonumu çıkardım, bir bilgisayara bağladım ve COM portu üzerinden Arduino'dan veri aktarımı yaptığımı hatırladım. Ve sonra Arduino'dan COM portu üzerinden veri alan ve bu verileri kamusal izlemeye aktaran bir program yazma fikrini aldım.Sistemin ayrı parçalarını bir Arduino UNO'da test ettim. Şunlar. ESP modülünü UNO'ya bağladım ve inceledim, bağlantısını kestim, sonra nRF24'ü bağladım vb. Sensörün pencere dışındaki son uygulaması için minyatür olanlardan Uno'ya en yakın olan Arduino Pro Mini'yi seçtim.
Güç tüketimi açısından Arduino Pro Mini de iyi görünüyor:
- tek başına çok "yiyen" bir USB-TTL dönüştürücü yoktur,
- lED, 10k'lık bir direnç üzerinden bağlanır.
Gelişmiş enerji tasarrufu için planlandı:
- arduino Pro Mini üzerindeki LED - güç göstergesini çıkarın (kartı bozmadığım için pişman oldum)
- veya bir Atmel ATmega328 mikroişlemci üzerinde "çıplak" bir montaj kullanın (kullanılmıyor)
- düşük Güç Kitaplığını veya JeeLib'i kullanın.
Düşük Güç Kitaplığını kütüphanelerden seçtim, basit ve sadece gerekli olanı içeriyor.
Merkezi ünite için çok sayıda çevre biriminin bağlanması planlandığı için Arduino Mega kartı seçildi. Ek olarak, tamamen UNO uyumludur ve daha fazla belleğe sahiptir. İleriye baktığımda, bu seçimin tamamen haklı olduğunu söyleyeceğim.
Arduino Mega'yı yaklaşık 8 dolara satın alabilirsiniz.
Güç ve enerji tüketimi
Şimdi güç ve enerji tüketimi hakkında.
Arduino Pro Mini'nin iki çeşidi vardır:
- 5V besleme gerilimi ve 16MHz frekans için
- 3.3V besleme voltajı ve 8MHz frekans için.
NRF24L01 + radyo modülü güç kaynağı için 3,3 V gerektirdiğinden ve burada performans önemli olmadığından, 8MHz ve 3.3V'de bir Arduino Pro Mini satın alın.
Bu durumda, Arduino Pro Mini'nin besleme voltajı aralığı:
- 3,3V model için 3,35-12V
- 5V model için 5-12V.
Zaten 5V Arduino Pro Mini'm vardı, bu yüzden kullandım. Arduino Pro Mini'yi yaklaşık 4 dolara satın alabilirsiniz.
Merkezi ünite, çıkışta 12V, 450mA, 5W sağlayan küçük bir güç kaynağı ünitesi aracılığıyla 220 V'luk bir ağdan beslenecektir. 5 dolara böyle. Ayrıca 5V için ayrı bir çıkış vardır.
Ve bu yeterli değilse, o zaman daha güçlü koyabilirsiniz. Diğer bir deyişle, merkezi ünite için güç tasarrufu yapmak pek mantıklı değil. Ancak uzak bir kablosuz sensör için enerji tasarrufu en önemli kısımdır. Ama ben de işlevselliği kaybetmek istemem.
Bu nedenle, Arduino Pro Mini ve nRF24 radyo modülü, 4 Ni-Mh pil paketi ile çalıştırılacaktır.
Ve Hatırla modern bir pilin maksimum kapasitesi yaklaşık 2500-2700mAh, bunların hepsi ya pazarlama hileleri (Ansmann 2850) ya da aldatma (UltraFire 3500).
Li-Ion pilleri birkaç nedenden dolayı kullanmıyorum:
- çok pahalı
- ortam sıcaklığı 0 ° C'nin altına düştüğünde, lityum iyon pilin gücü% 40-50'ye düşer
- ucuz olanlar korumasız üretilir ve güvensizdir (kısa devre veya deşarj ile patlayabilir ve yanabilir, YouTube'da bir sürü video görebilir)
- kullanılmasalar bile yaşlanırlar (ancak bu tüm kimyasal elementler için söylenebilir), 2 yıl sonra Li-Ion pil kapasitesinin yaklaşık% 20'sini kaybeder.
Bir prototip için, yüksek kaliteli Ni-MH AA veya AAA pillerle idare etmek oldukça mümkündür. Dahası, büyük akımlara ihtiyacımız yok. Ni-MH pillerin tek dezavantajı uzun şarj süreleridir.
Meteoroloji istasyonunun genel şeması
Özetleyelim. İşte nasıl çalıştığına dair genel bir taslak.
Devam edecek.
Etiketler: Etiket Ekle
Meteoroloji istasyonumuzu geliştirmeye devam ediyoruz.
Güncellemeye geçmeden önce biraz açıklığa kavuşturmak istiyorum.
Meslektaşlarımızdan biri bana bekçi köpeğinin neden tanıtıldığını sordu.
Bekçi köpeği zamanlayıcısı acil durumda çalışır. Pratikte görüldüğü gibi, ENC28J60 aynı anda 4 bağlantı daha fazla çekmez (bellekte başarısız olmazsa). Ağın kendisinin işleyişini sürdürmek için kaç tane servis bağlantısı olduğunu ve sadece her türden ev oyuncağının yarattığı sol trafiği (örneğin, modern TV'ler ağdaki mevcut ana bilgisayarları tarar ve onlar için bağlantı noktalarını açar) göz önüne alındığında, tasarım basitçe bir sersemlik haline gelir. ENC28J60, ağ protokolleriyle nasıl bağımsız olarak çalışılacağını bilmez ve her şey kitaplıklarda uygulanır. Belki de onların içindedir.
Mevcut tüm kütüphaneleri ve farklı modülleri (aniden bir evlilik) kontrol ettim, ancak uzun süre istikrarlı bir çalışma yapamadım. Maksimum süre yaklaşık 3-4 haftadır.
Bunun için "köpek" orada dönüyor ve bu durumda kontrolör çekiliyor. Bundan sonra sorun ortadan kalktı.
Ayrıca, ev ağımda belirli nüanslar veya sorunlar olabileceğini de inkar etmiyorum. Ama bir sorunum olduğu için başka biriyle ortaya çıkabilir. Şimdiye kadar sadece böyle bir çözüm buldum.
Bildiğim kadarıyla, Wiznet çipleri (W5100 ve üstü) buna sahip değil ya da kötü görünüyorlardı.
Güncellemeye geçme
En önemlisi, çipi bırakıyoruz ENC28J60ve git W5100... Her şeyi eski bir yonga üzerinde uygulamaya çalıştım, ancak çok büyük kitaplıklar nedeniyle yeterli mikro denetleyici belleği yok. ENC28J60... Yeni bir çip kullanırken standartkütüphaneler geliştiriciden ve yapılan tüm değişikliklerden, daha da fazlası var 20% ücretsiz mikro denetleyici belleği ATMega328... Ve bu, yeni çörekler!
Bu sürüm (buna ikinci diyelim), frekansı kullanarak sensörlerden kablosuz olarak okuma iletme yeteneği ekledi. 433 MHz... Modülleri kendileri Çinlilerden aldım. XY-MK-5V... İletim kalitesinin mükemmel olmaktan uzak olduğunu belirtmek isterim. Sinyal kaybı, gürültü, aynı anda iletilememe vb. Mümkündür. Ancak fiyatları (set başına 1 dolardan az) bu dezavantajları telafi ediyor. Bu (en ucuz) modüllerin ev kullanımı için birçok markalı hava istasyonunda bulunduğunu size bir sır olarak anlatacağım. Vay canına, beklenmedik mi?
Baz istasyonundan başlayalım
Taşınıyoruz Arduino UNO ve Ethernet Kalkanı (ilk sürüm) çip tabanlı W5100... Bu bir sandviç ve onu tarif etmenin bir anlamı yok. Modüller için yalnızca ek olarak kullanılan kişileri açıklayacağım XY-MK-5V.
Verici modülü güç kullanıyor 5V, GND (o zaman annesiz nerede) ve D2 denetleyicideki pin. Kişiyi değiştir D2 (VERİ) işlevi kullanabilirsiniz vw_set_tx_pin vw kütüphanesinden.
Önceki taslaktan farklı olarak, bu iki ek kitaplık içerir:
#Dahil etmek
Çizimin kendisi
Gizli metin
#Dahil etmek
#Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #Dahil etmek #define DHTTYPE DHT22 #define DHTPIN 5 DHT dht (DHTPIN, DHTTYPE); bayt mac \u003d (0x54, 0x34, 0x31, 0x31, 0x31, 0x31); char server \u003d "narodmon.ru"; int bağlantı noktası \u003d 8283; IPAdresi ip (192,168,0,201); EthernetClient istemcisi; BMP085 dps \u003d BMP085 (); uzun Sıcaklık \u003d 0, Basınç \u003d 0; şamandıra H, dP, dPt; bool aralığı \u003d true; EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE (bayt kimliği; // Cihaz Kimliği int Sıcaklık; // Sıcaklık şamandıra Basıncı; // Basınç şamandırası Nem; // Nem şamandıra çiy noktası; // Çiğ / donma noktası); SEND_DATA_STRUCTURE yayını; void setup () (// Watchdog zamanlayıcısını başlatın wdt_disable (); delay (8000); wdt_enable (WDTO_8S); // Konsolu başlatın Serial.begin (9600); // DHT sensörünü başlatın dht.begin (); // 433 MHz modülü ET.begin (ayrıntılar (yayın)); vw_set_ptt_inverted (true); vw_set_tx_pin (2); vw_setup (2000); // DHCP sunucusundan veri beklemediysek ağı başlatın, o zaman // kendimize bir adres atayın if (Ethernet.begin (mac) \u003d\u003d 0) Ethernet.begin (mac, ip); // 1-Wire Wire.begin (); delay (200); // BMP180'i yükseklik düzeltme ile başlat // dps.init (MODE_STANDARD, 3200, true); // BMP180 dps.init (); Serial.println (Ethernet.localIP ()); // İlk veriyi, cihazı açtıktan hemen sonra gönder send_info (true);) // dewPoint fonksiyonu NOAA / / referans (1): http://wahiduddin.net/calc/density_algorithms.htm // referans (2): http://www.colorado.edu/geography/weather_station/Geog_site/about.htm double dewPoint (çift santigrat, çift nem) (// (1) Doygunluk Buhar Basıncı \u003d ESGG (T) çift ORAN \u003d 373.15 / (273.15 + santigrat); çift \u200b\u200bRHS \u003d -7.90298 * (ORAN - 1); RHS + \u003d 5.02808 * log10 (ORAN); RHS + \u003d -1.3816e-7 * (pow (10, (11.344 * (1 - 1 / ORAN))) - 1); RHS + \u003d 8.1328e-3 * (pow (10, (-3.49149 * (ORAN - 1))) - 1); RHS + \u003d log10 (1013.246); // faktör -3 birimleri ayarlamaktır - Buhar Basıncı SVP * nem çift VP \u003d pow (10, RHS - 3) * nem; // (2) DEWPOINT \u003d F (Buhar Basıncı) double T \u003d log (VP / 0.61078); // temp var return (241.88 * T) / (17.558 - T); ) void send_info (bool eth) (bool fail \u003d true; while (fail) (// Bir sonuç alana kadar DHT nem sensöründen veri okumaya çalışırız. Vakaların% 90'ında her şey yolunda gider, ancak 100'e ihtiyacımız var % if ((H \u003d dht.readHumidity ())\u003e \u003d 0) (// BMP180 sensöründen nem ve sıcaklık alınıyor dps.getPressure (& Pressure); dps.getTemperature (& Temperature); // Sıcaklık dışarıdaysa çiğ noktasını hesapla 0 santigrat derecenin üzerinde // ve 0'ın üzerinde bir sonuç bekliyoruz, aksi takdirde 0 çıktı. Kış mevsiminde // yanılmamak için bu gereklidir. // dP \u003d Sıcaklık\u003e 0? ((dPt \u003d çiy noktası (Sıcaklık * 0.1, H))<0?0:dPt):0; dP = dewPoint(Temperature*0.1, H); // Отправляем данные в эфир 433 мГц broadcast.ID = 1; broadcast.Temperature = floor(Temperature*0.1); broadcast.Pressure = floor(Pressure/133.3*10)/10; broadcast.Humidity = floor(H*10)/10; broadcast.dewPoint = floor(dP*10)/10; ET.sendData(); delay(250); if(eth) { // Подключаемся к серверу "Народный мониторинг" if(client.connect(server, port)) { // Начинаем передачу данных // адрес_устройства_в_проекте, имя_устройства, GPS широта, GPS долгота client.print(F("#fe-31-31-0e-5a-3b#Arduino Uno#71.344699#27.200014\n")); // Температура client.print(F("#T0#")); client.print(Temperature*0.1); client.print(F("#Температура\n")); // Давление client.print("#P1#"); client.print(Pressure/133.3); client.print(F("#Давление\n")); // Влажность client.print("#H1#"); client.print(H); client.print(F("#Влажность\n")); // Точка росы\инея client.print("#T1#"); client.print(dP); client.print((dP <= 0)? F("#Точка инея\n"):F("#Точка росы\n")); //client.print(F("#Точка росы\n")); // Отправляем конец телеграммы client.print("##"); // Даем время отработать Ethernet модулю и разрываем соединение delay(250); client.stop(); } } // Останавливаем цикл, если передача завершена fail = !fail; break; } delay(250); } } void loop() { // Каждые 4 секунды сбрасываем сторожевой таймер микроконтроллера // Каждые 6 минут отправляем данные на "Народный мониторинг" // Каждые 30 секунд отсылаем данные в эфир 433 if(!(millis()%1000)) wdt_reset(); if(!(millis()%360000)) send_info(true); if(!(millis()%30000)) send_info(false); }
Modüllere bir anten eklenmelidir. İçin 433 MHz yeterince uzun sıradan bir bakır tel 17 santimetre... Anten olmadan normal çalışmayı unutabilirsiniz.
Bu güncellemenin en önemli kısmına geçiyoruz - yerel kablosuz istasyon
Bunu uygulamak için (dizime) bir analog kullandım Arduino NANO (tabanda ATMega328) ve TFT çipte göster ST7735S izinle 128 x 160
Gizli metin
Pin çıkışı ekran -\u003e kontrolör
\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d LED | 3.3V SCK | SCK (13) SDA | MOSI (11) A0 | DC (9) SIFIRLA | RST (8) CS | CS (10) GND | GND VCC | 5V \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003dAlıcı modülü, yalnızca vericiyle aynı şekilde bağlanır. VERİ sabitlemek D7.
Nasıl göründüğüne dair birkaç resim:
Gizli metin
Alıcı çizimi
Gizli metin
#Dahil etmek
#Dahil etmek #Dahil etmek #Dahil etmek int x, y; int w \u003d 128, h \u003d 160; int boyutu; // 433 EasyTransferVirtualWire ET; struct SEND_DATA_STRUCTURE (bayt kimliği; // Cihaz Kimliği int Sıcaklık; // Sıcaklık şamandıra Basıncı; // Basınç şamandırası Nem; // Nem şamandıra çiy noktası; // Çiğ / donma noktası); SEND_DATA_STRUCTURE yayını; int Log_Temperature \u003d -1; float Log_Pressure \u003d -1; float Log_Humidity \u003d -1; float Log_dewPoint \u003d -1; // TFT #define cs 10 #define dc 9 #define ilk 8 karakter Sıcaklık, Basınç, Nem, çiy noktası; Dize bilgisi; TFT TFT ekranı \u003d TFT (cs, dc, rst); void setup () (Serial.begin (9600); // 433 MHz modülünü ET.begin (ayrıntılar (yayın)) başlatın; vw_set_ptt_inverted (true); vw_set_rx_pin (7); vw_setup (2000); vw_rx_start (); // Başlat ve ilk görüntü ayarı TFTscreen.begin (); TFTscreen.setRotation (2); TFTscreen.background (0, 0, 0); // Statik öğeler çizin // 1. Bizi ziyaret edin TFTscreen.stroke (255, 255, 255); TFTscreen.setTextSize (1); TFTscreen.text ("", 10, 10); // 2. Sensörlerden gelen okumaların açıklaması TFTscreen.text ("mmHg", w / 2 + 5, 80); TFTscreen.text ("%", w / 2 + 5, 100); TFTscreen.text ("C", w / 2 + 5, 120); yayın.Temperature \u003d 0; yayın.Basınç \u003d 0; yayın.Nem \u003d 0; yayın .dewPoint \u003d 0; TFTPrint ();) void loop () (if (ET.receiveData ()) (if (broadcast.ID \u003d\u003d 1) TFTPrint (); / * Serial.println (yayın.Temperature); Seri. println (broadcast.Pressure); Serial.println (broadcast.Humidity); Serial.println (broadcast.dewPoint); Serial.println (); * /)) void değişiklikleri (int boyut, int x , int y, bool up, bool clear \u003d false) (if (temizle) TFTscreen.stroke (0, 0, 0); else (değişiklikler (boyut, x, y,! yukarı, doğru); TFTscreen.stroke ((yukarı)? 0: 255, 0, (yukarı)? 255: 0);) if ((boyut% 2) \u003d\u003d 0 ) boyut ++; while (size\u003e 0) (TFTscreen.line (x, y, x + (size--), y); ++ x, (up)? - y: ++ y, --size;) / * while ( boyut\u003e 0) (TFTscreen.line (x, y, (yukarı)? x + boyut-1: x, (yukarı)? y: y + boyut-1); ++ x, ++ y, --size; ) * /) int x_center (int w, int length, int size) (return floor ((w-length * (size * 5) + size * 2) / 2);) int x_alignment_right (int w, int length, int size) (return ceil (w-uzunluk * (size * 5) + size * 2);) void TFTPrint () (size \u003d 3; // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d // Sıcaklık okumalarını görüntüleme // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d if (broadcast.Temperature! \u003d Log_Temperature) (TFTscreen.setTextSize (size); // Eski verileri sil String info \u003d String (Log_Temperature); info.concat ("C"); if (Log_Temperature\u003e 0) info \u003d "+" + bilgi; info.toCharArray (Sıcaklık, bilgi.uzunluk () + 1); TFTscreen.stroke (0, 0, 0); TFTscreen.text (Sıcaklık, x_center (w, bilgi.length () + 1 , boyut), 35); // Yeni okumaları görüntüle i info \u003d Dize (yayın. Sıcaklık); info.concat ("C"); eğer (yayın.Sıcaklık\u003e 0) bilgi \u003d "+" + bilgi; info.toCharArray (Sıcaklık, bilgi.uzunluk () + 1); // Sıcaklığın kendisine bağlı olarak sıcaklık değerinin rengini değiştirin int r, g \u003d 0, b; if (yayın.Sıcaklık\u003e 0) (r \u003d harita (yayın.Sıcaklık, 0, 40, 255, 150); // Kırmızı b \u003d harita (yayın.Sıcaklık, 0, 40, 30, 0); // Tonu değiştir sıfırdan daha görsel bir geçiş için) else (r \u003d map (yayın.Sıcaklık, -40, 0, 0, 30); // Sıfırdan daha görsel bir geçiş için tonu değiştirin b \u003d harita (yayın.Sıcaklık, -40, 0, 150, 255); // Mavi) TFTscreen.stroke (b, g, r); // UYARI: kitaplıkta renk konumları karıştırılır, RGB alanı BGR tarafından kullanılır! TFTscreen.text (Sıcaklık, x_center (w, info.length () + 1, size), 35); ) boyut \u003d 1; // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d // Basınç okumalarının göstergesi // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d if (broadcast.Pressure! \u003d Log_Pressure) (TFTscreen.setTextSize (size); // Eski verileri sil info \u003d String (Log_Pressure ); info.toCharArray (Pressure, info.length ()); TFTscreen.stroke (0, 0, 0); TFTscreen.text (Pressure, x_alignment_right (w / 2-5, info.length (), size), 80 ); // Yeni okumaları görüntüle info \u003d String (broadcast.Pressure); info.toCharArray (Pressure, info.length ()); TFTscreen.stroke (255, 255, 255); TFTscreen.text (Pressure, x_alignment_right (w / 2-5, info.length (), size), 80); değişiklikler (10, 106, 85, (broadcast.Pressure\u003e Log_Pressure)? True: false);) else (değişiklikler (10, 106, 85, true, doğru); değişiklikler (10, 106, 85, yanlış, doğru);) // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d // Nem okumalarını görüntüleyin // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d if (broadcast.Humidity! \u003d Log_Humidity) (TFTscreen.setTextSize (size); // Eski verileri sil info \u003d String (Log_Humidity); info.toCharArray (Nem, bilgi.uzunluk ()); TFTscreen.stroke (0, 0, 0); TFTscreen.text (Nem, x_alignment_right (w / 2-5, bilgi.length (), boyut), 100); // Yeni okumaları yazdır info \u003d String (broadcast.Humidity); info.toCharArray (Nem, bilgi.uzunluk ()); TFTscreen.stroke (255, 255, 255); TFTscreen.text (Nem, x_alignment_right (w / 2-5, bilgi.length (), boyut), 100); değişiklikler (10, 106, 105, (yayın.Nem\u003e Log_Humidity)? true: false); ) else (değişiklikler (10, 106, 105, doğru, doğru); değişiklikler (10, 106, 105, yanlış, doğru);) // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d // Çiy / don noktalarını görüntüleme // \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d if (broadcast.dewPoint! \u003d Log_dewPoint) (TFTscreen.setTextSize (size); // Eski verileri sil info \u003d String (Log_dewPoint); info.toCharArray (dewPoint, info.length ()); TFTscreen.stroke (0, 0, 0); TFTscreen.text (dewPoint, x_alignment_right (w / 2-5, info.length (), size), 120); // Yeni okumaları görüntüleme info \u003d String (broadcast.dewPoint); info.toCharArray (dewPoint, info.length ()); TFTscreen.stroke (255, 255, 255); TFTscreen.text (dewPoint, x_alignment_right (w / 2-5, info.length (), size), 120); değişiklikler (10, 106, 125, (broadcast.dewPoint\u003e Log_dewPoint)? True: false);) else (değişiklikler (10, 106, 125, true, true); değişiklikler (10, 106, 125, false, true);) // Okumaların sonraki karşılaştırması için günlüklerdeki değerleri güncelleyin Log_Temperature \u003d yayın.Sıcaklık; Log_Pressure \u003d broadcast.Pressure; Log_Humidity \u003d yayın. Nemlilik; Log_dewPoint \u003d broadcast.dewPoint; )
Göstergeler oldukça kısa bir şekilde sergileniyor, ancak uygulamanın gösterdiği gibi (ve yoldaşlarımın tavsiyesi) - "zevk ve renkte, karım bile arkadaş değil." Bir dizi tavsiye ve öneriyi dinledim, ancak birbirleriyle çelişiyorlar. Öyleyse beğeninize göre yapın.
Bana öyle geldi ki, tasarım, projenin çoğu zaman alan kısmı!
Gizli metin
Verilerin bir kısmı, bazı tasarım öğelerini göstermek için üretilmiştir.
Ekrandaki artefaktlar, ekranın içinde uzun süre biriken toz ve diğer kirlerdir ... orada bir yerde, ... peki, nereden aldığımı hatırlamıyorum! Beni yalnız bırak!
Çizim, konumlandırma işlevlerine sahiptir. Oldukça ilkeldirler, ancak belirli etkilere ulaşabilirler.
- x_center
- x_alignment_right
Birincisi metni ortalar ve ikincisi onu belirtilen alanın sağına hizalar. Tüm hesaplamalar, ifadeye göre belirtilen metnin boyutuna göre gerçekleştirilir. 1 boyut \u003d 1PX x 1PX yazı tipinin bölümü.
Ekran ayrıca okumaların bu veya değerinin artması veya azalmasına karşılık gelen öğeleri de gösterir. Üçgen olarak gösterilirler. Ama fonksiyon kodunda değişiklikler45 derece döndürülmüş üçgen şeklinde alternatif bir ekran var. Okuma yükselirse, öğe kırmızı, aksi takdirde mavidir.
Bu arada, ana sıcaklığın rengi ve gölgesi, sıcaklığın kendisine bağlı olarak değişir. Oldukça tartışmalı bir karar, ama bence görsel olarak rahat. Bir süre bunun için savaştım ve fonksiyondaki değerlerin inme, TFT görüntüleme nesneleri yanlış sırada listeleniyor. BGR bir yer RGB... Bu bir geliştiricinin hatası veya anlamadığım bir şey.
PS: Her şey oldukça ilginç ama bence daha fazla gelişmeyi hak ediyor. Bir süre sonra ne yapacağız?
Şehirde yürürken açılmış olan yeni bir elektronik mağazası gördüm. Girdikten sonra Arduina için çok sayıda kalkan buldum. Evde bir Arduino Uno vardı ve bir Arduino Nano hemen uzaktan sinyal vericileriyle oynama fikrini aldı. En ucuz 433 MHz verici ve alıcıyı almaya karar verdim:
Sinyal verici.
Sinyal alıcı.
Veri aktarımının en basit taslağını yazdıktan sonra (buradan bir örnek alınmıştır), verici cihazların sıcaklık, nem gibi basit verileri iletmek için oldukça uygun olabileceği ortaya çıktı.
Verici aşağıdaki özelliklere sahiptir:
1. Model: MX -FS - 03V
2. Etki yarıçapı (engelleyen nesnelerin varlığına bağlıdır): 20-200 metre
3. Çalışma voltajı: 3,5 -12V
4. Modül boyutları: 19 * 19 mm
5. Sinyal modülasyonu: AM
6. Verici gücü: 10mW
7. Frekans: 433 MHz
8. Gerekli harici anten uzunluğu: 25cm
9. Bağlanması kolay (yalnızca üç kablo): DATA; VCC; Dünya.
Modül özelliklerini alma:
1. Çalışma voltajı: DC 5V
2. Akım: 4mA
3. Çalışma frekansı: 433.92 MHz
4. Hassasiyet: - 105dB
5. Modül boyutları: 30 * 14 * 7 mm
6. Harici anten gerekli: 32 cm.
İnternetin genişliğinde 2Kb / s'deki bilgi aktarım aralığının 150m'ye kadar ulaşabileceği söyleniyor. Kendim kontrol etmedim, ancak iki odalı bir dairede her yeri kabul ediyor.
Ev hava istasyonu donanımı
Bazı deneylerden sonra Arduino Nano'ya bir sıcaklık, nem sensörü ve bir verici bağlamaya karar verdim.
DS18D20 sıcaklık sensörü arduino'ya aşağıdaki şekilde bağlanır:
1) Mikrodenetleyicinin eksisine GND.
2) DQ, bir çekme direnci üzerinden toprağa ve Arduino'nun D2 pinine
3) Vdd ila + 5V.
Verici modülü MX-FS - 03V, 5 Volt'tan güç alır, veri çıkışı (ADATA) D13 pinine bağlanır.
Arduino Uno'ya bağlı LCD ekran ve BMP085 barometre.
Arduino uno'ya bağlantı şeması
Sinyal alıcı, D10 pinine bağlanır.
BMP085 modülü, dijital bir atmosferik basınç sensörüdür. Sensör, sıcaklık, basınç ve yüksekliği ölçmenize olanak tanır. Bağlantı arayüzü: I2C. Sensör besleme voltajı 1,8-3,6 V
Modül, Arduino'ya diğer I2C cihazlarıyla aynı şekilde bağlanır:
- VCC - VCC (3.3V);
- GND - GND;
- SCL - analog pin 5'e;
- SDA - analog pin 4'e.
- Çok düşük maliyet
- Güç ve G / Ç 3-5V
- % 5 doğrulukla% 20-80 nem tayini
- 0-50 derece sıcaklık tayini. % 2 doğrulukla
- Örnekleme oranı 1 Hz'den fazla değil (1 saniyede bir defadan fazla değil)
- Boyutlar 15.5mm x 12mm x 5.5mm
- 4 pim aralığı 0,1 "
DHT'nin 4 iğnesi vardır:
- Vcc (3-5V güç kaynağı)
- Veri çıkışı - Veri çıkışı
- Kullanılmamış
- Genel
D8 Arduin'e bağlanır.
Ev hava istasyonunun yazılım bölümü
Verici modül sıcaklığı her 10 dakikada bir ölçer ve iletir.
Program aşağıdadır:
/ * Sketch version 1.0 Sıcaklığı her 10 dakikada bir gönder. * / #include #include #include #define ONE_WIRE_BUS 2 // Dallas OneWire oneWire sensörünü bağlamak için pin (ONE_WIRE_BUS); DallasTemperature sensörleri (& oneWire); DeviceAddress insideTermometer; void setup (void) (//Serial.begin(9600); vw_set_ptt_inverted (true); // DR3100 için gereklidir vw_setup (2000); // Baud hızı (bps) sensörlerini ayarlayın.begin (); if (! sensörler .getAddress (insideThermometer, 0)); printAddress (insideThermometer); sensörler.setResolution (insideThermometer, 9);) void printTemperature (DeviceAddress deviceAddress) (float tempC \u003d sensörler.getTempC (deviceAddress); //Serial.print("Temp C : "); //Serial.println(tempC); // int numarası göndermek için veri oluşturma \u003d tempC; char symbol \u003d" c "; // Bunun bir sensör olduğunu belirlemek için hizmet sembolü String strMsg \u003d" z "; strMsg + \u003d simge; strMsg + \u003d ""; strMsg + \u003d sayı; strMsg + \u003d ""; char msg; strMsg.toCharArray (msg, 255); vw_send ((uint8_t *) msg, strlen (msg)); vw_wait_tx (); / / Transferin gecikmeyi (200) sona erdirmesini bekliyoruz;) void döngüsü (void) (for (int j \u003d 0; j<= 6; j++) { sensors.requestTemperatures(); printTemperature(insideThermometer); delay(600000); } } //Определение адреса void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16); //Serial.print("0"); //Serial.print(deviceAddress[i], HEX); } }
Alıcı cihaz verileri alır, odadaki basınç ve sıcaklığı ölçer ve ekrana iletir.
#include # LiquidCrystal lcd (12, 10, 5, 4, 3, 2); #include dht11 sensörü; #define DHT11PIN 8 #include #include BMP085 dps \u003d BMP085 (); uzun Sıcaklık \u003d 0, Basınç \u003d 0, Yükseklik \u003d 0; void setup () (Serial.begin (9600); vw_set_ptt_inverted (true); // DR3100 için gereklidir vw_setup (2000); // Alma oranını ayarlayın vw_rx_start (); // Yayını izlemeye başlayın lcd.begin (16, 2); Wire.begin (); delay (1000); dps.init (); //lcd.setCursor(14,0); //lcd.write(byte(0)); //lcd.home ();) void loop () (uint8_t buf; // Mesaj için tampon uint8_t buflen \u003d VW_MAX_MESSAGE_LEN; // Tampon uzunluğu if (vw_get_message (buf, & buflen)) // Bir mesaj alınırsa (// Ayrıştırmaya başla int i; // Mesaj bize adresli değilse , exit if (buf! \u003d "z") (return;) char command \u003d buf; // Komut dizin 2'de // Sayısal parametre dizin 4'te başlar i \u003d 4; int sayı \u003d 0; // Aktarım karakter karakter olduğundan , daha sonra karakter kümesini bir sayıya dönüştürmeniz gerekir while (buf [i]! \u003d "") (sayı * \u003d 10; sayı + \u003d buf [i] - "0"; i ++;) dps.getPressure (& Pressure); dps.getAltitude (& Rakım); dps.getTemperature (& Temperature); //Serial.print(command); Serial.print (""); Serial.println (numara); lcd.print ("T \u003d"); lcd.setCursor (2.0); lcd.print (sayı); lcd.setCursor (5.0); lcd.print ("P \u003d"); lcd.print (Basınç / 133.3); lcd.print ("mmH"); lcd.setCursor (0,1); lcd.print ("T \u003d"); lcd.print (Sıcaklık * 0.1); lcd.print ("H \u003d"); lcd.print (sensor.humidity); lcd.home (); // gecikme (2000); int chk \u003d sensor.read (DHT11PIN); switch (chk) (case DHTLIB_OK: //Serial.println("OK "); break; case DHTLIB_ERROR_CHECKSUM: //Serial.println("Checksum error"); break; case DHTLIB_ERROR_TIMEOUT: //Serial.println("Zaman aşımı error "); break; default: //Serial.println("Unknown hata"); break;)))
Not: Gelecekte aşağıdakileri eklemeyi planlıyorum:
- vericiye nem sensörü, veri aktarım algoritmasını yeniden işleyin
- rüzgar hızı ve yönünü ölçmek için sensör.
- alıcı cihaza başka bir ekran ekleyin.
- alıcı ve vericiyi ayrı bir mikro denetleyiciye aktarın.
Aşağıda olanların bir fotoğrafını ekliyorum:
Radyoelementlerin listesi
Tanımlama | Bir tür | Mezhep | numara | Not | Puan | Benim defterim | |
---|---|---|---|---|---|---|---|
Gönderen kısım. | |||||||
Arduino kurulu | Arduino Nano 3.0 | 1 | Not defterine | ||||
Sıcaklık sensörü | DS18B20 | 1 | Not defterine | ||||
Direnç | 220 ohm | 1 | Not defterine | ||||
Verici modülü | MX-FS-03V (433 MHz) | 1 | Not defterine | ||||
Radyo alma kısmı. | |||||||
Arduino kurulu | Arduino Uno | 1 | Not defterine | ||||
Giyotin direnci | 1 | Not defterine | |||||
Direnç |
V. Petin'in "Arduino denetleyicisini kullanan projeler" 2. baskısından (Ek 2 proje 5) meteoroloji istasyonu projesi esas alınmıştır. Windows 10'da Arduino IDE 1.8.5'i kullandık.
Çizime başlarken bir hata aldım
İnternette, aynı ada sahip ancak farklı içeriğe sahip Arduino için kitaplıkları indirebilirsiniz. Yanlış kitaplığı kullanıyorsanız çizim çalışmayabilir. Görünüşe göre yanlış kütüphanelere rastladım. Atmosferik basıncı ölçmek için projeye bir BMP180 sensörü eklendi ve taslağı yeniden tasarladı.
Bağlantı şeması
Adres taranıyor
Önce BMP180 sensörünü ve LCD1602 göstergesini Arduino ya bağlayın. I2C tarayıcı taslağını derleyin ve I2C veriyolundaki cihazların adreslerini belirlemek için çalıştırın.
Program her 5 saniyede bir cihazları tarar ve adresleri COM portuna gönderir. 0x3F ve 0x77 adreslerine sahip iki cihaz buldum. BMP180 varsayılan olarak 0x77 adresine sahiptir, bu nedenle LCD göstergesinin adresi 0x3F'dir.
Bazı diyagramlarda kitaplar, SDA ve SCL sinyallerinin Arduino kartına bağlandığı yerlerle karıştırılır. Olmalıdır: SDA - A4, SCL - A5. BMP180'in beş pimi varsa, VIN pini +5 Volt ile sağlanır.
Bağlantı şeması
Şimdi devreyi tamamlayın. 150 ohm dirençlerle birlikte bir karta monte edilmiş ortak bir katot RGB LED kullandım. Ortak katot GND kontağına bağlanır, diğer pimler şemaya göre bağlanır. LED'lerin parlaklığı döngüsel bir şekilde değiştiğinden çizimde değişiklik yapmaya gerek yoktur.
Şema, kitapta olduğu gibi bir RGB LED'in ortak bir anotla bağlantısını göstermektedir.
LCD1602 ekranında hiçbir karakter görünmüyorsa, parlaklık kontrolünü çevirin. Gösterge arka ışığı oldukça fazla akım tüketir, bu nedenle en az 2 A akımlı bir güç kaynağı kullanın. Harici 2 A güç kaynağı olan bir USB hub kullandım.
Devrede ZP-22 piezo çan kullandım. Zile bağlı bir direnç 100 ohm'dur. Programda ses frekansı değiştirilebilir. 1000 Hz frekans seçtim. Sabit bir ses frekansına sahip bir zil sesiyle karşılaşırsanız, normal bir LED gibi basitçe voltaj uygulayıp çıkararak onu açıp kapatabilirsiniz. Çizim başladığında kısa bir bip sesi duyulur. // bzz (100) satırının açıklamasını kaldırarak program çalışırken periyodik sinyallemeyi etkinleştirebilirsiniz; taslakta.
Projede, halihazırda monte edilmiş 4,7 kOhm dirençli bir modül şeklinde bir DHT11 sensörü kullandım. Direnç 4,7 ila 10 kΩ arasında olabilir.
DS1302 saat modülünün Vcc pinini +5 Volt veriyoluna bağlayın. Bu, pilin tüketimini azaltacaktır, aslında sadece Arduino kapalıyken çalışacaktır.
Program (taslak)
Bmp085 kitaplığı BMP180'e hizmet vermek için kullanıldı. Basınç değeri arazinin yüksekliğine bağlıdır. Atmosferik basıncın doğru değeri için yüksekliği seçmeniz gerekir. Bunu yapmak için dps.init (MODE_STANDARD, 10000, true) satırını düzenleyin; Boyum 100 m (10000 cm). Basınç hesaplamasının bir parçası, bmp085 kitaplığının BMP085_test2.ino örneğinden alınmıştır.
Meteo_P taslağı
#Dahil etmek
#Dahil etmek
#Dahil etmek
#include "DHT.h"
#Dahil etmek
BMP085 dps \u003d BMP085 ();
uzun Basınç \u003d 0, Yükseklik \u003d 0;
işaretsiz uzun süre1 \u003d 0;
#define DHTPIN 10
#define DHTTYPE 11 // 11 - DHT11, 22 - DHT22
DHT dht (DHTPIN, DHTTYPE);
int kCePin \u003d 4; // RST DS1302
int kIoPin \u003d 3; // Veri DS1302
int kSclkPin \u003d 2; // CLK DS1302
DS1302 rtc (kCePin, kIoPin, kSclkPin);
int REDpin \u003d 9;
int GREENpin \u003d 6;
int MAVİpin \u003d 11;
LiquidCrystal_I2C lcd (0x3f, 16, 2); // adresinizi girin 0x20 ... 0xff adres
imzasız uzun memTime;
int bzzPin \u003d 8;
void HumTempRead () (
float hum \u003d dht.readHumidity ();
float temp \u003d dht.readTemperature ();
eğer (isnan (hum) || isnan (temp)) (
Serial.println ("DHT sensöründen okunamadı!");
lcd.setCursor (0, 1);
lcd.print ("H \u003d -% T \u003d ---");
lcd.setCursor (11, 1);
lcd.print ((karakter) 223);
lcd.setCursor (12, 1);
lcd.print ("C");
) Başka (
lcd.setCursor (0, 1);
lcd.print ("H \u003d");
lcd.setCursor (2, 1);
lcd.print (uğultu);
lcd.setCursor (4, 1);
lcd.print ("% T \u003d +");
lcd.setCursor (9, 1);
lcd.print (geçici);
lcd.setCursor (11, 1);
lcd.print ((karakter) 223);
lcd.setCursor (12, 1);
lcd.print ("C");
}
}
void setup_bzz () (
pinMode (bzzPin, OUTPUT);
}
void bzz (int _bzzTime) (
ton (bzzPin, 1000, _bzzTime); // frekans 1000 Hz
}
geçersiz kurulum () (
Serial.begin (9600);
Wire.begin ();
gecikme (1000);
dps.init (MODE_STANDARD, 10000, doğru); // 100 metre (cm cinsinden deniz seviyesinden yükseklik)
dht.begin ();
setup_bzz ();
bzz (100);
Lcd.init ();
lcd.backlight ();
lcd.home ();
// lcd.setCursor (0, 0);
rtc.halt (yanlış);
rtc.writeProtect (yanlış);
//rtc.setDOW(FRIDAY); // Haftanın Gününü CUMA olarak ayarlayın haftanın gününü ayarlayın
//rtc.setTime(4, 58, 0); // Saati 12:00:00 (24 saat biçimi) olarak ayarlayın, saati ayarlayın
//rtc.setDate(6, 8, 2010); // Tarihi 6 Ağustos 2010 olarak ayarlayın tarihi ayarlayın (gün, ay, yıl)
}
lcd.setCursor (8, 0);
lcd.print (rtc.getTimeStr ());
eğer ((millis () - memTime\u003e 2000) veya (millis ()< memTime)) { // DHT11/22 1 time each 2 seconds
HumTempRead ();
memTime \u003d milis ();
}
gecikme (100);
eğer (((milis () - zaman1) / 1000.0)\u003e \u003d 1.0) (
dps.calcTrueTemperature ();
zaman1 \u003d milis ();
}
dps.getPressure (& Pressure);
Seri.print ("Basınç (Pa):");
Serial.println (Basınç);
uzun p2;
int pi;
p2 \u003d (Basınç / 133.3224); // Pa, mm Hg cinsinden
pi \u003d kesik (p2); // sayının kesirli kısmını atın
lcd.setCursor (0, 0);
lcd.print ("P \u003d");
lcd.setCursor (2, 0);
lcd.print (pi); // çıktı atm. basınç LCD'de
lcd.setCursor (5, 0);
lcd.print ("mm");
// gecikme (3000);
// bzz (100); // sinyalleri dinlemek istiyorsanız yorum yapmayın
{
for (int değer \u003d 0; değer<= 255; value += 1) {
analogWrite (REDpin, değer);
analogWrite (YEŞİL pin, 255 - değer);
analogWrite (MAVİ pin, 255);
gecikme (5);
}
for (int değer \u003d 0; değer<= 255; value += 1) {
analogWrite (REDpin, 255);
analogWrite (YEŞİL pin, değer);
analogWrite (MAVİ pin, 255 - değer);
gecikme (5);
}
for (int değer \u003d 0; değer<= 255; value += 1) {
analogWrite (REDpin, 255 - değer);
analogWrite (YEŞİL pin, 255);
analogWrite (MAVİ pin, değer);
gecikme (5);
}
}
}
Dosya Kataloğunda, projede kullanılan taslak ve kitaplıkları indirebilirsiniz.
LiquidCrystal_I2C.zip, bmp085.zip, DS1302.zip ve DHT.zip kitaplıklarını indirilen arşivden Arduino IDE'ye aktarın. Menüye git Eskiz Kitaplığı bağla .ZIP kitaplığı ekle ... ve pencerede kütüphanenin zip arşivini seçin.
Taslağı meteo_P yükleyin. Çizimdeki LCD1602 adresini, I2C veriyolunu tarayarak elde edilen değerle değiştirin. Çizimi derleyin ve çalıştırın.
Çizim çalışıyorsa, bağlantı noktası monitörünü açın ve görünen mesajları görüntüleyin. Dps.init deyimini (MODE_STANDARD, 10000, true) kullanarak yüksekliği ayarlayın; gerçek basınç değerlerini elde etmek için.
Saati ayarlayın. //Rtc.setTime(4, 58, 0) satırının açıklamasını kaldırın; ve parantez içinde, geçerli saati (virgülle ayrılmış saat, dakika ve saniye) belirtin ve çizimi kontrolöre yeniden yükleyin. Zaman dolduktan sonra, bu satırı yeniden yorumlayın ve çizimi yeniden başlatın.
Gece ışığının aydınlatması sizi rahatsız ediyorsa, taslağın sonundaki for döngülerindeki gecikmenin uzunluğunu değiştirerek bunu özelleştirebilirsiniz. Gecikmeli (2); döngü gecikmeli olarak 2-3 saniye sürer (5); - gecikmeli 4 ila 5 saniye (30); - 15-16 saniyeye kadar. Gösterge üzerindeki bilgiler aynı aralıklarla güncellenecektir.
Meteoroloji istasyonunu bağımsız olarak kullanırken, örn. COM bağlantı noktası monitörüne bilgi çıkışını devre dışı bırakmak için bilgisayarın USB bağlantı noktasına bağlanmadan, taslakta Seri ... sözcükleriyle satırları yorumlayın.
PS. Kitabın taslağında ve DHT kütüphanesi örneklerinde tanım satırı belirtilmiştir. #define DHTTYPE DHT 11... Çizim başlıyor ancak birkaç saat sonra çöküyor. Saat durur, ekran değişmez. Bağlantı noktası monitöründe dht bağlantısıyla birlikte belirsiz bir mesaj belirir.
Bu satırdaki DHT harflerini kaldırdım, yani yapılmış #define DHTTYPE 11... Bundan sonra eskiz istikrarlı bir şekilde çalışmaya başladı.
Makale 25.06.2018 tarihinde güncellenmiştir.
Kullanılan kaynaklar
1. Petin V.A. Arduino denetleyicisini (Elektronik) 2. baskı, St. Petersburg kullanan projeler. BHV-Petersburg, 2015 464 s.
2. Petin V. A., Binyakovsky A. A. Arduino'nun Pratik ansiklopedisi. - M., DMK Press, 2017. - 152 s.
3. http://arduinolearning.com/code/i2c-scanner.php
4. http://arduino.ru/forum/programmirovanie/ds1302lcd1602
5. http://robotekhnika18.rf/how-connect-lcd-1602-k-arduino-po-i2c/
6. bmp085.zip kitaplığından örnek BMP085_test2.ino
7. http://proginfo.ru/round/
8. http://homes-smart.ru/index.php?id\u003d14&Itemid\u003d149&option\u003dcom_content&view\u003darticle
9. http://iarduino.ru/lib/datasheet%20bmp180.pdf
10. http://it-donnet.ru/hd44780_dht11_arduino/
Aspire bir 722 ağ sürücüsü
Windows'u optimize etmek ve hızlandırmak için yardımcı program
Fujitsu LIFEBOOK U554 Bağlantı Noktaları ve İletişim
BlueStacks android öykünücüsünde dil nasıl değiştirilir Bluestacks'ta İngilizce'ye geçmiyor
Samsung Galaxy S6 Edge incelemesi ve karşılaştırmaları