me saque la licencia para hacer esto .. no lo he probado hay que montar muchas cosas para no merse en lios y bueno no se si funciona esto : void Moduladores::ModulaFM2() { // Leer la señal de modulación desde el pin analógico int modulatingSignal = analogRead(PinAudioIn); float modulatingVoltage = (modulatingSignal / 1023.0) * 5.0; // Convertir a voltaje // Calcular la frecuencia de la señal modulada float FrequenciaModulacion = frecuenciaPortadora + (modulatingVoltage * indiceModulacion); // Generar la señal de audio modulada for (int i = 0; i < frecuenciaMuestreo; i++) { // Calcular el valor de PWM para la señal de audio int pwmValue = (sin(2 * PI * FrequenciaModulacion * (i / (float)frecuenciaMuestreo)) + 1) * 127.5; // Normalizar a 0-255 analogWrite(PinModulatingSignal, pwmValue); // Enviar el valor PWM al pin de audio delayMicroseconds(1000000 / frecuenciaMuestreo); // Esperar el tiempo de muestreo } // Imprimir la frecuencia modulada en el monitor serial Serial.print("Frecuencia modulada: "); Serial.println(FrequenciaModulacion); } void Moduladores::ModulaAM3() { // Leer la señal de audio int valorAnalogico = analogRead(PinAudioIn); float señalAudio = map(valorAnalogico, 0, 1023, -1, 1); // Normalizar a un rango de -1 a 1 fase += 2 * PI * frecuenciaPortadora / frecuenciaMuestreo; float ondaPortadora = sin(fase); float señalModulada = (1 + indiceModulacion * señalAudio) * ondaPortadora; señalModulada = constrain(señalModulada, -1, 1); int valorDAC = map(señalModulada, -1, 1, 0, 4095); // Ajustar según la resolución del DAC // Aplicar el filtro float valor = b[0] * valorDAC + b[1] * x[1] + b[2] * x[2] - a[1] * y[1] - a[2] * y[2]; x[2] = x[1]; x[1] = x[0]; x[0] = valorDAC; y[2] = y[1]; y[1] = y[0]; y[0] = valor; analogWrite(PinModulatingSignal, valor); } //¿ funciona esto ? me suena a un idioma extraterrestre void Moduladores::ModulaSSB() { // Leer la señal de datos desde el pin analógico int dataSignal = analogRead(PinAudioIn); // Leer el valor analógico int bit = (dataSignal > 512) ? 1 : 0; // Convertir a bit (0 o 1) // Generar la señal de portadora modulada for (int i = 0; i < frecuenciaMuestreo; i++) { float t = i / (float)frecuenciaMuestreo; // Tiempo normalizado float carrierSignal; // Modulación BPSK: cambiar la fase de la portadora if (bit == 1) { carrierSignal = sin(2 * PI * carrierFrequency * t); // Fase 0 } else { carrierSignal = sin(2 * PI * carrierFrequency * t + PI); // Fase 180 } // Normalizar la señal a 0-255 para PWM int pwmValue = (carrierSignal + 1) * 127.5; // Normalizar a 0-255 analogWrite(PinModulatingSignal, pwmValue); // Enviar el valor PWM al pin de audio delayMicroseconds(1000000 / frecuenciaMuestreo); // Esperar el tiempo de muestreo } // Imprimir el bit en el monitor serial Serial.print("Bit: "); Serial.println(bit); } void Moduladores::ModulaSSB3() { // Leer la señal de audio int valorAnalogico = analogRead(PinAudioIn); float señalAudio = map(valorAnalogico, 0, 1023, -1, 1); // Normalizar a un rango de -1 a 1 // Aplicar pre-énfasis señalAudio = preEnfasis(señalAudio); // Crear la señal de modulación en fase y en cuadratura float señalEnFase = señalAudio; float señalEnCuadratura = 0; // Inicialmente cero para SSB // Si es LSB, invertir la fase de la señal en cuadratura if (!isUSB) { señalEnCuadratura = -señalAudio; } // Aplicar la transformada de Hilbert (aproximación) //float señalEnCuadratura = 0.0; // for (int i = 0; i < sizeof(coeficientesHilbert); i++) { // int indice = (indice - i + sizeof(coeficientesHilbert)) % sizeof(coeficientesHilbert); // Índice circular // señalEnCuadratura += coeficientesHilbert[i] * buffer[indice]; // } // Combinar la señal en fase y en cuadratura para obtener la señal SSB float señalSSB = señalEnFase + señalEnCuadratura; // Aplicar el filtro Butterworth // ... (aplicar el filtro Butterworth a señalSSB) // Escribir la señal SSB en el DAC // ... (escribir señalSSB en el DAC) } void Moduladores::ModulaSSB3LSB() { // Leer la señal de entrada y almacenarla en el buffer for (int i = 0; i < bufferSize; i++) { bufferI[i] = analogRead(PinAudioIn) - 512; // Centrar la señal en 0 delayMicroseconds(1000000 / frecuenciaMuestreo); } // Calcular la transformada de Hilbert para obtener las señales I y Q hilbertTransform(bufferI, bufferI, bufferQ, bufferSize); // Generar la señal LSB for (int i = 0; i < bufferSize; i++) { float t = (float)i / frecuenciaMuestreo; float carrierI = cos(2 * PI * carrierFrequency * t); float carrierQ = sin(2 * PI * carrierFrequency * t); // Modulación LSB (Lower Sideband) float lsbSignal = bufferI[i] * carrierI + bufferQ[i] * carrierQ; // Salida de la señal LSB por el DAC int dacValue = (int)(lsbSignal + 128); // Centrar la señal en el rango 0-255 //dac_output_voltage(PinModulatingSignal, constrain(dacValue, 0, 255)); analogWrite(PinModulatingSignal, constrain(dacValue, 0, 255)); } //delay(10); // Pequeño retraso antes de la siguiente iteración } // Filtro FIR de Hilbert con ventana Blackman // Tamaño del filtro (número de coeficientes) const int N = 51; // Puedes ajustar este valor según tus necesidades // Coeficientes del filtro float h[N]; void calculateHilbertCoefficients() { for (int k = 0; k < N; k++) { float m = k - (N - 1) / 2.0; h[k] = (1.0 / PI) * (sin(PI * m) / m) * 0.42 - 0.5 * cos(2.0 * PI * m / (N - 1)) + 0.08 * cos(4.0 * PI * m / (N - 1)); } } void Moduladores::hilbertTransform(float* input, float* outputI, float* outputQ, int size) { for (int i = 0; i < size; i++) { outputI[i] = input[i]; outputQ[i] = 0; } for (int i = 1; i < size; i += 2) { outputQ[i] = input[i]; } } float Moduladores::transformadaHilbert(float entrada) { static float buffer[sizeof(coeficientesHilbert)]; // Buffer circular static int indice = 0; // Desplazar el buffer for (int i = sizeof(coeficientesHilbert) - 1; i > 0; i--) { buffer[i] = buffer[i - 1]; } // Almacenar la nueva muestra buffer[0] = entrada; // Aplicar la convolución float salida = 0; for (int i = 0; i < sizeof(coeficientesHilbert); i++) { salida += coeficientesHilbert[i] * buffer[i]; } indice = (indice + 1) % sizeof(coeficientesHilbert); return salida; } void Moduladores::ModulaQPSK(bool bit1, bool bit2, float carrierFreq, float sampleRate, float* output) { // Convertir bits a índice de fase int index = 2 * bit1 + bit2; float phases[4] = { 0, M_PI / 2, M_PI, 3 * M_PI / 2 }; fase = phases[index]; // Generar señales I y Q float i = cos(fase); float q = sin(fase); // Combinar I y Q para obtener la señal modulada *output = i * cos(2 * M_PI * carrierFreq / sampleRate); //El asterisco (*) es una variable que almacena la dirección de memoria de otra variable } void Moduladores::mapBitsToSymbol(uint8_t bits[4], float& I, float& Q) { int index = 0; for (int i = 0; i < 4; i++) { index |= (bits[i]
jaja para modular LSB con vocoder cuando me dicen que así no jejej
me saque la licencia para hacer esto .. no lo he probado hay que montar muchas cosas para no merse en lios y bueno no se si funciona esto :
void Moduladores::ModulaFM2() {
// Leer la señal de modulación desde el pin analógico
int modulatingSignal = analogRead(PinAudioIn);
float modulatingVoltage = (modulatingSignal / 1023.0) * 5.0; // Convertir a voltaje
// Calcular la frecuencia de la señal modulada
float FrequenciaModulacion = frecuenciaPortadora + (modulatingVoltage * indiceModulacion);
// Generar la señal de audio modulada
for (int i = 0; i < frecuenciaMuestreo; i++) {
// Calcular el valor de PWM para la señal de audio
int pwmValue = (sin(2 * PI * FrequenciaModulacion * (i / (float)frecuenciaMuestreo)) + 1) * 127.5; // Normalizar a 0-255
analogWrite(PinModulatingSignal, pwmValue); // Enviar el valor PWM al pin de audio
delayMicroseconds(1000000 / frecuenciaMuestreo); // Esperar el tiempo de muestreo
}
// Imprimir la frecuencia modulada en el monitor serial
Serial.print("Frecuencia modulada: ");
Serial.println(FrequenciaModulacion);
}
void Moduladores::ModulaAM3() {
// Leer la señal de audio
int valorAnalogico = analogRead(PinAudioIn);
float señalAudio = map(valorAnalogico, 0, 1023, -1, 1); // Normalizar a un rango de -1 a 1
fase += 2 * PI * frecuenciaPortadora / frecuenciaMuestreo;
float ondaPortadora = sin(fase);
float señalModulada = (1 + indiceModulacion * señalAudio) * ondaPortadora;
señalModulada = constrain(señalModulada, -1, 1);
int valorDAC = map(señalModulada, -1, 1, 0, 4095); // Ajustar según la resolución del DAC
// Aplicar el filtro
float valor = b[0] * valorDAC + b[1] * x[1] + b[2] * x[2] - a[1] * y[1] - a[2] * y[2];
x[2] = x[1];
x[1] = x[0];
x[0] = valorDAC;
y[2] = y[1];
y[1] = y[0];
y[0] = valor;
analogWrite(PinModulatingSignal, valor);
}
//¿ funciona esto ? me suena a un idioma extraterrestre
void Moduladores::ModulaSSB() {
// Leer la señal de datos desde el pin analógico
int dataSignal = analogRead(PinAudioIn); // Leer el valor analógico
int bit = (dataSignal > 512) ? 1 : 0; // Convertir a bit (0 o 1)
// Generar la señal de portadora modulada
for (int i = 0; i < frecuenciaMuestreo; i++) {
float t = i / (float)frecuenciaMuestreo; // Tiempo normalizado
float carrierSignal;
// Modulación BPSK: cambiar la fase de la portadora
if (bit == 1) {
carrierSignal = sin(2 * PI * carrierFrequency * t); // Fase 0
} else {
carrierSignal = sin(2 * PI * carrierFrequency * t + PI); // Fase 180
}
// Normalizar la señal a 0-255 para PWM
int pwmValue = (carrierSignal + 1) * 127.5; // Normalizar a 0-255
analogWrite(PinModulatingSignal, pwmValue); // Enviar el valor PWM al pin de audio
delayMicroseconds(1000000 / frecuenciaMuestreo); // Esperar el tiempo de muestreo
}
// Imprimir el bit en el monitor serial
Serial.print("Bit: ");
Serial.println(bit);
}
void Moduladores::ModulaSSB3() {
// Leer la señal de audio
int valorAnalogico = analogRead(PinAudioIn);
float señalAudio = map(valorAnalogico, 0, 1023, -1, 1); // Normalizar a un rango de -1 a 1
// Aplicar pre-énfasis
señalAudio = preEnfasis(señalAudio);
// Crear la señal de modulación en fase y en cuadratura
float señalEnFase = señalAudio;
float señalEnCuadratura = 0; // Inicialmente cero para SSB
// Si es LSB, invertir la fase de la señal en cuadratura
if (!isUSB) {
señalEnCuadratura = -señalAudio;
}
// Aplicar la transformada de Hilbert (aproximación)
//float señalEnCuadratura = 0.0;
// for (int i = 0; i < sizeof(coeficientesHilbert); i++) {
// int indice = (indice - i + sizeof(coeficientesHilbert)) % sizeof(coeficientesHilbert); // Índice circular
// señalEnCuadratura += coeficientesHilbert[i] * buffer[indice];
// }
// Combinar la señal en fase y en cuadratura para obtener la señal SSB
float señalSSB = señalEnFase + señalEnCuadratura;
// Aplicar el filtro Butterworth
// ... (aplicar el filtro Butterworth a señalSSB)
// Escribir la señal SSB en el DAC
// ... (escribir señalSSB en el DAC)
}
void Moduladores::ModulaSSB3LSB() {
// Leer la señal de entrada y almacenarla en el buffer
for (int i = 0; i < bufferSize; i++) {
bufferI[i] = analogRead(PinAudioIn) - 512; // Centrar la señal en 0
delayMicroseconds(1000000 / frecuenciaMuestreo);
}
// Calcular la transformada de Hilbert para obtener las señales I y Q
hilbertTransform(bufferI, bufferI, bufferQ, bufferSize);
// Generar la señal LSB
for (int i = 0; i < bufferSize; i++) {
float t = (float)i / frecuenciaMuestreo;
float carrierI = cos(2 * PI * carrierFrequency * t);
float carrierQ = sin(2 * PI * carrierFrequency * t);
// Modulación LSB (Lower Sideband)
float lsbSignal = bufferI[i] * carrierI + bufferQ[i] * carrierQ;
// Salida de la señal LSB por el DAC
int dacValue = (int)(lsbSignal + 128); // Centrar la señal en el rango 0-255
//dac_output_voltage(PinModulatingSignal, constrain(dacValue, 0, 255));
analogWrite(PinModulatingSignal, constrain(dacValue, 0, 255));
}
//delay(10); // Pequeño retraso antes de la siguiente iteración
}
// Filtro FIR de Hilbert con ventana Blackman
// Tamaño del filtro (número de coeficientes)
const int N = 51; // Puedes ajustar este valor según tus necesidades
// Coeficientes del filtro
float h[N];
void calculateHilbertCoefficients() {
for (int k = 0; k < N; k++) {
float m = k - (N - 1) / 2.0;
h[k] = (1.0 / PI) * (sin(PI * m) / m) * 0.42 - 0.5 * cos(2.0 * PI * m / (N - 1)) + 0.08 * cos(4.0 * PI * m / (N - 1));
}
}
void Moduladores::hilbertTransform(float* input, float* outputI, float* outputQ, int size) {
for (int i = 0; i < size; i++) {
outputI[i] = input[i];
outputQ[i] = 0;
}
for (int i = 1; i < size; i += 2) {
outputQ[i] = input[i];
}
}
float Moduladores::transformadaHilbert(float entrada) {
static float buffer[sizeof(coeficientesHilbert)]; // Buffer circular
static int indice = 0;
// Desplazar el buffer
for (int i = sizeof(coeficientesHilbert) - 1; i > 0; i--) {
buffer[i] = buffer[i - 1];
}
// Almacenar la nueva muestra
buffer[0] = entrada;
// Aplicar la convolución
float salida = 0;
for (int i = 0; i < sizeof(coeficientesHilbert); i++) {
salida += coeficientesHilbert[i] * buffer[i];
}
indice = (indice + 1) % sizeof(coeficientesHilbert);
return salida;
}
void Moduladores::ModulaQPSK(bool bit1, bool bit2, float carrierFreq, float sampleRate, float* output) {
// Convertir bits a índice de fase
int index = 2 * bit1 + bit2;
float phases[4] = { 0, M_PI / 2, M_PI, 3 * M_PI / 2 };
fase = phases[index];
// Generar señales I y Q
float i = cos(fase);
float q = sin(fase);
// Combinar I y Q para obtener la señal modulada
*output = i * cos(2 * M_PI * carrierFreq / sampleRate); //El asterisco (*) es una variable que almacena la dirección de memoria de otra variable
}
void Moduladores::mapBitsToSymbol(uint8_t bits[4], float& I, float& Q) {
int index = 0;
for (int i = 0; i < 4; i++) {
index |= (bits[i]