RPi Pico DDS und Scope  

Elektronik-Labor  Projekte  Mikrocontroller  Raspberry     





Inzwischen habe ich einen etwas besseren Eindruck von der Genauigkeit und Auflösung des AD-Wandlers bekommen. Für die neuen Versuche habe ich Thonny in der Versuin 3.3.13 verwendet. Dass dadurch eine Verbesserung eingetreten ist, kann ich nicht ausschließen. Zusätzlich habe ich einen anderen Masse-Pin, nämlich AGND am Pin 33 verwendet. Beim letzten Versuche war es GND am Pin 38. Dadurch könnten zusätzliche Störungen vom Spannungsregler induziert worden sein. 


import machine
from machine import Pin
import utime
import time

u2 = machine.ADC(2)
ad_in = Pin(28, Pin.IN)
freq = machine.freq()

#Spannungwandler im PWM Mode sauberer:
p23 = Pin(23, Pin.OUT)
p23.value(1)

   
while True:
    u=u2.read_u16()//16
    print(u)
    utime.sleep(1)


Der Versuch wurde mit unterschiedlichen Taktraten von 10 MHz bis 250 MHz getestet. Aber dabei war kein Unterschied in der AD-Auflösung feststellbar, weil der AD-Wandler grundsätzlich mit 48 MHz getaktet wird. Die Referenz wurde mit 100 µF abgeblockt, und an A2 lag ein Elko mit 22 k, der über 10 k geladen und entladen wurde. Die Ladespannung vom Netzteil war nur 160 mV, womit der 12-Bit-Messwert bis 204 stieg. Nachgerechnet: 204 /4095 * 3300 mV = 164 mV.



Das Flattern der AD-Werte beträgt jetzt nur noch eine Stufe. Was bleibt, ist der Offsetfehler von 15 mV am unteren Rand nahe 0 V. Wenn man den Bereich bis 3,3 V ausnutzt, sieht es gar nicht so schlecht aus.



Ein Versuch mit der Arduino-IDE und der Boarderweiterung von Earle F. Philhower (https://arduino-pico.readthedocs.io/_/downloads/en/latest/pdf/) hatte das Ziel, eine schnelle Messung mit einem DDS-Generator zu verbinden. Dabei habe ich mich an der Software zum Arduino-Messlabor orientiert. Erreicht wurde eine Abtastrate von rund 50 kHz. DDS-Ausgabe und Messung laufen in einem Timer-Interrupt. Im Beispiel wird ein Sinussignal mit einer Frequenz von 300 Hz erzeugt und gleich wieder gemessen. Weil 500 Messwerte an den PC übertragen werden, können sie direkt im seriellen Plotter dargestellt werden.

//50-kHz-DDS + Scope
#include "RPi_Pico_TimerInterrupt.h"
#include <math.h>
unsigned char dds[256];
unsigned int ad[1000];
unsigned int f, n, i, j, a1, a2, ph1, ph2, adn;


// Init RPI_PICO_Timer
RPI_PICO_Timer ITimer0(0);
RPI_PICO_Timer ITimer1(1);


bool TimerHandler0(struct repeating_timer *t)
{
digitalWrite (2,1);
a1+=ph1; //256;
a1&=65535;
analogWrite(0, (dds[a1>>8]));
if (adn<1000){
ad[adn] = analogRead(A2);
adn++;
}
digitalWrite (2,0);
return true;
}

void setup() {
Serial.begin(115200);
pinMode(2,OUTPUT);
analogWriteFreq(125000000);
analogWriteRange(255);
for (n=0;n<256;n++) dds[n]= 128+127.9*sin(PI*n/128.0);
ITimer0.attachInterruptInterval(13, TimerHandler0); //50 kHz
}

void loop() {
f=300;
ph1 = f*256/195;
adn=0;
delay(1000);
for(n=0;n<500;n++)Serial.println (ad[n+500]);
}
 



Das PWM-Signal entsteht am Pin 0 und wurde über 10 k und 100 nF geglättet an AD2 geleitet und für das Oszilloskop gemessen. Alles funktioniert schon ähnlich wie bei der Arduino-Vorlage. Einige Fragen bleiben noch offen. Warum liefert der AD-Wandler 10-Bit-Werte bis 1023? Und warum liefert der Timer-Interrupt relativ krumme Zeiten? Es gibt noch viel zu tun. Vermutlich sind beim Einsatz des DMA-Systems noch wesentlich höhere Abtastraten möglich.

Nachtrag
Martin Müller hat mich darauf hingewiesen, dass die AD-Auflösung von 10 Bit in der Arduino-Umgebung Standard ist. Und die Timing-Probleme mit dem Interrupt hat er auch beobachtet und führt sie darauf zurück, dass im Hintergrund die Zeit im Mikrosekundentakt erfasst wird.









Elektronik-Labor  Projekte  Mikrocontroller  Raspberry