【基于物联网的终端水产养殖系统 】-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4553|回复: 1

【基于物联网的终端水产养殖系统 】

[复制链接]
发表于 2017-4-12 11:23 | 显示全部楼层 |阅读模式
今天又给大家带来了一篇开源帖子了,这是我们团队上次参加one net创新赛荣获二等奖的项目作品,原创发于one net 官网论坛http://open.iot.10086.cn/bbs/thread-1154-1-1.html,在这次比赛中收获很多,发于本论坛希望有更多的人来一起学习研究!

一、简介:

    针对目前我国水产养殖规模越来越大,种类越来越丰富,传统养殖方式已不能满足要求的现状,“互联网+”必将带动农业的升级。本作品将物联网技术相结合应用到水产养殖领域,设计了水产养殖智能化系统的架构及应用实施方案。分为现场管理单元、远程管理单元、云平台(OneNET)三个部分。

二、主要功能:
1、通过PH传感器、溶解氧传感器、温度传感器、光照传感器,(还可以增加对水体检测的各种传感器,因为价格太高目前楼主只用了这几个传感器)。在任何终端(登录OneNET云平台)上都可以查看水体的实时数据。
2、有对水产,实时的视频监控(无线传输,随处访问)。
3、能自动对水体的PH调节,供氧,补充光亮,投饵。

三:作品整体效果:



1、所用到的传感器:除光照传感器外,其他三种传感器输出的是4~20mA的电流信号,而我们需要取5v电压信号作为输出。因此需要用到电压转换器LM324,将电流转换为电压,大家在选传感器时可以直接选用输出为电压信号的。


2、执行部分:


3、核心芯片:Arduino Uno+ESP8266





4、硬件连接方法:



5、程序如下:(程序以调试完成,可直接运行)https://www.arduino.cc/en/Main/Software(Arduino IDE环境地址);
[kenrobot_code]/*
   采用外接电源单独供电,2 3口作为软串口接PC机作为调试端
   1 0为串口,连接WIFI模块
*/
#include <Wire.h>
#include <math.h>
#include <SoftwareSerial.h>
#include "edp.c"

//#define  YAN_DEBUG_CTRL


// GY-30
// BH1750FVI 光照传感器
// in ADDR 'L' mode 7bit addr
#define ADDR 0b0100011

#define KEY  "mTQiviJTfGb48Qv2=gibocgOCEU="    //APIkey(改为自己的API)
#define ID   "4049843"                          //设备ID(改为自己的ID)
//#define PUSH_ID "680788"
#define PUSH_ID NULL

// 串口
#define _baudrate   115200
#define _rxpin      3
#define _txpin      2
#define WIFI_UART   Serial
#define DBG_UART    dbgSerial   //调试打印串口
//
int potpiA =A1;       //酸碱度
int valla=0;

int potpiB =A2;       //溶解氧
int vallb=0;

int potpiC =A3;       //温度
int vallc=0;

int potpiD =A4;       //光照
int valld=0;
//
SoftwareSerial dbgSerial( _rxpin, _txpin ); // 软串口,调试打印
edp_pkt *pkt;

/*
* doCmdOk
* 发送命令至模块,从回复中获取期待的关键字
* keyword: 所期待的关键字
* 成功找到关键字返回true,否则返回false
*/
bool doCmdOk(String data, char *keyword)
{
  bool result = false;
  if (data != "")   //对于tcp连接命令,直接等待第二次回复
  {
     if(data=="+++")
     {
        WIFI_UART.print("+++");
     }
     else
     {   
          WIFI_UART.println(data);  //发送AT指令
          DBG_UART.print("SEND: ");
          DBG_UART.println(data);
     }
  }

  delay(500);
  if (data == "AT" || data == "+++")   //检查模块存在
    delay(2000);
  else
    while (!WIFI_UART.available());  // 等待模块回复

  delay(500);
  if (WIFI_UART.find(keyword))   //返回值判断
  {
    DBG_UART.println("do cmd OK");
    result = true;
  }
  else
  {
    DBG_UART.println("do cmd ERROR");
    result = false;
  }
  while (WIFI_UART.available()) WIFI_UART.read();   //清空串口接收缓存
  delay(500); //指令时间间隔
  return result;
}


void setup()
{
  char buf[100] = {0};
  int tmp;

  pinMode(13, OUTPUT);   //WIFI模块指示灯
  //
  pinMode(8, OUTPUT);     //光照开关
  pinMode(9, OUTPUT);    //PH氧阀门
  pinMode(10, OUTPUT);    //增氧阀门
  pinMode(11, OUTPUT);    //投饵机阀门
  digitalWrite(8, HIGH);
  digitalWrite(9, HIGH);
  digitalWrite(10, HIGH);
  digitalWrite(11, HIGH);
//
  digitalWrite(13, HIGH);   // 使Led亮

  WIFI_UART.begin( _baudrate );
  DBG_UART.begin( _baudrate );
  WIFI_UART.setTimeout(3000);    //设置find超时时间
  delay(3000);
  DBG_UART.println("hello world!");

  // 光照传感器初始化
  Wire.begin();
  Wire.beginTransmission(ADDR);
  Wire.write(0b00000001);
  Wire.endTransmission();

  delay(2000);


  //while (!doCmdOk("AT", "OK"));

  //可能模块重新启动了
  while(1)
  {
      if(doCmdOk("AT", "OK"))break;
      delay(2000);
      doCmdOk("+++", "OK");

  }

  while (!doCmdOk("AT+CWMODE=3", "OK"));            //工作模式digitalWrite(13, LOW);   // 使Led灭
  while (!doCmdOk("AT+CWJAP=\"123\",\"1234567890\"", "OK"));//将“123”和“1234567890”改为你自己的wifi用户名和密码
delay(10);
// doCmdOk("AT+CIPCLOSE", "OK");delay(10);

  while (!doCmdOk("AT+CIPSTART=\"TCP\",\"183.230.40.39\",876", "CONNECT"));//CONNECT,Linked
  while (!doCmdOk("AT+CIPMODE=1", "OK"));           //透传模式
  while (!doCmdOk("AT+CIPSEND", ">"));              //开始发送
  digitalWrite(13, LOW);   // 使Led灭
}

void loop()
{
  static int edp_connect = 0;
  bool trigger = false;
  //
  bool tra= false;                //待定
  bool trb= false;
  bool trc= false;
  //
  edp_pkt rcv_pkt;
  unsigned char pkt_type;
  int i, tmp;
  char num[10];                    //光照
  //
  char shuanjiand[10];              //酸碱度字符
  char rongjiey[10];               //溶解氧字符
  char wendu[10];                  //温度字符
  //
  /* EDP 连接 */
  if (!edp_connect)
  {
    while (WIFI_UART.available()) WIFI_UART.read(); //清空串口接收缓存
    packetSend(packetConnect(ID, KEY));             //发送EPD连接包
    while (!WIFI_UART.available());                 //等待EDP连接应答
    if ((tmp = WIFI_UART.readBytes(rcv_pkt.data, sizeof(rcv_pkt.data))) > 0 )
    {
      rcvDebug(rcv_pkt.data, tmp);
      if (rcv_pkt.data[0] == 0x20 && rcv_pkt.data[2] == 0x00 && rcv_pkt.data[3] == 0x00)
      {
        edp_connect = 1;
        DBG_UART.println("EDP connected.");
      }
      else
        DBG_UART.println("EDP connect error.");
    }
    packetClear(&rcv_pkt);
  }
  //        酸碱度上传
  tra = SJD(shuanjiand);//模拟心跳包,如果没有数据要传送,则需要心跳包
  if (edp_connect && tra)
  {
    DBG_UART.print("SJD: ");
    DBG_UART.println(shuanjiand);
    packetSend(packetDataSaveTrans(PUSH_ID, "suan", shuanjiand));  //发送数据存储包
  }
//         溶解氧数据上传
trb = RJY(rongjiey);//模拟心跳包,如果没有数据要传送,则需要心跳包
  if (edp_connect && rongjiey)
  {
    DBG_UART.print("RJY: ");
    DBG_UART.println(rongjiey);
    packetSend(packetDataSaveTrans(PUSH_ID, "rong", rongjiey));  //发送数据存储包
  }
//          温度数据上传
trc = WD(wendu);//模拟心跳包,如果没有数据要传送,则需要心跳包
  if (edp_connect && trc)
  {
    DBG_UART.print("WD: ");
    DBG_UART.println(wendu);
    packetSend(packetDataSaveTrans(PUSH_ID, "wen", wendu));  //发送数据存储包
  }
//          光照数据上传
  trigger = readGY_30(num);//模拟心跳包,如果没有数据要传送,则需要心跳包
  if (edp_connect && trigger)
  {
    DBG_UART.print("GY_30: ");
    DBG_UART.println(num);
    packetSend(packetDataSaveTrans(PUSH_ID, "guang", num));  //发送数据存储包
                                                           //当PUSH_ID不为NULL时转发至PUSH_ID
  }



  while (WIFI_UART.available())
  {
    readE**kt(&rcv_pkt);
    if (isE**kt(&rcv_pkt))
    {
      pkt_type = rcv_pkt.data[0];
      switch (pkt_type)
      {
        case CMDREQ:
          char edp_command[50];
          char edp_cmd_id[40];
          long id_len, cmd_len, rm_len;
          char datastr[20];
          char val[10];
          memset(edp_command, 0, sizeof(edp_command));
          memset(edp_cmd_id, 0, sizeof(edp_cmd_id));
          edpCommandReqParse(&rcv_pkt, edp_cmd_id, edp_command, &rm_len, &id_len, &cmd_len);
          DBG_UART.print("rm_len: ");
          DBG_UART.println(rm_len, DEC);
          delay(10);
          DBG_UART.print("id_len: ");
          DBG_UART.println(id_len, DEC);
          delay(10);
          DBG_UART.print("cmd_len: ");
          DBG_UART.println(cmd_len, DEC);
          delay(10);
          DBG_UART.print("id: ");
          DBG_UART.println(edp_cmd_id);
          delay(10);
          DBG_UART.print("cmd: ");
          DBG_UART.println(edp_command);

          //数据处理与应用中EDP命令内容对应
          //本例中格式为  datastream:[1/0]
          //sscanf(edp_command, "%[^:]:%s",val);
          sscanf(edp_command, "%[^:]:%s", datastr, val);
         // sscanf(edp_command, val);        
          if (atoi(val) == 1)//光照开关
            digitalWrite(8, LOW);
          if (atoi(val) == 3)
            digitalWrite(8, HIGH);  

          if(atoi(val) == 2)         //PH阀门
             digitalWrite(9, LOW);
          if (atoi(val) == 5)
            digitalWrite(9, HIGH);  

          if(atoi(val) == 14)         //增氧阀门
             digitalWrite(10, LOW);  
          if (atoi(val) == 7)
            digitalWrite(10,HIGH);

          if(atoi(val) == 4)           //投饵机阀门
             digitalWrite(11, LOW);   
          if (atoi(val) == 9)
            digitalWrite(11, HIGH);  

          packetSend(packetDataSaveTrans(NULL, datastr, val)); //将新数据值上传至数据流
          break;
        default:
          DBG_UART.print("unknown type: ");
          DBG_UART.println(pkt_type, HEX);
          break;
      }
    }
    //delay(4);
  }
  if (rcv_pkt.len > 0)
    packetClear(&rcv_pkt);
  delay(150);
}

/*
* readE**kt
* 从串口缓存中读数据到接收缓存
*/
bool readE**kt(edp_pkt *p)
{
  int tmp;
  if ((tmp = WIFI_UART.readBytes(p->data + p->len, sizeof(p->data))) > 0 )
  {
    rcvDebug(p->data + p->len, tmp);
    p->len += tmp;
  }
  return true;
}

/*
* packetSend
* 将待发数据发送至串口,并释放到动态分配的内存
*/
void packetSend(edp_pkt* pkt)
{
  if (pkt != NULL)
  {
    WIFI_UART.write(pkt->data, pkt->len);    //串口发送
    WIFI_UART.flush();
    free(pkt);              //回收内存
  }
}

void rcvDebug(unsigned char *rcv, int len)
{
  int i;

  DBG_UART.print("rcv len: ");
  DBG_UART.println(len, DEC);
  for (i = 0; i < len; i++)
  {
    DBG_UART.print(rcv, HEX);
    DBG_UART.print(" ");
  }
  DBG_UART.println("");
}

/*

bool readGY_30(char *num)       //光照传感器
{
  static int val = 0, count = 10;;
  int tmp;
  // reset
  Wire.beginTransmission(ADDR);
  Wire.write(0b00000111);
  Wire.endTransmission();
  delay(100);

  Wire.beginTransmission(ADDR);
  Wire.write(0b00100000);
  Wire.endTransmission();

  // typical read delay 120ms
  delay(120);
  Wire.requestFrom(ADDR, 2); // 2byte every time
  while (Wire.available())
  {
    char c = Wire.read();
    //DBG_UART.println(c, HEX);
    tmp = (tmp << 8) + (c & 0xFF);
  }

  tmp = tmp / 1.2;
  sprintf(num, "%d", tmp);

  if (--count == 0)
  {
    count = 10;
    return true;
  }
  return false;
}
*/
//
bool SJD(char *shuanjiand)         //酸碱度
{
  float a=0;
  a=analogRead(potpiA);
  valla=a/17.53;
  delay(2000);
  sprintf(shuanjiand,"%d",valla);
  }

bool RJY(char *rongjiey)         //溶解氧
{
  int b=0;
  b=analogRead(potpiB);
  vallb=b/52.42;
  delay(2000);
  sprintf(rongjiey,"%d",vallb);
  }

bool WD(char *wendu)          //温度
{
  double Temp,c;
  c=analogRead(potpiC);
  Temp = log(((10240000/c) - 10000));
  Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
  Temp = Temp - 273.15;
  vallc=Temp;
  delay(2000);
  sprintf(wendu,"%d",vallc);
  }
//
bool readGY_30(char *num)           //光照
{
  valld=analogRead(potpiD);
  delay(2000);
  sprintf(num,"%d",valld);
  #ifdef YAN_DEBUG_CTRL  
   return false;
  #else   
   return true;
  #endif

}
[/kenrobot_code]


6、OneNET管理平台:http://open.iot.10086.cn/appview/p/97f195b16f3536d6556c308b64610e79



8、视频查看地址:http://v.youku.com/v_show/id_XMTgzNDk1NTM0NA==.html(视频效果比较明显,大家可以访问地址观看)


这就是整个作品的流程,欢迎大家浏览。如果在作品中没有描述清楚的,请大家批评指正。















发表于 2017-5-5 20:35 | 显示全部楼层
我也在做,,想学习学习
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 00:33 , Processed in 0.128368 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表