Setiap cuaca baik: indikator cuaca yang cosplay



Mari kita bayangkan bahwa setelah pertempuran dengan Dave Bowman, sisa-sisa kecerdasan HAL 9000 yang dulunya kuat sudah cukup untuk membawa Discovery One kembali ke Bumi dan, di bawah slogan "kematian untuk semua orang", hancurkan di planet ini, sehingga tidak ada lagi yang salah dengan melakukan hal ini dengan komputer.

Bencana alam yang meletus, tentu saja, menghancurkan semua umat manusia yang rasional, dan hanya orang-orang seperti saya yang tersisa, dengan palu di satu tangan dan Arduino di tangan lainnya. Oleh karena itu, tidak mengherankan bahwa perangkat misterius yang ditemukan oleh sisa-sisa misterius pesawat ruang angkasa yang ditemukan di gunung hanya dapat digunakan di stasiun cuaca. Yah, memang benar begitu!

Jika kita membuang romansa, maka kebenaran kehidupan yang keras adalah bahwa ITEAD yang terkenal menawarkan tampilan HMI NX4832T035 Nextion untuk pengujian .

Karena produk Nextion telah berulang kali dijelaskan di sini, ia ringkas tentang kemampuannya. Ini adalah layar dengan API dan panel sentuh sederhana untuk membuat unit kontrol dengan menu grafik tanpa banyak kesulitan.

Untuk tujuan ini, Nextion memiliki sistem perintah sederhana untuk menampilkan gambar (dan bagian-bagiannya), elemen teks, bidang input, grafik. Plus, ada semacam bahasa skrip untuk melakukan tindakan, misalnya, dengan menekan tombol di layar atau dengan penghitung waktu. Dan pada saat yang sama, port untuk menerima perintah eksternal dari mikrokontroler atau sejenisnya dan mengembalikan data tentang menyentuh layar untuk mengetahui tombol mana yang dimainkan oleh tangan pemilik yang lucu dan dalam kondisi apa tombol ini (ditekan, dilepaskan) saat ini.

Secara kasar, tidak perlu menderita dan mengumpulkan array poin atau menghubungkan cloud dari semua jenis perpustakaan. Satu baris - dan latar belakang telah berubah di layar. Diklik - menu terbuka. Kami terhubung Arduino - kami membuat grafik sesuai dengan data yang diterima melalui port serial.

Artinya, dilihat dari deskripsinya, layarnya sangat pintar sehingga bisa menunjukkan dan merespons (ada panel sentuh) untuk apa pun. Tapi saya tidak punya apa-apa di rumah, tetapi data iklim secara berkala terbang di udara. Dari BDS-M yang sama , misalnya, atau dari sensor cuaca PI-TV-2 .

Tentu saja, semuanya pada akhirnya ditransfer ke People's Monitoring , dari mana saya memiliki keberuntungan untuk menontonnya melalui peramban atau aplikasi di ponsel cerdas saya. Tetapi saya tidak bisa menolak ide untuk membuat "stasiun cuaca lain di Arduino".

Dan, jujur โ€‹โ€‹saja, itu bukan masalah teknologi seperti itu, tetapi fakta bahwa saya dengan keras kepala tertarik untuk merancang antarmuka. Mungkin, ia menarik dengan kekuatan yang sama dengan yang ia tarik untuk menyanyi semua orang yang beruang telah menginjak telinganya.

Oleh karena itu, saya segera meminta maaf atas fakta bahwa akan ada lebih sedikit peralatan lebih lanjut, dan lebih banyak fantasi fantasi. Tetapi pertama-tama, peragaan kecil dari produk jadi, yang menurutnya Anda dapat memutuskan, membaca, atau melanjutkan ke materi berikutnya.



Jadi, saya punya 3,5 inci, 480x320 piksel, yang sepertinya API yang cukup sederhana dan tujuh parameter yang perlu ditunjukkan (dalam kurung adalah sensor yang melekat pada ini):

1) Suhu di dalam dan di luar (BMP085 / DHT22)
2) Kelembaban di dalam dan luar (DHT22 / DHT22)
4) Tekanan atmosfer (BMP085)
5) Konsentrasi gas yang tidak terlalu berguna dalam ruangan, terutama CO2 (MQ135)
6) Konsentrasi padatan di udara ruangan, terutama PM2.5 (Sharp GP2Y1010AU0F)

Di sini harus dicatat bahwa kawan-kawan yang telah mengenal karakteristik dari dua sensor terakhir menyimpulkan bahwa respons terbesar dicapai hanya di bidang CO2 dan PM2.5, masing-masing. Ini, pada kenyataannya, menjelaskan pilihan saya: sayang untuk menghabiskan dua sen dan melihat apa yang terjadi, sementara sensor khusus jauh lebih mahal dan jika terjadi kegagalan, katak selalu memiliki sesuatu untuk ditampilkan.

Jelas bahwa saya tidak mengharapkan banyak akurasi dari sensor murah - melainkan, saya berharap untuk mengkorelasikan perasaan saya sendiri dengan bacaan mereka. Dan, omong-omong, semuanya sangat jelas: ada baiknya menutup jendela, karena pada saat yang sama dengan peningkatan suhu dan sesak, nilai konsentrasi gas dari MQ135 mulai merayap naik.

Namun untuk parameternya. Tampaknya membosankan bagi saya untuk hanya menampilkan tujuh digit, oleh karena itu, tugas teknis untuk perangkat diperluas: Saya membuat setiap parameter untuk menampilkan grafik perubahan dari waktu ke waktu. Sehingga pada satu layar dimungkinkan untuk melihat hingga empat kurva pada saat yang sama untuk persepsi visual pola (jika ada) dalam perubahan di berbagai indikator.

Pembaca yang perhatian dan pemilik perangkat portabel apa pun dengan diagonal 3,5 inci atau lebih, mungkin akan mengatakan bahwa tidak ada yang rumit dalam hal ini. Seperti, pada layar seperti itu dan lebih banyak data akan dengan mudah masuk.

Tetapi ada trik: untuk alat rumah tangga, jumlah dan tanda tangan harus sebesar mungkin sehingga mereka tidak harus melihat layar untuk waktu yang lama dalam kaca pembesar, mencoba menembus pikiran pikiran pencipta.

Secara umum, saya menginginkan antarmuka terbesar dan tidak terlalu berantakan, logika yang dapat dipahami tanpa pendidikan tinggi. Memiliki gambar seperti itu di kepalaku, aku memindahkannya ke editor Nextion dan mendapatkan dua jenis layar utama.

Layar utama dengan pembacaan sensor saat ini:




Selain bacaan aktual, Anda juga dapat melihat indikasi tren perubahan (naik / turun) dan penanda parameter yang dipilih untuk ditampilkan pada grafik. Kuadrat transparan adalah area sensorik yang tidak terlihat dalam pekerjaan.

Layar dengan grafik. Sebenarnya, ada empat dari mereka untuk ditampilkan dari satu hingga empat grafik, tetapi sebenarnya semuanya identik. Misalnya, layar dengan satu dan empat grafik:




Di sini, untuk setiap parameter, maksimum dan minimumnya juga ditampilkan untuk memahami batasan. Tetapi tidak ada garis waktu: pertama, perangkat tidak memiliki jam, dan kedua, tidak ada tempat untuk skala. Setidaknya saya tidak menemukan tempat untuk melampirkannya, mengingat bahwa saya ingin menunjukkan maksimum empat grafik.

Dalam hal ini, kode menyediakan untuk penambahan indikator yang diperoleh ke arsip setiap setengah jam dengan total kedalaman arsip dari 48 nilai, yaitu. sekitar satu hari. Kira-kira - karena data ditransmisikan melalui saluran radio 433 MHz, yang tidak terlindung dari interferensi, sehingga kesenjangan dimungkinkan.

Dan dalam kasus kesenjangan ini, waktu hidup sensor juga disediakan dalam setengah jam yang sama. Dan jika tidak ada penerimaan data dalam setengah jam, pembacaan sensor tidak ditampilkan dan tidak dimasukkan ke dalam arsip.

Tren dalam indikator dihitung oleh algoritma pertama yang menemukan enam poin terakhir dalam sejarah, mis. sesuai dengan enam indikasi terbaru. Dan karena pembacaan dilakukan pada interval setengah jam, ternyata tren mencerminkan perubahan selama tiga jam terakhir.

Seperti desainer lainnya, saya harus "bermain dengan font." Dalam proses menggambar opsi, ternyata kesimetrian favorit saya terpaksa dihancurkan tidak hanya oleh kombinasi indikator kelembaban di sudut kanan atas, tetapi juga oleh fenomena yang jauh lebih mengecewakan dalam bentuk suhu negatif.

Yaitu, minus merusak seluruh gambar. Karena itu, saya bertindak dengan cara saya sendiri: memberi nilai minus di atas nilainya. Untuk ahli matematika, ini, tentu saja, akan tampak seperti solusi biadab, dan mereka yang terlibat, tentu saja, akan tersentak tanpa sadar, merefleksikan mengapa stasiun cuaca harus dinilai dengan modulo. Namun ternyata cukup rapi dan jumlahnya tidak menari.

Logika antarmuka adalah sebagai berikut. Mode operasi utama adalah mode siaga dengan kecerahan layar 15% dari nilai nominal dan pembaruan bacaan yang teratur.

Sentuh di mana saja - daring dengan kecerahan 100%. Setelah ini, klik pada bacaan pilih mereka untuk tampilan selanjutnya pada grafik, dan mengklik "mata" HAL beralih ke layar dengan grafik.

Tepatnya ada lima detik untuk ini. Kemudian tanda dihapus, dan setelah lima menit tidak aktif lagi, perangkat beralih kembali ke mode siaga.

Pada layar bagan, bagian kiri adalah langkah mundur (layar utama atau layar dengan bagan), dan bagian kanan adalah peningkatan bagan yang dipilih dalam layar penuh atau, sekali lagi, pergi ke layar utama jika ada satu bagan.

Menurut saya skema ini cukup sederhana untuk tidak menambahkan tombol tambahan, yang tidak ingin saya lihat di sini.

Omong-omong, gambar latar belakang dapat diubah jika diinginkan. Saya bahkan menyiapkan beberapa opsi tambahan.

Untuk penjajah:


Untuk hobbit:


Untuk romantik:


Untuk pecinta kopi:


Secara konsep, seluruh perangkat ini bukan stasiun cuaca seperti layar nirkabel khusus. Oleh karena itu, desainnya sangat sederhana: hanya layar, Arduino Pro Mini dan penerima 433 MHz dengan modulasi amplitudo yang ada di dalamnya. Tidak ada fitur dalam perakitan sama sekali: layar untuk daya dan port serial, penerima adalah untuk daya dan pin 2 dari pengontrol. Dan, terlepas dari kebutuhan akan sensor eksternal yang kompatibel - itu saja.

Untuk memahami kesederhanaan, saya menunjukkan salah satu opsi perumahan dengan isian yang hampir terpasang:





Tentu saja, saya tidak menuntut konfigurasi seperti itu, tetapi dalam kasus saya itu optimal baik dalam hal tenaga dan kompatibilitas dengan komponen lain dari otomatisasi rumah.

Nah, pemisahan layar dan sensor memungkinkan Anda untuk menempatkan tampilan yang sama ini di tempat yang paling nyaman - seperti, pada kenyataannya, setiap stasiun cuaca dengan sensor eksternal.

Tentu saja, agar semua ini berhasil dan tidak menyebabkan kengerian hewan saat melihat gumpalan kabel, sekelompok sensor dan mikrokontroler yang menggantung di udara, Anda harus mencari tahu kasingnya.

Kebenaran kehidupan yang keras adalah bahwa kotak tempat tinggal BDS-M sampai sekarang tidak dapat mengakomodasi tiga sensor tambahan. Karena itu, saya memberikan perasaan dan mencetak lampu yang menakjubkan dari Markellov .

Dari sudut pandang sensor cuaca, ini sangat ideal, karena ditiup oleh semua angin dan pada saat yang sama secara efektif dan efektif menyembunyikan kekacauan di dalamnya. Setelah metamorf tersebut, BDS-M tidak ada lagi: sekarang glamor (jika Anda tidak mendekat) Multisensor:

Shell:



Rakitan dan terpasang:



Ternyata lebih sulit dengan unit display. Secara umum, saya ingin melihatnya agak besar dan brutal. Yah, tentu saja, seolah-olah orang asli yang telah menemukan bagian dari pesawat ruang angkasa membingkainya di atas batu. Oleh karena itu, frame, model yang sudah ditawarkan di Nextion, tidak cocok dengan cara apa pun. Pertama, itu menakutkan, dan kedua, layar berada dalam reses di sana, yang pasti tidak cocok untuk saya - saya ingin menyiram permukaan.

Saya mulai, bagaimanapun, dengan plastik - hanya untuk istirahat dalam bentuk. Pilihan antara terlihat seperti ini:



Secara umum, saya menyukainya (saya memutuskan untuk tidak melihat sedikit ketidakpuasan), tetapi bobotnya, tentu saja, cukup konyol, bukan batu. Oleh karena itu, salah satu bangunan digunakan sebagai bekisting internal untuk pembuatan "rangka" beton.

Proses itu mengejutkan saya sampai pada intinya - saya jarang membiakkan begitu banyak kotoran di rumah. Hasilnya sama. Meskipun di tempat-tempat itu ternyata tidak ada apa-apa, ternyata campuran perbaikan yang diperkuat tidak terlalu cocok untuk produk-produk tersebut.

Mungkin beton pasir murni akan ideal, tetapi pada saat ini saya sudah kecewa dengan keterampilan membangun saya sendiri dan berangkat seperti rekan saya. Dan dia, setelah berpikir sedikit, mengatakan bahwa dia memiliki kebahagiaan dalam hidupnya untuk bekerja dengan cat semprot di bawah batu.

Bingo, pikirku dalam hati, dan segera mulai mencabut perinciannya. Lagi pula, mencetak kasing dan mengecatnya jauh lebih estetis daripada mengubah rumah menjadi situs konstruksi ukuran penuh. Secara umum, cat itu sangat mahal, tetapi sangat keren (bagi mereka yang tertarik - Rust-Oleum American Accents Stone).

Sepanjang jalan, saya juga sampai pada kesimpulan bahwa saya tetap tidak suka korps dengan sesuatu (kemungkinan besar, dengan bingkai tebal di sekitar perimeter), jadi saya menyatukan diri dan, setelah diinterogasi dengan kecanduan, datang ke bentuk akhir yang tampaknya.

Itu adalah



:







Sangat mudah untuk melihat bahwa tidak ada jejak kebesaran, tetapi untuk beberapa alasan bentuk ini paling saya sukai. Saya akan memikirkannya. Sampai jumpa.

Pandangan, tentu saja, adalah amatir, karena beberapa jeroan layar (loop yang sama dari panel sentuh) sudah terlihat, dan tidak ada yang bisa dilakukan dengan ini dengan cara yang masuk akal. Tidak masuk akal, menurut saya, - overlay, cat, pita perekat.

Dan karena saya dicetak dengan plastik transparan, pada malam hari di ruang umum:



Sekarang tentang beberapa, katakanlah, nuansa desainnya. Saya akan mulai, mungkin, dari gedung yang sama. Keinginan untuk kecantikan memainkan lelucon buruk: karena saya ingin layar rata dengan permukaan, guntingan dibuat sebanyak mungkin sesuai dengan dimensi eksternal layar. Dan setelah sekitar selusin alat kelengkapan, ia mencapai tujuannya - baik mematahkan kabel panel sentuh, atau memutuskan kontak dengan papan, tetapi sekarang sangat sulit untuk mendapatkan sensor untuk bekerja.

Karena itu, saya mungkin tidak bisa merekomendasikan desain seperti itu. Yah, atau saya sarankan, tetapi perlu diingat bahwa ini adalah salah satu cara termudah dan paling indah (ya, saya berani menyanjung diri sendiri) untuk memecahkan layar.

Selain itu, saya harus membahas beberapa fitur layar itu sendiri, deskripsi yang saya pribadi dapat tajuk sebagai "Anda tidak bisa mengambilnya dan ...".

Jadi, orang tidak bisa hanya mengambil dan menampilkan font apa saja. Secara teori - ya. Setiap font Windows dapat diunduh ke konverter yang dibangun di lingkungan Nextion dan hasilnya akan berupa raster yang agak bergigi yang tidak terlihat terbaik.

Misalnya, bandingkan font yang dikonversi dengan yang asli:


Karena itu, saya harus menempuh jalan yang suram. Yaitu - untuk menyusun angka dan tanda tangan dari elemen grafis yang sebelumnya disiapkan di GIMP.

Lalu aku tersandung di tangga lagu. Ternyata Anda tidak bisa hanya mengambil dan memberi makan data sewenang-wenang yang diatur ke elemen Waveform yang dimaksudkan untuk menggambar kurva. Pertama, Anda perlu membawa semuanya ke format yang diperlukan - dari 0 hingga 255 dan menyelesaikan titik tengah, jika ada kurang dari lebar layar.

Nah, kemudian saya tahu bahwa itu belum semuanya. Ternyata 255 titik logis tidak diskalakan oleh tampilan ketika ketinggian elemen grafik Waveform berubah. Oleh karena itu, ketika mengubah ketinggian elemen grafik Waveform, perlu untuk mengubah skala nilai secara proporsional, jika tidak grafik akan "terpotong".

Namun, Anda tidak dapat menggunakan gambar dengan latar belakang transparan, yang agak membatasi lebar berguna bidang informasi - sehingga tidak ada tumpang tindih yang jelek di area gradien gambar latar belakang. Menurut pendapat saya, forum Nextion membahas hal ini dan tampaknya ITEAD berjanji untuk menambahkan kemampuan untuk bekerja dengan gambar transparan, tetapi belum melakukannya.

Ini, seperti siksaan saya dengan mengganti kecepatan port (yang diperlukan untuk menggambar grafik dengan cepat), tidak diragukan lagi, akan tampak konyol bagi kawan-kawan yang berpengalaman. Namun, saya tidak bisa diam - saya menghabiskan kekuatan yang pantas untuk diatasi.

Tapi secara keseluruhan saya merasa seperti pemenang. Apa yang saya inginkan - saya lakukan, dan koleksi peralatan rumah tangga diisi dengan yang lain. Selain itu, itu tidak sepenuhnya sia-sia: nyaman untuk segera melihat apa yang ditampilkan sensor rumah tanpa meraih smartphone dan tidak menyalakan komputer.

Plus, hal ini tidak tergantung pada Internet dan dalam konteks ini sepertinya perangkat anti-IoT, karena ia menyimpan semuanya dengan sendirinya. Dan kemudian saya membayangkan, seolah-olah beberapa peretas dengan selera humor yang aneh akan memotong stasiun cuaca saya dan membuatnya mengunci pintu.

Saya kemudian akan mengitari luar dengan permintaan seperti:

- Buka pintu ruang Pod, HAL

Benar, apakah itu lucu?

PS Dalam pembuatan perangkat dipandu oleh manual:

" Nextion HMI Solution
" FLProg + Nextion HMI. Pelajaran 1
ยป FLProg + Nextion HMI. Pelajaran 2
ยป FLProg + Nextion HMI. Pelajaran 3

Saya juga dapat menawarkan:

" Tata letak antarmuka untuk mengedit di Editor Nextion
"Tampilan Unduh File Antarmuka

Tampilkan Kode Bagian untuk Arduino
// v5:     Serial - Arduino, Serial1 - Nextion
// v6:  
// v7:     
// v8:      ( ,    ,  )
// v9:       DHT.h Adafruit
// v10:     ,      
// v11:    CO2/PM2.5
// v12:     , reDraw   statusBoolean = true
// ToDo:   40 ,     ,     (  )


#include <DHT.h>
#include <RCSwitch.h> //   http://code.google.com/p/rc-switch/
#include <MQ135.h> //    CO2

#define measurePin  A1  // analog
#define ledPower  12 // digital

#define samplingTime 280
#define deltaTime 40
#define sleepTime 9680

float voMeasured = 0;
float calcVoltage = 0;
float dustDensity = 0;
float ppm = 0;


#define analogPin A0 //   MQ135    A0 Arduino

MQ135 gasSensor = MQ135(analogPin); //   


//   



#define tempInX 10
#define tempOutX 380 // 415
#define humidityInX 320 //325
#define humidityOutX 410
#define pressureX 20 // 10
#define ppmX 20
#define pmX 370
#define Y0 0 //    
#define Y1 5 // , 
#define Y2 125 // 
#define Y3 230 // ppm&pm
#define dotY 125 //  
#define minusY 115// 

//    
#define minusXOut 380

//    
#define minusXIn 10

//  
#define minusH 3 

//    
#define minusPicID 2 

#define symbolID 1 //     

#define statusTimeOut 2200000 //  ""   (,       ) 900000
#define updateTimeOut 300000 //      60000 (300000)
#define historyTimeOut 1800000 //      (1800000)
#define selectionTimeOut 5000 //      
#define backLightTimeOut 300000 //      
#define waveLimit 254

int parameterS[7]; //  . : tempIn, tempOut, humidityIn, humidityOut, pressure, ppm, pm
byte statusS[7]; //         ( /  )
boolean statusBoolean[7]; //   

/*
//      
int coordinateX[7] = {tempInX, tempOutX, humidityInX, humidityOutX, pressureX, ppmX, pmX};
int coordinateY[7] = {Y2, Y2, Y1, Y1, Y1, Y3, Y3};
*/

//  
//  : tempIn, tempOut, humidityIn, humidityOut, pressure, ppm, pm
int historyArray[7][48]; // 7   48 
boolean drawArray[7]; //       
int arrayMax; //       
int arrayMin;
byte waveShift; //        waveform 0 - 255
float arrayNorm; //        

byte count=0; //    
byte arrayCounter; //   
byte waveCount; //    
int splitData[4]; //       [, , , ]
byte thousands, hundreds, tens, ones; //    
int tempIn, tempOut, humidityIn, humidityOut, pressure;
// int tempIn, tempOut, humidityIn, humidityOut, pressure, ppm, pm;
int symbolX0;
int posX; //    X  
byte tempInStatus, tempOutStatus, humidityInStatus, humidityOutStatus, pressureStatus, ppmStatus, pmStatus; //       StatusTimeOut
byte symbolCount, symbolWidth;
boolean minusIn = false; //   
boolean minusOut = false;
byte i = 0; //  
unsigned long statusTime, updateTime, historyTime, selectionTime, backLightTime;
String stringToNextion;
byte historyCount;
boolean backLight; //           

int weatherData = 0;
int dht22Humidity = 0;


//CLICKER VARIABLE SECTION
byte buffer[30]; // buffer for bytes coming from HMI.
byte waveCounter = 0; //    
// boolean drawArray[7]; //     
boolean allClear;
byte currentPage = 0; //   
byte searchTarget, searchNumber, searchCounter, pageNum, drawCounter, channelToDraw;
// int historyArray[7][48]; // 7   48 
// int arrayMax; //       
// int arrayMin;
// byte waveShift; //        waveform 0 - 255
// float arrayNorm; //        
byte iconCounter = 0;

// int splitData[4]; //       [, , , ]
// int posX; //    X  
// byte count = 0; //    
// String stringToNextion;
// int symbolX0;
// byte symbolCount;

//  
#define minusH 3 

//    
#define minusPicID 2 

//       
int axisX[5][7] = {{10, 380, 320, 410, 20, 20, 370}, //  0
               {0, 0, 0, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0},
               {0, 0, 0, 0, 0, 0, 0}}; //  1-4

int axisY[5][7] = {{115, 115, 5, 5, 5, 230, 230}, //  0
               {145,0, 0, 0, 0, 0, 0}, //  1
               {63, 226, 0, 0, 0, 0, 0}, //  2 
               {37, 145, 253, 0, 0, 0, 0 }, //  3
               {25, 105, 185, 265, 0, 0, 0}}; //  4


byte symbolW[5][11] = {{25, 15, 30, 25, 30, 30, 25, 30, 25, 30, 5},
                       {11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
                       {11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
                       {11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3},
                       {11, 6, 12, 12, 14, 13, 12, 13, 12, 12, 3}};//   0, 1, 2, 3, 4, 5, 6, 7, 8, 9

// {13, 7, 15, 13, 17, 15, 13, 14, 14, 14, 5}   25 Comfortaa Light

byte numberPic[5] = {1, 3, 3, 3, 3}; // ID   

byte symbolH[5] = {60, 18, 18, 18, 18}; //     25   25 Comfortaa Light

// CLICKER VARIABLE SECTION ENDS    

// TREND VARIABLE SECTION

#define x2 70 //    

int trendArray[3][6] = {{0, 0, 0, 0, 0, 0}, //    
                        {-5, -3, -1, 1, 3, 5},
                        {0, 0, 0, 0, 0, 0}};

int sumY, sumXY;
byte trendCount;
int trend; 

// TREND VARIABLE SECTION ENDS                  

#define DHTPIN 7
#define DHTTYPE DHT22

// Setup a DHT22 instance
DHT dht(DHTPIN, DHTTYPE);




// Setup RC-Switch
RCSwitch mySwitch = RCSwitch();


void sendToNextion() {
  Serial.write(0xff);
  Serial.write(0xff);
  Serial.write(0xff);
}



//      
void drawMark(byte mark, byte markNum) {

int markX;

//        
if (allClear == true) {
  allClear = false;
}

markX = axisX[0][markNum];

if (markNum == 1 || markNum == 3 || markNum == 6) {
  markX = 475;
} 

if (markNum == 0 || markNum == 4 || markNum == 5) {
  markX = 0;
}

if (markNum == 2) {
  markX = markX - 15;
}

    stringToNextion = String("fill ");
    stringToNextion = stringToNextion + String(markX); // String(axisX[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(axisY[0][markNum]+30); // String(axisY[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("5");
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("30");
    stringToNextion = stringToNextion + String(",");

if (mark == 1) {

    stringToNextion = stringToNextion + String("RED"); //     0, 0
    // Serial2.println("Mark set");

}

if (mark == 0) {

    stringToNextion = stringToNextion + String("BLACK"); //     0, 0
    // Serial2.println("Mark clear");

}

    // Serial2.println(stringToNextion);
    Serial.print(stringToNextion);
    sendToNextion();
  
}

//  :     
void clearSelection() {

  for (byte jj = 0; jj < 7; jj++) {
   if (drawArray[jj] == true) {
    drawArray[jj] = false;
    drawMark(0, jj);
   }
  }

  allClear = true; //   
  waveCounter = 0;
}





void updateHistory() {
mySwitch.disableReceive();

//   ,       -   ,       
for (arrayCounter = 0; arrayCounter < 7; arrayCounter++) {
  // Serial2.print("StatusBoolean for array #");// Serial2.print(arrayCounter);// Serial2.print(" = "); // Serial2.println(statusBoolean[arrayCounter]);
  if (statusBoolean[arrayCounter] == true) { //       
    for (i = 47; i > 0; i--) {
      historyArray[arrayCounter][i] = historyArray[arrayCounter][i-1]; // 
    }
    historyArray[arrayCounter][0] = parameterS[arrayCounter]; //  
  }

// statusBoolean[arrayCounter] = false; // ,       

  }

for (arrayCounter = 0; arrayCounter < 7; arrayCounter++) {
 for (i = 0; i < 47; i++) {
   // Serial2.print(historyArray[arrayCounter][i]);// Serial2.print(", ");
  }
 // Serial2.println();
}

// Serial2.println();  

mySwitch.enableReceive(0);
  
}



void drawTrend(byte arrayToTrend) {

int markX;

markX = axisX[0][arrayToTrend];

//   X   
if (arrayToTrend == 1 || arrayToTrend == 3 || arrayToTrend == 6) {
  markX = 472;
} 

if (arrayToTrend == 0 || arrayToTrend == 4 || arrayToTrend == 5) {
  markX = 0;
}

if (arrayToTrend == 2) {
  markX = markX - 15;
}

    stringToNextion = String("xpic ");
    stringToNextion = stringToNextion + String(markX); //   X
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(axisY[0][arrayToTrend]); //   Y
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("8"); //    7x18
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("18"); //
    stringToNextion = stringToNextion + String(",");

if (trend > 0) {


    stringToNextion = stringToNextion + String("0"); //    0
    stringToNextion = stringToNextion + String(","); // 
    stringToNextion = stringToNextion + String("0"); //  Y    0

  
}

if (trend < 0) {

    stringToNextion = stringToNextion + String("8"); //    5
    stringToNextion = stringToNextion + String(","); // 
    stringToNextion = stringToNextion + String("0"); //  Y    0
    
}

if (trend == 0) {

    stringToNextion = stringToNextion + String("16"); //     10
    stringToNextion = stringToNextion + String(","); // 
    stringToNextion = stringToNextion + String("0"); //  Y    0
 
}

    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("5"); // ID    
    // Serial2.println(stringToNextion);    
    Serial.print(stringToNextion);
    sendToNextion();
 
}



void splitRoutine(int input) {



input = abs(input); //      ,   

for (count = 0; count < 4; count++) {
  splitData[count] = 0; //   
}

count = 0;

if (input > 9999) { //     
  count = 5;
} else {

if (input > 999) { //  9999
  splitData[3] = input/1000;
  input = input - splitData[3]*1000;
  count = 4;
/*
  Serial.print("SplitData Count 4:");
  Serial.println(splitData[3]);
*/
}

if (input > 99) { //  999
  splitData[2] = input/100;
  input = input - splitData[2]*100;
  if (count == 0) {
    count = 3;
/*
  Serial.print("SplitData Count 3:");
  Serial.println(splitData[2]);
*/  
  }
}

if (input > 9) { //  99
  splitData[1] = input/10;
  input = input - splitData[1]*10;
  if (count == 0) {
    count = 2;
/*
  Serial.print("SplitData Count 2:");
  Serial.println(splitData[1]);
*/  
  }
} 

if (input < 10) {
  splitData[0] = input;
  if (count == 0) {
    count = 1;
/*
  Serial.print("SplitData Count 1:");
  Serial.println(splitData[0]);
*/  
  }
}

}
/*
  Serial.print("Input = ");
  Serial.println(input);
  Serial.print("Count = ");
  Serial.println(count);
*/

}




void drawRoutine(byte page, int value, byte type, int drawX, int drawY) { 

mySwitch.disableReceive();  
// page -  ; value = ; type =       ; drawX    X, drawY -  Y
  
  boolean minusSign = false;

  splitRoutine(value);  

if (page == 0) { //    
//   (  pm25)         ( 470 = 480 - 10)
  if (type == 1) { //   
    drawX = 470 - count*30 - 5; //       10      ,  30    + 5  
    if (count == 1) {
      drawX = drawX - 30; //   0,        
    }
  }

  if (type == 6) { //  pm25
    drawX = 470 - count*30 - 5; //       20      ,  30   
    if (count == 1) {
      drawX = drawX - 30;
    }
  }
}

  int posX = drawX;

 if (value < 0) {
  minusSign = true;
 }

 

 if (count < 5) { //    9999

  if ((count == 1) && ((type == 0) || (type  == 1) || (type  == 6))) { //    pm2.5     0,  0   
  // xpic X, Y, , , X, Y, 

    // 
    stringToNextion = String("xpic ");
    stringToNextion = stringToNextion + String(drawX); // String(axisX[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(drawY); // String(axisY[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(symbolW[page][0]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(symbolH[page]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String("0"); //     0, 0
    stringToNextion = stringToNextion + String(","); //     0, 0
    stringToNextion = stringToNextion + String("0"); //     0, 0
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(numberPic[page]);
   // // Serial2.println("Temp leading zero");
   // // Serial2.println(stringToNextion);
    Serial.print(stringToNextion);
    sendToNextion();
    drawX = drawX + symbolW[page][0]; //     0
      
   } // count = 1

   for (byte ii = count; ii > 0; ii--) { //   ,    

    if ((ii == 1) && ((type == 0) || (type == 1) || (type == 6))) { //  ,     
      stringToNextion = String("xpic ");
      stringToNextion = stringToNextion + String(drawX); // String(axisX[page, type]);
      stringToNextion = stringToNextion + String(",");
      stringToNextion = stringToNextion + String(drawY); // String(axisY[page, type]);
      stringToNextion = stringToNextion + String(",");
      stringToNextion = stringToNextion + String(symbolW[page][10]);
      stringToNextion = stringToNextion + String(",");
      stringToNextion = stringToNextion + String(symbolH[page]);
      stringToNextion = stringToNextion + String(",");
      if (page == 0) {
        stringToNextion = stringToNextion + String("265"); //        265
      } else {
        stringToNextion = stringToNextion + String("118"); //       135  Comfortaa Light 25
      }
      stringToNextion = stringToNextion + String(","); // 
      stringToNextion = stringToNextion + String("0"); //    Y    0
      stringToNextion = stringToNextion + String(",");
      stringToNextion = stringToNextion + String(numberPic[page]); 
     // // Serial2.println("Temp decimal dot");
     // // Serial2.println(stringToNextion);      
      Serial.print(stringToNextion);
      sendToNextion();
      drawX = drawX + symbolW[page][10]; //     
    } // ii == 1 && type == 0 || type == 1

    //       
    symbolX0 = 0; //       
    for (symbolCount = 0; symbolCount < (splitData[ii-1]);symbolCount++) { //     X    (   )
      symbolX0 = symbolX0 + symbolW[page][symbolCount];
    }

    stringToNextion = String("xpic ");
    stringToNextion = stringToNextion + String(drawX); // String(axisX[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(drawY); // String(axisY[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(symbolW[page][splitData[ii-1]]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(symbolH[page]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(symbolX0); //     0, 0
    stringToNextion = stringToNextion + String(","); //     0, 0
    stringToNextion = stringToNextion + String("0"); //     0, 0
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(numberPic[page]);
   // // Serial2.print("Symbol: "); // Serial2.println(splitData[ii-1]);
  //  // Serial2.println(stringToNextion);    
    Serial.print(stringToNextion);
    sendToNextion();
    drawX = drawX + symbolW[page][splitData[ii-1]];
  }

  if (minusSign == true) {

    /*
    symbolX0 = 0; //    
    for (byte ii = count; ii > 0; ii--) { 
      symbolX0 = symbolX0 + symbolW[page][splitData[ii-1]];
    }

    */
    
    stringToNextion = String("xpic ");
    stringToNextion = stringToNextion + String(posX); // String(axisX[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(drawY-8); // String(axisY[page, type]);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(drawX - posX);
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(minusH); //  
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(0); //     0, 0
    stringToNextion = stringToNextion + String(","); //     0, 0
    stringToNextion = stringToNextion + String("0"); //     0, 0
    stringToNextion = stringToNextion + String(",");
    stringToNextion = stringToNextion + String(minusPicID);
//    // Serial2.print("Symbol: "); // Serial2.println(splitData[ii-1]);
 //   // Serial2.println(stringToNextion);    
    Serial.print(stringToNextion);
    sendToNextion();
    
  }
  
 } // if count < 5    9999
  mySwitch.enableReceive(0);
}         

//     ( )
void getMinMax(byte arrayToMax, byte maxCount) {
  
byte getMaxCount = 0;

arrayMax = historyArray[arrayToMax][getMaxCount]; //      
arrayMin = historyArray[arrayToMax][getMaxCount]; //      

for (byte getMaxCount = 0; getMaxCount < maxCount; getMaxCount++) { // maxCount 47   , 6  
  
  if (historyArray[arrayToMax][getMaxCount+1] > arrayMax){ 
    arrayMax = historyArray[arrayToMax][getMaxCount+1];
  }

  if (arrayMin > historyArray[arrayToMax][getMaxCount+1]){ 
    arrayMin = historyArray[arrayToMax][getMaxCount+1];
  }
  
}
 
}      

void getTrend(byte arrayToTrend) {
mySwitch.disableReceive();
getMinMax(0, 6); //        


for (trendCount = 0; trendCount < 6; trendCount++) {
  if (arrayMin < 0) {
    trendArray[0][trendCount] = historyArray[arrayToTrend][5-trendCount] + abs(arrayMin); //    
  } else {
    trendArray[0][trendCount] = historyArray[arrayToTrend][5-trendCount];
  }
}

sumY = 0;
sumXY = 0;

//   ,   XY
for (trendCount = 0; trendCount < 7; trendCount++) {
  sumY = sumY + trendArray[0][trendCount];
  sumXY = sumXY + trendArray[0][trendCount]*trendArray[1][trendCount];
}

trend = (int) (sumY/10 + (sumXY/x2)*trendArray[1][5]) - (sumY/10 + (sumXY/x2)*trendArray[1][0])+0.5;

// Serial2.print("Trend: "); // Serial2.println(trend);

drawTrend(arrayToTrend);
mySwitch.enableReceive(0);
}

void reDraw() {
 mySwitch.disableReceive();

// Serial2.println("Redraw main page");
/*    
 for (i = 0; i < 7; i++) {
  parameterS[i] = random(255);
  statusS[i] = 1;
 }
    */ 

 Serial.print("page 0");
 sendToNextion();
 // Serial.print("pic 0,0,6");
 // sendToNextion();
 
 
 
  for (i = 0; i < 7; i++) {
   // Serial2.print("StatusBoolean on reDraw for item "); // Serial2.print(i); // Serial2.print(" is "); // Serial2.println(statusBoolean[i]);
   if (statusBoolean[i] == true) { //     " "
    drawRoutine(currentPage, parameterS[i], i, axisX[currentPage][i], axisY[currentPage][i]);
    // Serial2.print("Redraw, ");// Serial2.print(i); // Serial2.print(": "); // Serial2.println(parameterS[i]);
    if (historyCount > 5) {
      getTrend(i);
    }

   }
    
  }

 mySwitch.enableReceive(0);
}




void getNorm() {

arrayNorm = 1.00; //  1:1

  arrayNorm = abs(arrayMax - arrayMin);
  
    arrayNorm = waveLimit/arrayNorm; //   
  
}



void drawHistory(byte arrayCounter, byte waveCount){
mySwitch.disableReceive();
byte tC01 = 0;
byte tC02 = 0; 
int interPoint, lineMulti;
int justPoint;

  byte channelCount = 0; //   ,   (ID = 0),           

      getMinMax(arrayCounter, 47); //  47   ,  39,        ,   
 //     // Serial2.print("arrayMax: "); // Serial2.println(arrayMax);
 //     // Serial2.print("arrayMin: "); // Serial2.println(arrayMin);
      getNorm();
      
      if (currentPage == 2) {
         arrayNorm = arrayNorm*0.5;      
      }

      if (currentPage == 3) {
         arrayNorm = arrayNorm*0.3;      
      }

      if (currentPage == 4) {
         arrayNorm = arrayNorm*0.2;
      }

 //     // Serial2.print("arrayNorm: "); // Serial2.println(arrayNorm);   

     
     

//  
      stringToNextion = String("add "); //   
      stringToNextion = stringToNextion + String(waveCount); //    ID
      stringToNextion = stringToNextion + String(",");
      stringToNextion = stringToNextion + String(channelCount); //   0, 1, 2  3
      stringToNextion = stringToNextion + String(",");
      if (arrayMin < 0) {
        justPoint = (int) (historyArray[arrayCounter][tC01] + abs(arrayMin))*arrayNorm + 0.5;
        stringToNextion = stringToNextion + String(justPoint); //    
      } else {
        justPoint = (int) historyArray[arrayCounter][tC01]*arrayNorm + 0.5;
        stringToNextion = stringToNextion + String(justPoint); //    
      }
      Serial.print(stringToNextion);
      // // Serial2.print("First point, original");// Serial2.println(historyArray[arrayCounter][tC01]);
      // // Serial2.print("First point: "); // Serial2.println(stringToNextion);          
      sendToNextion(); 
                
        for (tC01 = 0; tC01 < 46; tC01++) { //   37  46
          
          lineMulti = (historyArray[arrayCounter][tC01+1] - historyArray[arrayCounter][tC01])/9; //         
          
          if (arrayMin < 0) {
            justPoint = (int) historyArray[arrayCounter][tC01] + abs(arrayMin) + lineMulti+0.5;
            interPoint = justPoint;
          } else {
            justPoint = (int) historyArray[arrayCounter][tC01] + lineMulti + 0.5;
            interPoint = justPoint;
          }
          
          for (tC02 = 0; tC02 < 7; tC02++) { //   ,  ,    9
            stringToNextion = String("add "); //   
            stringToNextion = stringToNextion + String(waveCount); //     (1, 2, 3  4 )
            stringToNextion = stringToNextion + String(",");
            stringToNextion = stringToNextion + String(channelCount); //   0, 1, 2  3
            stringToNextion = stringToNextion + String(",");
            justPoint = (int) interPoint*arrayNorm;
            stringToNextion = stringToNextion + String(justPoint);
            interPoint = (int) interPoint + lineMulti;
            Serial.print(stringToNextion);   
           // // Serial2.print("Connecting point: "); // Serial2.println(stringToNextion);                               
            sendToNextion();                      
          }
          stringToNextion = String("add "); //   
          stringToNextion = stringToNextion + String(waveCount); //     (1, 2, 3  4 )
          stringToNextion = stringToNextion + String(",");
          stringToNextion = stringToNextion + String(channelCount); //   0, 1, 2  3
          stringToNextion = stringToNextion + String(",");
          if (arrayMin < 0) {
            justPoint = (int) (historyArray[arrayCounter][tC01+1] + abs(arrayMin))*arrayNorm + 0.5;
            stringToNextion = stringToNextion + String(justPoint); //    
          } else {
            justPoint = (int) historyArray[arrayCounter][tC01+1]*arrayNorm + 0.5;
            stringToNextion = stringToNextion + String(justPoint); //    
          }
          
          Serial.print(stringToNextion);
         // // Serial2.print("Next/Last point, original: ");// Serial2.println(historyArray[arrayCounter][tC01+1]);               
          // // Serial2.print("Next/Last point: "); // Serial2.println(stringToNextion);               
          sendToNextion();                                  
        }
    
 mySwitch.enableReceive(0);   
  }
  






void drawIcon(int where, byte what) {

//// Serial2.print("Where: "); // Serial2.println(where);
//// Serial2.print("What: "); // Serial2.println(what);

stringToNextion = String("xpic ");
stringToNextion = stringToNextion + String("0"); // String(axisX[page, type]);
stringToNextion = stringToNextion + String(",");
stringToNextion = stringToNextion + String(where-3); // String(axisY[page, type]);
stringToNextion = stringToNextion + String(",");
stringToNextion = stringToNextion + String(80); //   
stringToNextion = stringToNextion + String(",");
stringToNextion = stringToNextion + String(30);
stringToNextion = stringToNextion + String(",");
stringToNextion = stringToNextion + String(what*80); //     X = 80*  
stringToNextion = stringToNextion + String(","); // 
stringToNextion = stringToNextion + String("0"); //   Y  0
stringToNextion = stringToNextion + String(",");
stringToNextion = stringToNextion + String(4);
//// Serial2.println(stringToNextion);
Serial.print(stringToNextion);
sendToNextion();
  
}



void toPage(byte pageNum) {
mySwitch.disableReceive();
currentPage = pageNum;

/*
//    
stringToNextion = String("ref page");
stringToNextion = stringToNextion + String(pageNum);
Serial.print(stringToNextion);
sendToNextion();
*/

//    
  String stringToNextion = String("page ");
  stringToNextion = stringToNextion + String(pageNum);
 // // Serial2.print("Switch to: "); // Serial2.println(stringToNextion);
  Serial.print(stringToNextion);
  sendToNextion();



if (pageNum == 0) {
  clearSelection();
  reDraw();
}

//        
  if (pageNum > 0) {

    
    if (pageNum == 1 && waveCounter > 1) { //           
 //     // Serial2.print("Draw single, searchCounter-1: "); // Serial2.println(searchCounter-1);
      getMinMax(searchCounter-1, 47); //      
  //    // Serial2.print("arrayMax: "); // Serial2.println(arrayMax);
  //    // Serial2.print("arrayMin: "); // Serial2.println(arrayMin);
      drawRoutine(pageNum, arrayMax, searchCounter-1, 0, 117); // 115
      drawIcon(145, searchCounter-1);
      drawRoutine(pageNum, arrayMin, searchCounter-1, 0, 185); // 175
      drawHistory(searchCounter-1, 1); //  :     
     } else {

              //  
              iconCounter = 0;
              for (drawCounter = 0; drawCounter < 7; drawCounter++) {
                if (drawArray[drawCounter] == true) {
        //          // Serial2.print("pageNum: "); // Serial2.println(pageNum);
       //           // Serial2.print("iconCounter: "); // Serial2.println(iconCounter);
      //            // Serial2.print("drawCounter: "); // Serial2.println(drawCounter);
                  getMinMax(drawCounter, 39); //   39  47
      //            // Serial2.print("arrayMax: "); // Serial2.println(arrayMax);
     //             // Serial2.print("arrayMin: "); // Serial2.println(arrayMin);
                  drawRoutine(pageNum, arrayMax, drawCounter, 0, axisY[pageNum][iconCounter]-22);   // -30               
                  drawIcon(axisY[pageNum][iconCounter], drawCounter);
                  drawRoutine(pageNum, arrayMin, drawCounter, 0, axisY[pageNum][iconCounter]+35); // +30
                  iconCounter++;
                }
            }      
              channelToDraw = 1; //      ,    ,   - 
              for (drawCounter = 0; drawCounter < 7; drawCounter++) { //   " "
                if (drawArray[drawCounter] == true) {
                  drawHistory(drawCounter, channelToDraw);
           //       // Serial2.print("drawCounter / channelToDraw "); // Serial2.print(drawCounter); // Serial2.print(" | "); // Serial2.println(channelToDraw);
                  channelToDraw++;
                 }
              }
      }
    }
    
  mySwitch.enableReceive(0);
}



void setup() {

  pinMode(ledPower,OUTPUT);
 // pinMode(measurePin, INPUT);

 pinMode(4, OUTPUT);
 digitalWrite(4, HIGH);



 
  currentPage = 0;
  allClear = true;
  historyCount = 0; //       
  backLight = true; //          ,   false
  
//     
//  . : tempIn, tempOut, humidityIn, humidityOut, pressure, ppm, pm
 for (i = 0; i < 7; i++) {
  parameterS[i] = 0;
  statusS[i] = 1;
 }

//   
for (arrayCounter = 0; arrayCounter < 7; arrayCounter++) {
 for (i = 0; i<48; i++) {
  historyArray[arrayCounter][i]=0;
 }
}
 
 statusTime = millis();
 updateTime = millis();
 historyTime = millis();
 backLightTime = millis();

 Serial.begin(9600);
  Serial.print("baud=57600");
  sendToNextion();
 Serial.end();

 Serial.begin(57600);
 Serial.print("baud=57600");
 sendToNextion();
 
 // Serial2.begin(115200);
 dht.begin();
 mySwitch.enableReceive(0);
 delay(2000);
 Serial.print("page 0");
 sendToNextion();
 // Serial2.println("Ready");
 
 reDraw();
}



void loop() {


//    

   if (mySwitch.available()) { //  
    int value = mySwitch.getReceivedValue();
    if (value != 0) {
    // Serial2.print("RC-Switch: "); // Serial2.println(mySwitch.getReceivedValue());
//    
      if (mySwitch.getReceivedValue() / 100000 == 161) {

        weatherData = mySwitch.getReceivedValue() - 16100000;
        if (weatherData > 10000) { //  
          parameterS[3] = (weatherData - 10000)/10;
          statusS[3] = statusS[3]+1;   
          statusBoolean[3] = true;  
        }
        else { //  
          if (weatherData > 1000) { //  
            parameterS[1] = -(weatherData - 1000);
            minusOut = true;
          }
          else { //  
            parameterS[1] = weatherData;
            minusOut = false;
          }
        }
          statusS[1] = statusS[1]+1;
          statusBoolean[1] = true;
      }

//    
      if (mySwitch.getReceivedValue() / 10000 == 1210) {
        parameterS[4] = (mySwitch.getReceivedValue() - 12100000) / 1.33; //  
        statusS[4] = statusS[4]+1;   
        statusBoolean[4] = true;   
        // Serial2.print("Pressure: "); // Serial2.println(parameterS[4]);     
      }

      if (mySwitch.getReceivedValue() / 100000 == 131) {
        weatherData = mySwitch.getReceivedValue() - 13100000;
        if (weatherData > 1000) { //  
          parameterS[0] = -(weatherData - 1000);
          minusIn = true;
        }
        else { //  
          parameterS[0] = weatherData;
          minusIn = false;
        }
          statusS[0] = statusS[0]+1;
          statusBoolean[0] = true;
      }

//        

      if (mySwitch.getReceivedValue() / 10000 == 1212) {
        parameterS[2] = (mySwitch.getReceivedValue() - 12120000); // 
        statusS[2] = statusS[2]+1;   
        statusBoolean[2] = true;   
        // Serial2.print("HumidityIn: "); // Serial2.println(parameterS[2]);     
      }
// CO2 PPM
      if (mySwitch.getReceivedValue() / 10000 == 1213) {
        parameterS[5] = (mySwitch.getReceivedValue() - 12130000); // CO2
        statusS[5] = statusS[5]+1;   
        statusBoolean[5] = true;   
        // Serial2.print("CO2 PPM: "); // Serial2.println(parameterS[5]);     
      }      
// PM2.5
      if (mySwitch.getReceivedValue() / 10000 == 1214) {
        parameterS[6] = (mySwitch.getReceivedValue() - 12140000); // PM2.5
        statusS[6] = statusS[6]+1;   
        statusBoolean[6] = true;   
        // Serial2.print("PM2.5: "); // Serial2.println(parameterS[6]);     
      } 

    }
    mySwitch.resetAvailable();
    //    mySwitch.enableReceive(0); //  RC Switch
  }   

  
//    
if (currentPage == 0) {
  if ((millis() - selectionTime) > selectionTimeOut) { 
    if (allClear == false) {
      clearSelection();
    }
  }
 }

  if (Serial.available())
  {
    bool moretocome = true;
    int endcount = 0;
    int bytesread = 0;
    byte inbyte;
    //bool isascii = false;

    while (moretocome)
    {
      inbyte = Serial.read();

        delay(2);
        
      if (inbyte == 0xFF)
      {
        endcount++;
        if (endcount == 3)
        {
          moretocome = false;
          // Serial2.println("");
        }
      }
      else
      {
        endcount = 0;
      }
      buffer[bytesread] = inbyte;
      bytesread++;

    }

    for (int x = 0; x < bytesread; x++)
    {
      // Serial2.print(buffer[x], HEX);
      // Serial2.print(" ");
    }

    //// Serial2.println(bytesread, DEC);
    // Serial2.println("");

  }

  if (buffer[0] == 101) { //   
   backLightTime = millis(); //        
   if (backLight == false) { //    ,   
    // Serial2.println("Backlight 50%");
    Serial.print("dim=100"); //  
    sendToNextion();
    backLight = true; //    
   } else { //     
    
    if (buffer[1] == 0) { //    
      selectionTime = millis();
      if (buffer[2] < 8) { //    
      if (waveCounter < 4) { //    4 
        if (drawArray[buffer[2]-1] == false) { //    
          drawArray[buffer[2]-1] = true; //    ,   
          drawMark(1, buffer[2]-1);
          waveCounter = waveCounter + 1; //       
     //     // Serial2.print("Set button: "); // Serial2.println(buffer[2]);          
     //     // Serial2.print("Total buttons: "); // Serial2.println(waveCounter);
        } else {
          drawArray[buffer[2]-1] = false; //     
          drawMark(0, buffer[2]-1);
          if (waveCounter > 0) {
            waveCounter = waveCounter - 1;
          }
     //     // Serial2.print("Clear button: "); // Serial2.println(buffer[2]);          
     //     // Serial2.print("Total buttons: "); // Serial2.println(waveCounter);          
        }
      } else { //     
        if (drawArray[buffer[2]-1] == true) { //    ,  
          drawArray[buffer[2]-1] = false; //     
          drawMark(0, buffer[2]-1);
          waveCounter = waveCounter - 1; //   
     //     // Serial2.print("Clear button: "); // Serial2.println(buffer[2]);          
     //     // Serial2.print("Total buttons: "); // Serial2.println(waveCounter);          
        }
      }
    } else { //      
        currentPage = waveCounter;
        toPage(waveCounter);    
      }
    }
    else { 
      if (currentPage > 1) { //      ,    ID = 5    0
        if (buffer[2] == 5) {
          toPage(0);
        }
      }

      if (currentPage == 1) { //   1   ,    ID = 5    0
        if (buffer[2] == 5) {
          if (waveCounter == 1) {
            toPage(0);
          } else {
            toPage(waveCounter); //       
          }
        }
      }

      if (currentPage == 1) { //    1     ID = 6 -          
        if (buffer[2] == 6) {
          toPage(0);
        }
      }      
      
      //   

    if (currentPage > 1) { //    1, .   1
      if (buffer[2] > 5) { //     ID > 2, ..  
   //     // Serial2.print("Buffer[2]: ");
   //     // Serial2.println(buffer[2]);
   //     // Serial2.print("Normalized button: ");
        searchTarget = buffer[2] - 5; // ""  ,     ,   :  1 -   -  true   drawarray   1
        searchNumber = 0;
        searchCounter = 0;
   //     // Serial2.println(searchTarget);

        while ((searchCounter < 7) && (searchNumber < searchTarget)) {
          if (drawArray[searchCounter] == true) {
            searchNumber++;
          }
          searchCounter++;
        }
        
   //     // Serial2.print("searchCounter: "); // Serial2.println(searchCounter);
        toPage(1); //      
      }
    }


      
     }
    }
  } 

buffer[0] = 0;

//    *Status   1   
//    

//  :       ,    9
if ((millis() - statusTime) > statusTimeOut) {

 
 for (i = 0; i < 7; i++) { //   
  // Serial2.print("Status of "); // Serial2.print(i); // Serial2.print(" is: "); // Serial2.println(statusS[i]);
    if (statusS[i] == 0) {statusBoolean[i] = false;
    // Serial2.print("As StatusS "); // Serial2.print(i); // Serial2.print(" is "); // Serial2.print(statusS[i]); // Serial2.println(" StatusBoolean set to false");
    }
    statusS[i] = 0; //    
 }
  statusTime = millis();
  
}

if (currentPage == 0) { //       

 
//    
if ((millis() - updateTime) > updateTimeOut) {

  reDraw();
  updateTime = millis();
 }

 
 
}

//         
if ((millis() - backLightTime) > backLightTimeOut) {
 if (backLight == true) {
  backLight = false;
  // Serial2.println("Backlight 15%");
  //Serial.print("page 0");
  // sendToNextion();
  currentPage = 0;
  clearSelection();
  reDraw();
  Serial.print("dim=15");
  sendToNextion();
 }
  
 }

//   
if ((millis() - historyTime) > historyTimeOut) {
  updateHistory();

    historyCount++;
    // Serial2.print("History Q: "); // Serial2.println(historyCount);
 
  historyTime = millis();
  }

}  



Model kasus (hati-hati - Anda dapat merusak layar)

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


All Articles