我正在使用几个二极管制作红外短信发送器和接收器。
它基本上可以看作是两个不同的电路,一个发送,一个接收。
发送的一个正常工作,将消息编码为基数4并发送我为其设置的合适频率。
收到的那个似乎遇到了麻烦,当它计算入射波的周期时,它只是挂起,我必须重置arduino才能处理另一个命令。 (此函数为calculator(),其他输入重构部分的函数为measure and reconstruye)
我做了一些调试,发现它在进入函数计算周期时挂起,但我不知道可能会做什么。
现在我不知道我能做些什么来修复arduino挂断,接下来我附上我做的代码,如果西班牙语评论有问题,我可以把它们变成英语。
提前感谢您的帮助!
#define Tonepin 11 //Pin where tone will play
#define Interrupt 2 //Pin to interrupt
#define maxNchars 8 //Array size
#define mil 1000 //Number 1000 in lettres
struct Alfabeto //We define an structure that contains both arrays for our alphabet
{
const char Mean[maxNchars] = //Array of letters
{ 'a', 'b', 'c', 'd', 'e', 'f', 'g' , 'k' };
const int Meaning [maxNchars] = //Array of letter to number
{ 0, 1, 2, 3, 4, 5, 6, 7};
const uint8_t Freq[maxNchars] = //Array of frequencies unmultiplied
{ 2, 3, 4, 5, 6, 7, 9, 16 };
const int ExpPeriods[maxNchars] = //Array of experimental periods in mS
{ 19968, 13312, 9984, 8000, 6656, 5696, 4416, 2496};
};
Alfabeto abc; //Create the abc member of the structure
/* Frequency guide (Hz)for FreqFactor=25
* a = 50
* b = 75
* c = 100
* d = 125
* e = 150
* f = 175
* g = 225
* k = 400
*/
int toneDur = 10; //Duration of the tone in mS
int FreqFactor = 25; //Factor to be multiplied by frequency
char vectorenviar[4]; // vector donde conservar el arreglo de letras
int Vectorauxiliar[9]; //Vector para ayudar con la recepcion
volatile int Decriptadorauxiliar[4]; //Arreglo auxiliar para decriptar mensaje
bool decriptador = false; //Condicional auxiliar para decriptar
int r = 0; //indice auxiliar para arreglo decriptador
volatile long time1 = 0;
volatile long time2 = 0;
volatile unsigned long intaux = false;
long period = 0;
String inputSerial = ""; //String to hold input data
String outputSerial = ""; //String to hold output data
bool finished = false; //check is string is complete
String codigo4letras = ""; //string auxiliar para reconstruir
void reconstruye()
{
// YA TENGO 4 potencias, convertir de vuelta a numero y luego
// convertir dicho numero en la letraDelMensaje ex= codigo4letrsa=2310
int n=0;
for(int power=0; power<codigo4letras.length(); power++)
{
char o = codigo4letras[power];
int u = (int)o;
u -= 48;
n += (u * (int)pow(4,power) );
}
char Letra= (char)n;
outputSerial+= Letra;
codigo4letras = "";
Serial.print(outputSerial);
Serial.println(" Is what you received\n");
}
int calculator() //Calcula el periodo de la onda recibida
{
// Serial.println(" *****Entering Calculator"); //calculator test
period = abs( time2 - time1 );
Serial.print(period);
Serial.println(" us is the period"); //Period Test
int i=0;
double incerteza = 600;
for ( i=0; i<sizeof(abc.ExpPeriods);i++)
{
double windowA = abc.ExpPeriods[i] + incerteza;
double windowB = abc.ExpPeriods[i] - incerteza;
if (period < windowA && period > windowB ) break;
}
//Serial.print("indice "); //Indice test
//Serial.println(i);
int indiceasociado = i;
return indiceasociado;
}
void measure() //Mide la diferencia de tiempos entre las ondas recibidas
{
bool y = (bool)digitalRead(Interrupt);
if(y == true && intaux == false) //Primera ves que se mete en el interrupt
{
time1=micros();
intaux=true;
}
else if(y == true && intaux == true) //Segunda ves que se mete, calcula cosas.
{
time2=micros();
intaux=false;
int indice = 6; //Reinicia el valor indice
indice = calculator(); //calcula el indice
for (int lalala=0;lalala<4;lalala++)
{
Serial.print(Decriptadorauxiliar[lalala]);
}
Serial.println(" *****Is The reconstructed number"); //Reconstructed number test
while (r < 4)
{
if (indice == 0 || indice == 1 || indice == 2 || indice == 3 && decriptador == false) //Si es un numero de 0 al 3, lo guarda en una matriz
{
Decriptadorauxiliar[r]=indice; //Establece el contenido
decriptador=true;
break;
}
else if (indice == 7 && decriptador == true) //Si es el numero 7, no lo guarda pero aumenta a la siguiente posicion
{
r++;
decriptador=false;
break;
}
}
//Si el ultimo contenido de la matriz, es un numero valido definido por nosotros, empieza a reconstruir
if (Decriptadorauxiliar[3]== 0 || Decriptadorauxiliar[3]== 1 || Decriptadorauxiliar[3]== 2 || Decriptadorauxiliar[3]== 3)
{
for(int j=0;j<4;j++)
{
codigo4letras += Decriptadorauxiliar[j]; //Llena un string auxiliar.
}
reconstruye(); //Reconstruye la letra
for(int z=0;z<4;z++) //Reinicia la matriz
{
Decriptadorauxiliar[z]=6;
}
r=0; //Reinicia un auxiliar para cuando venga la siguiente letra
}
// Serial.println(" *****Out of the else if"); //else if test
}
// Serial.println(" *****Out of the Interrupt"); //Interrupt test
}
void vectorizador(int numero, int base, char jey) //Guarda el numero en un arreglo de cuatro letras, que representa un numero en base 4
{
for(int i=0;i<4;i++)
{
vectorenviar[i]=abc.Mean[0];
}
Serial.print(jey);
Serial.print(" ");
Serial.print(numero);
Serial.println(" Character and number in ASCII table");
for(int indice=0; indice<4; indice++)
{
char a = abc.Mean[numero%base];
Serial.print(a);
vectorenviar[indice]=a;
numero=numero/base;
}
Serial.println(" Is the number in letters");
//Serial.println("SALIO");
Vectorauxiliar[0]=vectorenviar[0];
Vectorauxiliar[1]=abc.Mean[7];
Vectorauxiliar[2]=vectorenviar[1];
Vectorauxiliar[3]=abc.Mean[7];
Vectorauxiliar[4]=vectorenviar[2];
Vectorauxiliar[5]=abc.Mean[7];
Vectorauxiliar[6]=vectorenviar[3];
Vectorauxiliar[7]=abc.Mean[7];
}
void tonesender() //Manda los tonos correspondientes a las 4 letras del vector y guarda el periodo correspondiente a esa letra
{
for(int i=0; i< sizeof(Vectorauxiliar); i++)
{
int j = 0; //Auxiliar int to link both arrays
char any = Vectorauxiliar[i]; //Selects the first character of the input array.
// int index = 0; //define the index, to link both arrays
for(int j=0; j < sizeof(abc.Mean) ;j++)
{
if (any == abc.Mean[j]) //Sets the index to link to Freq array
{
break; //if any == abc.Mean[index], break for loop
}
}
int freqM = abc.Freq[j]; //defines the freq to use
freqM *= FreqFactor; //applies freq factor
tone(Tonepin, freqM, toneDur); //Sends tone from pin(tonepin), with freq(FreqM) and duration(toneDur)
Serial.println(" *****Sending tone"); //tone test test
delay(2*toneDur);
}
}
void setup() {
Serial.begin(9600); //Inizialize serial comunications
inputSerial.reserve(100); //reserves 100 bytes for string
pinMode(Tonepin, OUTPUT);
pinMode(Interrupt, INPUT);
attachInterrupt(digitalPinToInterrupt(Interrupt), measure, CHANGE);
Serial.print("Enter your Message to be transmitted: ");
Serial.println("");
}
void loop() {
if(finished==true)
{
outputSerial = "";
Serial.print(inputSerial);
Serial.print(" Is what you typed");
Serial.println("");
for(int i=0; i<(inputSerial.length()-2); i++)
{
for(int z=0;z<4;z++)
{
Decriptadorauxiliar[z]=6;
}
char h = inputSerial[i];
// Serial.println(h);
int k = (int) h;
// Serial.println(k);
vectorizador(k, 4, h);
tonesender();
}
finished= false;
inputSerial= "";
}
}
void serialEvent()
{
if(Serial.available())
{
//Get new byte:
char aux = (char)Serial.read();
//add it to inputSerial:
inputSerial += aux;
// if incoming character is carriage return or newline, finish the string concatenation
if (aux == '\n' || aux == '\rn')
{
finished= true;
}
}
}
答案 0 :(得分:2)
这段代码看起来很奇怪(即使是西班牙语的Arduino代码)。
我不知道您可以使用struct Alfabeto
执行您在那里所做的操作,即显示默认初始值设定项的模板。
但是这个:
for ( i=0; i<sizeof(abc.ExpPeriods);i++)
必须错误,即使在Arduino-land sizeof
中也应该产生以字节为单位的大小,而不是数组长度。由于这是一个int
的数组,这主要超越了数组,带来了随机的后果。它应该是:
for (i = 0; i < sizeof abs.ExpPeriods / sizeof *abs.ExpPeriods; ++i)'
除以sizeof (int)
(在我看来)是一个更糟糕的解决方案,因为它在第二位硬编码了关于变量类型的知识,如果类型发生变化,它将会中断。