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