无线电杂志

Microduino在物联网的应用

时间:2012-12-10 23:58:19  作者:Microduino  来源:  查看:5183  评论:1
导读:由于Microduino-nRF24L01+模块调试出现问题,今天早上改进的pcb才到,下午才调试通,所以现在才发文章,希望能赶上比赛。一、Microduino模块介绍由于物联网应用各种模块需求量比较大,重复应用比较多,所以这次比赛的所有模块都是自己设计,打板,焊接的。主要模块为..
由于Microduino-nRF24L01+模块调试出现问题,今天早上改进的pcb才到,下午才调试通,所以现在才发文章,希望能赶上比赛。

一、Microduino模块介绍

由于物联网应用各种模块需求量比较大,重复应用比较多,所以这次比赛的所有模块都是自己设计,打板,焊接的。主要模块为Microduino-Core,Microduino-FT232R,Microduino-Enc28J60(与Microduino-HR911105A模块构成完成的模块),Microduino-nRF24L01(为了阅读方便后文对模块名称省略前面的Microduino),这些模块通过Microduino总线进行叠加,以上模块及总线如下图所示。
Microduino模块.jpg
-Core模块为Arduino系统的核心最小系统,模块设计为支持Atmeg88/168/328系列TQFP32封装单片机,支持3.3V和5V两种电压供电,本文选用328p单片机,采用5V供电,晶振频率为16MHZ。Bootloader采用Arduino UNO的,用Arduino UNO 使用ArduinoISP程序用Arduino IDE对-Core烧写。本文程序使用的IDE版本为1.0.2。
-FT232R模块为USB转串口模块,主要作用为给单片机下载程序,以及在程序调试过程中对一些过程、变量进行监控。调试结束后,如果应用不进行串口通讯,这个模块为非必须的。
-ENC28J60模块和-HR911105A模块叠加一起构成一个有线网络模块,他们之间由内部6根专有的排针进行通讯。这样设计是出于成本及不影响外观考虑的,-Enc28J60和后续推出的Microduino-HLJ6115ANL模块可以构成一个简单poe网络模块,该模块占用SPI接口(D11,D12,D13),片选CS为D8。本文程序采用EtherCard库。
-nRF24L01+模块为无线通讯模块,同样占用SPI接口(D11,D12,D13),CE为D9,片选CSN为D10。本文程序采用RF24Network库。各个模块占用引脚如下图所示:
QQ截图20121210220900.jpg

二、Microduino模块组建物联网。

一)硬件

由于采用模块叠加方式,硬件很容易连接,-FT232R和-Core和-ENC28J60(含-HR911105A)和-nRF24L01+叠加组成网关,-FT232R-Core和-nRF24L01+叠加组成数据采集节点。网关通过-ENC28J60模块连接到Internet网络,通过nRF24L01+模块与其他节点通讯。各节点将传感器采集的数据通过-nRF24L01模块上传到网关。-FT232R模块仅在调试过程中作为下载程序和给模块供电用,实际应用供电以及传感器电路,集成到主板(洞洞板),该模块非必须。本文由于时间关系,未连接传感器电路,节点以0-100.0的随机数作为传感器数据上传到网关。-nRF24L01可以1对多通讯,由于时间关系,也仅1个节点为例。硬件连接如下图所示:
网关节点示意图.jpg

二)软件

1、节点端

节点端主要把传感器数据(本文为0.0-100.0随机数)发送到网关。代码如下:

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9,10);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 1;

// Address of the other node
const uint16_t other_node = 0;

// How often to send 'hello world to the other unit
const unsigned long interval = 15000; //ms

// When did we last send?
unsigned long last_sent;

// How many have we sent already
//unsigned long packets_sent;

// Structure of our payload
struct payload_t
{
  uint32_t ms;
  uint32_t sensorData;
};
uint32_t temp;
void setup(void)
{
  Serial.begin(57600);
  Serial.println("RF24Network/examples/helloworld_tx/");
 
  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);

  randomSeed(analogRead(0));
}

void loop(void)
{
  // Pump the network regularly
  network.update();

  // If it's time to send a message, send it!
  unsigned long now = millis();
  if ( now - last_sent >= interval  )
  {
    last_sent = now;

    Serial.print("Sending...");
    temp = random(0,1000);
    payload_t payload = { millis(),temp};
    RF24NetworkHeader header(/*to node*/ other_node);
    bool ok = network.write(header,&payload,sizeof(payload));
    if (ok)
      Serial.println("ok.");
    else
      Serial.println("failed.");
  }
}



2、网关端

网关主要把通过-nrf24L01模块接收到的传感器信息通过-ENC28J60模块传送到Yeelink服务器。代码如下:

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>
#include <EtherCard.h>

// nRF24L01(+) radio attached using Getting Started board 
RF24 radio(9,10);
// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

// Address of the other node
const uint16_t other_node = 1;

// Structure of our payload
struct payload_t
{
  uint32_t ms;
  uint32_t sensorData;
};

// ethernet interface mac address
static byte mymac[] = { 
  0x74,0x69,0x69,0x2D,0x30,0x31 };

// remote website name
char website[] PROGMEM = "api.yeelink.net";
char urlBuf[] PROGMEM = "/v1.0/device/XXXX/sensor/XXXX/datapoints";
char apiKey[] PROGMEM = "U-ApiKey: XXXXXXXXXXXXXXXXXXXXXXX";

byte Ethernet::buffer[700];
static long timer;
uint32_t temp;
// called when the client request is complete
static void my_result_cb (byte status, word off, word len) {
  Serial.print("<<< reply ");
  Serial.print(millis() - timer);
  Serial.println(" ms");
  Serial.println((const char*) Ethernet::buffer+off);
}




void setup(void)
{
  Serial.begin(57600);
  Serial.println("RF24Network/examples/helloworld_rx/");

  SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);

  Serial.println("\n[getDHCPandDNS]");
  
  if (ether.begin(sizeof Ethernet::buffer, mymac) == 0) 
    Serial.println( "Failed to access Ethernet controller");

  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");

  ether.printIp("My IP: ", ether.myip);
  // ether.printIp("Netmask: ", ether.mymask);
  ether.printIp("GW IP: ", ether.gwip);
  ether.printIp("DNS IP: ", ether.dnsip);

  if (!ether.dnsLookup(website))
    Serial.println("DNS failed");
  ether.printIp("Server: ", ether.hisip);
}

void loop(void)
{
  // Pump the network regularly
  network.update();
  ether.packetLoop(ether.packetReceive());
  // Is there anything ready for us?
  while ( network.available() )
  {
    // If so, grab it and print it out
    RF24NetworkHeader header;
    payload_t payload;
    network.read(header,&payload,sizeof(payload));
    temp=payload.sensorData;
    Serial.print("Received Sensor Data #");
    Serial.print(temp);
    Serial.print(" at ");
    Serial.println(payload.ms);
    Serial.println("\n>>> REQ");
    static char buf[20];
    get_send_string(buf);
    if (!ether.dnsLookup(website))
      Serial.println("DNS failed");
    ether.printIp("Server: ", ether.hisip);
    timer = millis();
    ether.httpPost (urlBuf, website, apiKey, buf, my_result_cb);
    
  }
}
void get_send_string(char *p){
  uint32_t Tc_100 = temp;
  Serial.println(Tc_100);
  uint8_t whole, fract;
  whole = Tc_100/10 ;  // separate off the whole and fractional portions
  fract = Tc_100 % 10;
  sprintf(p,"{\"value\":%d.%d}",whole,fract); 
}


数据记录见yeelink


 




三、结语

这里仅简单给个Microduino模块在物联网的一个应用,以后会用Microduino组成传感器网络,并对各个节点进行控制。时间关系,视频以后再传。


评论区

已有1位网友发表评论
帐  号: 密码: (如果您还不是博趣会员,欢迎注册)
表  情:
内  容:
网友评论仅供其表达个人看法,并不表明博趣网同意其观点或证实其描述。