| Line 1... | 
        Line 1... | 
      
      
        | 1 | 
        /**** Automatic weather station 01A ****/ | 
        1 | 
        /**** Automatic weather station 01A ****/ | 
      
      
        | 2 | 
        #define VERSION "0.1" | 
        2 | 
        #define VERSION "0.1" | 
      
      
        | 3 | 
        #define ID "$Id: main.c 3086 2013-06-22 16:48:02Z kaklik $" | 
        3 | 
        #define ID "$Id: main.c 3133 2013-07-04 11:36:46Z kaklik $" | 
      
      
        | 4 | 
        #include "main.h" | 
        4 | 
        #include "main.h" | 
      
      
        | 5 | 
        #include ".\common\dbloader.h" | 
        5 | 
        #include ".\common\dbloader.h" | 
      
      
        | 6 | 
        #include <string.h> | 
        6 | 
        #include <string.h> | 
      
      
        | 7 | 
          | 
        7 | 
          | 
      
      
        | 8 | 
        #CASE    // Case sensitive compiler | 
        8 | 
        #CASE    // Case sensitive compiler | 
      
      
        | 9 | 
          | 
        9 | 
          | 
      
      
        | 10 | 
        #define  SEND_DELAY     50       // Time between two characters on RS232 | 
        10 | 
        #define  SEND_DELAY     50       // Time between two characters on RS232 | 
      
      
        | - | 
          | 
        11 | 
        #define  RESPONSE_DELAY 100      // Reaction time after receiving a command | 
      
      
        | - | 
          | 
        12 | 
        #define  MEASURE_DELAY  1000     // Delay to a next measurement | 
      
      
        | 11 | 
          | 
        13 | 
          | 
      
      
        | 12 | 
        char  VER[4]=VERSION;   // Buffer for concatenate of a version string | 
        14 | 
        char  VER[4]=VERSION;   // Buffer for concatenate of a version string | 
      
      
        | 13 | 
          | 
        15 | 
          | 
      
      
        | 14 | 
        #define ONE_WIRE_PIN       PIN_B1    // DS18B20 sensor connection | 
        16 | 
        #define ONE_WIRE_PIN       PIN_B1    // DS18B20 sensor connection | 
      
      
        | 15 | 
        #include "..\ds1820.c" | 
        17 | 
        #include "..\ds1820.c" | 
      
      
        | Line 23... | 
        Line 25... | 
      
      
        | 23 | 
          | 
        25 | 
          | 
      
      
        | 24 | 
        #define CSN_SPI PIN_C2        // preassure sensor connection | 
        26 | 
        #define CSN_SPI PIN_C2        // preassure sensor connection | 
      
      
        | 25 | 
        #include "..\MPL115A1.c" | 
        27 | 
        #include "..\MPL115A1.c" | 
      
      
        | 26 | 
          | 
        28 | 
          | 
      
      
        | 27 | 
        unsigned int16 timer0_overflow_count; | 
        29 | 
        unsigned int16 timer0_overflow_count; | 
      
      
        | - | 
          | 
        30 | 
        unsigned int16 timer1_overflow_count; | 
      
      
        | 28 | 
        float anemo; | 
        31 | 
        float anemo_max; | 
      
      
        | 29 | 
          | 
        32 | 
          | 
      
      
        | 30 | 
        int1  barometer_present; | 
        33 | 
        int1  barometer_present; | 
      
      
        | 31 | 
          | 
        34 | 
          | 
      
      
        | - | 
          | 
        35 | 
        float anemo_compute() | 
      
      
        | - | 
          | 
        36 | 
        { | 
      
      
        | - | 
          | 
        37 | 
           float anemo; | 
      
      
        | - | 
          | 
        38 | 
           anemo = ((timer0_overflow_count * 0xFF) + get_timer0())/(((timer1_overflow_count * 0xFFFF) + get_timer1())/32768.0); // pulses per second calculation | 
      
      
        | - | 
          | 
        39 | 
           anemo = anemo / 10.5;  // frequency divided by anemomether constant. | 
      
      
        | - | 
          | 
        40 | 
           return anemo; | 
      
      
        | - | 
          | 
        41 | 
        } | 
      
      
        | - | 
          | 
        42 | 
          | 
      
      
        | 32 | 
        #int_TIMER1 | 
        43 | 
        #int_TIMER1 | 
      
      
        | 33 | 
        void  TIMER1_isr(void)  | 
        44 | 
        void  TIMER1_isr(void)  | 
      
      
        | 34 | 
        { | 
        45 | 
        { | 
      
      
        | 35 | 
        // wind speed calculation 32.768 kHz crystal on timer1 oscilator expected. | 
        46 | 
           float anemo; | 
      
      
        | 36 | 
          anemo = ((timer0_overflow_count * 0xFF) + get_timer0())/(0xFFFF/32768.0); // pulses per second calculation | 
        47 | 
           anemo = anemo_compute();    | 
      
      
        | 37 | 
          anemo = anemo / 10.5;  // frequency divided by anemomether constant. | 
        48 | 
           if (anemo > anemo_max) anemo_max=anemo; | 
      
      
        | 38 | 
          | 
        49 | 
          | 
      
      
        | 39 | 
          timer0_overflow_count=0; | 
        50 | 
           timer1_overflow_count++; | 
      
      
        | 40 | 
          set_timer0(0); | 
        - | 
          | 
      
      
        | 41 | 
          set_timer1(0); | 
        - | 
          | 
      
      
        | 42 | 
          output_toggle(PIN_E0); | 
        - | 
          | 
      
      
        | 43 | 
        } | 
        51 | 
        } | 
      
      
        | 44 | 
          | 
        52 | 
          | 
      
      
        | 45 | 
        #int_TIMER0		// anemometr pulses counting timer owerflow | 
        53 | 
        #int_TIMER0      // anemometr pulses counting timer owerflow | 
      
      
        | 46 | 
        void  TIMER0_isr(void)  | 
        54 | 
        void  TIMER0_isr(void)  | 
      
      
        | 47 | 
        { | 
        55 | 
        { | 
      
      
        | 48 | 
         timer0_overflow_count++; | 
        56 | 
           timer0_overflow_count++; | 
      
      
        | 49 | 
        } | 
        57 | 
        } | 
      
      
        | 50 | 
          | 
        58 | 
          | 
      
      
        | 51 | 
        /*#int_default | 
        59 | 
        /*#int_default | 
      
      
        | 52 | 
        void default_isr() | 
        60 | 
        void default_isr() | 
      
      
        | 53 | 
        { | 
        61 | 
        { | 
      
      
        | Line 64... | 
        Line 72... | 
      
      
        | 64 | 
        //   printf("# ver seq "); | 
        72 | 
        //   printf("# ver seq "); | 
      
      
        | 65 | 
        //   printf("#temp[mK] hum_temp[mK] hum[%%] "); | 
        73 | 
        //   printf("#temp[mK] hum_temp[mK] hum[%%] "); | 
      
      
        | 66 | 
        //   printf("bar_temp[mK] pressure[hPa]  Anemo[m/s]check\r\n\r\n"); | 
        74 | 
        //   printf("bar_temp[mK] pressure[hPa]  Anemo[m/s]check\r\n\r\n"); | 
      
      
        | 67 | 
        } | 
        75 | 
        } | 
      
      
        | 68 | 
          | 
        76 | 
          | 
      
      
        | - | 
          | 
        77 | 
        void print_slow(char *output, int8 *check) | 
      
      
        | - | 
          | 
        78 | 
        { | 
      
      
        | - | 
          | 
        79 | 
           int8 j;           // String pointer | 
      
      
        | - | 
          | 
        80 | 
           j=0; | 
      
      
        | - | 
          | 
        81 | 
           while(output[j]!=0)  | 
      
      
        | - | 
          | 
        82 | 
           {  | 
      
      
        | - | 
          | 
        83 | 
              delay_us(SEND_DELAY); | 
      
      
        | - | 
          | 
        84 | 
              putc(output[j]);  | 
      
      
        | - | 
          | 
        85 | 
              *check^=output[j++];  | 
      
      
        | - | 
          | 
        86 | 
           } | 
      
      
        | - | 
          | 
        87 | 
        } | 
      
      
        | - | 
          | 
        88 | 
          | 
      
      
        | - | 
          | 
        89 | 
          | 
      
      
        | 69 | 
        void main() | 
        90 | 
        void main() | 
      
      
        | 70 | 
        { | 
        91 | 
        { | 
      
      
        | 71 | 
        unsigned int16 seq=0; | 
        92 | 
           unsigned int16 seq=0; | 
      
      
        | 72 | 
          | 
        93 | 
          | 
      
      
        | 73 | 
           setup_oscillator(OSC_8MHZ);       // pri prouziti bootloaderu neni treba nastavovat | 
        94 | 
           setup_oscillator(OSC_8MHZ);       // pri prouziti bootloaderu neni treba nastavovat | 
      
      
        | 74 | 
           setup_wdt(WDT_2304MS); | 
        95 | 
           setup_wdt(WDT_2304MS); | 
      
      
        | 75 | 
           restart_wdt();  //---WDT | 
        96 | 
           restart_wdt();  //---WDT | 
      
      
        | 76 | 
           setup_adc_ports(NO_ANALOGS|VSS_VDD); | 
        97 | 
           setup_adc_ports(NO_ANALOGS|VSS_VDD); | 
      
      
        | Line 80... | 
        Line 101... | 
      
      
        | 80 | 
           setup_timer_2(T2_DISABLED,0,1); | 
        101 | 
           setup_timer_2(T2_DISABLED,0,1); | 
      
      
        | 81 | 
           setup_ccp1(CCP_OFF); | 
        102 | 
           setup_ccp1(CCP_OFF); | 
      
      
        | 82 | 
           setup_comparator(NC_NC_NC_NC);      // This device COMP currently not supported by the PICWizard | 
        103 | 
           setup_comparator(NC_NC_NC_NC);      // This device COMP currently not supported by the PICWizard | 
      
      
        | 83 | 
           setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_64); | 
        104 | 
           setup_spi(SPI_MASTER | SPI_MODE_0 | SPI_CLK_DIV_64); | 
      
      
        | 84 | 
           output_high(CSN_SPI); | 
        105 | 
           output_high(CSN_SPI); | 
      
      
        | - | 
          | 
        106 | 
           int1 repeat; | 
      
      
        | - | 
          | 
        107 | 
           float anemo; | 
      
      
        | 85 | 
          | 
        108 | 
          | 
      
      
        | 86 | 
           welcome();   // welcome print and device indentification | 
        109 | 
           welcome();   // welcome print and device indentification | 
      
      
        | 87 | 
            | 
        110 | 
            | 
      
      
        | 88 | 
           enable_interrupts(INT_TIMER1);   // interrupts used for anemometer readings | 
        111 | 
           enable_interrupts(INT_TIMER1);   // interrupts used for anemometer readings | 
      
      
        | 89 | 
           enable_interrupts(INT_TIMER0); | 
        112 | 
           enable_interrupts(INT_TIMER0); | 
      
      
        | Line 101... | 
        Line 124... | 
      
      
        | 101 | 
           // anemometer init | 
        124 | 
           // anemometer init | 
      
      
        | 102 | 
           set_timer0(0); | 
        125 | 
           set_timer0(0); | 
      
      
        | 103 | 
           set_timer1(0); | 
        126 | 
           set_timer1(0); | 
      
      
        | 104 | 
           timer0_overflow_count=0; | 
        127 | 
           timer0_overflow_count=0; | 
      
      
        | 105 | 
           anemo=0; | 
        128 | 
           anemo=0; | 
      
      
        | - | 
          | 
        129 | 
           repeat=TRUE; | 
      
      
        | 106 | 
            | 
        130 | 
            | 
      
      
        | 107 | 
           restart_wdt();  //---WDT | 
        131 | 
           restart_wdt();  //---WDT | 
      
      
        | - | 
          | 
        132 | 
           delay_ms(1000); | 
      
      
        | 108 | 
          | 
        133 | 
          | 
      
      
        | 109 | 
           while (TRUE) | 
        134 | 
           while (TRUE) | 
      
      
        | 110 | 
           { | 
        135 | 
           { | 
      
      
        | - | 
          | 
        136 | 
              do | 
      
      
        | - | 
          | 
        137 | 
              { | 
      
      
        | 111 | 
           char output[8];   // Output buffer | 
        138 | 
                 delay_ms(RESPONSE_DELAY); | 
      
      
        | - | 
          | 
        139 | 
        //---WDT | 
      
      
        | 112 | 
           int8 j;           // String pointer | 
        140 | 
                 restart_wdt(); | 
      
      
        | 113 | 
           int8 check=0;     // Checksum is calculated between '$' and '*' | 
        141 | 
              } while (!kbhit()&&!repeat); | 
      
      
        | - | 
          | 
        142 | 
          | 
      
      
        | - | 
          | 
        143 | 
        //---WDT | 
      
      
        | 114 | 
           float SHT_temp1=0,SHT_hum1=0; | 
        144 | 
              restart_wdt(); | 
      
      
        | - | 
          | 
        145 | 
          | 
      
      
        | 115 | 
           float SHT_temp2=0,SHT_hum2=0; | 
        146 | 
              {                 // Retrieve command | 
      
      
        | 116 | 
           float local_temp;  | 
        147 | 
                 char ch='k'; | 
      
      
        | - | 
          | 
        148 | 
          | 
      
      
        | 117 | 
           float barometer_temperature, barometer_pressure; | 
        149 | 
                 if(kbhit()) ch=getc(); | 
      
      
        | 118 | 
          | 
        150 | 
          | 
      
      
        | 119 | 
             delay_ms(1000); | 
        151 | 
                 switch (ch) | 
      
      
        | - | 
          | 
        152 | 
                 { | 
      
      
        | 120 | 
                 { // printf | 
        153 | 
                    case 'i': | 
      
      
        | - | 
          | 
        154 | 
                       welcome();              // Information about version, etc... | 
      
      
        | - | 
          | 
        155 | 
                       break;                  // Only when dome is closed | 
      
      
        | 121 | 
          | 
        156 | 
          | 
      
      
        | 122 | 
             local_temp = ds1820_read()+27315; | 
        157 | 
                    case 's': | 
      
      
        | 123 | 
             sht_rd(SHT_temp1,SHT_hum1); | 
        158 | 
                       repeat=FALSE;            // Single measure mode | 
      
      
        | 124 | 
             SHT_temp1 = (SHT_temp1 + 273.15)*100; | 
        159 | 
                       break; | 
      
      
        | 125 | 
              | 
        160 | 
          | 
      
      
        | 126 | 
             SHT_temp2 = SHT25_get_temp(); | 
        161 | 
                    case 'r': | 
      
      
        | 127 | 
             SHT_hum2 = SHT25_get_hum(); | 
        162 | 
                       repeat=TRUE;            // Repeat mode | 
      
      
        | 128 | 
             SHT_temp2 = (SHT_temp2 + 273.15)*100; | 
        163 | 
                       break; | 
      
      
        | 129 | 
          | 
        164 | 
          | 
      
      
        | 130 | 
             if (barometer_present == TRUE) | 
        165 | 
                    case 'u': | 
      
      
        | - | 
          | 
        166 | 
                       reset_cpu();             // Update firmware | 
      
      
        | - | 
          | 
        167 | 
                 } | 
      
      
        | 131 | 
             { | 
        168 | 
              } | 
      
      
        | - | 
          | 
        169 | 
          | 
      
      
        | 132 | 
               barometer_temperature =  (MPL_get_temperature() + 273.15)*100; | 
        170 | 
              char output[8];   // Output buffer | 
      
      
        | 133 | 
               barometer_pressure = MPL_get_pressure() * 10.0; // conversion to hectopascals | 
        171 | 
              int8 check=0;     // Checksum is calculated between '$' and '*' | 
      
      
        | - | 
          | 
        172 | 
              float SHT_temp1=0,SHT_hum1=0; | 
      
      
        | - | 
          | 
        173 | 
              float SHT_temp2=0,SHT_hum2=0; | 
      
      
        | 134 | 
             } | 
        174 | 
              float local_temp;  | 
      
      
        | - | 
          | 
        175 | 
              float barometer_temperature, barometer_pressure; | 
      
      
        | 135 | 
             else | 
        176 | 
              float anemo; | 
      
      
        | - | 
          | 
        177 | 
          | 
      
      
        | - | 
          | 
        178 | 
          | 
      
      
        | 136 | 
             { | 
        179 | 
              { // printf | 
      
      
        | - | 
          | 
        180 | 
          | 
      
      
        | 137 | 
               barometer_temperature =  0; | 
        181 | 
                 local_temp = ds1820_read()+27315; | 
      
      
        | 138 | 
               barometer_pressure = 0; | 
        182 | 
                 sht_rd(SHT_temp1,SHT_hum1); | 
      
      
        | 139 | 
             } | 
        183 | 
                 SHT_temp1 = (SHT_temp1 + 273.15)*100; | 
      
      
        | 140 | 
              | 
        184 | 
              | 
      
      
        | - | 
          | 
        185 | 
                 SHT_temp2 = SHT25_get_temp(); | 
      
      
        | - | 
          | 
        186 | 
                 SHT_hum2 = SHT25_get_hum(); | 
      
      
        | - | 
          | 
        187 | 
                 SHT_temp2 = (SHT_temp2 + 273.15)*100;               | 
      
      
        | - | 
          | 
        188 | 
                 if (barometer_present == TRUE) | 
      
      
        | - | 
          | 
        189 | 
                 { | 
      
      
        | - | 
          | 
        190 | 
                    barometer_temperature =  (MPL_get_temperature() + 273.15)*100; | 
      
      
        | - | 
          | 
        191 | 
                    barometer_pressure = MPL_get_pressure() * 10.0; // conversion to hectopascals | 
      
      
        | - | 
          | 
        192 | 
                 } | 
      
      
        | - | 
          | 
        193 | 
                 else | 
      
      
        | - | 
          | 
        194 | 
                 { | 
      
      
        | - | 
          | 
        195 | 
                    barometer_temperature =  0; | 
      
      
        | - | 
          | 
        196 | 
                    barometer_pressure = 0; | 
      
      
        | - | 
          | 
        197 | 
                 } | 
      
      
        | - | 
          | 
        198 | 
          | 
      
      
        | 141 | 
                 delay_us(SEND_DELAY); | 
        199 | 
                 delay_us(SEND_DELAY); | 
      
      
        | 142 | 
                 putc('$'); | 
        200 | 
                 putc('$'); | 
      
      
        | 143 | 
                 delay_us(SEND_DELAY); | 
        201 | 
                 delay_us(SEND_DELAY); | 
      
      
        | 144 | 
                 sprintf(output,"AWS%s \0",VER); | 
        202 | 
                 sprintf(output,"AWS%s \0",VER); | 
      
      
        | 145 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        203 | 
                 print_slow(output, &check); | 
      
      
        | 146 | 
                 sprintf(output,"%Lu \0", seq); | 
        204 | 
                 sprintf(output,"%Lu \0", seq); | 
      
      
        | 147 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        205 | 
                 print_slow(output, &check); | 
      
      
        | 148 | 
                 sprintf(output,"%5.0f \0", local_temp ); | 
        206 | 
                 sprintf(output,"%5.0f \0", local_temp ); | 
      
      
        | 149 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        207 | 
                 print_slow(output, &check); | 
      
      
        | 150 | 
                 sprintf(output,"%5.0f \0", SHT_temp1); | 
        208 | 
                 sprintf(output,"%5.0f \0", SHT_temp1); | 
      
      
        | 151 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        209 | 
                 print_slow(output, &check); | 
      
      
        | 152 | 
                 sprintf(output,"%3.1f \0", SHT_hum1); | 
        210 | 
                 sprintf(output,"%3.1f \0", SHT_hum1); | 
      
      
        | 153 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        211 | 
                 print_slow(output, &check); | 
      
      
        | 154 | 
                 sprintf(output,"%5.0f \0", SHT_temp2); | 
        212 | 
                 sprintf(output,"%5.0f \0", SHT_temp2); | 
      
      
        | 155 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        213 | 
                 print_slow(output, &check); | 
      
      
        | 156 | 
                 sprintf(output,"%3.1f \0", SHT_hum2); | 
        214 | 
                 sprintf(output,"%3.1f \0", SHT_hum2); | 
      
      
        | 157 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        215 | 
                 print_slow(output, &check); | 
      
      
        | 158 | 
                 sprintf(output,"%5.0f \0", barometer_temperature); | 
        216 | 
                 sprintf(output,"%5.0f \0", barometer_temperature); | 
      
      
        | 159 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        217 | 
                 print_slow(output, &check); | 
      
      
        | 160 | 
                 sprintf(output,"%5.1f \0", barometer_pressure); | 
        218 | 
                 sprintf(output,"%5.1f \0", barometer_pressure); | 
      
      
        | - | 
          | 
        219 | 
                 print_slow(output, &check); | 
      
      
        | - | 
          | 
        220 | 
                  | 
      
      
        | - | 
          | 
        221 | 
                 //anemo = ((timer0_overflow_count * 0xFF) + get_timer0())/(((timer1_overflow_count * 0xFFFF) + get_timer1())/32768.0); // pulses per second calculation | 
      
      
        | 161 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        222 | 
                 //anemo = anemo / 10.5;  // frequency divided by anemomether constant. | 
      
      
        | - | 
          | 
        223 | 
                 sprintf(output,"%3.1f \0", anemo_compute()); | 
      
      
        | - | 
          | 
        224 | 
          | 
      
      
        | - | 
          | 
        225 | 
                 timer0_overflow_count=0; | 
      
      
        | - | 
          | 
        226 | 
                 timer1_overflow_count=0; | 
      
      
        | - | 
          | 
        227 | 
                 set_timer0(0); | 
      
      
        | - | 
          | 
        228 | 
                 set_timer1(0); | 
      
      
        | - | 
          | 
        229 | 
                  | 
      
      
        | - | 
          | 
        230 | 
                 print_slow(output, &check); | 
      
      
        | 162 | 
                 sprintf(output,"%3.1f \0", anemo); | 
        231 | 
                 //sprintf(output,"%3.1f \0", anemo_max); | 
      
      
        | 163 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j]); check^=output[j++]; } | 
        232 | 
                 //print_slow(output, &check); | 
      
      
        | - | 
          | 
        233 | 
          | 
      
      
        | - | 
          | 
        234 | 
                 //anemo_max = 0; | 
      
      
        | - | 
          | 
        235 | 
          | 
      
      
        | 164 | 
                 sprintf(output,"*%X\r\n\0", check); | 
        236 | 
                 sprintf(output,"*%X\r\n\0", check); | 
      
      
        | 165 | 
                 j=0; while(output[j]!=0) { delay_us(SEND_DELAY); putc(output[j++]); } | 
        237 | 
                 print_slow(output, &check); | 
      
      
        | - | 
          | 
        238 | 
          | 
      
      
        | 166 | 
                 delay_us(SEND_DELAY); | 
        239 | 
                 delay_us(SEND_DELAY); | 
      
      
        | 167 | 
              } | 
        240 | 
              } | 
      
      
        | 168 | 
          | 
        241 | 
          | 
      
      
        | 169 | 
        //---WDT | 
        242 | 
        //---WDT | 
      
      
        | 170 | 
              restart_wdt(); | 
        243 | 
              restart_wdt(); | 
      
      
        | 171 | 
                    seq++;        // Increment the number of measurement | 
        244 | 
              seq++;        // Increment the number of measurement | 
      
      
        | - | 
          | 
        245 | 
              delay_ms(MEASURE_DELAY); | 
      
      
        | 172 | 
           } | 
        246 | 
           } | 
      
      
        | 173 | 
        } | 
        247 | 
        } | 
      
      
        | 174 | 
          | 
        248 | 
          |