1 |
1: #include <pic18.h> |
1: #include <pic18.h> |
2 |
2: #include <stdio.h> |
2: #include <stdio.h> |
3 |
3: #include <string.h> |
3: #include <htc.h> |
4 |
4: #include "lcd.h" |
4: #include <string.h> |
5 |
5: #include "Delay.h" |
5: |
6 |
6: // Delay.h is included inside lcd.c |
6: #include "lcd.h" |
7 |
7: |
7: #include "Delay.h" |
8 |
8: #define LCD_LENGTH 16 |
8: // Delay.h is included inside lcd.c |
9 |
9: #define LCD_ROWS 2 |
9: |
10 |
10: #define SEND_BUFFER 128 |
10: #define LCD_LENGTH 16 |
11 |
11: |
11: #define LCD_ROWS 2 |
12 |
12: |
12: #define SEND_BUFFER 128 |
13 |
13: unsigned char global_Pot_Hi, global_Pot_Lo; |
13: #define PWRFAIL RB1 |
14 |
14: unsigned char global_LCD_Buffer[LCD_ROWS][LCD_LENGTH]; |
14: #define FIREDET RB2 |
15 |
15: unsigned char global_serial_send[SEND_BUFFER]; |
15: #define FEEDING RB3 |
16 |
16: unsigned char global_serial_recieve_buffer[LCD_LENGTH]; |
16: #define EMPTYTANK RB4 |
17 |
17: bit global_recieve_done = 0; |
17: |
18 |
18: int global_serial_byte_counter = 0; |
18: |
19 |
19: |
19: unsigned char global_Pot_Hi, global_Pot_Lo; |
20 |
20: void serial_recieved(void); |
20: unsigned char global_LCD_Buffer[LCD_ROWS][LCD_LENGTH]; |
21 |
21: void serial_send(void); |
21: unsigned char global_serial_send[SEND_BUFFER], global_serial_recieve_buffer[SEND_BUFFER]; |
22 |
22: void update_lcd(void); |
22: bit global_recieve_done = 0, global_interval_changed = 0; |
23 |
23: |
23: unsigned int global_serial_byte_counter = 0, global_sms_counter = 1, global_time_counter = 0; |
24 |
24: // Nicked from H7 |
24: unsigned int global_emergency_counter = 600, global_time_interval = 3600; |
25 |
25: void ad_init(void) |
25: unsigned char global_temp = 0; |
26 |
26: { |
26: |
27 |
27: // AD Conversion clock |
27: unsigned char cell_nr[15] = ""; // = "21681784"; |
28 |
28: ADCS0 = 0; |
28: |
29 |
29: ADCS1 = 0; |
29: |
30 |
30: ADCS2 = 0; |
30: __EEPROM_DATA( 60, 0, 1, 8, '2', '1', '6', '8'); |
31 |
31: |
31: __EEPROM_DATA( '1', '7', '8', '4',0,0,0,0); |
32 |
32: //Select AN0/RA0 for AD source |
32: |
33 |
33: // In this (000) setup, it's only RA0/AN0 that does ad convertion. |
33: void serial_recieved(void); |
34 |
34: CHS0=0; |
34: void serial_send(void); |
35 |
35: CHS1=0; |
35: void update_lcd(void); |
36 |
36: CHS2=0; |
36: void convertTemp(void); |
37 |
37: |
37: void timer1_interrupt(void); |
38 |
38: //Only AN0 is selected for AD and with Vdd/Vss as limits |
38: |
39 |
39: PCFG0=0; |
39: // Nicked from H7 |
40 |
40: PCFG1=1; |
40: void ad_init(void) |
41 |
41: PCFG2=1; |
41: { |
42 |
42: PCFG3=1; |
42: // AD Conversion clock |
43 |
43: |
43: ADCS0 = 0; |
44 |
44: //Result is left justified |
44: ADCS1 = 0; |
45 |
45: ADFM=0; |
45: ADCS2 = 0; |
46 |
46: |
46: |
47 |
47: //Fire up for A/D converter module |
47: //Select AN0/RA0 for AD source |
48 |
48: ADON=1; |
48: // In this (000) setup, it's only RA0/AN0 that does ad convertion. |
49 |
49: } |
49: CHS0=0; |
50 |
50: |
50: CHS1=0; |
51 |
51: void rs232_init(void) |
51: CHS2=0; |
52 |
52: { |
52: |
53 |
53: SPEN = 0; // Serial Port Enable Bit... 0 = disabled |
53: //Only AN0 is selected for AD and with Vdd/Vss as limits |
54 |
54: TRISC6 = 0; |
54: PCFG0=0; |
55 |
55: TRISC7 = 1; |
55: PCFG1=1; |
56 |
56: |
56: PCFG2=1; |
57 |
57: SPBRG = 207; // 1200 baud rate... 25 = 9600 |
57: PCFG3=1; |
58 |
58: // x = (Fosc / (16*[baud rate]) )-1 |
58: |
59 |
59: TXSTA = 0x24; // Enables BRGH and TXEN inthe TXSTA register |
59: //Result is right justified |
60 |
60: RCSTA = 0x90; // 0x90 enables SPEN and CREN in the RCSTA register |
60: ADFM=1; |
61 |
61: } |
61: |
62 |
62: |
62: //Fire up for A/D converter module |
63 |
63: void interrupt_init(void) |
63: ADON=1; |
64 |
64: { |
64: } |
65 |
65: // Assumes that all interrupts default is 0 |
65: |
66 |
66: PEIE = 1; |
66: void rs232_init(void) |
67 |
67: GIE = 1; |
67: { |
68 |
68: RCIE = 1; // Recieve interrupt enable. |
68: SPEN = 0; // Serial Port Enable Bit... 0 = disabled |
69 |
69: IPEN = 0; // Nfo interrupt priority |
69: TRISC6 = 0; |
70 |
70: TXIE = 0; // Serial interrupt enabled |
70: TRISC7 = 1; |
71 |
71: } |
71: |
72 |
72: |
72: SPBRG = 207; // 1200 baud rate... 25 = 9600 |
73 |
73: void pic18_io_init(void) |
73: // x = (Fosc / (16*[baud rate]) )-1 |
74 |
74: { |
74: TXSTA = 0x24; // Enables BRGH and TXEN inthe TXSTA register |
75 |
75: TRISA0 = 1; // analog input |
75: RCSTA = 0x90; // 0x90 enables SPEN and CREN in the RCSTA register |
76 |
76: TRISB1 = 1; // TRISB1-4 Digital input |
76: } |
77 |
77: TRISB2 = 1; |
77: |
78 |
78: TRISB3 = 1; |
78: void interrupt_init(void) |
79 |
79: TRISB4 = 1; |
79: { |
80 |
80: } |
80: // Assumes that all interrupts default is 0 |
81 |
81: |
81: PEIE = 1; |
82 |
82: void sms_init(void) |
82: GIE = 1; |
83 |
83: { |
83: RCIE = 1; // Recieve interrupt enable. |
84 |
84: int i = 1; |
84: IPEN = 0; // Nfo interrupt priority |
85 |
85: sprintf(global_serial_send,"%s", "at+cpin=8043\r"); |
85: TXIE = 0; // Serial interrupt enabled |
86 |
86: serial_send(); |
86: TMR1IE = 1; // Enables timer 1 |
87 |
87: DelaySek(60); |
87: } |
88 |
88: |
88: |
89 |
89: update_lcd(); |
89: void timer_init(void) |
90 |
90: DelaySek(5); |
90: { |
91 |
91: |
91: TMR1CS = 1; //use external clock |
92 |
92: sprintf(global_serial_send,"%s%s", "at+cmgs=","\"22337617\"\r"); |
92: |
93 |
93: serial_send(); |
93: T1CKPS1 = 1; //1:8 prescale |
94 |
94: DelayMs(5000); |
94: T1CKPS0 = 1; |
95 |
95: |
95: |
96 |
96: sprintf(global_serial_send,"%s%d%c","Dette er test nr: ", i, 0x1A); |
96: TMR1H = 0xEF; |
97 |
97: serial_send(); |
97: TMR1L = 0xFF; |
98 |
98: DelayMs(5000); |
98: |
99 |
99: i++; |
99: T1OSCEN = 1; //enable oscillator circuit |
100 |
100: |
100: RD16 = 0; //normal 8 bit writes |
101 |
101: } |
101: TMR1ON = 1; |
102 |
102: |
102: } |
103 |
103: void interrupt interrupt_handler(void) |
103: |
104 |
104: { |
104: void pic18_io_init(void) |
105 |
105: // Finds out what interrupt have been trigged, and starts the respective function. |
105: { |
106 |
106: if(RCIF == 1) // Serial recieve interrupt |
106: TRISA0 = 1; // analog input |
107 |
107: { |
107: TRISA1 = 0; // Output |
108 |
108: serial_recieved(); |
108: TRISB1 = 1; // TRISB1-4 Digital input |
109 |
109: RCIF = 0; |
109: TRISB2 = 1; |
110 |
110: } |
110: TRISB3 = 1; |
111 |
111: } |
111: TRISB4 = 1; |
112 |
112: |
112: } |
113 |
113: |
113: |
114 |
114: |
114: void sms_init(void) |
115 |
115: void serial_send(void) |
115: { |
116 |
116: { |
116: int i; |
117 |
117: int i; |
117: |
118 |
118: // char tosend[3]; |
118: sprintf(global_serial_send,"at+cgsn\r"); |
119 |
119: char data; |
119: serial_send(); |
120 |
120: // sprintf(tosend,"%s", "at\r"); |
120: DelaySek(1); |
121 |
121: for(i = 0; i < SEND_BUFFER; i++) |
121: while(!global_recieve_done) ; |
122 |
122: { |
122: |
123 |
123: data = global_serial_send[i]; |
123: |
124 |
124: if( data == '\r') |
124: sprintf(global_serial_send,"%s", "at+cpin=8043\r"); |
125 |
125: i = (SEND_BUFFER - 1); |
125: serial_send(); |
126 |
126: TXREG = data; |
126: DelaySek(30); |
127 |
127: while(TRMT==0) ; |
127: |
128 |
128: DelayMs(1000); |
128: update_lcd(); |
129 |
129: } |
129: DelaySek(5); |
130 |
130: } |
130: } |
131 |
131: |
131: |
132 |
132: void serial_recieved(void) |
132: |
133 |
133: { |
133: void interrupt interrupt_handler(void) |
134 |
134: char data, saved_data[LCD_LENGTH]; |
134: { |
135 |
135: |
135: // Finds out what interrupt have been trigged, and starts the respective function. |
136 |
136: data = RCREG; |
136: if(RCIF == 1) // Serial recieve interrupt |
137 |
137: |
137: { |
138 |
138: global_serial_recieve_buffer[global_serial_byte_counter] = data; |
138: serial_recieved(); |
139 |
139: if(data == '\r') |
139: RCIF = 0; |
140 |
140: { |
140: } |
141 |
141: global_recieve_done = 1; |
141: |
142 |
142: global_serial_byte_counter = 0; |
142: if(TMR1IF == 1) // timer1 interrupt trigger. |
143 |
143: } |
143: { |
144 |
144: else |
144: timer1_interrupt(); |
145 |
145: { |
145: TMR1IF = 0; |
146 |
146: global_serial_byte_counter++; |
146: } |
147 |
147: } |
147: } |
148 |
148: |
148: |
149 |
149: } |
149: |
150 |
150: void update_lcd(void) |
150: void serial_send(void) |
151 |
151: { |
151: { |
152 |
152: if( global_recieve_done == 1 ) |
152: int i; |
153 |
153: { |
153: char data_byte; |
154 |
154: lcd_clear(); |
154: for(i = 0; i < SEND_BUFFER; i++) |
155 |
155: lcd_goto(0x00); |
155: { |
156 |
156: lcd_puts(global_serial_recieve_buffer); |
156: data_byte = global_serial_send[i]; |
157 |
157: global_recieve_done = 0; |
157: if( data_byte == '\r') |
158 |
158: } |
158: i = (SEND_BUFFER - 1); |
159 |
159: } |
159: TXREG = data_byte; |
160 |
160: |
160: while(TRMT==0) ; |
161 |
161: void main() |
161: DelayMs(10); |
162 |
162: { |
162: } |
163 |
163: ///////////////////////////////////////////// |
163: DelayMs(250); |
164 |
164: // Running Init's |
164: DelayMs(250); |
165 |
165: |
165: } |
166 |
166: // Running init for various components. |
166: |
167 |
167: //AD_init(); |
167: void serial_recieved(void) |
168 |
168: ad_init(); |
168: { |
169 |
169: rs232_init(); |
169: char data_byte, saved_data[LCD_LENGTH]; |
170 |
170: pic18_io_init(); |
170: |
171 |
171: lcd_init(0); |
171: data_byte = RCREG; |
172 |
172: lcd_clear(); |
172: |
173 |
173: interrupt_init(); |
173: global_serial_recieve_buffer[global_serial_byte_counter] = data_byte; |
174 |
174: sms_init(); |
174: if(data_byte == '\r') |
175 |
175: ///////////////////////////////////////////// |
175: { |
176 |
176: // Main loop |
176: global_recieve_done = 1; |
177 |
177: |
177: global_serial_byte_counter = 0; |
178 |
178: while(1) |
178: } |
179 |
179: { |
179: else |
180 |
180: // Checking if A/D convertion is done, and save the data in global_Pot_?? |
180: { |
181 |
181: if(GODONE==0) |
181: global_serial_byte_counter++; |
182 |
182: { |
182: } |
183 |
183: global_Pot_Hi = ADRESH; |
183: |
184 |
184: global_Pot_Lo = ADRESL; |
184: } |
185 |
185: GODONE = 1; |
185: |
186 |
186: } |
186: void timer1_interrupt(void) |
187 |
187: update_lcd(); |
187: { |
188 |
188: } |
188: TMR1H = 0xEF; |
189 |
189: } |
189: TMR1L = 0xFF; |
190 |
|
190: global_time_counter++; |
191 |
|
191: global_emergency_counter++; |
192 |
|
192: RA1 = !RA1; |
193 |
|
193: } |
194 |
|
194: |
195 |
|
195: void update_lcd(void) |
196 |
|
196: { |
197 |
|
197: if( global_recieve_done == 1 ) |
198 |
|
198: { |
199 |
|
199: lcd_clear(); |
200 |
|
200: lcd_goto(0x00); |
201 |
|
201: lcd_puts(global_serial_recieve_buffer); |
202 |
|
202: global_recieve_done = 0; |
203 |
|
203: } |
204 |
|
204: } |
205 |
|
205: |
206 |
|
206: void send_update(void) |
207 |
|
207: { |
208 |
|
208: sprintf(global_serial_send, "at+cmgs=\"%s\"\r", cell_nr); |
209 |
|
209: serial_send(); |
210 |
|
210: sprintf(global_serial_send, "%d:%d:%d:%d:%d:%d%c", global_sms_counter, global_temp, FIREDET, EMPTYTANK, FEEDING, PWRFAIL, 0x1A); |
211 |
|
211: lcd_goto(40); |
212 |
|
212: lcd_puts(global_serial_send); |
213 |
|
213: serial_send(); |
214 |
|
214: DelayMs(250); |
215 |
|
215: global_sms_counter++; |
216 |
|
216: } |
217 |
|
217: |
218 |
|
218: void convertTemp() |
219 |
|
219: |
220 |
|
220: { |
221 |
|
221: short adVal; |
222 |
|
222: adVal = (global_Pot_Hi << 8) | global_Pot_Lo; |
223 |
|
223: if( adVal >=840 ) |
224 |
|
224: global_temp = 100; |
225 |
|
225: else |
226 |
|
226: global_temp = (adVal / 8.3886); |
227 |
|
227: } |
228 |
|
228: |
229 |
|
229: |
230 |
|
230: |
231 |
|
231: void eeprom_writer(void) |
232 |
|
232: { |
233 |
|
233: char len,i; |
234 |
|
234: |
235 |
|
235: if( global_interval_changed ) |
236 |
|
236: { |
237 |
|
237: len = strlen(cell_nr); |
238 |
|
238: eeprom_write(0, (global_time_interval/60)); |
239 |
|
239: eeprom_write(1, global_sms_counter>>8); |
240 |
|
240: eeprom_write(2, global_sms_counter); |
241 |
|
241: eeprom_write(3, len); |
242 |
|
242: |
243 |
|
243: for (i=0; i<len; ++i) |
244 |
|
244: { |
245 |
|
245: eeprom_write(i+4, cell_nr[i] ); |
246 |
|
246: } |
247 |
|
247: |
248 |
|
248: global_interval_changed = 0; |
249 |
|
249: } |
250 |
|
250: } |
251 |
|
251: |
252 |
|
252: void eeprom_reader(void) |
253 |
|
253: { |
254 |
|
254: char len,i; |
255 |
|
255: |
256 |
|
256: global_time_interval = eeprom_read(0); |
257 |
|
257: global_time_interval *= 60; |
258 |
|
258: global_sms_counter = (eeprom_read(1)<<8) | eeprom_read(2); |
259 |
|
259: len = eeprom_read(3); |
260 |
|
260: |
261 |
|
261: for (i=0; i<len; ++i) |
262 |
|
262: { |
263 |
|
263: cell_nr[i] = eeprom_read(i+4); |
264 |
|
264: } |
265 |
|
265: |
266 |
|
266: cell_nr[i] = 0; //zero terminated! |
267 |
|
267: } |
268 |
|
268: |
269 |
|
269: |
270 |
|
270: void main() |
271 |
|
271: { |
272 |
|
272: ///////////////////////////////////////////// |
273 |
|
273: // Running Init's |
274 |
|
274: |
275 |
|
275: // Running init for various components. |
276 |
|
276: pic18_io_init(); |
277 |
|
277: rs232_init(); |
278 |
|
278: ad_init(); |
279 |
|
279: lcd_init(0); |
280 |
|
280: interrupt_init(); |
281 |
|
281: sms_init(); |
282 |
|
282: //eeprom_init(); |
283 |
|
283: timer_init(); |
284 |
|
284: eeprom_reader(); |
285 |
|
285: ///////////////////////////////////////////// |
286 |
|
286: // Main loop |
287 |
|
287: send_update(); |
288 |
|
288: while(1) |
289 |
|
289: { |
290 |
|
290: if( (global_temp >= 90 || PWRFAIL == 1 || FIREDET == 0 || FEEDING == 1 || EMPTYTANK == 1) && global_emergency_counter >= 600 ) |
291 |
|
291: { |
292 |
|
292: send_update(); |
293 |
|
293: global_emergency_counter = 0; |
294 |
|
294: } |
295 |
|
295: |
296 |
|
296: if(global_time_counter >= 3600) |
297 |
|
297: { |
298 |
|
298: send_update(); |
299 |
|
299: global_time_counter = 0; |
300 |
|
300: } |
301 |
|
301: // to avoid buffer overrun. |
302 |
|
302: if( global_emergency_counter > 7200 ) |
303 |
|
303: global_emergency_counter = 600; |
304 |
|
304: |
305 |
|
305: // Checking if A/D convertion is done, and save the data in global_Pot_?? |
306 |
|
306: if(GODONE==0) |
307 |
|
307: { |
308 |
|
308: global_Pot_Hi = ADRESH; |
309 |
|
309: global_Pot_Lo = ADRESL; |
310 |
|
310: convertTemp(); |
311 |
|
311: |
312 |
|
312: GODONE = 1; |
313 |
|
313: } |
314 |
|
314: |
315 |
|
315: update_lcd(); |
316 |
|
316: } |
317 |
|
317: |
318 |
|
318: } |