Rev 419 Rev 420
1 //******** Mrakomer ****************************************** 1 //******** Mrakomer ******************************************
2 #define VERSION "2.1" 2 #define VERSION "2.1" // Special version for the BART
3 #define ID "$Id: irmrak.c 419 2006-12-29 19:37:38Z kakl $" 3 #define ID "$Id: irmrak.c 420 2006-12-29 21:43:11Z kakl $"
4 //************************************************************ 4 //************************************************************
5   5  
6 #include "irmrak.h" 6 #include "irmrak.h"
7 #include <string.h> 7 #include <string.h>
8   8  
9 #use rs232(baud=9600,parity=N,xmit=PIN_A6,rcv=PIN_A7,bits=8) 9 #use rs232(baud=9600,parity=N,xmit=PIN_A6,rcv=PIN_A7,bits=8)
10   10  
11 char VER[4]=VERSION; 11 char VER[4]=VERSION;
12 char REV[50]=ID; 12 char REV[50]=ID;
13   13  
14 #define TRESHOLD 8 // nebo 9 14 #define TRESHOLD 8 // nebo 9
15 // nad_diodou=H je + teplota 15 // nad_diodou=H je + teplota
16 // pod_diodou=L je - teplota 16 // pod_diodou=L je - teplota
17   17  
18 #define MINUS !C1OUT // je kladny impuls z IR teplomeru 18 #define MINUS !C1OUT // je kladny impuls z IR teplomeru
19 #define PLUS C2OUT // je zaporny impuls z IR teplomeru 19 #define PLUS C2OUT // je zaporny impuls z IR teplomeru
20 #define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu 20 #define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu
21 // topeni je na RB3 (vystup PWM) 21 // topeni je na RB3 (vystup PWM)
22   22  
23 #define MAX_TEMP 10000 23 #define MAX_TEMP 10000
24   24  
25 int port; // stav brany B pro krokove motory 25 int port; // stav brany B pro krokove motory
26 int j; // pro synchronisaci fazi 26 int j; // pro synchronisaci fazi
27 unsigned int8 uhel; // pocitadlo prodlevy mezi merenimi 27 unsigned int8 uhel; // pocitadlo prodlevy mezi merenimi
28 unsigned int8 i; // pro cyklus for 28 unsigned int8 i; // pro cyklus for
29 unsigned int16 nn; // pocitadlo mereni 29 unsigned int16 nn; // pocitadlo mereni
30 unsigned int32 timer; // casovac pro topeni 30 unsigned int32 timer; // casovac pro topeni
31 unsigned int8 topit; // na jaky vykon se ma topit? 31 unsigned int8 topit; // na jaky vykon se ma topit?
32   32  
33 unsigned int16 teplota; // prectena teplota 33 unsigned int16 teplota; // prectena teplota
34 int1 sign; // nad nulou / pod nulou 34 int1 sign; // nad nulou / pod nulou
35   35  
36 // --- Jeden krok krokoveho motoru --- 36 // --- Jeden krok krokoveho motoru ---
37 void krok(int n) 37 void krok(int n)
38 { 38 {
39 while((n--)>0) 39 while((n--)>0)
40 { 40 {
41 if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;}; 41 if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;};
42 output_B(port); 42 output_B(port);
43 delay_ms(50); 43 delay_ms(50);
44 j++; 44 j++;
45 } 45 }
46 } 46 }
47   47  
48 // --- Dojet dolu magnetem na cidlo --- 48 // --- Dojet dolu magnetem na cidlo ---
49 void dolu() 49 void dolu()
50 { 50 {
51 unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otaceni 51 unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otaceni
52   52  
53 err=0; 53 err=0;
54 while(!input(HALL)) // otoceni trubky dolu az na hall 54 while(!input(HALL)) // otoceni trubky dolu az na hall
55 { 55 {
56 krok(1); 56 krok(1);
57 err++; 57 err++;
58 if(40==err) // do 40-ti kroku by se melo podarit otocit dolu 58 if(40==err) // do 40-ti kroku by se melo podarit otocit dolu
59 { 59 {
60 output_B(0); // vypnuti motoru 60 output_B(0); // vypnuti motoru
61 printf("Error movement.\n\r"); 61 printf("Error movement.\n\r");
62 err=0; 62 err=0;
63 } 63 }
64 }; 64 };
65 delay_ms(700); // cas na ustaleni trubky 65 delay_ms(700); // cas na ustaleni trubky
66 output_B(0); // vypnuti motoru 66 output_B(0); // vypnuti motoru
67 } 67 }
68   68  
69 // --- Najeti na vychozi polohu dole --- 69 // --- Najeti na vychozi polohu dole ---
70 void nula() 70 void nula()
71 { 71 {
72 int n; 72 int n;
73   73  
74 for (n=0; n<7; n++) 74 for (n=0; n<7; n++)
75 { 75 {
76 if (!input(HALL)) return; 76 if (!input(HALL)) return;
77 krok(1); 77 krok(1);
78 } 78 }
79 } 79 }
80   80  
81 // --- Precti teplotu z IR teplomeru --- 81 // --- Precti teplotu z IR teplomeru ---
82 void prevod() 82 void prevod()
83 { 83 {
84 unsigned int16 t; // cas 84 unsigned int16 t; // cas
85 unsigned int16 tt; 85 unsigned int16 tt;
86   86  
87 t=0; 87 t=0;
88 while(!PLUS && !MINUS) 88 while(!PLUS && !MINUS)
89 { 89 {
90 t++; 90 t++;
91 if(t>65000) 91 if(t>65000)
92 { 92 {
93 printf("Error thermometer.\n\r"); 93 printf("Error thermometer.\n\r");
94 teplota=0; 94 teplota=0;
95 sign=true; 95 sign=true;
96 return; 96 return;
97 } 97 }
98 }; // ceka se na 0 98 }; // ceka se na 0
99   99  
100 teplota=0; 100 teplota=0;
101 sign=false; 101 sign=false;
102 for(t=0;t<=MAX_TEMP;t++) 102 for(t=0;t<=MAX_TEMP;t++)
103 { 103 {
104 if(PLUS || MINUS) // ceka se na + nebo - 104 if(PLUS || MINUS) // ceka se na + nebo -
105 { 105 {
106 if(MINUS) sign=true; 106 if(MINUS) sign=true;
107 for(tt=1;tt<=MAX_TEMP;tt++) 107 for(tt=1;tt<=MAX_TEMP;tt++)
108 { 108 {
109 if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0 109 if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0
110 } 110 }
111 break; 111 break;
112 } 112 }
113 } 113 }
114 teplota=teplota*19/100; // 1 stupen celsia je asi 10us 114 teplota=teplota*19/100; // 1 stupen celsia je asi 10us
115 } 115 }
116   116  
117 // --- Prevod a vystup jedne hodnoty --- 117 // --- Prevod a vystup jedne hodnoty ---
118 void vystup() 118 void vystup()
119 { 119 {
120 delay_ms(200); // pockej na ustaleni napeti po krokovani 120 delay_ms(200); // pockej na ustaleni napeti po krokovani
121 printf(" "); 121 printf(" ");
122 prevod(); // precti teplotu z teplomeru 122 prevod(); // precti teplotu z teplomeru
123 if(sign) 123 if(sign)
124 printf("-%Lu", teplota); 124 printf("-%Lu", teplota);
125 else 125 else
126 printf("%Lu", teplota); 126 printf("%Lu", teplota);
127 } 127 }
128   128  
129 //------------------------------------------------ 129 //------------------------------------------------
130 void main() 130 void main()
131 { 131 {
132 setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilator 132 setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilator
133   133  
134 setup_adc_ports(NO_ANALOGS|VSS_VDD); 134 setup_adc_ports(NO_ANALOGS|VSS_VDD);
135 setup_adc(ADC_OFF); 135 setup_adc(ADC_OFF);
136 setup_spi(FALSE); 136 setup_spi(FALSE);
137 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWM 137 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWM
138 setup_timer_1(T1_DISABLED); 138 setup_timer_1(T1_DISABLED);
139 setup_ccp1(CCP_OFF); 139 setup_ccp1(CCP_OFF);
140 setup_comparator(A0_VR_A1_VR); // inicializace komparatoru 140 setup_comparator(A0_VR_A1_VR); // inicializace komparatoru
141 setup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd 141 setup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd
142   142  
143 // nastav PWM pro topeni 143 // nastav PWM pro topeni
144 set_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupu 144 set_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupu
145 setup_ccp1(CCP_PWM); 145 setup_ccp1(CCP_PWM);
146 setup_timer_2(T2_DIV_BY_16,100,1); // perioda 146 setup_timer_2(T2_DIV_BY_16,100,1); // perioda
147   147  
148 output_B(0); // vypnuti motoru 148 output_B(0); // vypnuti motoru
149 set_tris_B(0b00000111); // faze a topeni jako vystup 149 set_tris_B(0b00000111); // faze a topeni jako vystup
150   150  
151 delay_ms(1000); 151 delay_ms(1000);
152 printf("Mrakomer V%s (C) 2006 KAKL\n\r", VER); 152 printf("Mrakomer V%s (C) 2006 KAKL\n\r", VER);
153 printf("%s\n\r", REV); 153 printf("%s\n\r", REV);
154   154  
155 topit=0; // na zacatku netopime 155 topit=0; // na zacatku netopime
156   156  
157 while(true) 157 while(true)
158 { 158 {
159 port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru 159 port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
160 j=0; // smer dolu 160 j=0; // smer dolu
161 dolu(); // otoc trubku do vychozi pozice dolu 161 dolu(); // otoc trubku do vychozi pozice dolu
162   162  
163 while(!kbhit()) 163 while(!kbhit())
164 { 164 {
165 timer--; 165 timer--;
166 if (0==timer) // casovac, aby se marakomer neupek 166 if (0==timer) // casovac, aby se marakomer neupek
167 { 167 {
168 topit=0; 168 topit=0;
169 set_pwm1_duty(0); // zastav topeni 169 set_pwm1_duty(0); // zastav topeni
170 printf("H %u\n\r", topit); 170 printf("H %u\n\r", topit);
171 }; 171 };
172   172  
173 if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil 173 if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil
174 { 174 {
175 set_pwm1_duty(0); // zastav topeni, aby byl odber do 1A 175 set_pwm1_duty(0); // zastav topeni, aby byl odber do 1A
176 dolu(); 176 dolu();
177 set_pwm1_duty(topit); // spust topeni 177 set_pwm1_duty(topit); // spust topeni
178 } 178 }
179 }; // pokracuj dal, kdyz prisel po RS232 znak 179 }; // pokracuj dal, kdyz prisel po RS232 znak
180   180  
181   181  
182 uhel=getc(); // prijmi znak 182 uhel=getc(); // prijmi znak
183 if ((uhel>='a') && (uhel<='k')) // nastaveni topeni [a..k]=(0..100%) 183 if ((uhel>='a') && (uhel<='k')) // nastaveni topeni [a..k]=(0..100%)
184 { 184 {
185 topit=uhel-'a'; 185 topit=uhel-'a';
186 topit*=10; 186 topit*=10;
187 timer=500000; // cca 11s 187 timer=500000; // cca 11s
188   188  
189 // ochrana proti upeceni 189 // ochrana proti upeceni
190 prevod(); 190 prevod();
191 if(sign) 191 if(sign)
192 { 192 {
193 if ((teplota <= 5) && (topit > 60)) topit=0; // do -5°C se da topit maximalne na 60% 193 if ((teplota <= 5) && (topit > 60)) topit=0; // do -5°C se da topit maximalne na 60%
194 printf("H %u;G -%Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating) 194 printf("H %u;G -%Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating)
195 } 195 }
196 else 196 else
197 { 197 {
198 if (teplota > 10) topit=0; // kdyz je vic jak +10°C, tak netopit 198 if (teplota > 10) topit=0; // kdyz je vic jak +10°C, tak netopit
199 if (topit > 40) topit=0; // pokud nemrzne, tak se neda topit vic jak na 40% 199 if (topit > 40) topit=0; // pokud nemrzne, tak se neda topit vic jak na 40%
200 printf("H %u;G %Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating) 200 printf("H %u;G %Lu\n\r", topit, teplota); // zobraz hodnotu topeni (<H>eating)
201 } 201 }
202 set_pwm1_duty(topit); // spust topeni 202 set_pwm1_duty(topit); // spust topeni
203 continue; 203 continue;
204 }; 204 };
205   205  
206   206  
207 if ('m'==uhel) // standardni mereni ve trech polohach 207 if ('m'==uhel) // standardni mereni ve trech polohach
208 { 208 {
209 prevod(); //jeden prevod na prazdno pro synchnonisaci 209 prevod(); //jeden prevod na prazdno pro synchnonisaci
210   210  
211 j++; // reverz, nahoru 211 j++; // reverz, nahoru
212 nula(); 212 nula();
213   213  
214 printf("G"); // mereni teploty Zeme (<G>round) 214 printf("G"); // mereni teploty Zeme (<G>round)
215 vystup(); 215 vystup();
216   216  
217 krok(15); 217 krok(15);
218 printf(";S45"); // mereni teploty 45° nad obzorem 218 printf(";S45"); // mereni teploty 45° nad obzorem
219 vystup(); 219 vystup();
220 krok(7); 220 krok(7);
221 printf(";S90"); // mereni teploty v zenitu 221 printf(";S90"); // mereni teploty v zenitu
222 vystup(); 222 vystup();
223 krok(7); 223 krok(7);
224 printf(";S135"); // mereni teploty 45° nad obzorem na druhou stranu 224 printf(";S135"); // mereni teploty 45° nad obzorem na druhou stranu
225 vystup(); 225 vystup();
226 printf("\n\r"); 226 printf("\n\r");
227   227  
228 j++; // reverz 228 j++; // reverz
229 dolu(); 229 dolu();
230   230  
231 continue; 231 continue;
232 } 232 }
233   233  
234   234  
235 if ((uhel>='0') && (uhel<='@')) // mereni v pozadovanem uhlu [0..;]=(0..11) 235 if ((uhel>='0') && (uhel<='@')) // mereni v pozadovanem uhlu [0..;]=(0..11)
236 { 236 {
237 uhel-='0'; 237 uhel-='0';
238 }; 238 };
239   239  
240 if(uhel>11) continue; // ochrana, abysme neukroutili draty 240 if(uhel>11) continue; // ochrana, abysme neukroutili draty
241   241  
242 printf("A %u;", uhel); // zobraz pozadovany uhel (<A>ngle) 242 printf("A %u;", uhel); // zobraz pozadovany uhel (<A>ngle)
243   243  
244 prevod(); // jeden prevod na prazdno pro synchnonisaci 244 prevod(); // jeden prevod na prazdno pro synchnonisaci
245   245  
246 j++; // reverz, nahoru 246 j++; // reverz, nahoru
247 nula(); 247 nula();
248   248  
249 printf("G"); // mereni teploty Zeme (<G>round) 249 printf("G"); // mereni teploty Zeme (<G>round)
250 vystup(); 250 vystup();
251   251  
252 printf(";S"); // mereni teploty pozadovanym smerem do vesmiru (<S>pace) 252 printf(";S"); // mereni teploty pozadovanym smerem do vesmiru (<S>pace)
253 krok(12); // odkrokuj do roviny 253 krok(12); // odkrokuj do roviny
254 for(i=0; i<uhel; i++) // dale odkrokuj podle pozadovaneho uhlu 254 for(i=0; i<uhel; i++) // dale odkrokuj podle pozadovaneho uhlu
255 { 255 {
256 krok(2); 256 krok(2);
257 }; 257 };
258 vystup(); 258 vystup();
259 printf("\n\r"); 259 printf("\n\r");
260   260  
261 j++; // reverz 261 j++; // reverz
262 dolu(); 262 dolu();
263 } 263 }
264 } 264 }
265   265