zoukankan      html  css  js  c++  java
  • 用arduino制作具有无线数据传输功能的气象站

    本项目是用arduino开源硬件,来快速制作具有无限数据传输功能的气象站,我之前做过一个带数据记录功能的气象站项目,这次算是升级和改进的版本。

     arduino制作具有无限数据传输功能的气象站

    第1步:构想

    首先,需要增加从气象站到室内接收器的无线数据传输功能,去掉了SD卡模块,换成Arduino Uno接口扩展板。

    这样做的主要原因是为了节省空间,接口扩展版完全兼容Arduino Uno,因此无需使用导线进行连接。气象站支架也进行了重新设计。之前的支架太低,而且不稳,所以我又做了一个新的支架(更高而且更稳)。对于直接安装到气象站支架上的外壳而言,我还增加了一个新的托架。此外,还增加了用于供电的太阳能板。

     arduino官网

    2步:原材料

    arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    硬件清单:

    在制作气象站支架时需要:

    • 大约3.4米长的钢管(或者钢板)。
    • 钢丝(大约4米)
    • 钢丝夹(8x)
    • 不锈钢螺丝扣(2x)
    • fi10钢棒(大约50厘米)
    • 钢吊环螺母(4x)

    您还将需要以下工具:

    • 烙铁
    • 螺丝刀
    • 钳子
    • 电钻
    • 焊机
    • 角磨机
    • 钢刷

    3步:小结

    如前文所述,本篇教程是对上篇气象站教程的升级。

    arduino制作具有无限数据传输功能的气象站

    如果您想了解如何组装气象站套件,请看组装视频:

     

    4步:气象站安装方案

    还有一个问题,那就是如何安装能够承受室外条件的气象站支架。

    关于气象站支架的类型和设计,我做了一些研究。最后我决定使用3米长的钢管来制作支架。通常建议将风速计安装到最高点(大约10米(33英尺)),但是由于我使用的是一体化气象站套件,我选择了套件建议的高度 - 大约3米(10英尺)。

    我考虑的主要问题是,这个支架必须模块化且易于拆卸,这样便于转移到其他位置。

    组装:

    1、先从fi18 3.4m(11.15ft)长钢管开始。在钢管上涂一层酸性除锈剂,对钢管进行除锈处理。

    2、2到3小时后,除锈完成,接着把钢管焊接起来。先把吊环螺母焊到钢管两端,然后把钢管放到距地面2米的位置。当然还可以放到更高的位置,但是不能更低,否则靠上的部分就会变得不稳。

    3、然后,需要在每一侧制作一个“锚”。为此我使用了两个fi12 50cm(1.64ft)钢棒。在每个钢棒的顶端焊上一个吊环螺母和一个小钢板,这样就可以把它踩到或用锤子砸到地里面。

    如图所示:

    arduino制作具有无限数据传输功能的气象站

    4、然后,使用钢丝把“锚”上的吊环连到支架两端。先拿来两根1.7 m(5.57ft)长的钢丝,一端用钢丝夹直接固定到吊环螺母上,另一端固定到不锈钢螺丝扣上。不锈钢螺丝扣用于紧固钢丝。

     arduino制作具有无限数据传输功能的气象站

    5、然后,使用一个3D打印托架将塑料接线盒安装到支架上。更多详情参见第5步。

    6、最后,对每一个钢制零件都涂上两层底漆。在此基础上,您可以涂上任何喜欢的颜色。

    5步:3D打印零件

    为使安装支架易于拆卸,需要制作一些3D打印零件。每一个零件都是我亲自设计并使用PLA塑料打印出来的。

    arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    塑料接线盒托架

    在上一篇教程中,我用钢板制作了托架,但是不是特别实用。所以我决定使用3D打印零件再做一个。一共有五个3D打印零件,损坏的零件可以快速更换。

    arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    有了这个托架,塑料接线盒就能直接安装到钢管上。安装高度也可以灵活调节。

    温湿度传感器外壳

    我需要为温湿度传感器设计一个外壳。在参考网上资料之后,我确定了这个外壳的最终形状。我设计了带托架的史蒂文森百叶箱,这样所有部件都可以安装到钢管上。 

    它一共包括10个零件。主体底座由两部分组成,顶部是一个“盖子”,这样就可以实现密封,不会进水。每一个零件都是使用PLA耗材打印而成。

    6步:室内数据接收器

    本项目的主要升级就是增加了无线数据传输功能。所以还需要增加一个室内数据接收器。

    为此,我使用了适合Arduino的430 MHz接收器,然后使用17厘米(6.7英寸)天线对其进行了升级。接着,需要测试一下该模块的通信距离。第一项测试在室内进行,以确定墙壁对信号范围的影响,以及会不会造成信号中断。第二项测试是在室外进行。结果表明,该模块的通信距离在10米(33英尺)以上,远远超出室内接收器的要求。

     arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    接收器所需零件:

    • Arduino Nano
    • Arduino 430 MHz接收器模块
    • RTC模块
    • LCD显示器
    • 一些接头

    如图所示,这个接收器可以显示室外温度和湿度、日期和时间。

    arduino制作具有无限数据传输功能的气象站

    7步:测试

    在将各零部件组装起来之前,必须进行一些测试。

    首先要测试Arduino的发送和接收模块。先得找到合适的代码,然后进行修改以使其符合项目需求。我从最简单的例子开始,从发射器向接收器发送一个字,测试成功之后再发送更多的数据。

    arduino制作具有无限数据传输功能的气象站

    arduino制作具有无限数据传输功能的气象站

    然后需要对这两个模块的范围进行测试。先把天线去掉,测试发现通信距离非常短,大约4米(13英尺)。然后把天线加上进行测试。通过相关研究和分析,我认为天线长度最好是17厘米(6.7英寸)。之后分别在室内和室外进行了测试,以确定环境对信号的影响。

    最后,将发射器置于室外,接收器置于室内,再进行测试,以确定能否实现良好的室内接收效果。最初有一些信号中断的问题,因为接收到的数据和发射的数据不一致。后来换上从ebay购买的433 Mhz模块天线,才解决了这个问题。

     arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站

    这个模块整体不错,因为非常便宜,而且简单易用,只不过由于存在信号中断问题,使用距离会受到一定的限制。

    代码:

    #include <SD.h>   //SD
    #include <SPI.h>  //SD
    
    File myFile;      //SD
    
    int pinCS = 10;
    ////////////
    //LCD
    #include <Wire.h> 
    #include <LiquidCrystal_I2C.h>
    
    #define BACKLIGHT_PIN 3
    
    LiquidCrystal_I2C lcd(0x20, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 
    ///////////
    int sensorPin = A0;    //battery voltage pin
    int sensorValue = 0;
    /////////////////// 
    int sensorPin_solar = A1;  //solar panel voltage pin
    int sensorValue_solar = 0;
    ////////////////
    
    char                 databuffer[35];
    double               temp;
    
    void getBuffer()                                                                    //Get weather status data
    {
      int index;
      for (index = 0;index < 35;index ++)
      {
        if(Serial.available())
        {
          databuffer[index] = Serial.read();
          if (databuffer[0] != 'c')
          {
            index = -1;
          }
        }
        else
        {
          index --;
        }
      }
    }
    
    int transCharToInt(char *_buffer,int _start,int _stop)                               //char to int)
    {
      int _index;
      int result = 0;
      int num = _stop - _start + 1;
      int _temp[num];
      for (_index = _start;_index <= _stop;_index ++)
      {
        _temp[_index - _start] = _buffer[_index] - '0';
        result = 10*result + _temp[_index - _start];
      }
      return result;
    }
    
    int WindDirection()                                                                  //Wind Direction
    {
      return transCharToInt(databuffer,1,3);
    }
    
    float WindSpeedAverage()                                                             //air Speed (1 minute)
    {
      temp = 0.44704 * transCharToInt(databuffer,5,7);
      return temp;
    }
    
    float WindSpeedMax()                                                                 //Max air speed (5 minutes)
    {
      temp = 0.44704 * transCharToInt(databuffer,9,11);
      return temp;
    }
    
    float Temperature()                                                                  //Temperature ("C")
    {
      temp = (transCharToInt(databuffer,13,15) - 32.00) * 5.00 / 9.00;
      return temp;
    }
    
    float RainfallOneHour()                                                              //Rainfall (1 hour)
    {
      temp = transCharToInt(databuffer,17,19) * 25.40 * 0.01;
      return temp;
    }
    
    float RainfallOneDay()                                                               //Rainfall (24 hours)
    {
      temp = transCharToInt(databuffer,21,23) * 25.40 * 0.01;
      return temp;
    }
    
    int Humidity()                                                                       //Humidity
    {
      return transCharToInt(databuffer,25,26);
    }
    
    float BarPressure()                                                                  //Barometric Pressure
    {
      temp = transCharToInt(databuffer,28,32);
      return temp / 10.00;
    }
    
    void setup()
    {
    
      lcd.begin (20,4);  
      lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
      lcd.setBacklight(HIGH);
      lcd.home ();
      //////////
      Serial.begin(9600);
      ////////
       pinMode(pinCS, OUTPUT);
      // SD Card Initialization
      if (SD.begin())
      {
        Serial.println("SD card is ready to use.");
      } else
      {
        Serial.println("SD card initialization failed");
        return;
      }
      //////////
    }
    void loop()
    { 
      //////////////////
      sensorValue = analogRead(sensorPin);                 //Monitoring battery voltage
      float voltage = sensorValue*(5.0/1023.0);
      lcd.setCursor(0,3); //0,3
      lcd.print("Voltage bat: ");
      lcd.print(voltage);
      lcd.print(" V");
      /////////////////
      sensorValue_solar = analogRead(sensorPin_solar);
      float voltage_solar = 2*sensorValue_solar*(5.0/1023.0)-0.07;
      Serial.println(voltage_solar);
     // lcd.setCursor(0,2);              //This is example how to set your LCD commands
    //  lcd.print("Voltage sol: ");
    //  lcd.print(voltage_solar);
    // lcd.print(" v");
    
      /////////////////////
      getBuffer();              //Begin!
      ///////
      if(WindDirection()==0){
        Serial.print("Wind Direction: ");
        Serial.print("SW");
        Serial.println("  ");
      }
      if(WindDirection()==45){
        Serial.print("Wind Direction: ");
        Serial.print(" W");
        Serial.println("  ");
      }
      if(WindDirection()==90){
        Serial.print("Wind Direction: ");
        Serial.print("NW");
        Serial.println("  ");
      }
      if(WindDirection()==135){
        Serial.print("Wind Direction: ");
        Serial.print(" N");
        Serial.println("  ");
      }
      if(WindDirection()==180){
        Serial.print("Wind Direction: ");
        Serial.print("NE");
        Serial.println("  ");
      }
      if(WindDirection()==225){
        Serial.print("Wind Direction: ");
        Serial.print(" E");
        Serial.println("  ");
      }
      if(WindDirection()==270){
        Serial.print("Wind Direction: ");
        Serial.print("SE");
        Serial.println("  ");
      }
      if(WindDirection()==315){
        Serial.print("Wind Direction: ");
        Serial.print(" S");
        Serial.println("  ");
      }
     // Serial.print("Wind Direction: ");
      //Serial.print(WindDirection());
     // Serial.println("  ");
      Serial.print("Average Wind Speed (One Minute): ");
      Serial.print(WindSpeedAverage());
      Serial.println("m/s  ");
      Serial.print("Max Wind Speed (Five Minutes): ");
      Serial.print(WindSpeedMax());
      Serial.println("m/s");
     // lcd.setCursor(0,0);
     // lcd.print("Max Speed");
     // lcd.print(" ");
      //lcd.print(WindSpeedMax());
     // lcd.print(" ");
     // lcd.print("m/s");
      Serial.print("Rain Fall (One Hour): ");
      Serial.print(RainfallOneHour());
      Serial.println("mm  ");
      Serial.print("Rain Fall (24 Hour): ");
      Serial.print(RainfallOneDay());
      Serial.println("mm");
      Serial.print("Temperature: ");
      Serial.print(Temperature());
      Serial.println("C  ");
     // lcd.setCursor(0,2);
     // lcd.print("Temperature: ");
     // lcd.print(Temperature());
     // lcd.print("C ");
      Serial.print("Humidity: ");
      Serial.print(Humidity());
      Serial.println("%  ");
      Serial.print("Barometric Pressure: ");
      Serial.print(BarPressure());
      Serial.println("hPa");
      Serial.println("");
      Serial.println("");
    
    
     
       ////
       myFile = SD.open("test.txt", FILE_WRITE);
      if (myFile) {    
         if(WindDirection()==0){
        myFile.print("Wind Direction: ");
        myFile.print("SW");
        myFile.println("  ");
      }
      if(WindDirection()==45){
        myFile.print("Wind Direction: ");
        myFile.print(" W");
        myFile.println("  ");
      }
      if(WindDirection()==90){
        myFile.print("Wind Direction: ");
        myFile.print("NW");
        myFile.println("  ");
      }
      if(WindDirection()==135){
        myFile.print("Wind Direction: ");
        myFile.print(" N");
        myFile.println("  ");
      }
      if(WindDirection()==180){
        myFile.print("Wind Direction: ");
        myFile.print("NE");
        myFile.println("  ");
      }
      if(WindDirection()==225){
        myFile.print("Wind Direction: ");
        myFile.print(" E");
        myFile.println("  ");
      }
      if(WindDirection()==270){
        myFile.print("Wind Direction: ");
        myFile.print("SE");
        myFile.println("  ");
      }
      if(WindDirection()==315){
        myFile.print("Wind Direction: ");
        myFile.print(" S");
        myFile.println("  ");
      }
     // myFile.print("Wind Direction: ");
     // myFile.print(WindDirection());
     // myFile.println("  ");
      myFile.print("Average Wind Speed (One Minute): ");
      myFile.print(WindSpeedAverage());
      myFile.println("m/s  ");
      myFile.print("Max Wind Speed (Five Minutes): ");
      myFile.print(WindSpeedMax());
      myFile.println("m/s");
      myFile.print("Rain Fall (One Hour): ");
      myFile.print(RainfallOneHour());
      myFile.println("mm  ");
      myFile.print("Rain Fall (24 Hour): ");
      myFile.print(RainfallOneDay());
      myFile.println("mm");
      myFile.print("Temperature: ");
      myFile.print(Temperature());
      myFile.println("C  ");
      myFile.print("Humidity: ");
      myFile.print(Humidity());
      myFile.println("%  ");
      myFile.print("Barometric Pressure: ");
      myFile.print(BarPressure());
      myFile.println("hPa");
      myFile.println("");
      myFile.println("");
      myFile.print("Voltage bat: ");
      myFile.print(voltage);
      myFile.println(" V");
      myFile.print("Voltage sol: ");
      myFile.print(voltage_solar);
      myFile.println(" V"); 
      
      
        myFile.close(); // close the file
      }
      // if the file didn't open, print an error:
      else {
        Serial.println("error opening test.txt");
      }
      delay(100);
    }
    

      

    总结

    arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站arduino制作具有无限数据传输功能的气象站

    这个项目从最初的想法变成最终的产品,整个过程非常有趣,也很有挑战性。你需要花时间思考不同的选项。所以,整个项目要顺利完成,就需要投入大量时间和精力,才能让它变成你真正想要的样子。

     但是类似的项目也提供了很好的机会,让你能够不断扩充升级在设计和电路方面的知识。此外,项目还包含了许多其他技术领域,比如3D建模、3D打印、焊接等等。所以,它不仅能让你了解某一个技术领域,更重要的是让你了解不同的技术领域如何交互作用,从而实现一个完整的项目。

    该项目设计简单,只要具备电路、焊接、研磨、设计等方面的基本技能,每个人都可以完成。最关键的要素还是时间。

  • 相关阅读:
    Android入门第六篇之ListView (一)
    mysql触发器的作用及语法
    查询记录时rs.previous()的使用
    Microsoft Visual C++ Runtime Library Runtime Error的解决的方法
    Ubuntu中编译链接Opencv应用的简便方式
    24点经典算法
    CMS系统简介(从简介到使用)
    编程学习资源
    Django是什么
    Thinkphp中的自动验证
  • 原文地址:https://www.cnblogs.com/esp32/p/iwoox.html
Copyright © 2011-2022 走看看