-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
443 lines (398 loc) · 15.2 KB
/
main.c
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
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#include <stdio.h> // printf,
#include <stdlib.h> // atoi
#include <string.h> // strncpy, strtok, strlen, strcmp,
#include "display.h" // write_char, init_display, clear_display
#include "sensor.h" // Sensor, print_sensor_to_console,
#include "serial.h" // uart_configure, uart_send_string, serialReadBytes
#include "comunication.h" // command_to_int
#include "utils.h" // await
#include "menu.h" // menu
#include "help.h"
int get_number_of_digital_ios();
char *getSubstring(char *dst, const char *src, size_t start, size_t end);
void separate_string_in_3(char *str, char a[10], char b[10], char c[10]);
void print_io_name_and_id(int max_digital);
int add_digital_sensor(char *sensor_info, Sensor *digital);
/**
* @brief Realiza a leitura de sensores de forma automatizada atraves de comunicação serial
* da raspberry pi
*
* @param argc Numero de argumentos da linha de comando recebidos
* @param argv Lista de argumentos recebidos
* @return int Retorna 0 se executado com sucesso. Qualquer outro valor em caso de execução incorreta
*/
int main(int argc, char *argv[]) {
// Configuração inicial
init_display(); // configura o display
init_display();
init_display();
clear_display(); // Limpa o conteudo do diaplay
write_string("Iniciando");
uart_configure(); // configura a uart
unsigned char ler[100]; // Leitura de respostas
Sensor analogico;
Sensor digital[31];
int digitalQtd = 0; // Quantidade de sensores digitais selecionados
if (argc < 2) { // Se não tiver argumentos, encerra o programa
printf("Uso inválido. Não há argumentos\n");
return 0;
}
/**
* Percorre a lista de argumentos para definir os sensores
*/
for (int index = 1; index < argc; index++) {
char str[6] = "\0\0\0";
/**
* @brief Se adicionado um sensor analogico
*/
if (strcmp(argv[index], "-analogic") == 0) {
printf("Há um sensor na porta analogica\n");
char *j = "Analogico";
analogico.name[9] = '\0';
for (int i = 0; i < strlen(j) && i < 10; i++) {
//printf("%c", ptr[i]);
analogico.name[i] = j[i];
}
analogico.name[10] = '\0';
analogico.value = 0;
analogico.id = 'A';
analogico.type = Analogic;
}
/**
* Se inserido uma porta digital
*/
else if (strcmp(getSubstring(str, argv[index], 0, 2), "-d") == 0) {
//char name[10];
if (digitalQtd >= 31) {
printf("Atingido maximo de sensores digitais!\n");
continue;
}
int res = add_digital_sensor(argv[index], &digital[digitalQtd]);
if (res == -1) { // se hoube erro
exit(0); // termina o programa
} // do contrario
digitalQtd++; // contabilize o sensor adicionado
}
/**
* @brief Se listando os sensores disponíveis
*/
else if (strcmp(argv[index], "-l") == 0) {
unsigned char read[100]; // Leitura de respostas
//printf("\nPegando o numero de portas digitais disponíveis: \n");
int max_digital = get_number_of_digital_ios();
if (max_digital < 0) {
printf("Erro na leitura do numero de portas disponíveis\n");
return 0; // encerra programa
}
/** Numero de portas digitais disponíveis */
print_io_name_and_id(max_digital);
}
/** Se opção manual */
else if (strcmp(argv[index], "-m") == 0) {
// exibe menu
char notice[80] = " ";
while (1)
{
menu_item entries[] = {
{
.item_name = "Status da NodeMCU", .id = 0
},
{
.item_name = "Ligar o led", .id = 1
},
{
.item_name = "Desligar o led", .id = 2
},
{
.item_name = "Ler sensor analogico", .id = 3
},
{
.item_name = "Ler sensor digital", .id = 4
},
{
.item_name = "Sair", .id = 5
},
};
int selected_entrie_id = menu(
entries,
Lenght(entries),
"Use as setas para navegar entre as opções do menu. Pressione enter para selecionar a opção",
"",
notice
);
switch (selected_entrie_id)
{
case 0:
send_command(GET_NODE_MCU_STATUS, 'O');
printf("Obtendo status da NodeMCU...\n");
await(3000);
serialReadBytes(ler); // lê resposta
if (ler[0] == NODE_MCU_STATUS_OK && ler[1] == NODE_MCU_STATUS_ERROR) {
sprintf(notice, "Status: OK"); // Limpa mensagem
} else {
sprintf(notice, "Status: ERRO!");
}
clear_display();
write_string(notice);
break;
case 1:
send_command(NODE_MCU_ON_LED_BUILTIN, 'L');
sprintf(notice, "LED ligado");
clear_display();
write_string(notice); // Limpa mensagem
break;
case 2:
send_command(NODE_MCU_OFF_LED_BUILTIN, 'L');
sprintf(notice, "LED desligado");
clear_display();
write_string(notice); // Limpa mensagem
break;
case 3:
send_command(GET_ANALOG_INPUT_VALUE, GET_ANALOG_INPUT_VALUE);
printf("Lendo sensor analogico...\n");
await(3000);
serialReadBytes(ler); // lê resposta
print_sensor_to_console("Analogico", command_to_int(ler[1], ler[2]));
sprintf(notice, "%9s: %4i", "Analogico", command_to_int(ler[1], ler[2]));
break;
case 4:
printf("Digite o endereço do sensor: ");
scanf("%s", ler);
int sensor_address = atoi(ler);
printf("Lendo sensor digital...\n");
send_command(GET_DIGITAL_INPUT_VALUE, (char) sensor_address); // Solicita leitura do sensor
await(3000); // Aguarda comando ser processado
serialReadBytes(ler); // lê resposta
if (ler[0] == NODE_MCU_STATUS_ERROR) { // Se houve erro na leitura
printf("NodeMCU com problema. Endereço do sensor é inválido!\n");
clear_display();
write_string("NodeMCU com erro");
} else { // Se lido com sucesso
print_sensor_to_console("Sensor", ler[1] - '0'); // Exibe informações lidas
sprintf(notice, "Sensor: %i: %4i", sensor_address, ler[1] - '0');
}
break;
case 5:
exit(0);
break;
default:
sprintf(notice, " "); // Limpa mensagem
break;
}
}
}
// menu de ajuda
else if (strcmp(argv[index], "-h") == 0) {
help("general");
exit(0);
}
// Comando inválido
else {
printf("\n\nComando inválido!!\nEncerrando...\n");
exit(0);
}
}
printf("Iniciando leitura\n\n");
while(1) {
/**
* Lê o sensor analogico
*/
if (analogico.type == Analogic) { // Se existe um sensor analogico
send_command(GET_ANALOG_INPUT_VALUE, GET_ANALOG_INPUT_VALUE);
await(3000);
serialReadBytes(ler); // lê resposta
analogico.value = command_to_int(ler[1], ler[2]);
print_sensor_to_console(analogico.name, analogico.value);
}
/**
* Lê o sensor digital
*/
for (int i = 0; i < digitalQtd; i++) {
send_command(GET_DIGITAL_INPUT_VALUE, (char) digital[i].id); // Solicita leitura do sensor
await(3000); // Aguarda comando ser processado
serialReadBytes(ler); // lê resposta
if (ler[0] == NODE_MCU_STATUS_ERROR) { // Se houve erro na leitura
printf("NodeMCU com problema. Endereço do sensor é inválido!\n");
clear_display();
write_string("NodeMCU com erro");
} else { // Se lido com sucesso
digital[i].value = ler[1] - '0'; // salva o valor lido
print_sensor_to_console(digital[i].name, digital[i].value); // Exibe informações lidas
}
}
if (analogico.type != Analogic && digitalQtd < 1) { // Se não houver nenhum sensor
printf("\nNão foram adicionados sensores. Ecerrando...\n");
return 0; // Encerra o programa
}
}
}
/**
* @brief Obtem o numero de entradas digitais disponíveis para
* leitura
*
* @return int o numero de entradas digitais ou -1 em caso de erro
*/
int get_number_of_digital_ios() {
unsigned char read[100];
send_command(GET_NUMBER_OF_SENSORS, GET_NUMBER_OF_SENSORS);
await(3000);
serialReadBytes(read);
if (read[0] != NUMBER_OF_DIGITAL_PORTS || strlen(read) < 2) {
return -1;
}
/** Numero de portas digitais disponíveis */
return read[1] - '0';
}
/**
* @brief Exibe no terminal o nome e o endereço de cada uma das
* entradas digitais disponíveis.
*
* @param max_digital Numero maximo de entradas digitais. (valor
* retornado pela função get_number_of_digital_ios)
* @see get_number_of_digital_ios
*/
void print_io_name_and_id(int max_digital) {
unsigned char read[100];
char command[100];
printf("Portas digitais disponíveis: %i\n\n", max_digital);
printf("%10s: %8s\n", "Nome", "Endereço\n");
for (int p = 1; p <= max_digital; p++) {
send_command(GET_SENSOR_ADDRESS, p); // Solicita o endereço do sensor
await(3000); // Aguarda processamento da solicitação
serialReadBytes(read); // faz a leitura
/** Se problema com a node, encerra a leitura*/
if (read[0] == NODE_MCU_STATUS_ERROR) { // se houver erro
printf("NodeMCU com problema!!!\n\n");
clear_display();
write_string("NodeMCU com erro");
exit(0); // termina o programa
}
unsigned char sensor_address = read[1]; // endereço do sensor
/** Obtendo o nome */
send_command(GET_SENSOR_NAME, sensor_address); // Solicita o nome do sensor
await(3000); // Aguarda processamento da solicitação
serialReadBytes(read); // Lê a resposta
command[0] = read[1];
command[1] = read[2];
// exibe a informação
printf("%10s: %2i\n", command, sensor_address); // Exibe os dados lidos
}
}
/**
* @brief Get the Substring object
*
* @param dst Destination variable
* @param src String to get a substring
* @param start Initial position of the substring
* @param end Ending position of the substring
* @return char* Substring
*/
char *getSubstring(char *dst, const char *src, size_t start, size_t end) {
return strncpy(dst, src + start, end);
}
/**
* @brief Separa um argumento lido em 3 substrings
*
* @param str string lida
* @param a priemira substring de tamanho 10
* @param b segunda substring de tamanho 10
* @param c terceira substring de tamanho 10
*/
void separate_string_in_3(char *str, char a[10], char b[10], char c[10]) {
char *ptr = strtok(str, ".");
int index = 0;
while(ptr != NULL && index < 3)
{
//printf("%s\n", ptr);
//res[i] = ptr;
//strcpy(res[index], ptr);
if (index == 0) {
for (int i = 0; i < strlen(ptr) && i < 10; i++) {
//printf("%c", ptr[i]);
a[i] = ptr[i];
}
a[10] = '\0';
}
if (index == 1) {
for (int i = 0; i < strlen(ptr) && i < 10; i++) {
//printf("%c", ptr[i]);
b[i] = ptr[i];
}
b[10] = '\0';
}
if (index == 2) {
for (int i = 0; i < strlen(ptr) && i < 10; i++) {
//printf("%c", ptr[i]);
c[i] = ptr[i];
}
c[10] = '\0';
}
//printf("\n");
ptr = strtok(NULL, ".");
index++;
}
}
/**
* @brief Adiciona um sensor digital a lista de sensores salvos
*
* @param sensor_info String (argumento recebido pelo programa) contendo
* as informações do sensor digital
* @param digital Ponteiro para uma estrutura onde as informações serão salvas
* @return int Retorna 1 se sucesso, ou -1 se houver algum erro.
*/
int add_digital_sensor(char *sensor_info, Sensor *digital) {
printf("Há um sensor na porta digital\n");
char arr[3][11] = {"", "", ""};
separate_string_in_3(sensor_info, arr[0], arr[1], arr[2]);
/**
* @brief Os parametros para adiconar um sensor digital não
* podem ser vazios. O nome e o endereço são obrigatórios
*/
if (strlen(arr[0]) == 0 || strlen(arr[1]) == 0 || strlen(arr[2]) == 0) {
printf("\nComando ilegal!!!\n\n");
//exit(0);
return -1;
}
/**
* O endereço do sensor nunca é zero
*/
int address = atoi(arr[2]);
if (address == 0) {
printf("Endereço invalido para o sensor!!!\n");
//exit(0);
return -1;
}
/**
* @brief Salvando o nome do sensor
*/
for (int i = 0; i < strlen(arr[1]) && i < 10; i++) {
//printf("%c", ptr[i]);
digital->name[i] = arr[1][i];
}
int end = 10;
if (strlen(arr[1]) < 10) {
end = strlen(arr[1]);
}
digital->name[end] = '\0';
//digital[0].name = arr[1];
/**
* @brief Definido as outras propriedades do sensor
*
*/
digital->value = 0;
digital->id = atoi(arr[2]);
digital->type = Digital;
//printf("cmd: %s\n", digital[0].name);
printf("Nome: %s\n", digital->name);
printf("Endereço: %i\n", digital->id);
/**
* Limpando substrings
*/
for (int i = 0; i < 11; i++) {
arr[0][i] = '\0';
arr[1][i] = '\0';
arr[2][i] = '\0';
}
//printf("nome %s", arr[1]);
return 1;
}