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

王顺 发表于 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调节,供氧,补充光亮,投饵。
三:作品整体效果:
http://upfiles.heclouds.com/forum-app/2016/11/24/51c957d871a1ad770d0418ae3382d318.jpg
http://upfiles.heclouds.com/forum-app/2016/11/25/a9a6290cd9c1985fcfc81c9b566e1400.jpg

1、所用到的传感器:(除光照传感器外,其他三种传感器输出的是4~20mA的电流信号,而我们需要取5v电压信号作为输出。因此需要用到电压转换器LM324,将电流转换为电压,大家在选传感器时可以直接选用输出为电压信号的。)
http://upfiles.heclouds.com/forum-app/2016/11/24/edf3cc27a7bb035502b0d85cac3c5666.jpg

2、执行部分:
http://upfiles.heclouds.com/forum-app/2016/11/24/c7b825b69e12273afb3d221eda4c5cf1.png

3、核心芯片:Arduino Uno+ESP8266

http://upfiles.heclouds.com/forum-app/2016/11/24/331138a0d30c2daf0f8648e3c58ac7bc.jpg

http://upfiles.heclouds.com/forum-app/2016/11/24/63919f2e555e8be0b67436728cd160b0.jpg

4、硬件连接方法:

http://upfiles.heclouds.com/forum-app/2016/11/25/f48afd7b3e0489d71d4a2f15b95a0058.png

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

//#defineYAN_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 = {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;                  //光照
//
char shuanjiand;            //酸碱度字符
char rongjiey;               //溶解氧字符
char wendu;                  //温度字符
//
/* 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 == 0x20 && rcv_pkt.data == 0x00 && rcv_pkt.data == 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;
      switch (pkt_type)
      {
      case CMDREQ:
          char edp_command;
          char edp_cmd_id;
          long id_len, cmd_len, rm_len;
          char datastr;
          char val;
          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:
          //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

}



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

http://upfiles.heclouds.com/forum-app/2016/11/24/090a192b95b7fef9f6c06c42ce012617.jpg

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


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















liaojikang 发表于 2017-5-5 20:35

我也在做,,想学习学习
页: [1]
查看完整版本: 【基于物联网的终端水产养殖系统 】