//******** Mrakomer **********#define VERSION "2.0"#define ID "$Id: irmrak.c 418 2006-12-29 19:37:29Z kakl $"//****************************#include "irmrak.h"#include <string.h>#use rs232(baud=9600,parity=N,xmit=PIN_A6,bits=8)#define TXo PIN_A3 // To the transmitter modulator#include "AX25.c" // Podprogram pro prenos telemetriechar AXstring[50]; // Buffer pro prenos telemetriechar G[5];char S45[5];char S90[5];char S135[5];char VER[4]=VERSION;#define TRESHOLD 8 // nebo 9// nad_diodou=H je + teplota// pod_diodou=L je - teplota#define MINUS !C1OUT // je kladny impuls z IR teplomeru#define PLUS C2OUT // je zaporny impuls z IR teplomeru#define HALL PIN_A4 // Hallova sonda pro zjisteni natoceni dolu// topeni je na RB3 (vystup PWM)#define MAX_TEMP 10000int port; // stav brany B pro krokove motoryint j; // pro synchronisaci faziunsigned int16 n, prodleva; // pocitadlo prodlevy mezi merenimiunsigned int16 nn; // pocitadlo mereniunsigned int8 topit; // na jaky vykon se ma topit?unsigned int16 teplota; // prectena teplotaint1 sign; // nad nulou / pod nulouvoid krok(int n){while((n--)>0){if (1==(j&1)) {port^=0b11000000;} else {port^=0b00110000;};output_B(port);delay_ms(40);j++;}}void dolu(){unsigned int8 err; // pocitadlo pro zjisteni zaseknuti otacenierr=0;while(!input(HALL)) // otoceni trubky dolu az na hall{krok(1);err++;if(40==err) // do 40-ti kroku by se melo podarit otocit dolu{output_B(0); // vypnuti motorusprintf(AXstring,"Error movement.");SendPacket(&AXstring[0]);printf("%s\n\r", AXstring);err=0;}};delay_ms(700); // cas na ustaleni trubkyoutput_B(0); // vypnuti motoru}void prevod(){unsigned int16 t; // casunsigned int16 tt;t=0;while(!PLUS && !MINUS){t++;if(t>65000){sprintf(AXstring,"Error thermometer.");SendPacket(&AXstring[0]);printf("%s\n\r", AXstring);teplota=0;sign=true;return;}}; // ceka se na 0teplota=0;sign=false;for(t=0;t<=MAX_TEMP;t++){if(PLUS || MINUS) // ceka se na + nebo -{if(MINUS) sign=true;for(tt=1;tt<=MAX_TEMP;tt++){if(!PLUS && !MINUS) {teplota=tt; break;}; // ceka se na 0}break;}}teplota=teplota*19/100; // 1 stupen celsia je asi 10us}void main(){unsigned int8 ble;setup_oscillator(OSC_4MHZ|OSC_INTRC); // 4 MHz interni RC oscilatorsetup_adc_ports(NO_ANALOGS|VSS_VDD);setup_adc(ADC_OFF);setup_spi(FALSE);setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); // Casovac pro PWMsetup_timer_1(T1_DISABLED);setup_ccp1(CCP_OFF);setup_comparator(A0_VR_A1_VR); // inicializace komparatorusetup_vref(VREF_HIGH|TRESHOLD); // 32 kroku od 0.25 do 0.75 Vdd// nastav PWM pro topeniset_pwm1_duty(0); // Spust PWM, ale zatim s trvalou 0 na vystupusetup_ccp1(CCP_PWM);setup_timer_2(T2_DIV_BY_16,100,1); // periodaoutput_B(0); // vypnuti motorusprintf(AXstring,"Mrakomer V%s (C) 2006 KAKL", VER);SendPacket(&AXstring[0]);printf("%s\n\r", AXstring);if(input(HALL)) // pokud na zacatku byla trubka dolu,{ // vysilej pro nastaveni prijimace rychle za sebou 10minfor(n=0; n<(10*60); n++){prevod();if(sign)sprintf(AXstring,"Kalibrace: n %Lu, t -%Lu", n, teplota);elsesprintf(AXstring,"Kalibrace: n %Lu, t %Lu", n, teplota);delay_ms(1000); // 1sSendPacket(&AXstring[0]);printf("%s\n\r", AXstring);if(!input(HALL)) break; // pokud nekdo hne trubkou, zacni merit}}port=0b01010000; // vychozi nastaveni fazi pro rizeni motoruj=0; // smer doludolu(); // otoc trubku do vychozi pozice dolunn=0; // pocitadlo packetuwhile(true){set_tris_B(0b00000111); // faze a topeni jako vystupset_pwm1_duty(0); // netopitport=0b01010000; // vychozi nastaveni fazi pro rizeni motoruj=1; // smer, nahorudelay_ms(1000); // pockej pro ustaleni napeti po vypnuti topeniprevod(); // jeden prevod na prazdno pro synchnonisaciprevod(); // zemif(sign){sprintf(G,"-%Lu", teplota);topit=10;if (teplota>5) topit=20;if (teplota>10) topit=50;if (teplota>20) topit=80;if (teplota>30) topit=100;}else{sprintf(G,"%Lu", teplota);topit=0;}krok(2); // sjeti z koncakudelay_ms(1000);krok(17); // 45 stupnudelay_ms(200);prevod();if(sign)sprintf(S45,"-%Lu", teplota);elsesprintf(S45,"%Lu", teplota);strcpy(S90,"-");if (sign && (teplota>29)){krok(6); // 90 stupnudelay_ms(300);prevod();if(sign)sprintf(S90,"-%Lu", teplota);elsesprintf(S90,"%Lu", teplota);}strcpy(S135,"-");if (sign && (teplota>29)){krok(6); // 135 stupnudelay_ms(300);prevod();if(sign)sprintf(S135,"-%Lu", teplota);elsesprintf(S135,"%Lu", teplota);}j++; // reverzdolu(); // znovu otoc trubku dolu do vychozi pozice// odeslani vysledku merenisprintf(AXstring,"n %Lu;G %s;S45 %s;S90 %s;S135 %s", nn, G, S45, S90, S135);SendPacket(&AXstring[0]);printf("%s\n\r", AXstring);if (sign && (teplota>29)) // pauza do dalsiho mereni{prodleva=60; // 1 minnn++;}else{prodleva=600; // 10 min pri teplote atmosfery vyzsi jak -30 stupnunn+=10;}if (nn>9999) nn=0; // pocitadlo mereni modulo 10000set_pwm1_duty(topit); // spust topenifor(n=prodleva; n>0; n--) // cekej na dalsi mereni{delay_ms(1000);if (!input(HALL)) // znovuotoceni trubky dolu, kdyby ji vitr otocil{set_pwm1_duty(0); // zastav topeni, aby byl odber do 1Adolu();set_pwm1_duty(topit); // spust topeni}}}}