Advertisement
mx270a

ElectricImp DS18B20 via DS2482

Aug 4th, 2013
3,198
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.33 KB | None
  1. local i2c = hardware.i2c89;
  2. i2c.configure(CLOCK_SPEED_100_KHZ);
  3. const I2CAddr = 0x30; //Address of DS2482 on I2C bus
  4. owTripletDirection <- 1;
  5. owTripletFirstBit <- 0;
  6. owTripletSecondBit <- 0;
  7. owLastDevice <- 0;
  8. owLastDiscrepancy <- 0;
  9. owDeviceAddress <- [0,0]; //These are each 32 bits long.
  10.  
  11. //http://datasheets.maximintegrated.com/en/ds/DS2482-100.pdf
  12. //http://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
  13. //http://www.wulfden.org/downloads/datasheets/DS2482_AN3684.pdf
  14.  
  15. function loop() {
  16. if (OWSearch()) { //Search found something
  17. if ((owDeviceAddress[1] & 0xFF) == 0x28) { //Device is a DS18B20
  18. //server.log("Is a DS18B20");
  19. if (OWReset()) { //Reset was successful
  20. OWSelect();
  21. OWWriteByte(0x44); //start conversion
  22. imp.sleep(1); //Wait for conversion
  23. if (OWReset()) { //Reset was successful
  24. OWSelect();
  25. OWWriteByte(0xBE); //Read Scratchpad
  26. OWReadTemperature();
  27. }
  28. }
  29. }
  30. }
  31. imp.wakeup(1, loop);
  32. }
  33.  
  34. function DS2482Reset() {
  35. server.log(format("Function: Resetting DS2482 at %i (%#x)", I2CAddr, I2CAddr));
  36. i2c.write(I2CAddr, "\xF0"); //reset DS2482
  37. }
  38. function OWReset() {
  39. //server.log("Function: I2C Reset");
  40. local e = i2c.write(I2CAddr, "\xB4"); //1-wire reset
  41. if (e != 0) { //Device failed to acknowledge reset
  42. server.log("I2C Reset Failed");
  43. return 0;
  44. }
  45. local loopcount = 0;
  46. while (true) {
  47. loopcount++;
  48. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  49. if(data == null) {
  50. server.log("I2C Read Status Failed");
  51. return 0;
  52. } else {
  53. //server.log(format("Read Status Byte = %d", data[0]));
  54. if (data[0] & 0x01) { // 1-Wire Busy bit
  55. //server.log("One-Wire bus is busy");
  56. if (loopcount > 100) {
  57. server.log("One-Wire busy too long");
  58. return 0;
  59. }
  60. imp.sleep(0.001); //Wait, try again
  61. } else {
  62. //server.log("One-Wire bus is idle");
  63. if (data[0] & 0x04) { //Short Detected bit
  64. server.log("One-Wire Short Detected");
  65. return 0;
  66. }
  67. if (data[0] & 0x02) { //Presense-Pulse Detect bit
  68. //server.log("One-Wire Devices Found");
  69. break;
  70. } else {
  71. server.log("No One-Wire Devices Found");
  72. return 0;
  73. }
  74. }
  75. }
  76. }
  77. return 1;
  78. }
  79. function OWWriteByte(byte) {
  80. //server.log("Function: Write Byte to One-Wire");
  81. local e = i2c.write(I2CAddr, "\xE1\xF0"); //set read pointer (E1) to the status register (F0)
  82. if (e != 0) { //Device failed to acknowledge
  83. server.log("I2C Write Failed");
  84. return -1;
  85. }
  86. local loopcount = 0;
  87. while (true) {
  88. loopcount++;
  89. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  90. if(data == null) {
  91. server.log("I2C Read Status Failed");
  92. return -1;
  93. } else {
  94. //server.log(format("Read Status Byte = %d", data[0]));
  95. if (data[0] & 0x01) { // 1-Wire Busy bit
  96. //server.log("One-Wire bus is busy");
  97. if (loopcount > 100) {
  98. server.log("One-Wire busy for too long");
  99. return -1;
  100. }
  101. imp.sleep(0.001); //Wait, try again
  102. } else {
  103. //server.log("One-Wire bus is idle");
  104. break;
  105. }
  106. }
  107. }
  108.  
  109. //server.log(byte);
  110. local e = i2c.write(I2CAddr, format("%c%c", 0xA5, byte)); //set write byte command (A5) and send data (byte)
  111. if (e != 0) { //Device failed to acknowledge
  112. server.log(format("I2C Write Byte Failed. Data: %#.2X", byte));
  113. return -1;
  114. }
  115. loopcount = 0;
  116. while (true) {
  117. loopcount++;
  118. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  119. if(data == null) {
  120. server.log("I2C Read Status Failed");
  121. return -1;
  122. } else {
  123. //server.log(format("Read Status Byte = %d", data[0]));
  124. if (data[0] & 0x01) { // 1-Wire Busy bit
  125. //server.log("One-Wire bus is busy");
  126. if (loopcount > 100) {
  127. server.log("One-Wire busy for too long");
  128. return -1;
  129. }
  130. imp.sleep(0.001); //Wait, try again
  131. } else {
  132. //server.log("One-Wire bus is idle");
  133. break;
  134. }
  135. }
  136. }
  137. //server.log("One-Wire Write Byte complete");
  138. return 0;
  139. }
  140. function OWReadByte() {
  141. //See if the 1wire bus is idle
  142. //server.log("Function: Read Byte from One-Wire");
  143. local e = i2c.write(I2CAddr, "\xE1\xF0"); //set read pointer (E1) to the status register (F0)
  144. if (e != 0) { //Device failed to acknowledge
  145. server.log("I2C Write Failed");
  146. return -1;
  147. }
  148. local loopcount = 0;
  149. while (true) {
  150. loopcount++;
  151. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  152. if(data == null) {
  153. server.log("I2C Read Status Failed");
  154. return -1;
  155. } else {
  156. //server.log(format("Read Status Byte = %d", data[0]));
  157. if (data[0] & 0x01) { // 1-Wire Busy bit
  158. //server.log("One-Wire bus is busy");
  159. if (loopcount > 100) {
  160. server.log("One-Wire busy for too long");
  161. return -1;
  162. }
  163. imp.sleep(0.001); //Wait, try again
  164. } else {
  165. //server.log("One-Wire bus is idle");
  166. break;
  167. }
  168. }
  169. }
  170.  
  171. //Send a read command, then wait for the 1wire bus to finish
  172. local e = i2c.write(I2CAddr, "\x96"); //send read byte command (96)
  173. if (e != 0) { //Device failed to acknowledge
  174. server.log("I2C Write read-request Failed");
  175. return -1;
  176. }
  177. local loopcount = 0;
  178. while (true) {
  179. loopcount++;
  180. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  181. if(data == null) {
  182. server.log("I2C Read Status Failed");
  183. return -1;
  184. } else {
  185. //server.log(format("Read Status Byte = %d", data[0]));
  186. if (data[0] & 0x01) { // 1-Wire Busy bit
  187. //server.log("One-Wire bus is busy");
  188. if (loopcount > 100) {
  189. server.log("One-Wire busy for too long");
  190. return -1;
  191. }
  192. imp.sleep(0.001); //Wait, try again
  193. } else {
  194. //server.log("One-Wire bus is idle");
  195. break;
  196. }
  197. }
  198. }
  199.  
  200.  
  201. //Go get the data byte
  202. local e = i2c.write(I2CAddr, "\xE1\xE1"); //set read pointer (E1) to the read data register (E1)
  203. if (e != 0) { //Device failed to acknowledge
  204. server.log("I2C Write Failed");
  205. return -1;
  206. }
  207. local data = i2c.read(I2CAddr, "", 1); //Read the data register
  208. if(data == null) {
  209. server.log("I2C Read Status Failed");
  210. return -1;
  211. } else {
  212. //server.log(format("Read Data Byte = %d", data[0]));
  213. }
  214. //server.log("One-Wire Read Byte complete");
  215. return data[0];
  216. }
  217. function OWTriplet() {
  218. //server.log("Function: OneWire Triplet");
  219. if (owTripletDirection > 0) owTripletDirection = "\xFF";
  220.  
  221. local e = i2c.write(I2CAddr, "\x78" + owTripletDirection); //send 1-wire triplet and direction
  222. if (e != 0) { //Device failed to acknowledge message
  223. server.log("OneWire Triplet Failed");
  224. return 0;
  225. }
  226.  
  227. local loopcount = 0;
  228. while (true) {
  229. loopcount++;
  230. local data = i2c.read(I2CAddr, "", 1); //Read the status register
  231. if(data == null) {
  232. server.log("I2C Read Status Failed");
  233. return -1;
  234. } else {
  235. //server.log(format("Read Status Byte = %d", data[0]));
  236. if (data[0] & 0x01) { // 1-Wire Busy bit
  237. //server.log("One-Wire bus is busy");
  238. if (loopcount > 100) {
  239. server.log("One-Wire busy for too long");
  240. return -1;
  241. }
  242. imp.sleep(0.001); //Wait, try again
  243. } else {
  244. //server.log("One-Wire bus is idle");
  245. if (data[0] & 0x20) {
  246. owTripletFirstBit = 1;
  247. } else {
  248. owTripletFirstBit = 0;
  249. }
  250. if (data[0] & 0x40) {
  251. owTripletSecondBit = 1;
  252. } else {
  253. owTripletSecondBit = 0;
  254. }
  255. if (data[0] & 0x80) {
  256. owTripletDirection = 1;
  257. } else {
  258. owTripletDirection = 0;
  259. }
  260. return 1;
  261. }
  262. }
  263. }
  264. }
  265. function OWSearch() {
  266. //server.log("Function: OneWire Search");
  267. local bitNumber = 1;
  268. local lastZero = 0;
  269. local deviceAddress4ByteIndex = 1; //Fill last 4 bytes first, data from onewire comes LSB first.
  270. local deviceAddress4ByteMask = 1;
  271.  
  272. if (owLastDevice) {
  273. server.log("OneWire Search Complete");
  274. owLastDevice = 0;
  275. owLastDiscrepancy = 0;
  276. owDeviceAddress[0] = 0xFFFFFFFF;
  277. owDeviceAddress[1] = 0xFFFFFFFF;
  278. }
  279.  
  280. if (!owLastDevice) { //if the last call was not the last one
  281. if (!OWReset()) { //if there are no parts on 1-wire, return false
  282. owLastDiscrepancy = 0;
  283. return 0;
  284. }
  285. OWWriteByte(0xF0); //Issue the Search ROM command
  286.  
  287. do { // loop to do the search
  288. if (bitNumber < owLastDiscrepancy) {
  289. if (owDeviceAddress[deviceAddress4ByteIndex] & deviceAddress4ByteMask) {
  290. owTripletDirection = 1;
  291. } else {
  292. owTripletDirection = 0;
  293. }
  294. } else if (bitNumber == owLastDiscrepancy) { //if equal to last pick 1, if not pick 0
  295. owTripletDirection = 1;
  296. } else {
  297. owTripletDirection = 0;
  298. }
  299.  
  300. if (!OWTriplet()) return 0;
  301.  
  302. //if 0 was picked then record its position in lastZero
  303. if (owTripletFirstBit==0 && owTripletSecondBit==0 && owTripletDirection==0) lastZero = bitNumber;
  304.  
  305. //check for no devices on 1-wire
  306. if (owTripletFirstBit==1 && owTripletSecondBit==1) break;
  307.  
  308. //set or clear the bit in the SerialNum byte serial_byte_number with mask
  309. if (owTripletDirection==1) {
  310. owDeviceAddress[deviceAddress4ByteIndex] = owDeviceAddress[deviceAddress4ByteIndex] | deviceAddress4ByteMask;
  311. } else {
  312. owDeviceAddress[deviceAddress4ByteIndex] = owDeviceAddress[deviceAddress4ByteIndex] & ~deviceAddress4ByteMask;
  313. }
  314.  
  315. bitNumber++; //increment the byte counter bit number
  316. deviceAddress4ByteMask = deviceAddress4ByteMask << 1; //shift the bit mask left
  317.  
  318. if (deviceAddress4ByteMask == 0) { //if the mask is 0 then go to other address block and reset mask to first bit
  319. deviceAddress4ByteIndex--;
  320. deviceAddress4ByteMask = 1;
  321. }
  322. } while (deviceAddress4ByteIndex > -1);
  323.  
  324. if (bitNumber == 65) { //if the search was successful then
  325. owLastDiscrepancy = lastZero;
  326. if (owLastDiscrepancy==0) {
  327. owLastDevice = 1;
  328. } else {
  329. owLastDevice = 0;
  330. }
  331. //server.log(format("OneWire Device Address = %.8X%.8X", owDeviceAddress[0], owDeviceAddress[1]));
  332. if (OWCheckCRC()) {
  333. return 1;
  334. } else {
  335. server.log("OneWire device address CRC check failed");
  336. return 1;
  337. }
  338.  
  339. }
  340. }
  341.  
  342. server.log("No One-Wire Devices Found, Resetting Search");
  343. owLastDiscrepancy = 0;
  344. owLastDevice = 0;
  345. return 0;
  346. }
  347. function OWCheckCRC() {
  348. local crc = 0;
  349. local j;
  350. local da32bit = owDeviceAddress[1];
  351. for(j=0; j<4; j++) { //All four bytes
  352. crc = AddCRC(da32bit & 0xFF, crc);
  353. //server.log(format("CRC = %.2X", crc));
  354. da32bit = da32bit >> 8; //Shift right 8 bits
  355. }
  356. da32bit = owDeviceAddress[0];
  357. for(j=0; j<3; j++) { //only three bytes
  358. crc = AddCRC(da32bit & 0xFF, crc);
  359. //server.log(format("CRC = %.2X", crc));
  360. da32bit = da32bit >> 8; //Shift right 8 bits
  361. }
  362. //server.log(format("CRC = %#.2X", crc));
  363. //server.log(format("DA = %#.2X", da32bit));
  364. if ((da32bit & 0xFF) == crc) { //last byte of address should match CRC of other 7 bytes
  365. //server.log("CRC Passed");
  366. return 1; //match
  367. }
  368. return 0; //bad CRC
  369. }
  370. function AddCRC(inbyte, crc) {
  371. local j;
  372. for(j=0; j<8; j++) {
  373. local mix = (crc ^ inbyte) & 0x01;
  374. crc = crc >> 1;
  375. if (mix) crc = crc ^ 0x8C;
  376. inbyte = inbyte >> 1;
  377. }
  378. return crc;
  379. }
  380. function OWSelect() {
  381. //server.log("Selecting device");
  382. OWWriteByte(0x55); //Issue the Match ROM command
  383. local i;
  384. local j;
  385. for(i=1; i>=0; i--) {
  386. local da32bit = owDeviceAddress[i];
  387. for(j=0; j<4; j++) {
  388. //server.log(format("Writing byte: %.2X", da32bit & 0xFF));
  389. OWWriteByte(da32bit & 0xFF); //Send lowest byte
  390. da32bit = da32bit >> 8; //Shift right 8 bits
  391. }
  392. }
  393. }
  394. function OWReadTemperature() {
  395. local data = [0,0,0,0, 0];
  396. local i;
  397. for(i=0; i<5; i++) { //we only need 5 of the bytes
  398. data[i] = OWReadByte();
  399. //server.log(format("read byte: %.2X", data[i]));
  400. }
  401.  
  402. local raw = (data[1] << 8) | data[0];
  403. local SignBit = raw & 0x8000; // test most significant bit
  404. if (SignBit) {raw = (raw ^ 0xffff) + 1;} // negative, 2's compliment
  405. local cfg = data[4] & 0x60;
  406. if (cfg == 0x60) {
  407. //server.log("12 bit resolution"); //750 ms conversion time
  408. } else if (cfg == 0x40) {
  409. //server.log("11 bit resolution"); //375 ms
  410. raw = raw << 1;
  411. } else if (cfg == 0x20) {
  412. //server.log("10 bit resolution"); //187.5 ms
  413. raw = raw << 2;
  414. } else { //if (cfg == 0x00)
  415. //server.log("9 bit resolution"); //93.75 ms
  416. raw = raw << 3;
  417. }
  418. //server.log(format("rawtemp= %.4X", raw));
  419.  
  420. local celsius = raw / 16.0;
  421. if (SignBit) {celsius *= -1;}
  422. //server.log(format("Temperature = %.1f °C", celsius));
  423.  
  424. local fahrenheit = celsius * 1.8 + 32.0;
  425. //server.log(format("Temperature = %.1f °F", fahrenheit));
  426. server.log(format("OneWire Device %.8X%.8X = %.1f °F", owDeviceAddress[0], owDeviceAddress[1], fahrenheit));
  427. server.show(format("%.1f °F", fahrenheit));
  428. }
  429.  
  430. imp.configure("DS18B20-via-DS2482 Example", [], []);
  431. DS2482Reset();
  432. loop();
Advertisement
RAW Paste Data Copied
Advertisement