|
Arduino无线气象站代码
Arduino气象站室外设备的代码: - /*
- Arduino Wireless Communication Tutorial
- Outdoor unit - Transmitter
-
- by Dejan Nedelkovski, www.HowToMechatronics.com
- Libraries:
- NRF24L01 - TMRh20/RF24, https://github.com/tmrh20/RF24/
- DHT22 - DHTlib, https://github.com/RobTillaart/Arduino/tree/master/libraries/DHTlib
- LowPower - https://github.com/rocketscream/Low-Power
- */
- #include <SPI.h>
- #include <nRF24L01.h>
- #include <RF24.h>
- #include <dht.h>
- #include <LowPower.h>
- #define dataPin 8 // DHT22 data pin
- dht DHT; // Creates a DHT object
- RF24 radio(10, 9); // CE, CSN
- const byte address[6] = "00001";
- char thChar[32] = "";
- String thString = "";
- void setup() {
- radio.begin();
- radio.openWritingPipe(address);
- radio.setPALevel(RF24_PA_MIN);
- radio.stopListening();
- }
- void loop() {
- int readData = DHT.read22(dataPin); // Reads the data from the sensor
- int t = DHT.temperature; // Gets the values of the temperature
- int h = DHT.humidity; // Gets the values of the humidity
- thString = String(t) + String(h);
- thString.toCharArray(thChar, 12);
- // Sent the data wirelessly to the indoor unit
- for (int i = 0; i <= 3; i++) { // Send the data 3 times
- radio.write(&thChar, sizeof(thChar));
- delay(50);
- }
- // Sleep for 2 minutes, 15*8 = 120s
- for (int sleepCounter = 15; sleepCounter > 0; sleepCounter--)
- {
- LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
- }
- }
复制代码
代码描述:室外设备是无线通信的发射部分,因此首先我们需要包括RF24库、DHT库,以及用于将Arduino置于睡眠模式的LowPower库。 在定义了它们的实例,模块所连接的引脚和一些变量之后,在setup()函数中我们需要初始化无线通信地址。然后在loop()函数,首先我们读取DHT22传感器的数据(温度和湿度)。最初这些值是整数并且是分开的,因此我将它们转换为单个String变量,将它们放入字符数组中,并使用radio.write()函数将此数据发送到室内设备。使用for循环,我们发送数据3次,以确保接收器在发送时控制器忙时获得数据。 最后,我们将Arduino置于睡眠模式一段特定时间,以最大限度地降低功耗。
Arduino气象站室内设备代码: - /*
- Arduino Wireless Communication Tutorial
- Indoor unit - Receiver
- by Dejan Nedelkovski, www.HowToMechatronics.com
- Libraries:
- DS3231 - http://www.rinkydinkelectronics.com/library.php?id=73
- U8G2 - https://github.com/olikraus/u8g2
- */
- #include <SPI.h>
- #include <nRF24L01.h>
- #include <RF24.h>
- #include <dht.h>
- #include <DS3231.h>
- #include <U8g2lib.h>
- #include <Wire.h>
- #define dataPin 8 // DHT22 sensor
- dht DHT; // Creats a DHT object
- DS3231 rtc(SDA, SCL);
- U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
- RF24 radio(10, 9); // CE, CSN
- const byte address[6] = "00001";
- char text[6] = "";
- int readDHT22, t, h;
- String inTemp, inHum, outTemp, outHum;
- String rtcTime, rtcDate;
- int draw_state = 0;
- unsigned long previousMillis = 0;
- long interval = 3000;
- #define Temperature_20Icon_width 27
- #define Temperature_20Icon_height 47
- void setup() {
- radio.begin();
- radio.openReadingPipe(0, address);
- radio.setPALevel(RF24_PA_MIN);
- radio.startListening();
- u8g2.begin();
- rtc.begin();
- }
- void loop() {
- if (radio.available()) {
- radio.read(&text, sizeof(text)); // Read incoming data
- outTemp = String(text[0]) + String(text[1]) + char(176) + "C"; // Outdoor Temperature
- outHum = String(text[2]) + String(text[3]) + "%"; // Outdoor Humidity
- }
- unsigned long currentMillis = millis();
- if (currentMillis - previousMillis > interval) {
- previousMillis = currentMillis;
- u8g2.firstPage();
- do {
- switch (draw_state ) {
- case 0: drawDate(); break;
- case 1: drawInTemperature(); break;
- case 2: drawInHumidity(); break;
- case 3: drawOutTemperature(); break;
- case 4: drawOutHumidity(); break;
- }
- } while ( u8g2.nextPage() );
- draw_state++;
- if (draw_state > 4) {
- draw_state = 0;
- }
- }
- }
- void drawDate() {
- String dowa = rtc.getDOWStr();
- dowa.remove(3);
- rtcDate = dowa + " " + rtc.getDateStr();
- u8g2.setFont(u8g2_font_timB14_tr);
- u8g2.setCursor(0, 15);
- rtcTime = rtc.getTimeStr(); // DS3231 RTC time
- rtcTime.remove(5);
- u8g2.print(rtcDate);
- u8g2.setFont(u8g2_font_fub30_tf);
- u8g2.setCursor(8, 58);
- u8g2.print(rtcTime);
- }
- void drawInTemperature() {
- readDHT22 = DHT.read22(dataPin); // Reads the data from the sensor
- t = DHT.temperature; // Gets the values of the temperature
- inTemp = String(t) + char(176) + "C";
- u8g2.setFont(u8g2_font_helvR14_tr);
- u8g2.setCursor(24, 15);
- u8g2.print("INDOOR");
- u8g2.setFont(u8g2_font_fub30_tf);
- u8g2.setCursor(36, 58);
- u8g2.print(inTemp);
- u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
- }
- void drawInHumidity() {
- h = DHT.humidity; // Gets the values of the humidity
- inHum = String(h) + "%";
- u8g2.setFont(u8g2_font_helvR14_tr);
- u8g2.setCursor(24, 15);
- u8g2.print("INDOOR");
- u8g2.setFont(u8g2_font_fub30_tf);
- u8g2.setCursor(36, 58);
- u8g2.print(inHum);
- u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
- }
- void drawOutTemperature() {
- u8g2.setFont(u8g2_font_helvR14_tr);
- u8g2.setCursor(12, 15);
- u8g2.print("OUTDOOR");
- u8g2.setFont(u8g2_font_fub30_tf);
- u8g2.setCursor(36, 58);
- u8g2.print(outTemp);
- u8g2.drawXBMP( 0, 17, Temperature_20Icon_width, Temperature_20Icon_height, Temperature_20Icon_bits);
- }
- void drawOutHumidity() {
- u8g2.setFont(u8g2_font_helvR14_tr);
- u8g2.setCursor(12, 15);
- u8g2.print("OUTDOOR");
- u8g2.setFont(u8g2_font_fub30_tf);
- u8g2.setCursor(36, 58);
- u8g2.print(outHum);
- u8g2.drawXBMP( 0, 17, Humidity_20Icon_width, Humidity_20Icon_height, Humidity_20Icon_bits);
- }
复制代码
代码描述:在另一侧,室内设备或接收器,我们需要包括两个库,一个用于DS3231实时时钟模块,另一个用于OLED显示器 -U8G2库。 与前一个一样,我们需要为下面的程序定义实例,引脚和一些变量。 此外,我们还需要将温度和湿度图标定义为位图。
温度图标位图: - #define Temperature_20Icon_width 27
- #define Temperature_20Icon_height 47
- static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00,
- 0xc0, 0xe1, 0x00, 0x00, 0xe0, 0xc0, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
- 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x79, 0x00,
- 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0xf9, 0x03,
- 0x60, 0x80, 0x01, 0x00, 0x60, 0x80, 0x01, 0x00, 0x60, 0x8c, 0x79, 0x00,
- 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
- 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x79, 0x00,
- 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0xf9, 0x03,
- 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00, 0x60, 0x9e, 0x01, 0x00,
- 0x70, 0x9e, 0x03, 0x00, 0x38, 0x1e, 0x07, 0x00, 0x18, 0x3e, 0x0e, 0x00,
- 0x1c, 0x3f, 0x0c, 0x00, 0x0c, 0x7f, 0x18, 0x00, 0x8c, 0xff, 0x18, 0x00,
- 0x8e, 0xff, 0x38, 0x00, 0xc6, 0xff, 0x31, 0x00, 0xc6, 0xff, 0x31, 0x00,
- 0xc6, 0xff, 0x31, 0x00, 0x8e, 0xff, 0x38, 0x00, 0x8c, 0xff, 0x18, 0x00,
- 0x0c, 0x7f, 0x1c, 0x00, 0x3c, 0x1c, 0x0e, 0x00, 0x78, 0x00, 0x06, 0x00,
- 0xe0, 0x80, 0x07, 0x00, 0xe0, 0xff, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00,
- 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
复制代码
我们可以使用GIMP,一个开源图像编辑器,通过它我们可以绘制任何东西,然后将其导出为位图(.xbm)。
然后我们可以使用记事本打开这个文件,将位图复制到Arduino代码中。 请注意,在这里我们可以使用PROGMEM变量修饰符将位图定义为常量,这样位图将存储在闪存而不是Arduino板的SRAM中。 - static const unsigned char Temperature_20Icon_bits[] U8X8_PROGMEM // Save in the Flash memory
- static unsigned char Temperature_20Icon_bits[] // Save in the SRAM
复制代码
在setup函数中,我们需要初始化无线通信以及初始化OLED显示器和实时时钟模块。 然后在loop函数,我们不断检查是否有通过NRF24L01模块读取的输入数据。如果为true,则使用radio.read()函数读取它,并将前两个字符存储到温度String变量中,将接下来的两个字符存储到湿度String变量中。 然后我们使用millis()函数,以显示间隔变量定义的显示器上的各种数据,我将其设置为3秒。我们使用millis()函数,因为以这种方式可以重复执行其余代码,而且如果使用delay()函数,程序会等待那段时间,这样我们可能会错过从室外设备传入的数据。 接下来,使用U8G2库的firstPage()和nextPage()函数,我们打印使用自定义函数定义的五个不同界面。 drawDate()自定义函数从实时时钟模块获取日期和时间信息,并将其正确打印在显示器上。 drawInTemperature()函数读取室内温度并在显示屏上正确显示。实际上,在显示器上的所有屏幕的打印采用相同的方法。
以上就是本篇文章的全部内容,我希望你喜欢这个Arduino项目,并学到一些新东西。如果遇到问题,请随时在本帖下面进行回复。
|