Intel Galileo驱动单总线设备(DHT11\DHT22)(转)
Intel Galileo一代的IO翻转速度不够,无法直接驱动单总线设备,二代听说改进了,但没有库,于是国外开发者想出了另一种法子,转过来给大家学习下。如果后面有时间,再来翻译。
原文地址:http://www.cnblogs.com/jikexianfeng/p/6279260.html
Many people have had trouble with getting 1-Wire devices to work with the Galileo and Galileo Gen2 boards.
The main reason is that the Galileo and Galileo Gen2 uses IO expanders for many of its GPIOs. Even with the pins Arduno header pins that have native SoC IO speeds, it is not possible because the GPIOs that control the muxing of those pins uses pins from the IO expanders.
Galileo Muxing For Pin2
Galileo Cypress IO Expander
If we look at the two images taken form the Galileo schematic, IO which is connected to the Arduino Digital 2 pin, is controlled by a mux pin IO2_MUX. This pin is then connected to the Cypress IO expander.
The end result is there is significant latency when switching pin direction using pinMode() becuase it requires I2C transactions with the IO expanders.
I will show a way to use 1-Wire device with the Galileo and Galileo Gen2 boards.
The trick is to use 2 pins instead of 1. For the Galileo, pins 2 and 3 must be used since they are the only pins fast enough to achieve this. For the Galileo Gen2, any pins except pins 7 and 8 can be used.
For this tutorial, I will use a DHT11 sensor which a very cheap and popular 1-Wire humidity and temperature sensor.
The Proper Way
The proper way of doing this is to use a tri-state buffer.
This works because, when pin 3 is pulled HIGH, the tri-state buffer prevents the HIGH signal from being passed to the other side. However, the 1-Wire device still sees a high signal because of the pull-up resistor.
When pin 3 is pulled LOW, the signal passes through the tri-state buffer and a LOW signal is detected by the 1-Wire device.
The Easy Way
For the easy way the only extra hardware needed is a diode such as the 1N4148 signal diode. This essential works the same way as the tri-state buffer method where only a LOW signal passes through because current only passes in one direction through a diode.
Since we are now using two pins, we will also need to make changes in the libraries used. As an example, I modified the DHT-11 library from Adafruit.
#ifndef DHT_H
#define DHT_H
#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif /* DHT library MIT license
written by Adafruit Industries Modified by Dino Tinitigan ([url=mailto:dino.tinitigan@intel.com]dino.tinitigan@intel.com[/url] to work on Intel Galileo boards
*/ // how many timing transitions we need to keep track of. 2 * number bits + extra
#define MAXTIMINGS 85 #define DHT11 11
#define DHT22 22
#define DHT21 21
#define AM2301 21 class DHT {
private:
uint8_t data[];
uint8_t _inpin, _outpin, _type, _count;
unsigned long _lastreadtime;
boolean firstreading;
int pulseLength(int pin);
void delayMicrosGal(unsigned long usec);
int bitsToByte(int bits[]); public:
DHT(uint8_t inPin, uint8_t outPin,uint8_t type, uint8_t count=);
void begin(void);
float readTemperature(bool S=false);
float convertCtoF(float);
float computeHeatIndex(float tempFahrenheit, float percentHumidity);
float readHumidity(void);
boolean read(void); };
#endif
/* DHT library MIT license
written by Adafruit Industries Modified by Dino Tinitigan ([url=mailto:dino.tinitigan@intel.com]dino.tinitigan@intel.com[/url] to work on Intel Galileo boards
*/ #include "DHT.h" DHT::DHT(uint8_t inPin, uint8_t outPin, uint8_t type, uint8_t count) {
_inpin = inPin;
_outpin = outPin;
_type = type;
_count = count;
firstreading = true;
} void DHT::begin(void) {
// set up the pins!
pinMode(_inpin, INPUT);
pinMode(_outpin, INPUT);
digitalWrite(_outpin, HIGH);
_lastreadtime = ;
} //boolean S == Scale. True == Farenheit; False == Celcius
float DHT::readTemperature(bool S) {
float f; if (read()) {
switch (_type) {
case DHT11:
f = data[];
if(S)
f = convertCtoF(f); return f;
case DHT22:
case DHT21:
f = data[] & 0x7F;
f *= ;
f += data[];
f /= ;
if (data[] & 0x80)
f *= -;
if(S)
f = convertCtoF(f); return f;
}
}
return NAN;
} float DHT::convertCtoF(float c) {
return c * / + ;
} float DHT::readHumidity(void) {
float f;
if (read()) {
switch (_type) {
case DHT11:
f = data[];
return f;
case DHT22:
case DHT21:
f = data[];
f *= ;
f += data[];
f /= ;
return f;
}
}
return NAN;
} float DHT::computeHeatIndex(float tempFahrenheit, float percentHumidity) {
// Adapted from equation at: [url=https://github.com/adafruit/DHT-sensor-library/issues/9]https://github.com/adafruit/DHT-sensor-library/issues/9[/url] and
// Wikipedia: [url=http://en.wikipedia.org/wiki/Heat_index]http://en.wikipedia.org/wiki/Heat_index[/url]
return -42.379 +
2.04901523 * tempFahrenheit +
10.14333127 * percentHumidity +
-0.22475541 * tempFahrenheit*percentHumidity +
-0.00683783 * pow(tempFahrenheit, ) +
-0.05481717 * pow(percentHumidity, ) +
0.00122874 * pow(tempFahrenheit, ) * percentHumidity +
0.00085282 * tempFahrenheit*pow(percentHumidity, ) +
-0.00000199 * pow(tempFahrenheit, ) * pow(percentHumidity, );
} boolean DHT::read(void) {
uint8_t laststate = HIGH;
uint8_t counter = ;
uint8_t j = , i;
unsigned long currenttime; int bitContainer[]; // Check if sensor was read less than two seconds ago and return early
// to use last reading.
currenttime = millis();
if (currenttime < _lastreadtime) {
// ie there was a rollover
_lastreadtime = ;
}
if (!firstreading && ((currenttime - _lastreadtime) < )) {
return true; // return last correct measurement
//delay(2000 - (currenttime - _lastreadtime));
}
firstreading = false;
/*
Serial.print("Currtime: "); Serial.print(currenttime);
Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
*/
_lastreadtime = millis(); data[] = data[] = data[] = data[] = data[] = ; // pull the pin high and wait 250 milliseconds
pinMode(_outpin, OUTPUT_FAST);
pinMode(_inpin, INPUT_FAST);
digitalWrite(_outpin, HIGH);
delay(); // now pull it low for ~20 milliseconds
noInterrupts();
digitalWrite(_outpin, LOW);
delay();
digitalWrite(_outpin, HIGH);
delayMicrosGal(); //read the 40 bits
delayMicrosGal();
for(int bytes = ; bytes < ; bytes++)
{
for(int i = ; i < ; i++)
{
int pulse = pulseLength(_inpin);
if(pulse > )
{
bitContainer[i] = ;
}
else
{
bitContainer[i] = ;
}
}
data[bytes] = bitsToByte(bitContainer);
} interrupts(); //Serial.println(j, DEC);
/**
Serial.print(data[0], HEX); Serial.print(", ");
Serial.print(data[1], HEX); Serial.print(", ");
Serial.print(data[2], HEX); Serial.print(", ");
Serial.print(data[3], HEX); Serial.print(", ");
Serial.print(data[4], HEX); Serial.print(" =? ");
Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
**/
/**
Serial.println(data[0]);
Serial.println(data[1]);
Serial.println(data[2]);
Serial.println(data[3]);
Serial.println(data[4]);
**/
// check we read 40 bits and that the checksum matches if((data[] == ((data[] + data[] + data[] + data[]) & 0xFF)))
{
return true;
} return false; } void DHT::delayMicrosGal(unsigned long usec)
{
unsigned long a = micros();
unsigned long b = a;
while((b-a) < usec)
{
b = micros();
}
} int DHT::pulseLength(int pin)
{
unsigned long a = micros();
unsigned long b = a;
unsigned long c = a;
int timeout = ;
int fastPin = ;
int highValue = ; if(PLATFORM_NAME == "GalileoGen2")
{
switch(pin)
{
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x08);
highValue = 0x08;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x10);
highValue = 0x10;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x20);
highValue = 0x20;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x40);
highValue = 0x40;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x10);
highValue = 0x10;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_CW(0x01);
highValue = 0x01;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_CW(0x02);
highValue = 0x02;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x04);
highValue = 0x04;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x04);
highValue = 0x04;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x08);
highValue = 0x08;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x80);
highValue = 0x80;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x20);
highValue = 0x20;
break;
default:
highValue = ;
break;
}
}
else
{
switch(_inpin)
{
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x40);
highValue = 0x40;
break;
case :
fastPin = GPIO_FAST_ID_QUARK_SC(0x80);
highValue = 0x80;
break;
default:
highValue = ;
break;
}
}
a = micros();
while(fastGpioDigitalRead(fastPin) == )
{
b= micros();
if((b - a) >= timeout)
{
break;
}
}
a = micros();
while(fastGpioDigitalRead(fastPin) == highValue)
{
b= micros();
if((b - a) >= timeout)
{
break;
}
}
return (b - a);
return ;
} int DHT::bitsToByte(int bits[])
{
int data = ;
for(int i = ; i < ; i++)
{
if (bits[i])
{
data |= (int)( << ( - i));
}
}
return data;
}
// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain #include "DHT.h" #define DHTIN 2 // what pin we're connected to
#define DHTOUT 3 // Uncomment whatever type you're using!
#define DHTTYPE DHT11 // DHT 11
//#define DHTTYPE DHT22 // DHT 22 (AM2302)
//#define DHTTYPE DHT21 // DHT 21 (AM2301) // Connect pin 1 (on the left) of the sensor to +5V
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor DHT dht(DHTIN,DHTOUT, DHTTYPE); void setup() {
Serial.begin();
Serial.println("DHTxx test!"); dht.begin();
} void loop() {
// Wait a few seconds between measurements.
delay(); // Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius
float t = dht.readTemperature();
// Read temperature as Fahrenheit
float f = dht.readTemperature(true); // Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
return;
} // Compute heat index
// Must send in temp in Fahrenheit!
float hi = dht.computeHeatIndex(f, h); Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.print(" *C ");
Serial.print(f);
Serial.print(" *F\t");
Serial.print("Heat index: ");
Serial.print(hi);
Serial.println(" *F");
}
Intel Galileo驱动单总线设备(DHT11\DHT22)(转)的更多相关文章
- x86 构架的 Arduino 开发板Intel Galileo
RobotPeak是上海的一家硬件创业团队,团队致力于民用机器人平台系统.机器人操作系统(ROS)以及相关设备的设计研发,并尝试将日新月异的机器人技术融入人们的日常生活与娱乐当中.同时,RobotPe ...
- x86 版的 Arduino Intel Galileo 开发板的体验、分析和应用
1.前言 在今年(2013)罗马举办的首届欧洲 Make Faire 上,Intel 向对外发布了采用 x86 构架的 Arduino 开发板:Intel Galileo.这无疑是一个开源硬件领域的重 ...
- Using 1-Wire device with Intel Galileo
Using 1-Wire device with Intel Galileo 3 Replies Many people have had trouble with getting 1-Wire de ...
- Linux下的硬件驱动——USB设备(转载)
usb_bulk_msg函数 当对usb设备进行一次读或者写时,usb_bulk_msg 函数是非常有用的; 然而, 当你需要连续地对设备进行读/写时,建议你建立一个自己的urbs,同时将urbs 提 ...
- LinuxI2C核心、总线驱动与设备驱动
I2C体系结构分为三个部分:I2C核心.总线驱动.设备驱动 I2C核心: I2C核心提供了一组不依赖硬件的接口函数,I2C总线驱动和设备驱动之间依赖于I2C核心作为纽带 (1)增加/删除i2c_ada ...
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联
转载自:http://www.kancloud.cn/yueqian_scut/emlinux/106829 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sy ...
- 【转】Linux设备驱动--块设备(一)之概念和框架
原文地址:Linux设备驱动--块设备(一)之概念和框架 基本概念 块设备(blockdevice) --- 是一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,他使用缓冲区来存放暂时 ...
- 《天书夜读:从汇编语言到windows内核编程》六 驱动、设备、与请求
1)跳入到基础篇的内核编程第7章,驱动入口函数DriverEnter的返回值决定驱动程序是否加载成功,当打算反汇编阅读驱动内核程序时,可寻找该位置. 2)DRIVER_OBJECT下的派遣函数(分发函 ...
- 【驱动】linux设备驱动·字符设备驱动开发
Preface 前面对linux设备驱动的相应知识点进行了总结,现在进入实践阶段! <linux设备驱动入门篇>:http://infohacker.blog.51cto.com/6751 ...
随机推荐
- Java归去来第1集:手动给Eclipse配置Maven环境
一.Eclipse配置Maven 1.1.下载Maven http://maven.apache.org/download.cgi,选择对应的版本,window下载apache-maven-3.5.3 ...
- CHtmlEditCtrl (2): Add a Source Text Editor to Your HTML Editor
In a previous article, I described how to create an HTML editor using the MFC CHtmlEditCtrl class in ...
- LXC 容器集chroot使用说明
1.1 LXC是什么? 1.1.1 关于LXC LXC,其名称来自Linux软件容器(Linux Containers)的缩写,一种操作系统层虚拟化(Operating system–level vi ...
- linux下更改主机名方法hostname
一.永久修改修改/etc/sysconfig/network,在里面指定主机名称HOSTNAME=然后执行命令hostname 主机名这个时候可以注销一下系统,再重登录之后就行了. 或者修改/etc/ ...
- Spring Boot中Starter是什么
比如我们要在Spring Boot中引入Web MVC的支持时,我们通常会引入这个模块spring-boot-starter-web,而这个模块如果解压包出来会发现里面什么都没有,只定义了一些POM依 ...
- NSobject 结构
参考地址: https://iosdevelopmenttutorials.wordpress.com/tag/uiscrollview/ Apple Documentation
- tomcat管理员在远程(不同)机器上访问管理页面
tomcat8.5管理员默认只能在安装tomcat的机器上访问,如果想在其他机器上访问,则需要进行配置修改 添加用户和权限(<tomcat>\conf\tomcat-users.xml): ...
- 在TQ2440开发板上ping 127.0.0.1不通
问题:在TQ2440上ping 127.0.0.1,提示错误 ping: sendto: Network is unreachable 解决方法:ifconfig lo 127.0.0.1 up ...
- mule学习笔记
mule学习笔记 1.安装&配置 版本:mule 2.2.1 操作: 1) 下载.解压 2)配置环境变量:MULE_HOME.PATH 3)如果网络环境使用代理,找到%MULE_HOME%/c ...
- ES6 新增数据类型检测 Set Map Proxy
检测代码方法 function isNative(api){ return /native code/.test(api.toString())&&typeof api !== 'un ...