Browse Source

added 18B20 and iButton support

Ondřej Hruška 2 years ago
parent
commit
8ec65f2a25
Signed by: Ondřej Hruška <ondra@ondrovo.com> GPG key ID: 2C5FD5035250423D
3 changed files with 118 additions and 42 deletions
  1. 72 26
      main.c
  2. 41 12
      onewire.c
  3. 5 4
      onewire.h

+ 72 - 26
main.c View File

@@ -55,53 +55,99 @@ void main()
55 55
 	char charbuf[21];
56 56
 
57 57
 	int dots = 0;
58
+	bool signal = false, last_signal;
58 59
 	while (1) {
59
-        bool signal = ow_reset(OW_PIN);
60
+        last_signal = signal;
61
+        signal = ow_reset(OW_PIN);
60 62
         if (!signal) {
61
-            lcd_clear();
62
-            lcd_puts("No 1-Wire detected...");
63
+            if (last_signal) {
64
+                lcd_clear();
65
+            }
66
+            lcd_puts_xy(0,0,"No 1-Wire detected..");
63 67
             dots = 0;
64 68
         } else {
69
+            if (!last_signal) {
70
+                lcd_clear();
71
+            }
72
+
65 73
             ow_write(OW_PIN, 0x33);
66 74
             ow_read_arr(OW_PIN, addr, 8);
67 75
 
68
-            lcd_clear();
76
+            // Show chip type
77
+            switch (addr[0]) {
78
+                case 0x10:
79
+                    sprintf(charbuf, "18S20  ");
80
+                    break;
69 81
 
82
+                case 0x28:
83
+                    sprintf(charbuf, "18B20  ");
84
+                    break;
85
+
86
+                case 0x01:
87
+                    sprintf(charbuf, "iButton");
88
+                    break;
89
+
90
+                default:
91
+                    sprintf(charbuf, "UNKNOWN");
92
+                    break;
93
+            }
94
+            lcd_puts_xy(12, 0, charbuf);
95
+
96
+            // Show address
70 97
             char *p = charbuf;
71 98
             for(uint8_t i = 0; i < 4; i++) {
72 99
                 p += sprintf(p, "%02X", addr[i]);
73 100
                 if (i < 3) *p++ = ':';
74 101
             }
75
-            lcd_puts(charbuf);
76
-            lcd_xy(0, 1);
102
+            lcd_puts_xy(0, 0, charbuf);
103
+
77 104
 
78 105
             p = charbuf;
79 106
             for(uint8_t i = 0; i < 4; i++) {
80 107
                 p += sprintf(p, "%02X", addr[4+i]);
81 108
                 if (i < 3) *p++ = ':';
82 109
             }
83
-            lcd_puts(charbuf);
84
-
85
-            ds1820_single_measure(OW_PIN);
86
-            uint16_t cels = ds1820_read_temp_c(OW_PIN);
110
+            lcd_puts_xy(0, 1, charbuf);
111
+
112
+            // Measure temperature
113
+            int16_t cels;
114
+            if (addr[0] == 0x10 || addr[0] == 0x28) {
115
+                ds18x20_single_measure(OW_PIN);
116
+                if (addr[0] == 0x10) {
117
+                    // 18S20
118
+                    cels = ds18s20_read_temp_c(OW_PIN);
119
+                } else {
120
+                    // 18B20
121
+                    cels = ds18b20_read_temp_c(OW_PIN);
122
+                }
87 123
 
88
-            if (cels == 850) {
89
-                lcd_xy(12, 0);
90
-                for(uint8_t i = 0; i <= dots; i++) {
91
-                    lcd_putc('.');
124
+                if (cels == TEMP_ERROR || cels == 850) {
125
+                    lcd_xy(12, 1);
126
+                    for (uint8_t i = 0; i <= dots; i++) {
127
+                        lcd_putc('.');
128
+                    }
129
+                    dots = (dots + 1) % 3;
130
+                }
131
+                else {
132
+                    p = charbuf;
133
+
134
+                    if (cels < 0) {
135
+                        *p++ = '-';
136
+                        cels = -cels;
137
+                    }
138
+
139
+                    p += sprintf(p, "%d", cels / 10);
140
+                    *p++ = '.';
141
+                    p += sprintf(p, "%d", cels % 10);
142
+                    *p++ = 0xDF; // ring symbol
143
+                    *p++ = 'C';
144
+                    *p++ = ' '; // padding to prevent artifacts if the number shrinks (we're not clearing screen when 1w is connected)
145
+                    *p++ = ' ';
146
+                    *p++ = ' ';
147
+                    *p = 0;
148
+
149
+                    lcd_puts_xy(12, 1, charbuf);
92 150
                 }
93
-                dots = (dots+1)%3;
94
-            } else {
95
-                p = charbuf;
96
-                p += sprintf(p, "%d", cels/10);
97
-                *p++ = '.';
98
-                p += sprintf(p, "%d", cels%10);
99
-                *p++ = 0xDF;
100
-                *p++ = 'C';
101
-                *p++ = 0;
102
-
103
-                lcd_xy(12, 0);
104
-                lcd_puts(charbuf);
105 151
             }
106 152
         }
107 153
 

+ 41 - 12
onewire.c View File

@@ -189,9 +189,8 @@ uint8_t crc8(uint8_t *addr, uint8_t len)
189 189
 
190 190
 // --- utils for DS1820 ---
191 191
 
192
-
193
-/** Read temperature in 0.0625°C, or TEMP_ERROR on error */
194
-int16_t ds1820_read_temp(uint8_t pin)
192
+/** Read temperature in 0.0625°C */
193
+int16_t ds18s20_read_temp(uint8_t pin)
195 194
 {
196 195
 	ow_write(pin, READ_SCRATCHPAD);
197 196
 	uint8_t bytes[9];
@@ -213,24 +212,54 @@ int16_t ds1820_read_temp(uint8_t pin)
213 212
 	}
214 213
 }
215 214
 
215
+int16_t conv0_0625to0_1(int32_t temp) {
216
+	temp *= 625;
217
+	uint16_t rem = temp % 1000;
218
+	temp /= 1000;
219
+	if (rem >= 500) temp++;
220
+	return (int16_t) temp;
221
+}
222
+
216 223
 /** Read temperature in 0.1°C, or TEMP_ERROR on error */
217
-int16_t ds1820_read_temp_c(uint8_t pin)
224
+int16_t ds18s20_read_temp_c(uint8_t pin)
225
+{
226
+	int16_t value = ds18s20_read_temp(pin);
227
+	if (value == TEMP_ERROR) return TEMP_ERROR;
228
+	return conv0_0625to0_1(value);
229
+}
230
+
231
+/** Read temperature in 0.0625°C */
232
+uint16_t ds18b20_read_temp(uint8_t pin)
218 233
 {
219
-	int32_t temp = ds1820_read_temp(pin);
234
+	ow_write(pin, READ_SCRATCHPAD);
235
+	uint8_t bytes[9];
236
+	ow_read_arr(pin, bytes, 9);
220 237
 
221
-	if (temp == TEMP_ERROR)
238
+	uint8_t crc = crc8(bytes, 8);
239
+	if (crc != bytes[8]) {
222 240
 		return TEMP_ERROR;
241
+	}
223 242
 
224
-	temp *= 625;
225
-	uint16_t rem = temp % 1000;
226
-	temp /= 1000;
227
-	if (rem >= 500) temp++;
243
+	int32_t value = bytes[0] | ((bytes[1] & 0x7) << 8); // value in 0.0625
244
+	if (bytes[1] & 0x80) {
245
+		value = -value;
246
+	}
247
+	if (value == 0x0550) {
248
+		return TEMP_ERROR;
249
+	}
228 250
 
229
-	return (int16_t) temp;
251
+	return value;
230 252
 }
231 253
 
254
+/** Read temperature in 0.1°C, or TEMP_ERROR on error */
255
+int16_t ds18b20_read_temp_c(uint8_t pin)
256
+{
257
+	int16_t value = ds18b20_read_temp(pin);
258
+	if (value == TEMP_ERROR) return TEMP_ERROR;
259
+	return conv0_0625to0_1(value);
260
+}
232 261
 
233
-bool ds1820_single_measure(uint8_t pin)
262
+bool ds18x20_single_measure(uint8_t pin)
234 263
 {
235 264
 	ow_reset(pin);
236 265
 	ow_write(pin, SKIP_ROM);

+ 5 - 4
onewire.h View File

@@ -40,14 +40,15 @@ uint8_t crc8(uint8_t *addr, uint8_t len);
40 40
  * Read temperature in 0.0625°C, or TEMP_ERROR on error
41 41
  * Use this where you'd normally use READ_SCRATCHPAD
42 42
  */
43
-int16_t ds1820_read_temp(uint8_t pin);
44
-
43
+int16_t ds18s20_read_temp(uint8_t pin);
45 44
 
46 45
 /**
47 46
  * Read temperature in 0.1°C, or TEMP_ERROR on error
48 47
  * Use this where you'd normally use READ_SCRATCHPAD
49 48
  */
50
-int16_t ds1820_read_temp_c(uint8_t pin);
49
+int16_t ds18s20_read_temp_c(uint8_t pin);
50
+
51
+int16_t ds18b20_read_temp_c(uint8_t pin);
51 52
 
52 53
 /**
53 54
  * Perform a temperature measurement with single DS1820 device on the line
@@ -55,4 +56,4 @@ int16_t ds1820_read_temp_c(uint8_t pin);
55 56
  *
56 57
  * Returns false on failure (device not connected)
57 58
  */
58
-bool ds1820_single_measure(uint8_t pin);
59
+bool ds18x20_single_measure(uint8_t pin);