-->
Um
dia desses fuçando o Ebay encontrei um módulo de comando por voz baseado no CI
SPCE061A. Ele é capaz de armazenar até 15 comandos divididos em 3 bancos de 5
comandos. No projeto descrito aqui foram gravados cinco comandos no banco
"1" com a finalidade de controlar o acendimento, apagamento e frequência
de piscada de uma lâmpada comum ligada ao pino 13 do arduino através de um
módulo de força baseado em um triac.
A
comunicação com o módulo é feita via interface serial. As mensagens de
comando devem ser formadas pela chave 0xAA seguida do comando propriamente
dito. Para gravar o banco um, por exemplo, basta envia via terminal o valor em
0xAA seguido do comando 0x11 (é sempre bom lembra que o "0x" informa
que o número que o segue esta em hexadecimal) e, seguindo as mensagens de
retorno no terminal ou observando os dois leds na placa, pronunciar e
repetir cada um dos cinco comandos desejados para o banco em questão.
Após
a gravação é possível acessar o banco 1 através do comando 0xAA + 0x21 que
serve para importar o banco 01. Importar, neste caso, é ativar um determinado
grupo de comandos, pois apenas um dos grupos pode estar ativo por vês. Isso faz
com que o módulo compare o comando falado com os cinco gravados naquele banco.
O manual do modulo pode ser encontrado aqui. Ele é bastante completo inclusive indica um programa gratuito para
Resumidamente para fazer funcionar o módulo com o
arduino deve-se:
1. Selecionar a velocidade de comunicação serial
enviando, por exemplo, o comando "AA34" para 19200bps ou
"AA33" para 9600bps. Por padrão a velocidade é 9600;
2. Selecionar o modo de comunicação: modo comum
ou compacto. O modo determina se o módulo irá responder aos comandos com
respostas longas (mensagens) ou curtas (hexadecimal);
3. Iniciar a gravação de um dos três bancos
enviando o comando correspondente "AA11" para gravar o banco um
"AA12" para o dois ou "AA13" para o banco três.
Ao iniciar a gravação do banco um, por exemplo, o
módulo irá solicitar os cinco comandos de voz que deverão ser pronunciados
e repetidos conforme mensagens de solicitação. Estes comandos de voz são
associados a números. No banco um os números 0x11, 0x12, 0x13, 0x14 e
0x15 são associados aos comandos de voz um a cinco respectivamente. Sendo que o
comando de voz um é o primeiro que foi gravado no banco e assim
sucessivamente. Se um banco é ativado e o módulo recebe um comando de voz
válido ele envia o valor correspondente via serial.
Quando um comando de gravação é enviado através
do terminal, por exemplo, o modulo enviará um das seguintes respostas em
hexadecimal ou em texto:
"ERROR! \ n" (0xe0) | Erro de instrução |
"START \ n" (0x40) | Pronto para gravar |
"No voice \ n" (0x41) | Não detectada voz |
"Again \ n" (0x42) | Repita a instrução ( após proximo "START") |
"Too loud \ n" (0x43) | Muito alto para gravar |
"Different \ n" (0x44) | Repetição da instrução diferente da primera aguarde o START para repetir o comando de voz |
"Finish one \ n" (0x45) | Uma instrução gravada com sucesso. O proximo START é para o comando de voz seguinte. Isso se repete até o quinto comando |
"Group1 finished! \ n" (0x46) | Fim da gravação do grupo 1 |
No programa, mostrado abaixo, o arduino inicializa
o banco 1 e fica aguardando o comando enviado pelo modulo que por sua vez aguarda
comandos de voz compatíveis com os gravados.
/*
comandos de voz:
1 - liga
2 - desliga
3 - pisca
4 - mais
5 - menos
*/
#include <Servo.h>
long dist = 0;
int lampState = LOW;
long previousMillis = 0;
long intervalo = 1000;
unsigned long currentMillis;
int lampada =13;
byte com = 0;
void setup()
{
Serial.begin(9600);
pinMode(lampada, OUTPUT);
delay(2000);
// O modulo aceita comandos, em hexadecimal no seguinte formato:
// AA + comando
Serial.write(0xAA);
Serial.write(0x37); //configura o modulo para responder em modo compacto
delay(1000); // no modo compacto as respostas são numeros em hexadecimal
Serial.write(0xAA);
Serial.write(0x21);//importa o grupo 1
}
void loop() // inicio do programa principal
{
while(Serial.available())
{
com = Serial.read(); //recebe o byte referente ao comando
if(com == 0x11) // ao recxeber o comando de voz "liga" o modulo envia o valor em hexadecimal: 11
digitalWrite(lampada, HIGH); // se receber 0x11 acende a lampada
if(com == 0x12) // ao recxeber o comando de voz "desiga" o modulo envia o valor em hexadecimal: 12
digitalWrite(lampada, LOW);// se receber 0x12 apaga a lampada
if(com == 0x13)// ao recxeber o comando de voz "pisca" o modulo envia o valor em hexadecimal: 13
{
do // se receber 0x13 entra neste laço que faz a lamada piscar. Aqui existem tres possibilidades:
// Receber 0x14 "mais" e aumentar o intervalo entre as piscadas
// Receber 0x15 "menos" e diminuir o intervalo entre as piscadas
// Receber 0x11 (liga) 0u 0x12 (desliga) parar de piscar e fazer o que o comando pede
{
com = Serial.read(); //recebe o byte referente ao comando
// piscar sem delay
currentMillis = millis(); //armazena o valor referente ao tempo de execução do programa
if(currentMillis - previousMillis > intervalo)
{
previousMillis = currentMillis;
if (lampState == LOW)
lampState = HIGH;
else
lampState = LOW;
digitalWrite(lampada, lampState);
}
//
// se receber 0x14 aumenta o intervalo entre as piscadas
if(com == 0x14 && intervalo < 1000)
{
intervalo +=100;
}
// se receber 0x14 diminue o intervalo entre as piscadas
if(com == 0x15 && intervalo > 100)
{
intervalo -=100;
}
// se receber 0x11 (liga) 0u 0x12 (desliga) para de piscar
}while(com != 0x11 && com != 0x12);
}
}
}