Hallo,
ich bin momentan dabei mit einem Raspberry Pi sowie einem ADC MCP3208
und mit Hilfe der wiringPi-Bib Signale einzulesen. Ziel ist es
irgendwann einen FIR-Filter zu implementieren. Da ist aber noch
Zukunftsmusik :D
Momentan gebe ich über einen Signalgenerator einen Takt vor, welcher
wiederum den Interrupt auslöst. In der ISR wird der ADC getartet,
welcher über SPI die Daten an den Raspberry Pi sendet.
Das Problem: Am Signalgenerator stelle ich 40 kHz ein. Somit müsste ja
der Interrupt alle 25 µs ausgelöst werden. Um das ganze zu überprüfen
habe ich in der ISR einen Testpin so konfiguriert, dass er bei jedem
Aufruf des ISR den Zustand wechselt. Sprich von LOW auf HIGH und von
HIGH auf LOW wechselt. Diesen Pin messe ich mit dem Oszi. Auf dem Oszi
sind lese ich jedoch eine Frequenz von 17 kHz ab. Weiß eventuell jemand
wie das zustande kommt?
1
#include <stdio.h>
2
#include <string.h>
3
#include <errno.h>
4
#include <stdlib.h>
5
6
#include <wiringPi.h>
7
#include <wiringPiSPI.h>
8
9
#define CS_MCP3208 8 // BCM_GPIO8
10
11
#define BUTTON_PIN 3
12
#define DG_OUT 7
13
#define CHANNEL_BIT_MASK 0x07
14
#define BYTE_I_MASK 0x06
15
#define BYTE_II_MASK 0x00
16
#define BYTE_II_RCV_MASK 0x0F
17
#define SPI_CHANNEL 0
18
#define SPI_SPEED 2000000 // !! Start low here and if all works try to increase if needed on a breadboard I could go upto about 750000
19
20
int toggle = 1;
21
int start, end;
22
23
int read_mcp3208_adc(unsigned char adcChannel);
24
25
26
void myInterrupt(void) {
27
int adc1Channel = 0;
28
int adc1Value = 0;
29
30
start = micros();
31
toggle ^= 1;
32
digitalWrite(DG_OUT, toggle);
33
adc1Value = read_mcp3208_adc(adc1Channel);
34
adc1Value = (3.3/4096) * adc1Value;
35
end = micros();
36
37
//printf("\n int: 0 %d \n", end - start);
38
}
39
40
41
int main (void)
42
{
43
//int adc1Channel = 0;
44
//int adc1Value = 0;
45
46
47
if(wiringPiSetup() == -1)
48
{
49
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror(errno));
50
return 1 ;
51
}
52
53
wiringPiSPISetup(SPI_CHANNEL, SPI_SPEED);
54
55
if ( wiringPiISR (BUTTON_PIN, INT_EDGE_RISING, &myInterrupt) < 0 ) {
56
fprintf (stderr, "Unable to setup ISR: %s\n", strerror (errno));
Hmm, entweder ist einfach zu viel Code im ISR - diese sollten ja
normalerweise sehr kurz sein - oder das digitalWrite ist zu langsam da
es immer noch durch eine Treiberschicht durch muss, auf dem Raspi.
Versuch dahingehend zu debuggen.
Erstmal in die ISR nur einen double incrementieren und nach Separat nach
z.B. 5s anhalten und den Wert ausgeben.
Damit kannst du prüfen ob die ISR erfolgreich mit 40khz feuert.
Dann bau das Auslesen des ADC hinzu und prüfe erneut.
Zuletzt lass das ADC Zeug raus und mach nur den Toggle und miss die
Frequenz.
ADC19191 schrieb:> Momentan gebe ich über einen Signalgenerator einen Takt vor, welcher> wiederum den Interrupt auslöst. In der ISR wird der ADC getartet,> welcher über SPI die Daten an den Raspberry Pi sendet.
Damit taucht der Jitter der Interrupt Latenz als Abtastjitter auf und du
versaust dir bei höheren Abtastraten deine Zeitserie vom ADC.
Ist der Raspi der richtige Rechner für dein Vorhaben?
Wenn ich exaktes Timing brauche, dann nehme ich einen Rechner ohne OS,
welches mir meine Seiten auslagern könnte.
Nichts gegen Raspi, ich selbst habe mehrere, doch für Echtzeit ist der
nicht der richtige.
Das stimmt auch wieder..
Die Möglichkeit ISRs einzusetzen hat zwar einiges an interesanten
Einsatzgebieten eröffnet (z.B. den Takt von Hallsensoren an üblichen
Motoren auszuwerten), aber z.B. ein sinnvolles Oszilloskop kann man
damit trotzdem nicht bauen.
PittyJ schrieb:> Nichts gegen Raspi, ich selbst habe mehrere, doch für Echtzeit ist der> nicht der richtige.
Das kommt drauf an, wie "Echtzeit" spezifiziert ist. Für einen
Datenlogger, der im deutlichen Sub-Hz-Bereich abtastet und dessen
Eingangssignal frequenzmäßig vernünftig begrenzt ist, wird es vermutlich
reichen.