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
/********************************************************************
* Recoge el estado de activación de la campanilla y envía la novedad
* por un enlace de radio.
*********************************************************************/
#include <avr/wdt.h>
#include <avr/sleep.h>
#define ledPin 13
#define power_tx 4
byte Timbre_SI= 0x55; // Código para indicar que el timbre se activó
void setup (){
pinMode(2,INPUT_PULLUP);
Serial.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13,LOW );
pinMode(power_tx, OUTPUT);
digitalWrite(power_tx,LOW );
attachInterrupt( 0, ISR_Timbre, LOW);
wdt_disable();
wdt_enable(WDTO_4S);
}
void ISR_Timbre(){
wdt_reset();
delay(2500);
digitalWrite(power_tx,HIGH );
Serial.write(Timbre_SI);
digitalWrite(13,HIGH );
}
void loop (){
digitalWrite(13,LOW );
digitalWrite(power_tx,LOW );
wdt_reset();
}
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
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <SPI.h>
#include <Wire.h>
#include <string.h>
#include <math.h>
#include "text_to_speech_img.h"
#define S1V30120_RST 49
#define S1V30120_RDY 10
#define S1V30120_CS 53
#define S1V30120_MUTE A0
//------------------------------------------
#define F_CPU 16000000
#define USART_BAUDRATE 9600
#define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
#define led 13
#define sirena 4
volatile byte dato =0;
volatile byte bandera = 0;
// Define parameteros para S1V30120
#define ISC_VERSION_REQ 0x0005
#define ISC_BOOT_LOAD_REQ 0x1000
#define ISC_BOOT_RUN_REQ 0x1002
#define ISC_TEST_REQ 0x0003
#define ISC_AUDIO_CONFIG_REQ 0x0008
#define ISC_AUDIO_VOLUME_REQ 0x000A
#define ISC_AUDIO_MUTE_REQ 0x000C
#define ISC_TTS_CONFIG_REQ 0x0012
#define ISC_TTS_SAMPLE_RATE 0x01
#define ISC_TTS_VOICE 0x00
#define ISC_TTS_EPSON_PARSE 0x01
#define ISC_TTS_LANGUAGE 0x04 /// Lenguaje español
#define ISC_TTS_SPEAK_RATE_LSB 0xC8
#define ISC_TTS_SPEAK_RATE_MSB 0x00
#define ISC_TTS_DATASOURCE 0x00
#define ISC_TTS_SPEAK_REQ 0x0014
#define ISC_VERSION_RESP 0x0006
#define ISC_BOOT_LOAD_RESP 0x1001
#define ISC_BOOT_RUN_RESP 0x1003
#define ISC_TEST_RESP 0x0004
#define ISC_AUDIO_CONFIG_RESP 0x0009
#define ISC_AUDIO_VOLUME_RESP 0x000B
#define ISC_AUDIO_MUTE_RESP 0x000D
#define ISC_TTS_CONFIG_RESP 0x0013
#define ISC_TTS_SPEAK_RESP 0x0015
#define ISC_ERROR_IND 0x0000
#define ISC_MSG_BLOCKED_RESP 0x0007
#define ISC_TTS_FINISHED_IND 0x0021
#define TTS_AUDIO_CONF_AS 0x00
#define TTS_AUDIO_CONF_AG 0x43
#define TTS_AUDIO_CONF_AMP 0x00
#define TTS_AUDIO_CONF_ASR 0x01
#define TTS_AUDIO_CONF_AR 0x00
#define TTS_AUDIO_CONF_ATC 0x00
#define TTS_AUDIO_CONF_ACS 0x00
#define TTS_AUDIO_CONF_DC 0x00
//-----------------------------------------------------
void S1V30120_reset(void);
unsigned short S1V30120_get_version(void);
bool S1V30120_download(void);
bool S1V30120_load_chunk(unsigned short);
bool S1V30120_boot_run(void);
void show_response(bool);
bool S1V30120_registration(void);
bool S1V30120_parse_response(unsigned short, unsigned short, unsigned short);
void S1V30120_send_padding(unsigned short);
void S1V30120_send_message(volatile char, unsigned char);
bool S1V30120_configure_audio(void);
bool S1V30120_configure_tts(void);
bool S1V30120_speech(String , unsigned char);
bool S1V30120_set_volume(void);
bool S1V30120_load_chunk(unsigned short);
String m0 = "Atencion atencion";
String m1 = "Estan tocando el timbre";
String m2 = "Sistema listo y atento";
char rcvd_msg[20] = {0};
static volatile char send_msg[200] = {0};
static volatile unsigned short msg_len;
static volatile unsigned short txt_len;
unsigned short tmp;
long idx;
bool success;
static volatile unsigned short TTS_DATA_IDX;
void setup() {
pinMode(led, OUTPUT);
digitalWrite(led,LOW );
pinMode(S1V30120_RST, OUTPUT);
pinMode(S1V30120_RDY, INPUT);
pinMode(S1V30120_CS, OUTPUT);
pinMode(S1V30120_MUTE, OUTPUT);
// Unmute
digitalWrite(S1V30120_MUTE,LOW);
// Configura los baudios
UBRR2H = (uint8_t)(UBRR_VALUE >> 8);
UBRR2L = (uint8_t)UBRR_VALUE;
UCSR2C |= (1 << UCSZ20) | (1 << UCSZ21);
UCSR2B |= (1 << RXEN2) | (0 << TXEN2) | (1 << RXCIE2);
UCSR2A = 0x00;
interrupts();
bandera = 0;
SPI.begin();
S1V30120_reset();
success = S1V30120_download();
success = S1V30120_boot_run();
show_response(success);
delay(150);
success = S1V30120_registration();
show_response(success);
S1V30120_get_version();
success = S1V30120_configure_audio();
show_response(success);
success = S1V30120_set_volume();
show_response(success);
success = S1V30120_configure_tts();
show_response(success);
show_response(success);
success = S1V30120_speech(m2,1);
wdt_enable(WDTO_4S);
}
/***************************************************************************
* Función ISR para la UART2.
* Procesa el caracter recibido. Si es 0x55 cambia bandera
* Argumentos: NINGUNO
* Retorna: Bandera
*
****************************************************************************/
ISR(USART2_RX_vect){
byte RX_Byte = UDR2;;
UDR2 = RX_Byte;
dato = UDR2;
if(dato == 0x55)
bandera = 1;
dato = 0;
}
//####################################################################
void loop() {
if(bandera == 1){
wdt_reset();
success = S1V30120_speech(m0,1);
delay(500);
wdt_reset();
success = S1V30120_speech(m1,1);
bandera = 0;
}
wdt_reset();
}
//########################################################################
void S1V30120_reset(void)
{
digitalWrite(S1V30120_CS,HIGH);
digitalWrite(S1V30120_RST,LOW);
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
SPI.transfer(0x00);
SPI.endTransaction();
delay(200);
digitalWrite(S1V30120_RST,HIGH);
delay(200);
}
unsigned short S1V30120_get_version(void)
{
unsigned short S1V30120_version = 0;
unsigned short tmp_disp;
char msg_ver[] = {0x04, 0x00, 0x05, 0x00};
S1V30120_send_message(msg_ver, 0x04);
while(digitalRead(S1V30120_RDY) == 0);
digitalWrite(S1V30120_CS,LOW);
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
while(SPI.transfer(0x00) != 0xAA);
for (int i = 0; i < 20; i++)
{
rcvd_msg[i]= SPI.transfer(0x00);
}
S1V30120_send_padding(16);
SPI.endTransaction();
digitalWrite(S1V30120_CS,HIGH);
S1V30120_version = rcvd_msg[4] << 8 | rcvd_msg[5];
Serial.print("HW version ");
Serial.print(rcvd_msg[4],HEX);
Serial.print(".");
Serial.println(rcvd_msg[5],HEX);
Serial.print("Firmware version ");
Serial.print(rcvd_msg[6],HEX);
Serial.print(".");
Serial.print(rcvd_msg[7],HEX);
Serial.print(".");
Serial.println(rcvd_msg[16],HEX);
Serial.print("Firmware features ");
Serial.println(((rcvd_msg[11] << 24) | (rcvd_msg[10] << 16) | (rcvd_msg[9] << 8) | rcvd_msg[8]),HEX);
Serial.print("Firmware extended features ");
Serial.println(((rcvd_msg[15] << 24) | (rcvd_msg[14] << 16) | (rcvd_msg[13] << 8) | rcvd_msg[12]),HEX);
return S1V30120_version;
}
bool S1V30120_load_chunk(unsigned short chunk_len)
{
char len_msb = ((chunk_len + 4) & 0xFF00) >> 8;
char len_lsb = (chunk_len + 4) & 0xFF;
digitalWrite(S1V30120_CS,LOW);
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
SPI.transfer(0xAA);
SPI.transfer(len_lsb);
SPI.transfer(len_msb);
SPI.transfer(0x00);
SPI.transfer(0x10);
for (int chunk_idx = 0; chunk_idx < chunk_len; chunk_idx++)
{
SPI.transfer(pgm_read_byte_near(TTS_INIT_DATA + TTS_DATA_IDX));
TTS_DATA_IDX++;
}
SPI.endTransaction();
digitalWrite(S1V30120_CS,HIGH);
return S1V30120_parse_response(ISC_BOOT_LOAD_RESP, 0x0001, 16);
}
bool S1V30120_download(void)
{
unsigned short len = sizeof (TTS_INIT_DATA);
unsigned short fullchunks;
unsigned short remaining;
bool chunk_result;
long data_index = 0;
fullchunks = len / 2044;
remaining = len - fullchunks * 2044;
return 1;
}
bool S1V30120_boot_run(void)
{
char boot_run_msg[] = {0x04, 0x00, 0x02, 0x10};
S1V30120_send_message(boot_run_msg, 0x04);
return S1V30120_parse_response(ISC_BOOT_RUN_RESP, 0x0001, 8);
}
void show_response(bool response)
{
if(response)
Serial.println("OK!");
else
{
Serial.println("Failed. System halted!");
while(1);
}
}
bool S1V30120_registration(void)
{
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
char reg_code[] = {0x0C, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
S1V30120_send_message(reg_code, 0x0C);
return S1V30120_parse_response(ISC_TEST_RESP, 0x0000, 16);
}
bool S1V30120_parse_response(unsigned short expected_message, unsigned short expected_result, unsigned short padding_bytes)
{
unsigned short rcvd_tmp;
while(digitalRead(S1V30120_RDY) == 0);
digitalWrite(S1V30120_CS,LOW);
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
while(SPI.transfer(0x00) != 0xAA);
for (int i = 0; i < 6; i++)
{
rcvd_msg[i]= SPI.transfer(0x00);
}
S1V30120_send_padding(padding_bytes);
SPI.endTransaction();
digitalWrite(S1V30120_CS,HIGH);
rcvd_tmp = rcvd_msg[3] << 8 | rcvd_msg[2];
if (rcvd_tmp == expected_message)
{
rcvd_tmp = rcvd_msg[5] << 8 | rcvd_msg[4];
if (rcvd_tmp == expected_result)
return 1;
else
return 0;
}
else
return 0;
}
void S1V30120_send_padding(unsigned short num_padding_bytes)
{
for (int i = 0; i < num_padding_bytes; i++)
{
SPI.transfer(0x00);
}
}
void S1V30120_send_message(volatile char message[], unsigned char message_length)
{
while(digitalRead(S1V30120_RDY) == 1);
digitalWrite(S1V30120_CS,LOW);
SPI.beginTransaction(SPISettings(750000, MSBFIRST, SPI_MODE3));
SPI.transfer(0xAA);
for (int i = 0; i < message_length; i++)
{
SPI.transfer(message[i]);
}
SPI.endTransaction();
}
//#########################################################################
bool S1V30120_configure_audio(void)
{
msg_len = 0x0C;
send_msg[0] = msg_len & 0xFF;
send_msg[1] = (msg_len & 0xFF00) >> 8;
send_msg[2] = ISC_AUDIO_CONFIG_REQ & 0xFF;
send_msg[3] = (ISC_AUDIO_CONFIG_REQ & 0xFF00) >> 8;
send_msg[4] = TTS_AUDIO_CONF_AS;
send_msg[5] = TTS_AUDIO_CONF_AG;
send_msg[6] = TTS_AUDIO_CONF_AMP;
send_msg[7] = TTS_AUDIO_CONF_ASR;
send_msg[8] = TTS_AUDIO_CONF_AR;
send_msg[9] = TTS_AUDIO_CONF_ATC;
send_msg[10] = TTS_AUDIO_CONF_ACS;
send_msg[11] = TTS_AUDIO_CONF_DC;
S1V30120_send_message(send_msg, msg_len);
return S1V30120_parse_response(ISC_AUDIO_CONFIG_RESP, 0x0000, 16);
}
//###########################################################################
bool S1V30120_set_volume(void)
{
char setvol_code[]={0x06, 0x00, 0x0A, 0x00, 0x00, 0x00};
S1V30120_send_message(setvol_code, 0x06);
return S1V30120_parse_response(ISC_AUDIO_VOLUME_RESP, 0x0000, 16);
}
bool S1V30120_configure_tts(void)
{
msg_len = 0x0C;
send_msg[0] = msg_len & 0xFF;
send_msg[1] = (msg_len & 0xFF00) >> 8;
send_msg[2] = ISC_TTS_CONFIG_REQ & 0xFF;
send_msg[3] = (ISC_TTS_CONFIG_REQ & 0xFF00) >> 8;
send_msg[4] = ISC_TTS_SAMPLE_RATE;
send_msg[5] = ISC_TTS_VOICE;
send_msg[6] = ISC_TTS_EPSON_PARSE;
send_msg[7] = ISC_TTS_LANGUAGE;
send_msg[8] = ISC_TTS_SPEAK_RATE_LSB;
send_msg[9] = ISC_TTS_SPEAK_RATE_MSB;
send_msg[10] = ISC_TTS_DATASOURCE;
send_msg[11] = 0x00;
S1V30120_send_message(send_msg, msg_len);
return S1V30120_parse_response(ISC_TTS_CONFIG_RESP, 0x0000, 16);
}
bool S1V30120_speech(String text_to_speech, unsigned char flush_enable)
{
bool response;
txt_len = text_to_speech.length();
msg_len = txt_len + 6;
send_msg[0] = msg_len & 0xFF;
send_msg[1] = (msg_len & 0xFF00) >> 8;
send_msg[2] = ISC_TTS_SPEAK_REQ & 0xFF;
send_msg[3] = (ISC_TTS_SPEAK_REQ & 0xFF00) >> 8;
send_msg[4] = flush_enable;
for (int i = 0; i < txt_len; i++)
{
send_msg[i+5] = text_to_speech[i];
}
send_msg[msg_len-1] = '\0';
S1V30120_send_message(send_msg, msg_len);
response = S1V30120_parse_response(ISC_TTS_SPEAK_RESP, 0x0000, 16);
while (!S1V30120_parse_response(ISC_TTS_FINISHED_IND, 0x0000, 16));
return response;
}