Nur einmal abtasten

hallo zusammen,
ich bin neu hier und kaum Erfahrung, auch mit Arduino an sich.
Ich arbeite an einem Projekt, wo ich zuerst nur einmal 2 analoge Signale mit Arduino Giga-r1 abtasten soll, den Buffer voll machen und dann diese Werte zu pc übertragen.
Wenn ich irgendwas in diesem Code ändern, sind die Ausgaben dann falsch.
Vielen dank im Voraus für eure Tipps.

#include <Arduino_AdvancedAnalog.h>
const float MAX_VOLTAGE = 3.3; // Maximale Spannung der Quelle

// ADC-Objekte für A0 und A1
AdvancedADC adc1(A0);
AdvancedADC adc2(A1);
AdvancedADCDual adc_dual(adc1, adc2);
uint64_t last_millis = 0;

void setup() {
    Serial.begin(115200);

    // ADC 1 (A0) konfigurieren
    if (!adc_dual.begin(AN_RESOLUTION_16, 16000, 64, 32)) {
        Serial.println("Fehler: ADC1 konnte nicht initialisiert werden!");
        while (1);
    }


    Serial.println("Messung gestartet...");
    Serial.println("A0 A1"); // Beschriftung für den Serial Plotter (optional)
}

void loop() {
    if (millis() - last_millis > 1) { // Abtastung alle 1ms
        if (adc1.available() && adc2.available()) {
            SampleBuffer buf1 = adc1.read();
            SampleBuffer buf2 = adc2.read();

            // Spannung berechnen
            float voltage1 = (buf1[0] / 65535.0) * MAX_VOLTAGE;
            float voltage2 = (buf2[0] / 65535.0) * MAX_VOLTAGE;

            // Ausgabe für den Serial Plotter
            Serial.print(voltage1, 2);
            Serial.print(" ");
            Serial.println(voltage2, 2);

            buf1.release();
            buf2.release();
        }
        last_millis = millis();
    }
}

Gibt es die Beschreibung auch in verständlicher Form?
Welchen Puffer sollst (Hausaufgabe, Semesterarbeit, ...) Du voll machen? Davon ist nichts in Deinem Code zu sehen.

Gruß Tommy

wie groß sind denn deine Buffer ?

SampleBuffer buf1

von der Laufzeit her wäre es vermutlich gut

  • wenn du während dem Auslesen auf die Testausgabe an Serial verzichtest
  • die millis() nur einmal abfrägt (currentMillis = millis() und dann sowohl den Zeitvergleich wie auch das merken in last_millis auf currentMillis umbaust).

Der TO hat das Example um eine Zeile gekürzt...


    // Initialize ADC with: resolution, sample rate, number of samples per channel, queue depth
    if (!adc1.begin(AN_RESOLUTION_16, 16000, 32, 64)) {

.read() gibt den gesamten Puffer zurück:

Ich bin hier mal so frei meine Gedanken zu äußern die mir beim Lesen dieser Anfrage gekommen sind.

"Da hat jemand keinen Bock auf das Projekt und deswegen haut er lustlos eine Kurzanfrage im Arduino-Forum raus"

Du arbeitest an einem Informatik-Projekt und was man am meisten braucht in einem Informatik-Project ist präzise, detaillierte Information

Mit was für einer Abstastrate sollst du die AD-Werte erfassen?
Wie lange sollst du die Abstastwerte erfassen?

Soll immer einmal erfasst werden und dann hast du minutenlang Zeit die Werte an den PC zu übertragen oder sollen die Werte pausenlos = in Echtzeit übertragen werden?

Daraus ergeben sich Puffergröße und Abtastrate und auch evtl. die erforderliche Baurate

Danke für die Antworten. Es geht um eine Semesterarbeit. Ich soll einen Arduino Giga-R1 in ein Oszilloskop umwandeln.
Als Erstes müssen zwei Signale abgetastet werden, und die Abtastwerte sollen danach ausgewertet werden. Diese Abtastwerte soll ich anhand einer einzigen Abtastung bekommen. Wenn ich ein 1 kHz Signal mit einer Abtastrate von 10 KHz nur einmal abtaste, dann soll ich theoretisch 10.000 Werte erhalten und diese anschließend auswerten.
Inzwischen habe ich ein Beispiel mit STMSpeeduino gefunden und entsprechend geändert:

#include "STMSpeeduino.h"


const long ValuesToStore = 100000; //How many values to store, max 30000, the more the higher accuracy
int16_t CurrentValue = 0;        //tracks current stored value


uint16_t ADC1Values[ValuesToStore] = {}; 
uint16_t ADC2Values[ValuesToStore] = {}; 

// ADC-Konfiguration
const int ADC1Channel = A0;      //ADC 1 channel
const int ADC2Channel = A1;      //ADC 2 channel
const int Resolution = 16;       //8, 10, 12, 14, 16
double ClockSpeed = 10;          //Clock speed in mhz, stable up to 40mhz, may decrease range further
int SampleTime = 0;              //0 to 7
int Samplenum = 0;               //Number of samples, is 1 more, 0 to 1023

void setup() {
    Serial.begin(9600); 
    while (!Serial); 

    Serial.println("Start des Programms");

    ADCSimultaneous(ADC1Channel, ADC2Channel, Resolution, ClockSpeed, SampleTime, Samplenum);

    Serial.println("Beginne mit der Datenerfassung...");

    // Werte sammeln
    for (int i = 0; i < ValuesToStore; i++) {
        ADC1Values[i] = CatchADCValue(ADC1);
        ADC2Values[i] = CatchADCValue(ADC2);
    }

    Serial.println("Datenerfassung abgeschlossen. Ausgabe der Werte:");

    // Werte ausgeben
    for (int i = 0; i < ValuesToStore; i++) {
        Serial.print(i);
        Serial.print(" ");
        float voltage1 = ADC1Values[i] * 3.3f / pow(2, Resolution);
        float voltage2 = ADC2Values[i] * 3.3f / pow(2, Resolution);
        Serial.print(voltage1, 4); 
        Serial.print(",");
        Serial.println(voltage2, 4); 
    }

    Serial.println("Ausgabe abgeschlossen.");
    while (1); // Endlosschleife, um das Programm zu stoppen
}

void loop() {
    // 
}

Die Ausgaben sehen gut aus, ob mit 1 oder 10 MHz.
Ist meine Denk- und Arbeitsweise hier richtig?

Mit Arduino_AdvancedAnalog muss ich weiter testen:

#include <Arduino_AdvancedAnalog.h>

const float MAX_VOLTAGE = 3.3;
const int Resolution = 16;       //8, 10, 12, 14, 16
const int buffSize = 10000;  // Number of samples to capture
bool dataCaptured = false;

AdvancedADC adc1(A0);  // ADC channel A0
AdvancedADC adc2(A1);  // ADC channel A1
AdvancedADCDual adc_dual(adc1, adc2);  // Dual ADC object

void setup() {
    Serial.begin(9600);
    while (!Serial) {
        
    }

    // Initialize the dual ADC with resolution, sample rate, buffer size, and queue depth
    if (!adc_dual.begin(AN_RESOLUTION_10, 10000, buffSize, 4)) {
        Serial.println("Error: ADC_Dual initialization failed!");
        while (1);  
    }

    Serial.println("Waiting for data capture...");

    // Wait until both ADCs have data available
    while (!adc1.available() || !adc2.available()) {
        // Optionally, add a small delay to avoid busy-waiting
        delay(10);
    }

    // Capture the buffers
    SampleBuffer buf1 = adc1.read();
    SampleBuffer buf2 = adc2.read();

    Serial.println("Captured data from A0 and A1:");

    // Process and output the data
    for (int i = 0; i < buffSize; i++) {
        float voltage1 = buf1[i] * 3.3f / pow(2, Resolution);
        float voltage2 = buf2[i] * 3.3f / pow(2, Resolution);

        // Print the data
        Serial.print(i);
        Serial.print(" A0: ");
        Serial.print(voltage1, 4);
        Serial.print(" V, A1: ");
        Serial.print(voltage2, 4);
        Serial.println(" V");
    }

    
    buf1.release();
    buf2.release();

    Serial.println("Data capture and output complete.");
    while (1);  
}

void loop() {
    // Empty loop
}

Das geht schon mal nicht

Das stimmt so auch nicht.

ergibt pro Sekunde 10000 Messwerte. Die Signalfrequenz von

ist dabei erst mal egal.

Ich verstehe unter einer einzigen Abtastung das Einlesen eines einzelnen Messwertes.

Das ergäbe auf einem Oszilloskop einen einzelnes winziges Pünktchen aber keinesfalls einen Signalverlauf über den ganzen Bildschirm.

Also was du möchtest ist mehrere hundert oder auch mehrere tausend Messwerte einlesen.

Semesterarbeit bedeutet wissenschaftlich arbeoten. Und da ist eine hochpräzise Ausdrucksweise gefragt. Wenn du das in der schriftlichen Ausarbeitung so schwammig ausdrücken würdest, würde ich dich durchfallen lassen.

Ist dir die Aufgabenstellung in der lauten Mensa einmal kurz zugerufen worden?
Vermutlich nicht. Sondern es gibt eine schriftliche Aufgabenstellung.
Und diese Aufgabenstellung müssten alle möglichen Spezfikationen angegeben worden sein.

Eventuell auch nicht. Dann ist es deine Aufgabe herauszufinden was denn ein Arduino Giga R1 als Oszilloskop zu leisten vermag.

verwechselst du da milli- mit micro-Sekunden ?
Brauchbare zeitliche Abläufe kann man nur aufzeichnen, wenn man das einigermaßen regelmäßig macht.

BTW: Die Funktion pow hat Gleitpunktwerte als Parameter und Ergebnis. Ganzzahlige Zweierpotenzen kriegst du damit nur langsam und fehlerbehaftet hin. Bits schieben tut man mit den Operatoren >> oder << . Ist hier nicht ganz so relevant, weil du du es eh mit Gleitpunktwerten verknüpfst, sieht aber immer dumm aus.

Ich habe tatsächlich keine Aufgabenstellung.
Das habe ich als Notiz bekommen und soll zunächst daran arbeiten und dann wird es geschaut, wie es weiter gehen soll:
Arduino Datenerfassung:

  • Zunächst nicht periodisch erfassen.
    --> z.B. 1024 Werte zwischenspeichern. --> zu PC übertragen --> plotten und auswerten.

Und ja, so ist es meine Aufgabe letzendes.

Ja, mein Gedanke ist, diese 10000 Messwerte zu erfassen, oder z.B. die ersten 1000 Werte davon.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.