-
Notifications
You must be signed in to change notification settings - Fork 0
/
Mini_Project_v3.terra
211 lines (191 loc) · 4.45 KB
/
Mini_Project_v3.terra
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
#include "/home/terra/TerraNG/terra/TerraNet.defs"
#define _DEBUG 1
/* DEBUG liga os leds de acordo com estados:
Led0: Node encontrou um pai
Led1: Fila do node passou de 8 em algum momento
Led2: SEND_ACK do node está dando retry
*/
#if _DEBUG == 1
var ubyte led1_state = 0;
var ubyte led2_state = 0;
#endif
pktype usrMsg from radioMsg with
var ubyte[4] d8;
var ushort[4] d16;
var ulong[2] d32;
end
// Informacoes de transmissao
var ushort nodeId = getNodeId();
var ushort targetPai = getNodeId();
var ulong iteracao = 0;
var ubyte distancia = 0; // distancia até o Node raiz ( 11 )
// Estrutura de mensagem
var usrMsg msgRadio;
var ubyte queueStat;
// Calculo do tempo de transmissão
/* Hash, onde:
A = |Categorias de distancia ate a raiz|
B = |Categorias de possiveis NodeID|
Ai = distancia do no atual a raiz
Bi = NodeID do no atual
p = Constante de dispersão
Para um melhor aproveitamento do hash, é bom selecionar A, B e p como primos.
H1(Bi) = ( ( Bi * p ) % B ) x A
H2(Ai) = ( ( Ai * ( A/2 ) ) % A )
Objetivo do hash:
Nos com mesma quantidades de pulos ate a raiz o tempo de tranmissáo dos nodes devem ficar dispersadas.
O motivo é que possivelmente eles tem o mesmo pai.
*/
#define SEND_INTERVAL 10000
#define SEND_JUMP_CATEGORIES 5
#define SEND_NODEID_CATEGORIES 11
#define SEND_HASH_TOTAL (SEND_JUMP_CATEGORIES*SEND_NODEID_CATEGORIES)
var ushort sendDelay = (SEND_INTERVAL / SEND_HASH_TOTAL ); // ms
var ushort sendOffset; // ms
// ETAPA 1 - Encontrar arvore geradora
/*
Convencao:
d8[0] = Numero de saltos a partir do o Node raiz ( 11 )
*/
par/and do
await 3s; // Ajuda a garantir sincronia
with
par/or do
await 3s; // Timeout para essa etapa
with
if nodeId == 11 then
// Manda msg para todos
await 1s;
targetPai = 1;
msgRadio.source = nodeId;
msgRadio.target = BROADCAST;
msgRadio.d8[0] = 0;
emit SEND(msgRadio);
await SEND_DONE;
else
// Aguarda mensagem e descobre o pai
msgRadio = await RECEIVE;
targetPai = msgRadio.source;
distancia = msgRadio.d8[0];
sendOffset = ( ( ( nodeId * 3 ) % SEND_NODEID_CATEGORIES ) * SEND_JUMP_CATEGORIES ) + ( ( distancia * ( SEND_JUMP_CATEGORIES / 2) ) % SEND_JUMP_CATEGORIES ); // Hash do offset
// Passa a diante
msgRadio.source = nodeId;
msgRadio.target = BROADCAST;
inc msgRadio.d8[0];
emit SEND(msgRadio);
await SEND_DONE;
end
end
end
// ETAPA 2 - Trava quem nao tem pai
par/and do
await (100)ms;
with
if targetPai == nodeId then
await FOREVER;
#if _DEBUG ==1
else
emit LED0(1);
#endif
end
end
// ETAPA 3 - Transmitir temperatura para o pai
/*
Convencao:
d8[0] = Numero de saltos
d16[0] = Temperatura Lida
d16[1] = No ID de origem
d16[3] = Pai do no de origem
d32[1] = iteracao ( rodadas de leitura )
*/
// Loop funcional
par do
// Offset inicial para reduzir colisões
if nodeId != 11 then
await ( sendOffset * sendDelay )ms;
end
// Fazendo leitura de temperatura
loop do
par/and do
await (SEND_INTERVAL)ms;
with
emit REQ_TEMP();
msgRadio.d8[0] = 0; // Numero de saltos
msgRadio.d16[0] = await TEMP;
msgRadio.d16[1] = nodeId; // No origem
msgRadio.d16[3] = targetPai;
msgRadio.d32[1] = iteracao;
inc iteracao;
msgRadio.target = targetPai;
queueStat = qPut(msgRadio);
end
end
with
// Recebendo mensagens
loop do
msgRadio = await RECEIVE;
if msgRadio.target != BROADCAST then
msgRadio.target = targetPai;
inc msgRadio.d8[0]; // Numero de saltos
queueStat = qPut(msgRadio);
end;
end
with
// Enviando mensagens acumuladas
loop do
await Q_READY;
loop do
if qSize() < 1 then
break;
end;
queueStat = qGet(msgRadio);
// Fica tentando enviar a mensagem ( retry )
loop do
emit SEND_ACK(msgRadio);
queueStat = await SEND_DONE_ACK;
if queueStat == TRUE then
await (sendDelay/2)ms;
break;
#if _DEBUG == 1
else
emit LED2(ON);
led2_state = 1;
#endif
end
await (sendDelay/4)ms;
end
end
end
#if _DEBUG == 1
with
// Debug - liga led 1 de acordo com o estado da fila
loop do
if qSize() >= 8 then
emit LED1(ON);
led1_state = 1;
end;
await 5ms;
end
with
// Debug - Espera para desligar led da fila
loop do
if led1_state == 1 then
await 3s;
emit LED1(OFF);
led1_state = 0;
end
await 500ms;
end
with
// Debug - Espera para desligar led ddo retry
loop do
if led2_state == 1 then
await 3s;
emit LED2(OFF);
led2_state = 0;
end
await 500ms;
end
#endif
end
// ----------------------------------------