极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 13613|回复: 7

两块Widuino无线互联,实现温度及电压的无线读取

[复制链接]
发表于 2013-12-14 18:50:51 | 显示全部楼层 |阅读模式
本帖最后由 komoya 于 2013-12-14 18:58 编辑

我为什么喜欢rfm12b这款芯片呢? 因为它很适合设备之间的通讯,传输距离比较远,轻松穿两堵墙。我上次提到,我做了个小应用,就是做了一个带RFM12B的arduino,接上DS18B20温度传感器放在室外。室内用另一块带rfm12b的arduino+LCD12864放在室内。两块板子可以无线通讯,室内的液晶屏可以显示室外的温度。早上起来,我看一眼液晶屏,就知道室外是多少度,然后决定今天穿多少衣服。

后来我为了方便学习,就在Sparkfun的开源电路的基础上捣鼓了一块带rfm12b接口的Arduino电路板。也就是后来我起名字的Widuino。在代码方面,是个新手,捣鼓电路也是为了兴趣爱好,让生活有个某方面的追求。今天我放上我测试的代码,欢迎高手提点,改进。(这次偷懒,注释少了点{:soso_e113:} )

arduino如何连接DS18B20我就不啰嗦了,本论坛有现成的教材可以参考。测试用的是D4接口。

发送端Widuino代码:
[pre lang="arduino" line="1" file="Widuino_test_send"]//----------------------------------------------------------------------------------------------------------------
//Widuino无线温度测量 V0.1  ---  发送端

//功能:发送Widuino A板上的DS18b20温度值

//------------------------------------------komoya Labs-----------------------------------------------------------

#define MYNODE 19            // Node名
#define freq RF12_433MHZ     //  频率设定(国内一般买的都是433Mhz)
#define network 210            //  网络组名

#include <JeeLib.h>                                                     
#include <OneWire.h>
#include <DallasTemperature.h>

#define ONE_WIRE_BUS 4                                                  
OneWire oneWire(ONE_WIRE_BUS);                                          
DallasTemperature sensors(&oneWire);                                    
DeviceAddress sensor;                                                  

typedef struct {          //数据格式定义,这里特别注意,要和发送端保持一致
  float temp;                                                      
  int battery;                                                      
}
PayloadTx;
PayloadTx widuinomon;

void setup() {
  Serial.begin(9600);
  Serial.print("Node: ");
  Serial.print(MYNODE);  
  Serial.print(" Network: ");
  Serial.println(network);

  delay(10);

  sensors.begin();
  if (!sensors.getAddress(sensor, 0)) Serial.println("Unable to find DS18B20 Temperature Sensor"); //如果不能读取温度,输出错误。一般为接线错误。
  rf12_initialize(MYNODE, freq, network);                          // 初始化 RFM12B
  rf12_control(0xC040);                                                
  delay(10);
}

void loop()
{

  sensors.requestTemperatures();                                        // 获取温度
  float temp=(sensors.getTempCByIndex(0));
  widuinomon.temp=temp;      
  widuinomon.battery=readVcc();

  //发送数据
  int i = 0;
  while (!rf12_canSend() && i<10) {
    rf12_recvDone();
    i++;
  }
  rf12_sendStart(0, &widuinomon, sizeof widuinomon);

  rf12_sendWait(2);
  Serial.print("the temp is:");
  Serial.println(widuinomon.temp);
  delay(5000);
}
//读取电池电压
long readVcc() {
  long result;
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2);
  ADCSRA |= _BV(ADSC);
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1126400L / result;
  return result;
}


[/code]

接收端Widuino代码:
[pre lang="arduino" line="1" file="Widuino_test_receive"]//----------------------------------------------------------------------------------------------------------------
//Widuino无线温度测量 V0.1  ---  接收端

//功能:无线读取Widuino A板上发送过来的DS18b20温度值

//------------------------------------------komoya Labs-----------------------------------------------------------

#include <JeeLib.h>

// RFM12B 网络设置
#define MYNODE 21            // Node名
#define freq RF12_433MHZ     //  频率设定(国内一般买的都是433Mhz)
#define network 210            //  网络组名

double temp;
int battery;

typedef struct {                 //数据格式定义
  float temp;                                                      
  int battery;                                                      
}
PayloadTx;
PayloadTx widuinomon;


void setup()
{

  Serial.begin(9600);
  delay(500);                                    //等待0.5秒
  rf12_initialize(MYNODE, freq, network);    //无线RF初始化

}


void loop()
{

  if (rf12_recvDone())  //接收数据开始
  {

    if (rf12_crc == 0 && (rf12_hdr & RF12_HDR_CTL) == 0)  // and no rf errors/检查RF没有错误,如没有错误,继续
    {

      int node_id = (rf12_hdr & 0x1F);
      if (node_id == 19)
      {
        widuinomon = *(PayloadTx*) rf12_data;
        Serial.print("received ok");
      }

    }
  }

  temp = widuinomon.temp;     // 得到板A的温度
  battery = widuinomon.battery;
  
  Serial.print("Temperature from Widuino is :");  //串口输出A板的温度
  Serial.print(temp);
  Serial.println("C");
  Serial.print("Battery Voltage from Widuino is :");  //串口输出A板的电池电压
  Serial.print(battery);
  Serial.println("mV");
  delay(2000);

}

[/code]
实验结果:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-12-14 19:06:35 | 显示全部楼层
rfm12b,可以一对多通信么?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-14 19:11:11 | 显示全部楼层
i7456 发表于 2013-12-14 19:06
rfm12b,可以一对多通信么?

可以啊。只要在一个network的都可以。

在定义的时候,MYNODE就是名字,network就是一个房间。同一个房间的人可以相互说话。无论是一对一,一对多。

#define MYNODE 19            // Node名
#define freq RF12_433MHZ     //  频率设定(国内一般买的都是433Mhz)
#define network 210            //  网络组名
回复 支持 反对

使用道具 举报

发表于 2013-12-14 22:49:47 | 显示全部楼层
不错的应用,关键是spi模式。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-14 23:33:51 | 显示全部楼层
topdog 发表于 2013-12-14 22:49
不错的应用,关键是spi模式。

下次用你给的那个类试试,说不定效果更好。
回复 支持 反对

使用道具 举报

发表于 2013-12-15 10:46:50 | 显示全部楼层
感谢分享,有代码了调试就方便多了~~~
回复 支持 反对

使用道具 举报

发表于 2013-12-15 11:03:41 | 显示全部楼层
别光上代码,上点设备图片
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-15 11:13:51 | 显示全部楼层
Cupid 发表于 2013-12-15 11:03
别光上代码,上点设备图片

忘记拍照片了。 不过也简单,接收端啥也没接,就FTDI连电脑,开串口。 发送端就接了一个DS18b20+4.7k电阻(暂时用的一节18620电池供电的,DS18B20可以工作)。我借个图片吧(图片的用的是D2口,程序用的是D4)。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-25 15:33 , Processed in 0.046273 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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