komoya 发表于 2013-12-14 18:50:51

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

本帖最后由 komoya 于 2013-12-14 18:58 编辑

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

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

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

发送端Widuino代码:
//----------------------------------------------------------------------------------------------------------------
//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;
}




接收端Widuino代码:
//----------------------------------------------------------------------------------------------------------------
//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);

}


实验结果:


i7456 发表于 2013-12-14 19:06:35

rfm12b,可以一对多通信么?

komoya 发表于 2013-12-14 19:11:11

i7456 发表于 2013-12-14 19:06 static/image/common/back.gif
rfm12b,可以一对多通信么?

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

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

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

topdog 发表于 2013-12-14 22:49:47

不错的应用,关键是spi模式。

komoya 发表于 2013-12-14 23:33:51

topdog 发表于 2013-12-14 22:49 static/image/common/back.gif
不错的应用,关键是spi模式。

下次用你给的那个类试试,说不定效果更好。:victory:

shenhaiyu 发表于 2013-12-15 10:46:50

感谢分享,有代码了调试就方便多了~~~

Cupid 发表于 2013-12-15 11:03:41

别光上代码,上点设备图片

komoya 发表于 2013-12-15 11:13:51

Cupid 发表于 2013-12-15 11:03 static/image/common/back.gif
别光上代码,上点设备图片

忘记拍照片了。 不过也简单,接收端啥也没接,就FTDI连电脑,开串口。 发送端就接了一个DS18b20+4.7k电阻(暂时用的一节18620电池供电的,DS18B20可以工作)。我借个图片吧(图片的用的是D2口,程序用的是D4)。http://bildr.org/blog/wp-content/uploads/2011/06/DS18S20-hookup-400x237.png
页: [1]
查看完整版本: 两块Widuino无线互联,实现温度及电压的无线读取