-
Notifications
You must be signed in to change notification settings - Fork 10
/
MainPage.dox
359 lines (244 loc) · 7.8 KB
/
MainPage.dox
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/**
@mainpage Weather fetching on Atmega32 + ESP8266 + LCD1602
### About
[See the full docs!](http://styczynski.ml/avr-weather-esp8266/)
[And also see this on git!](https://github.com/isis97/avr-weather-esp8266)
@image html view.gif
### Short description
This project tends to implement:
* ESP8266 module messaging from AVR controller
* Basic Http request + JSON parsing
* LCD support
### Why it has been made?
Because of the microcontroller exercises we did on our studies.
### What does it do?
* Boots up (if you press any key) the avr enters
`settings mode` and asks for wifi creditentials
* If no key was pressed during boot then normal procedure takes place
* AVR tries to connect to the wifi
* Then connects to `openweathermap.com`
* Asks politely for weather data for `Warsaw`
* Then fetches `JSON` with the most trivial ways
* Displays the data
* And sometimes refreshes the collected data :)
### Pinout
#### Main wirings
The AVR connections are basic and listed below:
```javascript
'ATMEGA32' PA0 -> D4 'LCD'
'ATMEGA32' PA1 -> D5 'LCD'
'ATMEGA32' PA2 -> D6 'LCD'
'ATMEGA32' PA3 -> D7 'LCD'
'ATMEGA32' PA4 -> RS 'LCD'
'ATMEGA32' PA5 -> RW 'LCD'
'ATMEGA32' PA6 -> E 'LCD'
'ATMEGA32' RXD -> TX 'ESP8266'
'ATMEGA32' TXD -> RX 'ESP8266'
'ESP8266' EN -> VCC 'ESP8266'
```
And of course `V0`, `VCC`, `GND`, `VSS`, `VDD`, `A`, `K` but they are trivial.
#### Buttons
And not mentioned in layout two buttons for settings screen:
```javascript
'ATMEGA32' PD6 -(BUTTON)-> GND
'ATMEGA32' PD7 -(BUTTON)-> GND
```
In settings mode:
* `PD6` is used have next character functionality.
* `PD7` changes current character.
Schematic of connections (pretty small - try to enlarge with zooming hand):
@image html scheme.svg
**Notice:**
*The `ESP8266` module was connected to the `5V USB` plug.
The module is designed to work for 3V but working on higher
voltage is possible (as demonstrated in this case).*
*It's straightforward method and in normal conidtions
you should redesign scheme a little and provide 3V voltage source
for your wifi module.*
*You will probably need logic level shifting
form `5V (atemga)` to `3V (esp8266)` or you can just run atmega on 3V
(notice that LCD needs standard 5V anyway!)*
#### Mounting
You can mount the wires propably on pcb plate I used universal brakboard
that does not require soldering but it's rather a messy pile of cables, huh!
### About building
#### Build process
**Warnning!**
*Before building make sure all it's configured correctly (see configuration for more details)!*
To build the project do the following:
* Create release folder e.g. `mkdir release`
* Go into that folder `cd release`
* Run CMAKE to generate needed makefiles `cmake ..`
* Build app using make `make`
* Optionally update documentation throught `make doc`
* Optionally setup manually the needed fuse bits using `avrdude`!
* Flash controller with `make upload`
* Optionally clean build with `make clean`
#### Configuration
Before continouing make sure that `USSID` and `PASSWD` Variables
in `src/main.c` are configured to use with your wifi access point.
Then make sure that `APIKEY` in line with `wifi_send` is matching
apikey for your openweathermap account.
And the url is for location desired by you.
See `openweathermap api documentation` for more details :)
The main controller config is placed in `CMakeLists.txt` file.
Please change these as you wish:
```bash
# Variables regarding the AVR chip
set(MCU atmega32)
set(F_CPU 8000000)
set(BAUD 9600)
set(PROG_TYPE usbasp)
set(PROG_ARGS )
```
`BAUD` is not really needed and `PROG_ARGS` are additional paramters for avrdude.
Basic example config for `Atmega328P-PU` running (by default) at 1MHz:
```bash
# Variables regarding the AVR chip
set(MCU atmega328p)
set(F_CPU 1000000)
set(BAUD 2400)
set(PROG_TYPE usbasp)
set(PROG_ARGS )
```
### Some source code
This snippet presents piece of source code from `main.c`
(and is good introduction to the project insides as well as wifi.h module):
@code
// Handle ESP8266 events
void wifi_event_handler(int event, const char* input, const int len) {
switch(event) {
case WIFI_EVENT_ANY: {
//
// You can display the input
// To provide debug info
// This kind of event (ANY)
// is called for any event
//
return;
} break;
case WIFI_EVENT_ERROR: {
// We got error!
} break;
// ESP8266 is not responding
case WIFI_EVENT_TIMEOUT: {
// We got timeout!
} break;
// Wifi was connected
case WIFI_EVENT_WIFI_CONNECTED: {
// We are conneted to the access point!
} break;
// Wifi was disconnected
case WIFI_EVENT_WIFI_DISCONNECTED: {
// We are disconneted to the access point!
} break;
// Connect to host
case WIFI_EVENT_CONNECTED: {
// We are connected to the ip/url specified earlier throug wifi_link_open
} break;
// Host sends data
case WIFI_EVENT_DATA: {
//
// Look for JSON data in response
//
search_json(weather_descr, input, "description");
search_json(weather_name, input, "name");
search_json(weather_data_buf, input, "humidity");
sscanf(weather_data_buf, "%lf", &weather_humidity);
search_json(weather_data_buf, input, "pressure");
sscanf(weather_data_buf, "%d", &weather_pressure);
search_json(weather_data_buf, input, "temp");
sscanf(weather_data_buf, "%lf", &weather_temp);
// We do not need this connection anymore
wifi_link_close();
// Format received data
sprintf(info1, "%s Weather:", weather_name);
sprintf(info2, "%s | Temp: %.1lf C | Humidity: %.0lf %% | Pressure: %d HPa", weather_name, weather_temp-273.15, weather_humidity, weather_pressure );
//
// Display data continously in text shifting manner
//
int shift = 0;
const int info_len = strlen(info2);
int cycles = 0;
while(1) {
lcd_clrscr();
lcd_gotoxy(0, 0);
lcd_nputs(info1, 16);
lcd_gotoxy(0, 1);
lcd_nputs(info2+shift, 16);
_delay_ms(500);
++shift;
if(shift > info_len - 4) {
shift = 0;
++cycles;
}
//
// End - return to main and then prepare next fetch request
//
if(cycles > 15) break;
}
lcd_nputs("Update...", 16);
lcd_clrscr();
} break;
}
}
int main(void) {
// Init UART
uart_init(UART_BAUD_SELECT(2400, F_CPU));
// Init buttons
//
// ...
//
// Init LCD
lcd_init(LCD_DISP_ON);
lcd_gotoxy(0, 0);
lcd_clrscr();
// Init wifi and connect to the desired network
lcd_clrscr();
lcd_puts("Initializing...");
_delay_ms(1000);
wifi_init();
//
// Check if any button was pressed
// then go into settings mode :)
//
//
// ...
//
//
// Normal boot sequence
//
normal_boot:
// Display greeting on lcd
lcd_puts("Hello");
_delay_ms(1000);
lcd_clrscr();
_delay_ms(1500);
lcd_clrscr();
lcd_puts("Conecting...");
_delay_ms(1000);
//
// Display USSID/PASSWD data on the screen
//
lcd_clrscr();
lcd_puts("ID: ");
lcd_puts(USSID);
lcd_puts("\nPASS: ");
lcd_puts(PASSWD);
_delay_ms(1500);
// Try to connect to the access point
wifi_connect(USSID, PASSWD);
while(1) {
// To make sure nothing dumb trash does not come
// through UART interface
uart_flush();
// Connect to openweathermap
wifi_link_open("TCP", "api.openweathermap.org", 80);
// Request data from REST api
wifi_send("GET /data/2.5/weather?q=warsaw&APPID=cf24c94ac2550178e2ea4e970cd0f416 HTTP/1.1\r\nHost: api.openweathermap.org\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\n\r\n\r\n");
// Wifi functions will call wifi_event_handler function on any event (it's callback function)
}
return 0;
}
@endcode
*/