In this post I will show how to use Universal Plus family hat to turn Raspberry Pi into an Arbitrary Waveform Generator and visualise the generated waveforms (ie to create the simple oscilloscope). I use the Universal Zero Plus hat – but all of them have the same functionality (except the SERVO version which has only one DAC port available).
From the Universal Plus datasheet:
DAC ports are on the pins 7 and 8. I will use ADC ports on the ports 3, 4 and 5. As a source of the digital signal I will use the port 28 which is the PWM port number 19
Waveform generator (DAC):
Universal Plus DAC can autonomously generate the analog signal. It is enough to create the list of the values (the DAC converter is 12 bit so the values should be in the range 0-4095), set the number of the samples and period or frequency of the generated signal and start the generation:
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 |
#two list of the samples as two waveforms will be generarted samples = [] samples1 = [] #number of the the samples per period nsamples = 512 #frequency of the generated signal. #the actual sample rate will be nsamples * DACfrequency DACfrequency = 1000 #DAC Initialisation uzp0.DACInit(uzp0.DAC1, obuff = 0, generate = 1) uzp0.DACInit(uzp0.DAC2, obuff = 0, generate = 1) #samples calculations for i in range(0, nsamples): samples.append(2048 + 1900 * math.cos(i*2*3.14/nsamples) * math.sin(i*32*3.14/nsamples)) for i in range(0, SawSamples): for j in range(0, int(nsamples / SawSamples)): samples1.append(600 + j * 3000 / (nsamples / SawSamples)) #start waveform generation uzp0.DACGenerate(uzp0.DAC1, nsamples, samples, frequency = DACfrequency) uzp0.DACGenerate(uzp0.DAC2, nsamples, samples1, frequency = 2 * DACfrequency) uzp0.DACStart(uzp0.DAC1) uzp0.DACStart(uzp0.DAC2) |
PWM generation (PWM)
Universal Plus hats can autonomously read the real time ADC data and then send it to the Raspberry Pi. Similar to DAC it is enough to configure the channels to be read, number of sequences (of the channels configured) of conversions and period or frequency.
1 2 3 4 5 6 7 8 9 10 11 |
PWMports = [uzp0.PWM19] uzp0.PWMInit(PWMports) uzp0.PWMFrequencyDuty(PWMports, frequency = PWMfrequency, duty = PWMratio) uzp0.PWMStart(PWMports) #PWM duty ratio change every iteration PWMratio += PWMdelta if PWMratio > 75 or PWMratio < 25: PWMdelta = -PWMdelta uzp0.PWMDuty(PWMports, PWMratio) |
Data acquisition (ADC)
Universal Plus hats can autonomously read the real time ADC data and then send it to the Raspberry Pi. Similar to DAC it is enough to configure the channels to be read, number of sequences (of the channels configured) of conversions and period or frequency.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#512 samples will be read in 1ms (1/1000Hz) ADCNsamples = 512 ADCfrequency = 1000 #configure ADC channels all three channels will be read in the sequence dports = [uzp0.ADC1, uzp0.ADC2, uzp0.ADC3] # ADC ports to act as the oscilloscope channnels. You can add the additional ones or just use one #ADC initialisation and Vref read uzp0.ADCInit(dports, speed = 4) #speed - sample time uzp0.ADCReadVref() #data acquisition 512 x 3 readings taken in 1ms data = uzp0.ADCReadData(dports, nsamples = ADCNsamples, frequency = ADCfrequency) |
And the result