Rev Author Line No. Line
1045 jacho 1 #include "C:\Users\Honza\Documents\pic\azimut\main.h"
2  
3  
4  
5 #define PIN_SDA PIN_C4
6 #define PIN_SCL PIN_C3
7 #use i2c(master, sda=PIN_SDA, scl=PIN_SCL)
8 #use rs232(baud=9600,parity=N,xmit=PIN_C7,rcv=PIN_C6,bits=8) //rcv TXD xmit RXD
9 #include <math.h>
10  
11 //Akcelerometr
12 #define AK_W 0x38 //adresa akcelerometru zápis
13 #define AK_R 0x39 //adresa akcelerometru ètení
14 #define AK_XH 0x01 //osa X LSB
15 #define AK_XL 0x02 //osa X MSB
16 #define AK_YH 0x03 //osa Y LSB
17 #define AK_YL 0x04 //osa Y MSB
18 #define AK_ZH 0x05 //osa Z LSB
19 #define AK_ZL 0x06 //osa Z MSB
20  
21 //Magnetometr
22 #define MAG_W 0x3C //adresa akcelerometru zápis
23 #define MAG_R 0x3D //adresa akcelerometru ètení
24 #define MAG_XH 0x03 //osa X LSB
25 #define MAG_XL 0x04 //osa X MSB
26 #define MAG_ZH 0x05 //osa Y LSB
27 #define MAG_ZL 0x06 //osa Y MSB
28 #define MAG_YH 0x07 //osa Z LSB
29 #define MAG_YL 0x08 //osa Z MSB
30  
31  
32  
33  
34  
35 //pøipojení motorù
36 //AIN1 - pro vysku slunce
37 #define AIN1 PIN_D0
38 #define AIN2 PIN_D1
39 //motor A -cerveny vodic na AOUT1
40 //motor A -modry vodic na Aout2
41  
42 //AIN2 - pro azimut
43 #define BIN1 PIN_D2
44 #define BIN2 PIN_D3
45 //motor B - èerveny vodic na BOUT2
46 //motor B - modrý vodic na BOUT1
47  
48 signed int16 X, Y, Z,AX, AY, AZ;
49  
50 void setAK (void) //nastaveni akcelerometru
51 {
52 i2c_start();
53 I2C_Write(AK_W);
54 I2C_write(0x2A);
55 I2C_write(0x01); //nastaví aktivní stav
56  
57 i2c_stop();
58 }
59  
60 void setmag (void)
61 {
62 i2c_start();
63 I2C_Write(MAG_W); // W
64 I2C_Write(0x00);
65 I2C_Write(0x78);
66 i2c_stop();
67 Delay_ms(6);
68  
69 i2c_start();
70 I2C_Write(MAG_W); // W
71 I2C_Write(0x01);
72 I2C_Write(0x00);
73 i2c_stop();
74  
75 Delay_ms(6);
76  
77 i2c_start();
78 I2C_Write(MAG_W); // W
79 I2C_Write(0x02);
80 I2C_Write(0x00);
81 i2c_stop();
82 Delay_ms(6);
83 }
84  
85 int16 akR (int8 H, int8 L) //vycitani hodnot z akcelerometru
86 {
87 unsigned int8 XL=0,XH=0;
88 signed int16 x;
89  
90 i2c_start();
91 I2C_Write(AK_W);
92 I2C_write(H);
93 i2c_start();
94 I2C_Write(AK_R);
95 XH=i2c_read(0);
96 i2c_stop();
97  
98 i2c_start();
99 I2C_Write(AK_W);
100 I2C_write(L);
101 i2c_start();
102 I2C_Write(AK_R);
103 XL=i2c_read(0);
104 i2c_stop();
105  
106 x = (((unsigned int16) XH << 8) + XL ); //prevod na 16bit hodnotu
107 x=x/4;
108  
109 return x;
110 }
111  
112 int16 magR (int8 H, int8 L) //vycitani hodnot z akcelerometru
113 {
114 unsigned int8 XL=0,XH=0;
115 signed int16 x;
116  
117 i2c_start();
118 I2C_Write(MAG_W);
119 I2C_write(H);
120 i2c_start();
121 I2C_Write(MAG_R);
122 XH=i2c_read(0);
123 i2c_stop();
124  
125 i2c_start();
126 I2C_Write(MAG_W);
127 I2C_write(L);
128 i2c_start();
129 I2C_Write(MAG_R);
130 XL=i2c_read(0);
131 i2c_stop();
132  
133 x = (((unsigned int16) XH << 8) + XL );
134  
135  
136 return x;
137 }
138  
139 float vyska (void) //vypocet aktualni vysky panelu
140 {
141 printf("Akcelerometr5: \r\n",);
142  
143 X= akR (AK_XH, AK_XL);
144 Y= akR (AK_YH, AK_YL);
145 Z= akR (AK_ZH, AK_ZL);
146  
147 AX=abs(X);
148 AY=abs(Y)+250;
149 AZ=abs(Z)+250;
150  
151 float a, b;
152 a=(float)Y/Z;
153 b=atan(a);
154 b = (b/3.14)*180;
155 b=abs(b);
156  
157 if(((AX>AY) || (AX>AZ))) //indikace prevraceni panelu
158 {
159 printf("Prevracený panel)\r\n", );
160 }
161 else
162 {
163 if(Z==0) //osetreni proti deleni 0
164 {
165 if(Y>0)
166 {
167 b=180;
168 }
169 else
170 {
171 b=0;
172 }
173 }
174 else
175 {
176 if(Z>0)
177 {
178 if(Y>=0)
179 {
180 b=90+b;
181 }
182 else
183 {
184 b=90-b;
185 }
186 }
187 else
188 {
189 if(Y>=0)
190 {
191 b=180-b;
192 }
193 else
194 {
195 b=270+b;
196 }
197 }
198  
199 }
200  
201  
202  
203 }
204 printf("uhel namìreny %10.2f \r\n", b);
205 return b;
206  
207 }
208  
209 float azimut (void) //vypocet aktualni vysky panelu
210 {
211 X= magR (MAG_XH, MAG_XL);
212 Y= magR (MAG_YH, MAG_YL);
213 Z= magR (MAG_ZH, MAG_ZL);
214  
215  
216  
217  
218 AX=abs(X);
219 AY=abs(Y);
220 AZ=abs(Z);
221  
222 float a, b;
223 a=(float)Y/X;
224 b=atan(a);
225 b = (b/3.14)*180;
226 b=abs(b);
227  
228  
229  
230  
231 if(X==0) //osetreni proti deleni 0
232 {
233 if(Y>0)
234 {
235 b=90;
236 }
237 else
238 {
239 b=270;
240 }
241 }
242 else
243 {
244 if(X>0)
245 {
246 if(Y>=0)
247 {
248 b=b;
249 }
250 else
251 {
252 b=360-b;
253 }
254 }
255 else
256 {
257 if(Y>=0)
258 {
259 b=180-b;
260 }
261 else
262 {
263 b=180+b;
264 }
265 }
266  
267 }
268  
269 return b;
270  
271 }
272  
273 void motorA (int8 H) //pro ovladani prvniho motoru nastaveni vysky
274 {
275 switch(H){
276 case 1: //reverzní chod
277 output_low (AIN2);
278 output_high (AIN1);
279 break;
280  
281 case 2: //dopøedu
282 output_low (AIN1);
283 output_high (AIN2);
284 break;
285  
286 default:
287 output_low (AIN2);
288 output_low (AIN1);
289 }
290 }
291  
292 void motorB (int8 H) //pro ovladani prvniho motoru nastaveni vysky
293 {
294 switch(H){
295 case 1: //reverzní chod
296 output_low (BIN2);
297 output_high (BIN1);
298 break;
299  
300 case 2: //dopøedu
301 output_low (BIN1);
302 output_high (BIN2);
303 break;
304  
305 default:
306 output_low (BIN2);
307 output_low (BIN1);
308 }
309 }
310  
311 void vyska_set (int8 H) //slouzi pro nastaveni nove vysky panelu
312 {
313 printf("Akcelerometr4: \r\n",);
314 float a;
315 int16 b,c;
316  
317 a=vyska();
318 b= (int16) a;
319  
320 if(b>350)
321 {
322 b=0;
323 }
324 else
325 {
326  
327 }
328 c=abs(H-b);
329  
330 while(c>2) //maximalni odchylka uhlu, aby nebylo potreba panelem hybat
331 {
332 while(H!=b) //probiha dokud se uhel panelu nerovna zadanemu na cele stupne
333 {
334  
335 if(H>b)
336 {
337 motorA(2);
338  
339 }
340 else
341 {
342 motorA(1);
343 }
344  
345 delay_ms (50); //cas sepnuti motoru
346  
347 motorA(3); //vypne motor
348 delay_ms (50); //doma na ustaleni panelu pred merenim
349 a=vyska();
350 b= (int16) a;
351  
352 if(b>350) //osetreni pro uhel 0. Zabezpeci ze neprejde stav z 0 na 359 kdy by se solar zacal tocit na druhou stranu
353 {
354 b=0;
355 }
356 else
357 {
358 b=b;
359 }
360 c=abs(H-b);
361 }
362 }
363 motorA(3); //vypne motor
364 printf("Podaøené nastavení výška: %Ld\r\n", b);
365 }
366  
367 void azimut_set (int8 H) //slouzi pro nastaveni nove vysky panelu
368 {
369 float a;
370 int16 b,c;
371  
372 a=azimut();
373 b= (int16) a;
374 //printf("auhel pro mereni: %Ld(procenta)\r\n", b);
375 if(b>350)
376 {
377 b=0;
378 }
379 else
380 {
381  
382 }
383 c=abs(H-b);
384  
385 while(c>3) //maximalni odchylka uhlu, aby nebylo potreba panelem hybat
386 {
387 while(H!=b) //probiha dokud se uhel panelu nerovna zadanemu na cele stupne
388 {
389  
390 if(H>b)
391 {
392 motorB(2);
393  
394 }
395 else
396 {
397 motorB(1);
398 }
399  
400 delay_ms (50); //cas sepnuti motoru
401  
402 motorB(3); //vypne motor
403 delay_ms (50); //doma na ustaleni panelu pred merenim
404 a=azimut();
405 b= (int16) a;
406  
407 if(b>350) //osetreni pro uhel 0. Zabezpeci ze neprejde stav z 0 na 359 kdy by se solar zacal tocit na druhou stranu
408 {
409 b=0;
410 }
411 else
412 {
413 b=b;
414 }
415 c=abs(H-b);
416 }
417 }
418 motorA(3); //vypne motor
419 printf("Podaøené nastavení azimut: %Ld\r\n", b);
420 }
421  
422  
423 void main()
424 {
425  
426 setup_adc_ports(NO_ANALOGS|VSS_VDD);
427 setup_adc(ADC_CLOCK_DIV_2);
428 setup_spi(SPI_SS_DISABLED);
429 setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
430 setup_timer_1(T1_DISABLED);
431 setup_timer_2(T2_DISABLED,0,1);
432 setup_ccp1(CCP_OFF);
433 setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
434  
435 setup_adc_ports(PIN_A0); //piny pro A/D RA0
436 setup_adc_ports(PIN_A1); //piny pro A/D RA1
437  
438 printf("Akcelerometr: \r\n",);
439  
440 motorA(3);
441  
442 float a, b;
443 unsigned int value1=10,value2=10;
444  
445  
446 setAK(); //nastaveni akcelerometru
447 setmag();
448 printf("Akcelerometr1: \r\n",);
449 while(TRUE)
450 {
451  
452 printf("Akcelerometr2: \r\n",);
453  
454  
455  
456  
457  
458 /// set_adc_channel(0); //nastavi AD na kanál 0 (RA0)
459 /// read_adc(ADC_START_ONLY); // Spustime A/D prevod
460 // Delay_ms(1);
461 // while(!adc_done()); // Cekame na dokonceni prevodu
462 // value1=read_adc(); // Precteme hodnotu z prevodniku
463 vyska_set (90);
464 azimut_set(0);
465 printf("zadaný azimut %d \r\n", value1);
466  
467 // set_adc_channel(1); //nastavi AD na kanál 1 (RA1)
468 // read_adc(ADC_START_ONLY); // Spustime A/D prevod
469 // Delay_ms(1);
470 // while(!adc_done()); // Cekame na dokonceni prevodu
471 // value2=read_adc();
472 //vyska_set (90);
473  
474  
475 delay_ms (2000);
476  
477  
478 }
479 }