Forum: Mikrocontroller und Digitale Elektronik Audio Sampling mit Arduino DUE und ADC


von amle (Gast)


Lesenswert?

Hallo
Ist ein Sampling (100Hz - 10Khz/16khz, Arrray64, 16/32 Kanäle) mit dem 
DUE überhaupt möglich mit dem ADC?
oder muss ich das mit einem Timer erledigen?
84000 / 512 = 164Khz maximale tiefste Rate.
Aber das funktioniert leider nicht. Eigentlich müsste das ja noch 10x 
tiefer sein. also 16.4khz

Kann mir jemand helfen, wie ich vorgehen muss?
Und was ich in ADC definieren muss  (wenn überhaupt möglich)?

Anbei etwas Code das ich zum Testen habe:
1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <string.h>
4
5
#include "arduinoFFT.h"
6
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
7
8
#define  DEBUG_INP          (0)
9
#define  DEBUG_OUT          (1)
10
11
#define OUT_Canel          (16)
12
#define FFT_Samples        (64)
13
#define OPT_Half          (2046)
14
15
double vReal[FFT_Samples];
16
double vImag[FFT_Samples];
17
18
char  sTemp[80];
19
20
void setup()
21
{
22
  Serial.begin(115200);
23
  while(!Serial);
24
  Serial.println("Ready");
25
  //--------------------------------------------
26
  // Init Register
27
  // setup mode register
28
  //analogReadResolution(12);
29
  ADC->ADC_MR = ADC_MR_FREERUN_ON | ADC_MR_SLEEP_NORMAL | ADC_MR_FWUP_OFF;
30
  ADC->ADC_MR |= ADC_MR_LOWRES_BITS_12;
31
  ADC->ADC_MR |= ADC_MR_STARTUP_SUT512; // startup time as per default
32
  ADC->ADC_MR |= ADC_MR_PRESCAL(168); // set clock prescalar to run as fast as possible
33
  ADC->ADC_MR |= ADC_MR_SETTLING_AST3; //settling time if the analog chanel is switched (dosn't mater if ANACH is not set)
34
  ADC->ADC_MR |= ADC_MR_ANACH_NONE;
35
  ADC->ADC_MR |= ADC_MR_TRACKTIM(0); // minimal tracking time
36
  ADC->ADC_MR |= ADC_MR_TRANSFER(0); // minimal transfer time
37
  // enable channel
38
  ADC->ADC_CHER = ADC_CHER_CH7 | ADC_CHER_CH6; //enable ADC on pin A0 (channel 7) + A1}
39
  delay(10); // wait for init adc
40
}
41
42
void loop() {
43
#if DEBUG_INP
44
  Serial.print("InpData:");
45
#endif
46
  int value = 0;
47
  while(ADC->ADC_ISR == ADC_ISR_EOC6);  // warte bis Messung fertig
48
  for (int i = 0; i < FFT_Samples; i++) { // Alle Samples Messen
49
#if DEBUG_INP
50
    if (i % 8 == 0)
51
      Serial.println("");
52
#endif
53
    // Read ADC
54
    while(ADC->ADC_ISR == ADC_ISR_EOC6);  // warte bis Messung fertig
55
    value = (int)ADC->ADC_CDR[6];          // Lese A1
56
    vReal[i] = ((value - OPT_Half) / 25.6f); // Copy to bins after compressing +-80.000
57
    vImag[i] = 0;     
58
#if DEBUG_INP
59
    sprintf(sTemp, "%++05ld,", (long)(vReal[i]));
60
    //sprintf(sTemp, "%++05ld,", value);
61
    Serial.print(sTemp);
62
#endif
63
  }
64
#if DEBUG_INP
65
  Serial.println("");
66
#endif
67
  //--------------------------------------------
68
  // Calc FFT
69
  int iData[16];
70
  FFT.Windowing(vReal, FFT_Samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
71
  FFT.Windowing(vReal, FFT_Samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
72
  FFT.Compute(vReal, vImag, FFT_Samples, FFT_FORWARD);
73
  FFT.ComplexToMagnitude(vReal, vImag, FFT_Samples);
74
  //double peak = FFT.MajorPeak(vReal, FFT_Samples, SAMPLING_FREQUENCY);
75
76
  int iStep = (FFT_Samples / 2) / OUT_Canel; 
77
  for(int i = 0, j = 0; i < (FFT_Samples / 2); i += iStep) {
78
    iData[j] = 0;
79
    for (int k=0 ; k < iStep ; k++) 
80
      iData[j] += vReal[i+k];
81
    iData[j] /= iStep; 
82
    j++;
83
  }
84
85
  FFT.Windowing(vReal, FFT_Samples ,FFT_WIN_TYP_BLACKMAN_HARRIS, FFT_FORWARD);  /* Weigh data */
86
  FFT.Compute(vReal, vImag, FFT_Samples , FFT_FORWARD); /* Compute FFT */
87
  FFT.ComplexToMagnitude(vReal, vImag, FFT_Samples ); /* Compute magnitudes */
88
  //FFT.MajorPeak(vReal, FFT_Samples , samplingFrequency, &x, &v);
89
90
  //--------------------------------------------
91
  // Werte Anzeigen
92
#if DEBUG_OUT
93
  Serial.print("OutData:");
94
  for(int i = 0; i < OUT_Canel; i++)  {
95
    sprintf(sTemp, "%+04d|", iData[i]);
96
    Serial.print(sTemp);
97
  }
98
  Serial.println("");
99
#endif
100
  delay(100);
101
}

von amle (Gast)


Lesenswert?

Hat sich erledigt funktioniert nun alles mit dem sam Due.
Habe nun alles mit ADC über Timer-Interrupt gemacht nicht mit dem 
Prescaler. Funktioniert einwandfrei.
Danke.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.