Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of Nucleo-DAC-Algorithm by
main.cpp
- Committer:
- pinofal
- Date:
- 2018-01-30
- Revision:
- 1:ffc7a5d0f629
- Parent:
- 0:3106d3fc6696
File content as of revision 1:ffc7a5d0f629:
#include "mbed.h"
AnalogIn InLocale(PA_6);
AnalogOut OutLocale(PA_4);
AnalogOut OutCampagna(PA_5);
Serial pc(SERIAL_TX, SERIAL_RX);
#if !DEVICE_ANALOGOUT
#error You cannot use this example as the AnalogOut is not supported on this device.
#else
#endif
// Numero di periodi di sinusoide di cui è composto ciascuno step della PSK
#define fPerStep1 23.0
#define fPerStep2 1.25
#define fPerStep3 15.0
#define fPerStep4 1.25
#define fPerStep5 7.0
#define fPerStep6 1.25
#define fPerStep7 7.0
#define fPerStep8 1.25
// numero di campioni che compongono un periodo della sinusoide in Output sull'ADC
#define SAMPLESINENUM 45 // consigliabile avere multipli di 45
// numero di campioni generati durante una intera modulazione PSK. Nominalmente la somma del numero di periodi degli step è 57.
#define nNumPeriodi (fPerStep1 + fPerStep2 + fPerStep3 + fPerStep4 + fPerStep5 + fPerStep6 + fPerStep7 + fPerStep8)
#define SAMPLEOUTNUM (SAMPLESINENUM*nNumPeriodi)
// numero di campioni acquisiti dall'ADC e che compongono l'array
#define SAMPLEINNUM (SAMPLESINENUM*nNumPeriodi*2)+2 // contiene una intera onda (in Byte) generata con PSK, + 2 caratteri
// periodo in millisecondi della 83.3 Hz
#define T833 (1/83.3)
// periodo in millisecondi della 50 Hz
#define T50 (1/50.0)
// periodo in millisecondi del Bridge tra le diverse fasi = 9,6 ms
#define T96 (0.0096)
// periodo di acquisizione dall'ADC
#define TADC (0.0048) // impostato aper avere 3 campioni nel periodo di bridge (1.25 * 9.6 ms)
// numero di campioni in 1/4 di periodo
#define QUARTERSAMPLEOUTNUM SAMPLESINENUM/4
// parametri dell'onda coseno da generare
#define PI (3.141592653589793238462)
#define AMPLITUDE 32767 //(1.0) // x * 3.3V
#define PHASE (PI/2) // 2*pi è un periodo
#define OFFSET 32767 //(0x7FFF)
// Output LED di diagnostica
DigitalOut led(LED1);
// ticker per la generazione dell'onda con DAC
Ticker SampleOutTicker;
// ticker per l'acquisizione dell'onda con ADC
//Ticker SampleInTicker;
// Buffer contenente la sinusoide da porre in output.
unsigned short usaSine[SAMPLESINENUM];
// array con i dati acquisiti dall'ADC Locale
//volatile unsigned short usaLocaleADC[SAMPLEINNUM];
volatile char caTxPacket[(int)SAMPLEINNUM];
// prototipo di funzione che genera i campioni della sinusoide da utilizzare per la generazione tramite DAC
void CalculateSinewave(void);
// carattere in arrivo dal PC
volatile char cReadChar;
// valore letto dall'ADC
volatile unsigned short usReadADC;
// Tipo di PSK da generare
volatile int nPSK;
// indice, nell'array, del campione da porre in output
volatile int nSampleOutIndex;
// indice, nell'array, del campione acquisito in input
volatile int nSampleInIndex;
// contatore dei campioni in output sul DAC
volatile int nSampleOutCount;
// contatore dei campioni in input dall'ADC
volatile int nSampleInCount;
// Periodo di generazione campioni in output DeltaT = T/NumSample
double fDeltaT;
// amplificazione per il dato da spedire sull'ADC
volatile double fAmp;
//volatile double fAmpNew;
// Step attuale e nuovo Step nella generazione di una PSK
volatile int nStep;
volatile int nNewStep;
//variabili ausiliarie
volatile unsigned short usAux;
volatile char cAux;
// flag per bloccare la generazione del segnale
volatile bool bStop;
// frequenza segnale da generare
volatile double fFreq;
//****************************
// Create the sinewave buffer
//****************************
void CalculateSinewave(int nOffset, int nAmplitude, double fPhase)
{
// variabile contenente l'angolo in radianti
double fRads;
// indici per i cicli
int nIndex;
// passo in frequenza fissato dal numero di campioni in cui voglio dividere un periodo di sinusoide: DeltaF = 360°/NUMSAMPLE
double fDeltaF;
// angolo per il quale bisogna calcolare il valore di sinusoide: fAngle = nIndex*DeltaF
double fAngle;
fDeltaF = 360.0/SAMPLESINENUM;
for (nIndex = 0; nIndex < SAMPLESINENUM; nIndex++)
{
fAngle = nIndex*fDeltaF; // angolo per il quale bisogna calcolare il campione di sinusoide
fRads = (PI * fAngle)/180.0; // Convert degree in radian
//usaSine[nIndex] = AMPLITUDE * cos(fRads + PHASE) + OFFSET;
usaSine[nIndex] = nAmplitude * cos(fRads + fPhase) + nOffset;
}
}
//***************************
// generazione sample da DAC
//***************************
void SampleOut()
{
// se è stato inviato il comando Stop, non fare niente fino a nuovo comando
if(bStop)
{
}
else // se non è stato inviato il comando di bStop continua
{
// output del campione della forma d'onda
//usAux=(usaSine[nSampleOutIndex])/fAmp;
//usAux=usaSine[nSampleOutIndex];
OutLocale.write_u16(usaSine[nSampleOutIndex]);
OutCampagna.write_u16(usaSine[nSampleOutIndex]);
// incrementa l'indice del campione in output, modulo NUMSAMPLE: se NUMSAMPLE è 360, nSampleOutIndex va da 0 a 359
nSampleOutIndex++;
if(nSampleOutIndex >= SAMPLESINENUM)
{
nSampleOutIndex=0;
}
// acquisisce dato da ADC
usReadADC = InLocale.read_u16();
// prepara il pacchetto di dati acquisiti da restituire al PC
caTxPacket[nSampleInCount]= (char)(usReadADC&0xFF);
//+++caTxPacket[nSampleInCount]= 'a';
nSampleInCount++;
caTxPacket[nSampleInCount] = (char)((usReadADC>>8)&0xFF);
//++++caTxPacket[nSampleInCount]= 'b';
// incrementa il numero di campioni inviati, e individua la fase in cui ci si trova, relativamente alla modulazione PSK selezionata
nSampleOutCount++;
nSampleInCount = nSampleOutCount*2;
switch(nPSK)
{
case 0:
{
// in questo caso sto generando sinusoidi a frequenza fissa, senza PSK; reinizializza gli indici degli array di campioni acquisiti e generati
if(nSampleOutCount >= SAMPLEOUTNUM) // nSampleInCount è sempre pari a nSampleOutCount*2
{
nSampleOutCount=0;
}
} break;
case 1:
{
switch(nSampleOutCount)
{
case 0: //if(nSampleOutCount == 0) // dopo il ciclo completo, si ritorna allo step 1
{
nNewStep = 1; // genera 23 periodi di sinusoide
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case (fPerStep1*SAMPLESINENUM): //if(nSampleOutCount == (23*SAMPLESINENUM)) // dopo 23 periodi a 83.3 Hz, passa allo step 2 in cui genera il primo Bridge
{
nNewStep = 2; // genera Bridge
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, e un Bridge genera 15 sinusoidi a 83.3 Hz
{
nNewStep = 3; // genera 15 periodi di sinusoide
//pc.printf(" nStep = %1d \n\r",nNewStep);
}
case ((fPerStep1+fPerStep2+fPerStep3)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge e 15 periodi a 83.3 Hz, genera un bridge
{
nNewStep = 4; // Genera Bridge
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2+fPerStep3+fPerStep4)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SSAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM)+(1.25*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge, genera 7 periodi a 83.3Hz
{
nNewStep = 5; // genera 7 periodi di sinusoide
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2+fPerStep3+fPerStep4+fPerStep5)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, genera bridge
{
nNewStep = 6; // Genera Bridge
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2+fPerStep3+fPerStep4+fPerStep5+fPerStep6)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM)+(1.25*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, bridge, genera 7 periodi a 83.3Hz
{
nNewStep = 7; // genera 7 periodi di sinusoide
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2+fPerStep3+fPerStep4+fPerStep5+fPerStep6+fPerStep7)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, bridge, 7 periodi a 83.3Hz, genera bridge
{
nNewStep =8; // genera bridge
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
case ((fPerStep1+fPerStep2+fPerStep3+fPerStep4+fPerStep5+fPerStep6+fPerStep7+fPerStep8)*SAMPLESINENUM): //if(nSampleOutCount == ((23*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(15*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM)+(1.25*SAMPLESINENUM)+(7*SAMPLESINENUM)+(1.25*SAMPLESINENUM))) // dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, bridge, 7 periodi a 83.3Hz, bridge, ritorna a generare 23 periodi a 83.3Hz
{
nNewStep =1;
nSampleOutCount =0;
//pc.printf(" nStep = %1d \n\r",nNewStep);
} break;
default: {} break;
}
} break;
default:{} break;
}
}
}
//*******************
// Loop Principale
//*******************
int main()
{
// indice per i cicli
int nIndex;
// configura velocità della comunicazione seriale su USB-VirtualCom e invia messaggio di benvenuto
pc.baud(921600); //921600 bps
//pc.baud(256000); //256000 bps
pc.printf("*** SineWave Generation ***\n\r");
//inizializza variabili
nSampleInIndex =0;
fAmp = 1.0;
cReadChar = 0;
nSampleOutIndex=0;
nSampleOutCount=0;
nPSK =0;
bStop= false;
fFreq = 83.3;
for(nIndex =0; nIndex < SAMPLEINNUM; nIndex++)
{
caTxPacket[nIndex]='\0';
}
// genera sinusoide
//+++SampleInTicker.attach(&SampleIn,TADC); // Ticker di acquisizione dall'ADC
// avvia il ciclo di generazione sinusoide
while(true)
{
// verifica se è arrivato un carattere dalla seriale del PC
if(pc.readable())
{
cReadChar = pc.getc(); // Read hyperterminal
bStop = false; // è stato inviato un comando, quindi resetta il flag di Stop: bStop = False
if(cReadChar == '1') // genera sinusoide a 83.3Hz con ampiezza ridotta a metà della nominale
{
pc.printf("\n\r--- Selezionato PSK-I ---\n\r");
bStop = false; // è stato inviato un comando, quindi bStop = False
nPSK = 1;
fAmp = 1.0;
nSampleOutIndex=0;
nSampleOutCount=0;
// generazione della sinusoide con valori nominali
CalculateSinewave(32767, 32767, (PI/2.0));
nStep = 0; // inizializza lo step che sarà aggiornato nella routine di generazione campione
//fAmpNew = 1.0;
//fDeltaT= T833/SAMPLEOUTNUM; // frequenza di generazione iniziale
}
if (cReadChar == 'a') // genera sinusoide a 83.3Hz con ampiezza nominale
{
bStop = true;
nPSK = 0; // nessuna PSK da generare
fFreq = 83.3;
pc.printf("\n\r--- Generazione %.1f Hz ampiezza nominale ---\n\r", fFreq);
//nSampleOutIndex=0;
//nSampleOutCount=0;
fAmp = 1.0;
// generazione della sinusoide con valori nominali
CalculateSinewave(32767, 32767, (PI/2.0));
fDeltaT = 1.0/(fFreq*SAMPLESINENUM);
bStop = false;
SampleOutTicker.attach(&SampleOut,fDeltaT);
}
if (cReadChar == 'b') // genera sinusoide a 50 Hz con ampiezza ridotta a metà della nominale
{
bStop = true;
nPSK = 0; // nessuna PSK da generare
fFreq = 50.0;
pc.printf("\n\r--- Generazione %.1f Hz ampiezza 1/2 della nominale ---\n\r", fFreq);
//nSampleOutIndex=0;
//nSampleOutCount=0;
fAmp = 1.0;
// genera sinusoide
CalculateSinewave(32767, (32767/2), (PI/2.0));
// attach ticker
fDeltaT = 1.0/(fFreq*SAMPLESINENUM);
bStop = false;
SampleOutTicker.attach(&SampleOut,fDeltaT);
}
if (cReadChar == 'c') // genera sinusoide a 45 Hz con ampiezza ridotta a 1/4 del valore nominale
{
bStop = true;
nPSK = 0; // nessuna PSK da generare
fFreq = 45.0;
pc.printf("\n\r--- Generazione %.1f Hz ampiezza 1/4 della nominale ---\n\r", fFreq);
//nSampleOutIndex=0;
//nSampleOutCount=0;
fAmp = 1.0;
// genera sinusoide
CalculateSinewave(32767, (32767/4), (PI/2.0));
// attach ticker
fDeltaT = (double)(1.0/((double)fFreq*(double)SAMPLESINENUM));
bStop = false; // è stato inviato un comando, quindi bStop = False
SampleOutTicker.attach(&SampleOut,fDeltaT);
}
if (cReadChar == 'z') // Stop
{
nPSK = 0; // nessuna PSK da generare
pc.printf("\n\r--- Stop Generazione ---\n\r");
bStop=true;
}
//led.write(1);
} // if (pc.readable())
// In base alla PSK selezionata, ci saranno diversi step da seguire
switch (nPSK)
{
case 0: {} break;
case 1: // PSK-I
{
// Avvia il primo step della PSK selezionata. Nello Step 0 non si ritornerà più
if(nStep == 0)
{
//pc.printf("*** Avvio generazione ***\n\r");
nNewStep = 1;
}
// se è stato raggiunto il numero di campioni per la variazione di Step, aggiorna il numero di Step e modifica i parametri di generazione
if(nStep != nNewStep)
{
// aggiorna il numero di Step e modifica i parametri di generazione
nStep = nNewStep;
switch (nStep)
{
case 1:
{
// invia il buffer di campioni relativi ad una intera generazione PSK con sfasamento totale di 360°
pc.printf("%s", caTxPacket); // 50 caratteri
// genera 23 periodi a 83.3 Hz
//+++pc.printf("+++ 23 sinusoidi a 83,3Hz +++\n\r");
fDeltaT = double((double)T833/(double)SAMPLESINENUM);
SampleOutTicker.attach(&SampleOut,fDeltaT);
} break;
case 2:
{
// dopo 23 periodi a 83.3 Hz, genera il primo Bridge
//+++pc.printf("+++ Primo Bridge +++\n\r");
fDeltaT = (double)((double)T96/(double)(SAMPLESINENUM));
SampleOutTicker.attach(&SampleOut,fDeltaT);
} break;
case 3:
{
// dopo 23 periodi a 83.3 Hz, e un Bridge genera 15 sinusoidi a 83.3 Hz
//+++pc.printf("+++ 15 sinusoidi a 83,3Hz +++\n\r");
fDeltaT = double((double)T833/(double)SAMPLESINENUM);
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
case 4:
{
// dopo 23 periodi a 83.3 Hz, Bridge e 15 periodi a 83.3 Hz, genera un bridge
//+++pc.printf("+++ Secondo Bridge +++\n\r");
fDeltaT = (double)((double)T96/(double)(SAMPLESINENUM));
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
case 5:
{
// dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge, genera 7 periodi a 83.3Hz
//+++pc.printf("+++ 7 Sinusoidi a 83.3Hz +++\n\r");
fDeltaT = double((double)T833/(double)SAMPLESINENUM);
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
case 6:
{
// dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, genera bridge
//+++pc.printf("+++ Terzo Bridge +++\n\r");
fDeltaT = (double)((double)T96/(double)(SAMPLESINENUM));
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
case 7:
{
// dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, bridge, genera 7 periodi a 83.3Hz
//+++pc.printf("+++ 7 sinusoidi a 83.3Hz +++\n\r");
fDeltaT = double((double)T833/(double)SAMPLESINENUM);
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
case 8:
{
// dopo 23 periodi a 83.3 Hz, Bridge, 15 periodi a 83.3 Hz, bridge,7 periodi a 83.3Hz, bridge, 7 periodi a 83.3Hz, genera bridge
//+++pc.printf("+++ Quarto Bridge +++\n\r");
fDeltaT = (double)((double)T96/(double)(SAMPLESINENUM));
SampleOutTicker.attach(&SampleOut, fDeltaT);
} break;
default: break;
} //switch (nStep)
} // if(nStep != nNewStep)
} break; //case 1:
default: {} break;
} //switch (nPSK)
} // while(true)
}
