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 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.

 1 #ifndef DHT_H
 2 #define DHT_H
 3 #if ARDUINO >= 100
 4  #include "Arduino.h"
 5 #else
 6  #include "WProgram.h"
 7 #endif
 8
 9 /* DHT library
10
11 MIT license
12 written by Adafruit Industries
13
14 Modified by Dino Tinitigan ([email protected] to work on Intel Galileo boards
15 */
16
17 // how many timing transitions we need to keep track of. 2 * number bits + extra
18 #define MAXTIMINGS 85
19
20 #define DHT11 11
21 #define DHT22 22
22 #define DHT21 21
23 #define AM2301 21
24
25 class DHT {
26  private:
27  uint8_t data[6];
28  uint8_t _inpin, _outpin, _type, _count;
29  unsigned long _lastreadtime;
30  boolean firstreading;
31  int pulseLength(int pin);
32  void delayMicrosGal(unsigned long usec);
33  int bitsToByte(int bits[]);
34
35  public:
36  DHT(uint8_t inPin, uint8_t outPin,uint8_t type, uint8_t count=6);
37  void begin(void);
38  float readTemperature(bool S=false);
39  float convertCtoF(float);
40  float computeHeatIndex(float tempFahrenheit, float percentHumidity);
41  float readHumidity(void);
42  boolean read(void);
43
44
45 };
46 #endif
  1 /* DHT library
  2
  3 MIT license
  4 written by Adafruit Industries
  5
  6 Modified by Dino Tinitigan ([email protected] to work on Intel Galileo boards
  7 */
  8
  9
 10 #include "DHT.h"
 11
 12 DHT::DHT(uint8_t inPin, uint8_t outPin, uint8_t type, uint8_t count) {
 13  _inpin = inPin;
 14  _outpin = outPin;
 15  _type = type;
 16  _count = count;
 17  firstreading = true;
 18 }
 19
 20 void DHT::begin(void) {
 21  // set up the pins!
 22  pinMode(_inpin, INPUT);
 23  pinMode(_outpin, INPUT);
 24  digitalWrite(_outpin, HIGH);
 25  _lastreadtime = 0;
 26 }
 27
 28 //boolean S == Scale. True == Farenheit; False == Celcius
 29 float DHT::readTemperature(bool S) {
 30  float f;
 31
 32  if (read()) {
 33  switch (_type) {
 34  case DHT11:
 35  f = data[2];
 36  if(S)
 37  f = convertCtoF(f);
 38
 39  return f;
 40  case DHT22:
 41  case DHT21:
 42  f = data[2] & 0x7F;
 43  f *= 256;
 44  f += data[3];
 45  f /= 10;
 46  if (data[2] & 0x80)
 47  f *= -1;
 48  if(S)
 49  f = convertCtoF(f);
 50
 51  return f;
 52  }
 53  }
 54  return NAN;
 55 }
 56
 57 float DHT::convertCtoF(float c) {
 58  return c * 9 / 5 + 32;
 59 }
 60
 61 float DHT::readHumidity(void) {
 62  float f;
 63  if (read()) {
 64  switch (_type) {
 65  case DHT11:
 66  f = data[0];
 67  return f;
 68  case DHT22:
 69  case DHT21:
 70  f = data[0];
 71  f *= 256;
 72  f += data[1];
 73  f /= 10;
 74  return f;
 75  }
 76  }
 77  return NAN;
 78 }
 79
 80 float DHT::computeHeatIndex(float tempFahrenheit, float percentHumidity) {
 81  // Adapted from equation at: https://github.com/adafruit/DHT-sensor-library/issues/9 and
 82  // Wikipedia: http://en.wikipedia.org/wiki/Heat_index
 83  return -42.379 +
 84  2.04901523 * tempFahrenheit +
 85  10.14333127 * percentHumidity +
 86  -0.22475541 * tempFahrenheit*percentHumidity +
 87  -0.00683783 * pow(tempFahrenheit, 2) +
 88  -0.05481717 * pow(percentHumidity, 2) +
 89  0.00122874 * pow(tempFahrenheit, 2) * percentHumidity +
 90  0.00085282 * tempFahrenheit*pow(percentHumidity, 2) +
 91  -0.00000199 * pow(tempFahrenheit, 2) * pow(percentHumidity, 2);
 92 }
 93
 94
 95 boolean DHT::read(void) {
 96  uint8_t laststate = HIGH;
 97  uint8_t counter = 0;
 98  uint8_t j = 0, i;
 99  unsigned long currenttime;
100
101  int bitContainer[8];
102
103  // Check if sensor was read less than two seconds ago and return early
104  // to use last reading.
105  currenttime = millis();
106  if (currenttime < _lastreadtime) {
107  // ie there was a rollover
108  _lastreadtime = 0;
109  }
110  if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
111  return true; // return last correct measurement
112  //delay(2000 - (currenttime - _lastreadtime));
113  }
114  firstreading = false;
115  /*
116  Serial.print("Currtime: "); Serial.print(currenttime);
117  Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
118  */
119  _lastreadtime = millis();
120
121  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
122
123  // pull the pin high and wait 250 milliseconds
124  pinMode(_outpin, OUTPUT_FAST);
125  pinMode(_inpin, INPUT_FAST);
126  digitalWrite(_outpin, HIGH);
127  delay(250);
128
129  // now pull it low for ~20 milliseconds
130  noInterrupts();
131  digitalWrite(_outpin, LOW);
132  delay(20);
133  digitalWrite(_outpin, HIGH);
134  delayMicrosGal(40);
135
136  //read the 40 bits
137  delayMicrosGal(160);
138  for(int bytes = 0; bytes < 5; bytes++)
139  {
140  for(int i = 0; i < 8; i++)
141  {
142  int pulse = pulseLength(_inpin);
143  if(pulse > 30)
144  {
145  bitContainer[i] = 1;
146  }
147  else
148  {
149  bitContainer[i] = 0;
150  }
151  }
152  data[bytes] = bitsToByte(bitContainer);
153  }
154
155  interrupts();
156
157
158  //Serial.println(j, DEC);
159  /**
160  Serial.print(data[0], HEX); Serial.print(", ");
161  Serial.print(data[1], HEX); Serial.print(", ");
162  Serial.print(data[2], HEX); Serial.print(", ");
163  Serial.print(data[3], HEX); Serial.print(", ");
164  Serial.print(data[4], HEX); Serial.print(" =? ");
165  Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
166  **/
167  /**
168  Serial.println(data[0]);
169  Serial.println(data[1]);
170  Serial.println(data[2]);
171  Serial.println(data[3]);
172  Serial.println(data[4]);
173  **/
174  // check we read 40 bits and that the checksum matches
175
176  if((data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)))
177  {
178  return true;
179  }
180
181
182  return false;
183
184 }
185
186 void DHT::delayMicrosGal(unsigned long usec)
187 {
188  unsigned long a = micros();
189  unsigned long b = a;
190  while((b-a) < usec)
191  {
192  b = micros();
193  }
194 }
195
196 int DHT::pulseLength(int pin)
197 {
198  unsigned long a = micros();
199  unsigned long b = a;
200  unsigned long c = a;
201  int timeout = 150;
202  int fastPin = 0;
203  int highValue = 0;
204
205  if(PLATFORM_NAME == "GalileoGen2")
206  {
207  switch(pin)
208  {
209  case 0:
210  fastPin = GPIO_FAST_ID_QUARK_SC(0x08);
211  highValue = 0x08;
212  break;
213  case 1:
214  fastPin = GPIO_FAST_ID_QUARK_SC(0x10);
215  highValue = 0x10;
216  break;
217  case 2:
218  fastPin = GPIO_FAST_ID_QUARK_SC(0x20);
219  highValue = 0x20;
220  break;
221  case 3:
222  fastPin = GPIO_FAST_ID_QUARK_SC(0x40);
223  highValue = 0x40;
224  break;
225  case 4:
226  fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x10);
227  highValue = 0x10;
228  break;
229  case 5:
230  fastPin = GPIO_FAST_ID_QUARK_NC_CW(0x01);
231  highValue = 0x01;
232  break;
233  case 6:
234  fastPin = GPIO_FAST_ID_QUARK_NC_CW(0x02);
235  highValue = 0x02;
236  break;
237  case 9:
238  fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x04);
239  highValue = 0x04;
240  break;
241  case 10:
242  fastPin = GPIO_FAST_ID_QUARK_SC(0x04);
243  highValue = 0x04;
244  break;
245  case 11:
246  fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x08);
247  highValue = 0x08;
248  break;
249  case 12:
250  fastPin = GPIO_FAST_ID_QUARK_SC(0x80);
251  highValue = 0x80;
252  break;
253  case 13:
254  fastPin = GPIO_FAST_ID_QUARK_NC_RW(0x20);
255  highValue = 0x20;
256  break;
257  default:
258  highValue = 1;
259  break;
260  }
261  }
262  else
263  {
264  switch(_inpin)
265  {
266  case 2:
267  fastPin = GPIO_FAST_ID_QUARK_SC(0x40);
268  highValue = 0x40;
269  break;
270  case 3:
271  fastPin = GPIO_FAST_ID_QUARK_SC(0x80);
272  highValue = 0x80;
273  break;
274  default:
275  highValue = 1;
276  break;
277  }
278  }
279  a = micros();
280  while(fastGpioDigitalRead(fastPin) == 0)
281  {
282  b= micros();
283  if((b - a) >= timeout)
284  {
285  break;
286  }
287  }
288  a = micros();
289  while(fastGpioDigitalRead(fastPin) == highValue)
290  {
291  b= micros();
292  if((b - a) >= timeout)
293  {
294  break;
295  }
296  }
297  return (b - a);
298  return 0;
299 }
300
301
302 int DHT::bitsToByte(int bits[])
303 {
304  int data = 0;
305  for(int i = 0; i < 8; i++)
306  {
307  if (bits[i])
308  {
309  data |= (int)(1 << (7 - i));
310  }
311  }
312  return data;
313 }
 1 // Example testing sketch for various DHT humidity/temperature sensors
 2 // Written by ladyada, public domain
 3
 4 #include "DHT.h"
 5
 6 #define DHTIN 2 // what pin we‘re connected to
 7 #define DHTOUT 3
 8
 9 // Uncomment whatever type you‘re using!
10 #define DHTTYPE DHT11 // DHT 11
11 //#define DHTTYPE DHT22 // DHT 22 (AM2302)
12 //#define DHTTYPE DHT21 // DHT 21 (AM2301)
13
14 // Connect pin 1 (on the left) of the sensor to +5V
15 // Connect pin 2 of the sensor to whatever your DHTPIN is
16 // Connect pin 4 (on the right) of the sensor to GROUND
17 // Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
18
19 DHT dht(DHTIN,DHTOUT, DHTTYPE);
20
21 void setup() {
22  Serial.begin(9600);
23  Serial.println("DHTxx test!");
24
25  dht.begin();
26 }
27
28 void loop() {
29  // Wait a few seconds between measurements.
30  delay(2000);
31
32  // Reading temperature or humidity takes about 250 milliseconds!
33  // Sensor readings may also be up to 2 seconds ‘old‘ (its a very slow sensor)
34  float h = dht.readHumidity();
35  // Read temperature as Celsius
36  float t = dht.readTemperature();
37  // Read temperature as Fahrenheit
38  float f = dht.readTemperature(true);
39
40  // Check if any reads failed and exit early (to try again).
41  if (isnan(h) || isnan(t) || isnan(f)) {
42  Serial.println("Failed to read from DHT sensor!");
43  return;
44  }
45
46  // Compute heat index
47  // Must send in temp in Fahrenheit!
48  float hi = dht.computeHeatIndex(f, h);
49
50  Serial.print("Humidity: ");
51  Serial.print(h);
52  Serial.print(" %\t");
53  Serial.print("Temperature: ");
54  Serial.print(t);
55  Serial.print(" *C ");
56  Serial.print(f);
57  Serial.print(" *F\t");
58  Serial.print("Heat index: ");
59  Serial.print(hi);
60  Serial.println(" *F");
61 }

原文地址:http://bigdinotech.com/tutorials/galileo-tutorials/using-1-wire-device-with-intel-galileo/

时间: 2024-12-24 12:48:15

Using 1-Wire device with Intel Galileo的相关文章

Intel Galileo Debian Image Prequits

Intel Galileo开发板 Debian镜像 在原发布者的基础上进行了更新,附带开发入门套件,打包内容: -intel_galileo_debian_xfce4镜像 -约3GB -putty -firmwire updater 固件更新工具 -win32diskmanager烧写工具 -------------------------------------------------------------- 考虑到galileo-debian的更新比较慢,cpu频率比较低.因此上传搭建好的

在Intel&#174; Galileo Gen 2开发板上运行Debian操作系统

    最近在研究Intel® Galileo Gen 2开发板的Linux开发.Intel® Galileo Gen 2开发板自带的Linux比较简单,缺少很多常用的软件,而且板子自身的容量很小.所以我打算在SD卡上运行Debian系统,这个系统里装有apt-get,缺少什么软件可以通过网络安装. 1. 下载Galileo的debian镜像.    到http://sourceforge.net/projects/galileodebian/下载Galileo的debian软件镜像galile

Intel&#174; Galileo Gen 2 Development Board

Intel 项目参考 Intel Galileo board articles and projects Burglar Alarm Using the Intel® Galileo Board > Create a Display to Track the Days Until MAKE hits Newsstands > Looking for a simple guide to write programs for Yocto on Galileo? > Tweets throug

Intel Galileo

Intel Galileo - Programming GPIO From Linux PuTTY 中文教程 Intel Galileo - Programming GPIO From Linux Intel Galileo Meets Wireless Intel Galileo - Introduction Intel-Galileo Intel® Galileo Gen 2 Development Board Using IPC for Wireless Encryption with I

x86 构架的 Arduino 开发板Intel Galileo

RobotPeak是上海的一家硬件创业团队,团队致力于民用机器人平台系统.机器人操作系统(ROS)以及相关设备的设计研发,并尝试将日新月异的机器人技术融入人们的日常生活与娱乐当中.同时,RobotPeak 将尽力为机器人技术在开源硬件.开源软件社区的普及做出贡献.陈士凯是 RobotPeak 联合创始人,他给我们带来了最新的  x86 构架的 Arduino 开发板 Intel Galileo 的深度使用报告. 1.前言 在今年(2013)罗马举办的首届欧洲 Make Faire 上,Intel

我的24小时-Intel Galileo Gen 2入门

Intel Galileo Gen 2 搞机之路 其实第一次听说要搞这个板子的时候我是拒绝的,因为,你不能让我搞,我就马上去搞,第一我要试一下,因为我不愿意搞完了以后再加一些特技上去,板子"咣"一下,很好.很棒,这样出来别人一定会骂我,根本没有这样的板子,就证明Intel那个板子是假的.后来我也经过证实他们确实是棒棒哒,我用了大概一天,感觉还不错,后来我在搞的时候也要求不要加特技,因为我要让别人看到,我搞完之后是这个样子,你们搞完之后也会是这个样子! 好吧,不逗了,以上是开玩笑,下面进

Intel Galileo Gen 2入门

Intel Galileo Gen 2入门 本文所介绍内容 Intel Galileo Gen 2简介 在Ubuntu上搭建环境 使用Arduino IDE刷入Sketch 在Galileo Gen 2中刷入定制版Linux系统 在Galileo Gen 2中刷入Debian系统 在Galileo Gen 2中编译运行OpenCV Intel Galileo Gen 2简介 Intel Galileo Gen 2是一款与Arduino* 兼容.搭载英特尔? 架构的开发板,相比上一代的Intel

Windows on Device 项目实践 5 - 姿态控制灯制作

在前面几篇文章中,我们学习了如何利用Intel Galileo开发板和Windows on Device来设计并完成PWM调光灯.感光灯.火焰报警器和智能风扇的制作,涉及到了火焰传感器.DC直流电机.温度传感器.光敏电阻等器件.在这个项目中,我们会使用滚珠开关和LED,完成一个简单的姿态控制灯的制作. 1.滚珠开关 滚珠开关利用开关中的小珠的滚动,制造与金属端子的触碰或改变光线行进的路线,就能产生导通或不导通的效果.滚珠开关目前已有许多不同类型的产品,包括角度感应开关.震动感应开关.离心力感应开

Windows on Device 项目实践 2 - 感光灯制作

在上一篇<Windows on Device 项目实践 1 - PWM调光灯制作>中,我们学习了如何利用Intel Galileo开发板和Windows on Device来设计并完成一个PWM调光灯的制作.该情况下,我们需要手动调节电位器,通过PWM波形来控制LED灯的亮度.在现在的智能家居系统设计中,很多设备都需要融入智能,即无需人为干预,就能够自动为我们服务. 在这个项目中,我们会使用光敏电阻,利用其感光特性,来设计并且制作一个感光灯.感光灯能够根据环境光的强度,自动调节LED灯的亮度.