- OWINIT save Register used in C
[owSlave2.git] / DS18B20_VOC_DS2438_SHT / DS18B20_DS2438.c
1
2 // Copyright (c) 2015, Tobias Mueller tm(at)tm3d.de
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //  * Redistributions of source code must retain the above copyright
10 //    notice, this list of conditions and the following disclaimer.
11 //  * Redistributions in binary form must reproduce the above copyright
12 //    notice, this list of conditions and the following disclaimer in the
13 //    documentation and/or other materials provided with the
14 //    distribution.
15 //  * All advertising materials mentioning features or use of this
16 //    software must display the following acknowledgement: This product
17 //    includes software developed by tm3d.de and its contributors.
18 //  * Neither the name of tm3d.de nor the names of its contributors may
19 //    be used to endorse or promote products derived from this software
20 //    without specific prior written permission.
21 //
22 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34 #define F_CPU 8000000UL
35 #include <avr/io.h>
36 #include <avr/interrupt.h>
37 #include <util/delay.h>
38 #include <avr/wdt.h>
39 #include <avr/sleep.h>
40 #include <avr/pgmspace.h>
41 #include "../common/I2C/USI_TWI_Master.h"
42 #include "../common/I2C/MAX1164x.h"
43 #include "../common/I2C/SHT2x.h"
44 #include "../common/calibr.h"
45
46 extern void OWINIT();
47 extern void EXTERN_SLEEP();
48
49
50
51 volatile uint8_t owid1[8]={0x28, 0xA3, 0xD9, 0x84, 0x00, 0x16, 0x05, 0x18};/**/
52 volatile uint8_t owid2[8]={0x26, 0xA3, 0xD9, 0x84, 0x00, 0x16, 0x05, 0x67};/**/
53 volatile uint8_t config_info1[16]={0x08,0x01, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};        
54 volatile uint8_t config_info2[16]={0x01,0x06, 0x05,0x08, 0x04,0x07, 0x07,0x08, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00};        
55         
56 #if (owid>128) 
57 #error "Variable not correct"
58 #endif
59
60 extern uint8_t mode;
61 extern uint8_t gcontrol;
62 extern uint8_t reset_indicator;
63 extern uint8_t alarmflag;
64 volatile uint8_t wdcounter=1;
65
66
67 #if  defined(__AVR_ATtiny24__)||defined(__AVR_ATtiny44__)  || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny24A__)||defined(__AVR_ATtiny44A__)  || defined(__AVR_ATtiny84A__)
68 ISR(WATCHDOG_vect) {
69 #else
70 ISR(WDT_vect) {
71 #endif 
72         wdcounter++;
73         if (reset_indicator==1) reset_indicator++;
74         else if (reset_indicator==2) mode=0;
75
76
77 }
78
79
80 typedef union {
81         volatile uint8_t bytes[8];
82         struct {
83                 uint16_t temp;  //0
84                 uint8_t TH;  //2
85                 uint8_t TL;  //3
86                 uint8_t config;  //4
87                 uint8_t rrFF; //5
88                 uint8_t rr00; //6
89                 uint8_t rr10; //7
90         };
91 } pack1_t;
92 volatile pack1_t pack1;
93
94
95
96 typedef union {
97         #if  defined(__AVR_ATtiny25__)
98         volatile uint8_t bytes[16];
99         #else
100         volatile uint8_t bytes[64];
101         #endif
102         struct {
103                 uint8_t status;  //1
104                 int16_t temp;  //2
105                 uint16_t voltage;  //4
106                 int16_t current;  //6
107                 uint8_t threshold; //8
108                 
109                 uint8_t page1[8]; //9
110                 #if  defined(__AVR_ATtiny25__)
111                 #else
112                 uint8_t page2[8]; //17
113                 uint8_t page3[8]; //25
114                 uint8_t page4[8];  //33
115                 uint8_t page5[8];  //41
116                 uint8_t page6[8];  //49
117                 uint8_t page7[8];  //57
118                 //uint8_t crc;  //65
119                 #endif
120         };
121 } pack2_t;
122 volatile pack2_t pack2;
123
124
125
126
127 volatile int16_t am2302_temp;
128 volatile uint16_t am2302_hum;
129
130
131 uint8_t userRegister[1];
132 int16_t sRH,sT;
133 double temperatureC,humidityRH,hhum;
134 double l;
135
136 uint8_t max_adr=0;
137 #define CH0_M MAX1164x_C_SCAN0|MAX1164x_C_SGL
138 #define CH1_M MAX1164x_C_SCAN0|MAX1164x_C_SGL|MAX1164x_C_CS0
139 #define CH0_CH1 MAX1164x_C_SCAN0
140 //|MAX1164x_C_CS0
141
142
143 inline double interp(double t, double h) {
144         double h2;
145          double t2;
146         h2=h*h;
147         t2=t*t;
148         return 4.76111e-9*h2*t2-3.96956e-7*h2*t+0.0000408889*h2-1.07132e-6*h*t2+0.000115968*h*t-0.0101333*h+0.000163806*t2-0.0241179*t+1.80591;
149 }
150
151 uint8_t cmode=0;
152 double R0=0;
153 int16_t hr;
154 uint8_t startup=5;
155 uint8_t reset_R0=0;
156 int16_t mr;
157 double ip;
158
159 int main(void){
160         //volatile double test=calibr_hum(20,1,20);
161     PRR|=(1<<PRADC);  // adc for save Power
162         pack1.temp=0x0550;
163         pack1.config=0x7F;
164         pack1.TH=75;
165         pack1.TL=70;
166         pack1.rrFF=0xFF;
167         pack1.rr00=0;
168         pack1.rr10=0x10;
169         PORTA=0xFF;
170         PORTB=0xFF;
171         OWINIT();
172         PORTB|=(1<<PINB1);
173         DDRB|=(1<<PINB1);
174         PORTA|=(1<<PINA0);
175         DDRA|=(1<<PINA0);
176         
177         MCUCR &=~(1<<PUD); //All Pins Pullup...
178         MCUCR |=(1<<BODS);
179         
180         while(EECR & (1<<EEPE));
181         EEARL=1;
182         EECR |= (1<<EERE);
183         hr=EEDR;
184         if (hr!=0xFF) {
185                 hr=hr<<8;
186                 while(EECR & (1<<EEPE));
187                 EEARL=0;
188                 EECR |= (1<<EERE);
189                 hr|=EEDR;
190                 R0=hr/100.0;
191                 pack2.page3[0]=hr&0xFF;
192                 pack2.page3[1]=(hr>>8)&0xFF;
193         }
194
195         
196
197         WDTCSR |= ((1<<WDCE) );   // Enable the WD Change Bit//| (1<<WDE)
198         WDTCSR |=   (1<<WDIE) |              // Enable WDT Interrupt
199         (1<<WDP0) |(1<<WDP2) | (1<<WDP1);    // Set Timeout to ~2 seconds
200         //(1<<WDP3) | (1<<WDP0);    // Set Timeout to ~8 seconds
201
202         MCUSR=0;
203         USI_TWI_Master_Initialise();
204         
205         SHT2x_SoftReset();
206         SHT2x_ReadUserRegister(userRegister);
207         //(userRegister & ~SHT2x_RES_MASK) | SHT2x_RES_10_13BIT;
208         SHT2x_WriteUserRegister(userRegister); //write changed user reg
209         // --- measure humidity with "Hold Master Mode (HM)" ---
210         //SHT2x_MeasurePoll(HUMIDITY, &sRH);
211         // --- measure temperature with "Polling Mode" (no hold master) ---
212         //SHT2x_MeasurePoll(TEMP, &sT);
213         //-- calculate humidity and temperature --
214         //temperatureC = SHT2x_CalcTemperatureC(sT);
215         //humidityRH = SHT2x_CalcRH(sRH);
216         MAX1164x_config(MAX1164x_S_SEL2|MAX1164x_S_SEL0,CH0_M);//#define MAX1164x_C_CS0
217         _delay_ms(30); //Internal Referenz start
218         //2970 -> 1,5V  
219         gcontrol=1;
220         sei();
221         //DDRB|=(1<<PINB1);
222     while(1)   {
223                 if (pack1.config==0x1F) {
224                         if (reset_R0==0) {
225                                 reset_R0=1;
226                                 pack1.config=0x7F;
227                                 R0=0;
228                                 hr=R0*100;
229                                 pack2.page3[0]=hr&0xFF;
230                                 pack2.page3[1]=(hr>>8)&0xFF;
231                                 
232                                 while(EECR & (1<<EEPE));
233                                 EECR = (0<<EEPM1)|(0<<EEPM0);
234                                 EEARL = 0;
235                                 EEDR = hr&0xFF;
236                                 EECR |= (1<<EEMPE);
237                                 EECR |= (1<<EEPE);
238                                 while(EECR & (1<<EEPE));
239                                 EECR = (0<<EEPM1)|(0<<EEPM0);
240                                 EEARL = 1;
241                                 EEDR = hr>>8;
242                                 EECR |= (1<<EEMPE);
243                                 EECR |= (1<<EEPE);
244
245                         }
246                 } else reset_R0=0;                      //PORTB|=(1<<PINB1); //Dauer 440ms
247                 if (wdcounter>0) {
248                         if (startup!=0) startup--;
249                         SHT2x_MeasurePoll(HUMIDITY, &sRH);
250                         // --- measure temperature with "Polling Mode" (no hold master) ---
251                         SHT2x_MeasurePoll(TEMP, &sT);
252                         //-- calculate humidity and temperature --
253                         temperatureC = SHT2x_CalcTemperatureC(sT);
254                         humidityRH = SHT2x_CalcRH(sRH);
255                         ip=interp(temperatureC,humidityRH);
256                         humidityRH=calibr_hum(temperatureC,-1,humidityRH)*10.0;
257                         //humidityRH=humidityRH*10.0;
258                         temperatureC =temperatureC *10.0-10;
259                         hhum=(1.0546-0.000216*temperatureC)*(humidityRH);
260                         am2302_hum=0.318*hhum +76.0;
261                         am2302_temp=temperatureC*25.6;
262                         //PORTB&=~(1<<PINB1);
263                         mr=0;
264 //Kritische Sektion !______________________________
265                         PORTB&=~(1<<PINB1);
266                         _delay_us(150);
267                         mr+=MAX1164x_read();
268                         _delay_us(150);
269                         mr+=MAX1164x_read();
270                         
271                         PORTB|=(1<<PINB1);
272 //ENDE Kritische Sektion !______________________________
273                         //l=mr/2.0*2.048/4096; 
274                         // l maximal 2  mr max 4096  //mr 2V=8000 
275                         
276                         if (cmode) {
277                                 //l+=1.5; //Spannung real
278                                 mr+=6000;
279                         } 
280                         //if (l>1.8) {
281                         if (mr>7200) {                          
282                                 if (cmode==0) {
283                                         MAX1164x_config(MAX1164x_S_SEL2|MAX1164x_S_SEL0,CH0_CH1);
284                                         cmode=1;
285                                         pack2.page3[4]=cmode;
286                                 }
287                         }
288                         //if (l<1.6) {
289                         if (mr<6400) {  
290                                 if (cmode==1) {
291                                         MAX1164x_config(MAX1164x_S_SEL2|MAX1164x_S_SEL0,CH0_M);
292                                         cmode=0;
293                                         pack2.page3[4]=cmode;
294                                 }
295                                 
296                                 
297                         }
298                         //hr=l*10000.0;
299                         hr=mr*5/2;
300                         pack2.page3[2]=hr&0xFF;
301                         pack2.page3[3]=(hr>>8)&0xFF;
302                         l=mr/4000.0;
303                         l=( 3/l- 1) *30;
304                         pack2.current=l*100;
305                         //ip=interp(temperatureC,humidityRH);
306                         hr=ip*1000;
307                         pack2.page3[5]=hr&0xFF;
308                         pack2.page3[6]=(hr>>8)&0xFF;
309                         
310                         l=l/ip;
311                         
312                         if (startup==0){
313                         if (l>R0) {
314                                 R0=l;
315                                 hr=R0*100;
316                                 pack2.page3[0]=hr&0xFF;
317                                 pack2.page3[1]=(hr>>8)&0xFF;
318                                 
319                                 while(EECR & (1<<EEPE));
320                                 EECR = (0<<EEPM1)|(0<<EEPM0);
321                                 EEARL = 0;
322                                 EEDR = hr&0xFF;
323                                 EECR |= (1<<EEMPE);
324                                 EECR |= (1<<EEPE);
325                                 while(EECR & (1<<EEPE));
326                                 EECR = (0<<EEPM1)|(0<<EEPM0);
327                                 EEARL = 1;
328                                 EEDR = hr>>8;
329                                 EECR |= (1<<EEMPE);
330                                 EECR |= (1<<EEPE);
331
332                         }
333                         }
334                          l=l/R0;
335                         l=log(1/l);
336                         l=l*160*4; //fuer DS18B20
337                         if (l>500) {
338                                 l=100;
339                         }
340                         wdcounter=0;
341                         
342                 }
343         
344                 if (gcontrol==1) {
345                         uint16_t w=l;
346                         uint8_t t8=w>>4;
347                         uint8_t af=0;
348                         if (t8>pack1.TH) af=1;
349                         if (t8<=pack1.TL) af=1; 
350                         cli();
351                         pack1.temp=w;
352                         //pack.temp++;
353                         alarmflag=af;
354                         sei();                  
355                         EXTERN_SLEEP();         
356                 }
357                 if ((gcontrol==2)||(gcontrol==3)) {
358                         gcontrol=0;
359                         
360                 }
361
362                 
363 #if  defined(__AVR_ATtiny25__)||defined(__AVR_ATtiny45__)  || defined(__AVR_ATtiny85__)
364                         if (((TIMSK & (1<<TOIE0))==0)&& (mode==0))
365 #endif                  
366 #if  defined(__AVR_ATtiny24__)||defined(__AVR_ATtiny44__)  || defined(__AVR_ATtiny84__) ||defined(__AVR_ATtiny24A__)||defined(__AVR_ATtiny44A__)  || defined(__AVR_ATtiny84A__)
367                         if (((TIMSK0 & (1<<TOIE0))==0)&& (mode==0))
368 #endif
369                           {
370
371                         MCUCR|=(1<<SE)|(1<<SM1);
372                         MCUCR&=~(1<<ISC01);
373                 } else {
374                         MCUCR|=(1<<SE);
375                         MCUCR&=~(1<<SM1);
376                 }
377                 asm("SLEEP");
378    }
379
380
381 }