Hallo liebe Raspberry Freunde,
ich habe ein riesen großes Problem.
Ich möchte meinen Raspberry als Datenlogger benutzen. Hierfür habe ich einen AD Wandler verbaut.
Mein erstes Programm diesbezüglich sah folgendermaßen aus.
C
/*
* Datenlogger
*/
#include <stdio.h> //Bsp.: fopen, fprintf
#include <stdlib.h> //Bsp.: exit
#include <pigpio.h> //Bsp.: gpioInitialise, gpioTime
//GPIO's
#define MOSI 10
#define MISO 9
#define CLK 11
#define NOT_CS 8
#define LED_GRUEN 13
#define LED_ROT 6
#define HIGH 1
#define LOW 0
#define DELAY 1 //halbe Periodendauer in Mikrosekunden
#define A 7 //Anfang der einzulesenden Kanäle; muss größer sein als E
#define E 0 //Ende der einzulesenden Kanäle; nur zusammenhängende Kanäle einlesbar
#define T 1000 //Abtastrate in Mikrosekunden
#define ANZAHL_MESSWERTE 100 //Anzahl der Werte, die eingelesen werden sollen
#define VREF 3.3 //Referenzspannung
#define AUFLOESUNG 4096 //Auflösung des AD-Wandlers (12 Bits)
//globale Variablen
FILE *file; //Pointer auf eine Datei
int sneu, usneu; //Zeit bei Eintritt in Funktion
int salt, usalt; //Zeit des letzten Eintritts in funktion
/*
*
*/
void readData()
{
int i,j,k,p,d; //Zählvariablen
int a; //zum Senden von Startbit(Bit4), Mode(Bit5) und Kanal(Bits6-8)
int stellenwert; //einzelne Stellen der Binärzahl (Zweierpotenzen)
int exponent; //Exponent der jeweiligen Stelle
int value[12]; //Array für 12-Bit-Binärzahl
int bit; //einzelne eingelesene Bits
int dezimal; //12Bit-Zahl in dezimal
float spg; //Spannung am AD-Wandler
int s,us; //Zeitdifferenz
for(d=A;d>=E;d--)
{
gpioTime(PI_TIME_RELATIVE, &sneu, &usneu);
//Variablen für erneutes Einlesen mit 0 initialisieren
for(k=0;k<12;k++)
{
value[k]=0;
}
dezimal=0;
spg=0.0;
exponent =0;
stellenwert=0;
switch(d) //Auswahl des Kanals
{
case 7: a=0b00011111; fprintf(file,"Kanal %d: \t",d); break;
case 6: a=0b00011110; fprintf(file,"Kanal %d: \t",d); break;
case 5: a=0b00011101; fprintf(file,"Kanal %d: \t",d); break;
case 4: a=0b00011100; fprintf(file,"Kanal %d: \t",d); break;
case 3: a=0b00011011; fprintf(file,"Kanal %d: \t",d); break;
case 2: a=0b00011010; fprintf(file,"Kanal %d: \t",d); break;
case 1: a=0b00011001; fprintf(file,"Kanal %d: \t",d); break;
case 0: a=0b00011000; fprintf(file,"Kanal %d: \t",d); break;
default: fprintf(file,"\n\nFehler\n\n"); break;
}
//auswählen des Slaves (fallende Flanke)
gpioWrite(NOT_CS,HIGH);
gpioDelay(DELAY);
gpioWrite(NOT_CS,LOW);
gpioDelay(DELAY);
//Senden an AD-Wandler (Startbit, Mode, Kanal)
for(i=0;i<5;i++)
{
//4. Bit von a wird überprüft, ob es 0 oder 1 ist
if(a & 0b00010000) //wenn 1, wird HIGH gesendet
{
gpioWrite(MOSI,HIGH);
}
else //wenn 0, wird LOW gesendet
{
gpioWrite(MOSI,LOW);
}
//zum Übertragen steigende Flanke benötigt
gpioWrite(CLK,LOW);
gpioDelay(DELAY);
gpioWrite(CLK,HIGH);
gpioDelay(DELAY);
a<<=1; //links schieben des Binärwertes
}
//3 Perioden Zeit für AD-Wandler zum Messen
gpioWrite(CLK,LOW);
gpioDelay(DELAY);
gpioWrite(CLK,HIGH);
gpioDelay(DELAY);
gpioWrite(CLK,LOW);
gpioDelay(DELAY);
gpioWrite(CLK,HIGH);
gpioDelay(DELAY);
gpioWrite(CLK,LOW);
gpioDelay(DELAY);
gpioWrite(CLK,HIGH);
gpioDelay(DELAY);
//12 Bits werden eingelesen und in Datei gespeichert
for(j=0;j<12;j++)
{
if(gpioRead(MISO)) //wenn HIGH anliegt, wird 1 in Array gespeichert
//wenn LOW anliegt, wird 0 gespeichert
{
bit=1;
//fprintf(file, "%d", bit);
}
else
{
bit=0;
//fprintf(file, "%d", bit);
}
value[j]=bit;
//zum Übertragen steigende Flanke benötigt
gpioWrite(CLK,LOW);
gpioDelay(DELAY);
gpioWrite(CLK,HIGH);
gpioDelay(DELAY);
}
gpioWrite(NOT_CS, HIGH); //"Ausschalten" des Chip-Select
//Umrechnung von Binärwert in Dezimalzahl
exponent=11;
for(j=0;j<12;j++)
{
stellenwert=1;
for(p=exponent;p>0;p--)
{
stellenwert=stellenwert*2;
}
dezimal=dezimal+(value[j]*stellenwert);
exponent--;
}
//Berechnen der Eingangsspannung
spg = dezimal*VREF/AUFLOESUNG;
s=sneu-salt;
us=usneu-usalt;
while(us<0)
{
us=us+1000000;
s--;
}
salt=sneu;
usalt=usneu;
fprintf(file,"%d \t%.3fV\t Zeit seit dem letzten Aufruf: %d \n" ,dezimal,spg,us);
}
fprintf(file,"\n");
}
int main(int argc, char** argv)
{
int zaehler=0; //wie oft wurde Funktion aufgerufen
int t_s, t_us; //Variablen für aktuelle Zeitabfrage
int tnext_s = 0; //Zeit des nächsten Timerüberlaufs in s
int tnext_us = 0; //Zeit des nächsten Timerüberlaufs in us
int programmstart_s, programmstart_us; //Zeitmessung bei Programmstart
int programmende_s, programmende_us; //Zeitmessung bei Programmende
int s,us; //Programmlaufzeit
//pigpio initialisieren
if (gpioInitialise() < 0)
{
fprintf(stderr, "Initialisierung pigpio fehlgeschlagen!");
exit(EXIT_FAILURE);
}
gpioTime(PI_TIME_RELATIVE, &programmstart_s, &programmstart_us); //PI_TIME_RELATIVE - Zeit, seit die Bibliothek initalisiert wurde;
//PI_TIME_ABSOLUTE - Zeit seit 1.1.1970
//Datei öffnen
file=fopen("/home/test.txt","w");
//Input oder Output
gpioSetMode(MOSI, PI_OUTPUT);
gpioSetMode(MISO, PI_INPUT);
gpioSetMode(CLK, PI_OUTPUT);
gpioSetMode(NOT_CS, PI_OUTPUT);
gpioSetMode(LED_GRUEN, PI_OUTPUT);
gpioSetMode(LED_ROT, PI_OUTPUT);
gpioWrite(LED_GRUEN,HIGH);
while(zaehler < ANZAHL_MESSWERTE) //Überprüfung, wie oft Funktion ausgeführt wurde
{
gpioTime(PI_TIME_RELATIVE, &t_s, &t_us);
if(t_us >= tnext_us) //Funktion wird alle T-Mikrosekunden aufgerufen
{
readData();
zaehler++;
tnext_us = t_us + T;
if(tnext_us >= 1000000) //Abfangen von Überlauf
{
tnext_us -= 1000000;
}
}
}
gpioTime(PI_TIME_RELATIVE, &programmende_s, &programmende_us);
s = programmende_s - programmstart_s;
us = programmende_us - programmstart_us;
while(us<0)
{
us=us+1000000;
s--;
}
fprintf(file, "\n\nProgrammlaufzeit: %d s %d us",s,us );
gpioWrite(LED_GRUEN,LOW);
fclose(file);
gpioTerminate();
return (EXIT_SUCCESS);
}
Alles anzeigen
Wie ihr sehen könnte setzte ich von Hand die steigende und fallende Flanke. Meine Aufgabe besteht darin nun dies nicht mehr von Hand sondern durch Funktionen aus einer Bibliothek ablaufen zu lassen.
Die ganze Kommunikation soll über SPI laufen. Ich bin derzeit total überfragt. =( :s
Zur Verfügung stehen mir die Bibliotheken pigpio.h und wiringPi.h
Verbaut ist ein MPC3204.
Als Anhang gebe ich euch den Verdrahtungsplan so wie das DATASHEET des A/D Wandlers