Rev Author Line No. Line
417 kakl 1 //******** Mrakomer **********
2 #define VERSION "2.0"
418 kakl 3 #define ID "$Id: irmrak.c 418 2006-12-29 19:37:29Z kakl $"
417 kakl 4 //****************************
5  
6 #include "irmrak.h"
7 #include <string.h>
8  
9 #use rs232(baud=9600,parity=N,xmit=PIN_A6,bits=8)
10  
11 #define TXo PIN_A3 // To the transmitter modulator
12 #include "AX25.c" // Podprogram pro prenos telemetrie
13 char AXstring[50]; // Buffer pro prenos telemetrie
14 char G[5];
15 char S45[5];
16 char S90[5];
17 char S135[5];
18 char VER[4]=VERSION;
19  
20 #define TRESHOLD 8 // nebo 9
21 // nad_diodou=H je + teplota
22 // pod_diodou=L je - teplota
23  
24 #define MINUS !C1OUT // je kladny impuls z IR teplomeru
25 #define PLUS C2OUT // je zaporny impuls z IR teplomeru
26 #define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu
27 // topeni je na RB3 (vystup PWM)
28  
29 #define MAX_TEMP 10000
30  
31 int port; // stav brany B pro krokove motory
32 int j; // pro synchronisaci fazi
33 unsigned int16 n, prodleva; // pocitadlo prodlevy mezi merenimi
34 unsigned int16 nn; // pocitadlo mereni
35 unsigned int8 topit; // na jaky vykon se ma topit?
36  
37 unsigned int16 teplota; // prectena teplota
38 int1 sign; // nad nulou / pod nulou
39  
40 void krok(int n)
41 {
42 while((n--)>0)
43 {
44 if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;};
45 output_B(port);
46 delay_ms(40);
47 j++;
48 }
49 }
50  
51 void dolu()
52 {
53 unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otaceni
54  
55 err=0;
56 while(!input(HALL)) // otoceni trubky dolu az na hall
57 {
58 krok(1);
59 err++;
60 if(40==err) // do 40-ti kroku by se melo podarit otocit dolu
61 {
62 output_B(0); // vypnuti motoru
63 sprintf(AXstring,"Error movement.");
64 SendPacket(&AXstring[0]);
65 printf("%s\n\r", AXstring);
66 err=0;
67 }
68 };
69 delay_ms(700); // cas na ustaleni trubky
70 output_B(0); // vypnuti motoru
71 }
72  
73 void prevod()
74 {
75 unsigned int16 t; // cas
76 unsigned int16 tt;
77  
78 t=0;
79 while(!PLUS && !MINUS)
80 {
81 t++;
82 if(t>65000)
83 {
84 sprintf(AXstring,"Error thermometer.");
85 SendPacket(&AXstring[0]);
86 printf("%s\n\r", AXstring);
87 teplota=0;
88 sign=true;
89 return;
90 }
91 }; // ceka se na 0
92  
93 teplota=0;
94 sign=false;
95 for(t=0;t<=MAX_TEMP;t++)
96 {
97 if(PLUS || MINUS) // ceka se na + nebo -
98 {
99 if(MINUS) sign=true;
100 for(tt=1;tt<=MAX_TEMP;tt++)
101 {
102 if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0
103 }
104 break;
105 }
106 }
107 teplota=teplota*19/100; // 1 stupen celsia je asi 10us
108 }
109  
110 void main()
111 {
112 unsigned int8 ble;
113  
114 setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilator
115  
116 setup_adc_ports(NO_ANALOGS|VSS_VDD);
117 setup_adc(ADC_OFF);
118 setup_spi(FALSE);
119 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWM
120 setup_timer_1(T1_DISABLED);
121 setup_ccp1(CCP_OFF);
122 setup_comparator(A0_VR_A1_VR); // inicializace komparatoru
123 setup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd
124  
125 // nastav PWM pro topeni
126 set_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupu
127 setup_ccp1(CCP_PWM);
128 setup_timer_2(T2_DIV_BY_16,100,1); // perioda
129  
130 output_B(0); // vypnuti motoru
131  
132 sprintf(AXstring,"Mrakomer V%s (C) 2006 KAKL", VER);
133 SendPacket(&AXstring[0]);
134 printf("%s\n\r", AXstring);
135  
136  
137 if(input(HALL)) // pokud na zacatku byla trubka dolu,
138 { // vysilej pro nastaveni prijimace rychle za sebou 10min
139 for(n=0; n<(10*60); n++)
140 {
141 prevod();
142 if(sign)
143 sprintf(AXstring,"Kalibrace: n %Lu, t -%Lu", n, teplota);
144 else
145 sprintf(AXstring,"Kalibrace: n %Lu, t %Lu", n, teplota);
146  
147 delay_ms(1000); // 1s
148 SendPacket(&AXstring[0]);
149 printf("%s\n\r", AXstring);
150 if(!input(HALL)) break; // pokud nekdo hne trubkou, zacni merit
151 }
152 }
153  
154 port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
155 j=0; // smer dolu
156 dolu(); // otoc trubku do vychozi pozice dolu
157 nn=0; // pocitadlo packetu
158  
159 while(true)
160 {
161 set_tris_B(0b00000111); // faze a topeni jako vystup
162 set_pwm1_duty(0); // netopit
163 port=0b01010000; // vychozi nastaveni fazi pro rizeni motoru
164 j=1; // smer, nahoru
165  
166 delay_ms(1000); // pockej pro ustaleni napeti po vypnuti topeni
167 prevod(); // jeden prevod na prazdno pro synchnonisaci
168  
169 prevod(); // zem
170 if(sign)
171 {
172 sprintf(G,"-%Lu", teplota);
173 topit=10;
174 if (teplota>5) topit=20;
175 if (teplota>10) topit=50;
176 if (teplota>20) topit=80;
177 if (teplota>30) topit=100;
178 }
179 else
180 {
181 sprintf(G,"%Lu", teplota);
182 topit=0;
183 }
184  
185 krok(2); // sjeti z koncaku
186 delay_ms(1000);
187 krok(17); // 45 stupnu
188 delay_ms(200);
189 prevod();
190 if(sign)
191 sprintf(S45,"-%Lu", teplota);
192 else
193 sprintf(S45,"%Lu", teplota);
194  
195 strcpy(S90,"-");
196 if (sign && (teplota>29))
197 {
198 krok(6); // 90 stupnu
199 delay_ms(300);
200 prevod();
201 if(sign)
202 sprintf(S90,"-%Lu", teplota);
203 else
204 sprintf(S90,"%Lu", teplota);
205 }
206  
207 strcpy(S135,"-");
208 if (sign && (teplota>29))
209 {
210 krok(6); // 135 stupnu
211 delay_ms(300);
212 prevod();
213 if(sign)
214 sprintf(S135,"-%Lu", teplota);
215 else
216 sprintf(S135,"%Lu", teplota);
217 }
218  
219 j++; // reverz
220 dolu(); // znovu otoc trubku dolu do vychozi pozice
221  
222 // odeslani vysledku mereni
223 sprintf(AXstring,
224 "n %Lu;G %s;S45 %s;S90 %s;S135 %s", nn, G, S45, S90, S135);
225 SendPacket(&AXstring[0]);
226 printf("%s\n\r", AXstring);
227  
228 if (sign && (teplota>29)) // pauza do dalsiho mereni
229 {
230 prodleva=60; // 1 min
231 nn++;
232 }
233 else
234 {
235 prodleva=600; // 10 min pri teplote atmosfery vyzsi jak -30 stupnu
236 nn+=10;
237 }
238  
239 if (nn>9999) nn=0; // pocitadlo mereni modulo 10000
240  
241 set_pwm1_duty(topit); // spust topeni
242 for(n=prodleva; n>0; n--) // cekej na dalsi mereni
243 {
244 delay_ms(1000);
245 if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil
246 {
247 set_pwm1_duty(0); // zastav topeni, aby byl odber do 1A
248 dolu();
249 set_pwm1_duty(topit); // spust topeni
250 }
251 }
252 }
253 }
254