Programmierung eines ADC mit Arduino

(Firma: HAWK Göttingen) #3929530
Lesenswert?

Hallo,

ich arbeite gerade an einem Projekt, bei dem es darum geht, ein analoges 
Signal von einem ADC in ein digitales umwandeln zu lassen. Ich habe mir 
hier auf dem Forum ähnliche Projekte angeguckt, leider habe ich bis 
jetzt keine Lösung zu meinem Problem gefunden.

Ich habe als Mikrokontroller das Arduino Due zur Steuerung des 
AD7911/AD7921. Ich habe leider keine Erfahrung mit 
Arduino-Programmierung und möchte jetzt lernen, wie das ganze läuft.

hier ist das Datenblatt für mein 
Bauteil:http://www.analog.com/static/imported-files/data_sheets/AD7911_7921.pdf

ich möchte gern wissen, wie die SPI Kommunikation funktioniert, das 
heißt wie ich den ADC mit dem Arduino anspreche.  anschließend möchte 
ich das Ergebnis der  Umwandlung an den Arduino schicken und in ein 
Register speichern.

Ich habe erstmals den Code nur für einen Channel geschrieben, aber es 
läuft gar nichts.

über eine Antwort würde ich mich sehr freuen.
1
  #include<SPI.h>
2
 
3
 const int cs = 4;
4
 unsigned int adcValue;
5
 unsigned int adcValue1;
6
 unsigned int config1;
7
 int j=0;
8

9
void setup()
10

11
{
12
  pinMode(cs, OUTPUT);
13
  digitalWrite(cs, HIGH);
14
  SPI.begin();
15
  SPI.setBitOrder(MSBFIRST);
16
  SPI.setClockDivider(cs,21);
17
  SPI.setDataMode(SPI_MODE0);
18
  Serial.begin(9600);
19

20
}
21

22

23
void loop()
24
{
25
  //Analog Digital Umwandlung 
26
  for (int i=0; i<16; i++)
27
  {
28
    digitalWrite(cs, LOW);
29
    setAdc(1);
30
  }
31
  digitalWrite(cs, HIGH);
32
  delayMicroseconds(10);
33
}  
34
 
35

36
//Analog Digital Funktion
37
void setAdc(int channel)
38
{
39
  int c=16;
40
 int feld1[c];
41
     config1=0010000000000000;
42

43
   byte adcValueLSB = SPI.transfer(cs,0x00);        // niederwertiges Byte zuerst, D15...D8
44
  byte adcValueMSB = SPI.transfer(cs,0x00);        // höherwertiges Byte zum Schluss, D7...D0
45
  adcValue = adcValueMSB << 8;
46
  adcValue = adcValue | adcValueLSB;
47
  adcValue1= adcValue | config1; 
48
  
49
     feld1[j] = adcValue1;
50
    Serial.print("analog value = ");
51
    Serial.println(feld1[j]);
52
    Serial.print('\n');
53

54
      j++;
55
  
56
  delayMicroseconds(0.25);//convertion time
57
 
58
      
59
}
Gast #3929741
Lesenswert?

Hi,

Erst einaml eine Grundlegende Frage: Ist ein externer ADC notwendig? 
Dein Arduino Due hat zwei ADC integriert die sich bequemer Auslesen 
lassen...

Nach einem kurzen Blick ins Datenblatt des ADCs bin ich, auf Seite 21, 
auf diesen Satzt gestoßen "Sixteen serial clock cycles
are required to perform the conversion process and to access
data from the AD7921". Wenn ich mir deinen Code ansehen könnte ich mir 
Vorstellen das der CS Pin nach jedem Byte wieder High wird und keine ADC 
Wandlung zustande kommt.
Versuch einmal die Chip Select Leitung "von Hand" zu setzen.
1
 CS PIn low setzten
2
 adcValue_high_byte = SPI.transfer(0x00)
3
 adcValue_low_byte = SPI.transfer(0x00)
4
CS Pin high setzten

Grüße

Hafax
(Firma: HAWK Göttingen) #3929792
Lesenswert?

hey ,

meintest du das?
1
 #include<SPI.h>
2

3
 const int cs = 4;
4
 unsigned int adcValue;
5
 unsigned int adcValue1;
6
 unsigned int config1;
7
 int j=0;
8

9
void setup()
10

11
{
12
  pinMode(cs, OUTPUT);
13
  digitalWrite(cs, HIGH);
14
  SPI.begin();
15
  SPI.setBitOrder(MSBFIRST);
16
  SPI.setClockDivider(cs,21);
17
  SPI.setDataMode(SPI_MODE0);
18
  Serial.begin(9600);
19

20
}
21

22

23
void loop()
24
{
25
  //Analog Digital Umwandlung
26
  for (int i=0; i<16; i++)
27
  {
28
    setAdc(1);
29
  }
30
  delayMicroseconds(10);
31
}
32

33

34

35
//Analog Digital Funktion
36
void setAdc(int channel)
37
{
38
  int c=16;
39
 int feld1[c];
40
     config1=0010000000000000;
41
 digitalWrite(cs, LOW);
42
SPI.transfer(cs,config1);
43
   byte adcValueLSB = SPI.transfer(cs,0x00);        // niederwertiges 
44
Byte zuerst, D15...D8
45
  byte adcValueMSB = SPI.transfer(cs,0x00);        // höherwertiges Byte 
46
zum Schluss, D7...D0
47
 digitalWrite(cs, HIGH);
48
  adcValue = adcValueMSB << 8;
49
  adcValue = adcValue | adcValueLSB;
50
  adcValue1= adcValue | config1;
51

52
     feld1[j] = adcValue1;
53
    Serial.print("analog value = ");
54
    Serial.println(feld1[j]);
55
    Serial.print('\n');
56

57
      j++;
58

59
  delayMicroseconds(0.25);//convertion time
60

61

62
}
Gast #3929902
Lesenswert?

Ok nachdem ich etwas mehr Zeit hatte mir das ganze Anzusehen mal eine 
etwas Detailiertere Antwort...

1: Du übergibst den Wert Channel machst dann aber nichts damit.

2: Du Deklarierst eine Varible
1
 int c=16;
 nur im die Größe des
1
 int feld1[c];
 Arrays zu Definieren. Das ging mit einem
1
#define buffer_gr 16
 schöner.

3: Die Werte in deinem Array feld1 sind nach dem Rücksprung aus der 
Funktion nicht mehr Vorhanden.

4: Versuch einheitlich einzurücken

5: Es besteht ein Unterschied zwischen
1
 SPI.transfer(cs,0x00);
 und
1
 SPI.transfer(0x00);

6: Du setzt deine Index Variable j nie zurück => Das ganze läuft einmal 
dann erst nach dem Überlauf von j. Das Aber noch viel größere Problem 
ist das du mit j auf eine Stelle im Array feld1 zugreifst. Dieses ist 
aber nur 16*Sizeof(int) lang. Ist j > 16 greifst du auf einen 
Speicherbereich zu der nicht im Array liegt. Gratuliere du hast einen 
Bufferoverflow Programmiert ;D

Sind auf die Schnelle die Gröbsten Schnitzer in der Programmierung.

Nun zum Funktionstechnischen...

Lies dich in SPI ein und wie es Funktioniert. Kleiner Tipp es werden 
bidirektional die Daten geschrieben und gelesen. SPI ist eigentlich ein 
Schieberegister...

Es müsste in etwa so aussehen.
1
 CS auf Low
2
adcValue_low_byte = SPI.transfer(config1);
3
adcValue_high_byte = SPI.transfer(0x00);
4
CS auf High
(Firma: HAWK Göttingen) #3931234
Lesenswert?

hallo,

ich habe mich heute nochmal mit dem Projekt beschäftigt, aber dabei kam 
nichts befriedigendes raus. Trotzdem glaube ich, dass das Programm schon 
besser aussieht :) ich hätte aber gern noch Hilfe und ein Paar Fragen.

hier ist mein Code, aber ich bin noch total unsicher.

  #include<SPI.h>
  #define BUFFER_SIZE1    16


 const int cs = 4;
 unsigned int adcValue;
 unsigned int config1;
 unsigned int feld1[BUFFER_SIZE1];


void setup()

{
  pinMode(cs, OUTPUT);
  digitalWrite(cs, HIGH);
  SPI.begin(cs);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(cs,21);
  SPI.setDataMode(cs,SPI_MODE0);
  Serial.begin(9600);

}


void loop()
{
 for(int i=0;i<16;i++)
 {
    feld1[i] =  setAdc();                              // damit will ich 
das ergebnis in einem Array speichern ,, ist dieser Befehl richtig?
    Serial.print("analog value = ");
    Serial.println(feld1[i]);
    Serial.print('\n');
    delayMicroseconds(10);
  }
}


//Analog Digital Funktion
int setAdc()
{
  config1=00100000;
  digitalWrite(cs, LOW);
  byte adcValueLSB = SPI.transfer(cs,config1);         // niederwertiges 
Byte zuerst, D15...D8
  byte adcValueMSB = SPI.transfer(cs,0x00);         // höherwertiges 
Byte zum Schluss, D7...D0
  adcValue = adcValueMSB << 8;
  adcValue = adcValue | adcValueLSB;                //wird sommit das 
umgewandelte Signal an adcValue zugewiesen?
  delayMicroseconds(4);                           //cycle time
  digitalWrite(cs, HIGH);
  return adcValue;

}




 1) wie kann ich das Ergebnis der Umwandlung in ein Array speichern
2) wie kann ich auf das Ergebnis ohne die ersten 4 Bits 
zugreifen(convertion result).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren