https://electronics.stackexchange.com/help/on-topic
......
and it is not about ...
Programming software for a PC
...
This question is somewhat... ish off-topic. But I thought that since I know of a C++ solution, then I might as well share it.
#include <iostream>
#include <fstream>
using namespace std;
int main(int argc, char* argv[]){
if(argc!=2){
cout << "Drop a file on me or"<<
"call me from the command line with one argument.\n\n";
//cin.get();//pause, useful for when you drop a file onto the exe.
return 1;
}else{
cout << "You rang?\n\n";
}
string suffix(argv[1]);//convert to string
if(suffix.length()<5){
//bad names are: "t", "xt", "txt", ".txt"
//good names are: "a.txt" or "abc.txt"
cout << "Doesn't look good Sonny," <<
" give me a file on the format of \"*.txt\".\n\n";
//cin.get();//pause, useful for when you drop a file onto the exe.
return 1;
}else{
cout << "The length checks out.\n\n";
}
suffix.erase(0,suffix.length()-3);
if(suffix!="txt"){
cout << "Accepted type is \"txt\", yours is \"" << suffix << "\"\n\n";
//cin.get();//pause, useful for when you drop a file onto the exe.
return 1;
}else{
cout << "Got a file of the correct type. Let's proceed.\n\n";
cout << "===========================================\n\n";
}
ifstream file(argv[1]);//let's finally open the file
string row; //contains row of document, with a ',' as a delimiter
unsigned int samples,
sample_rate,
ground,data,
previous_data,
zero_crossing=0,
end=0,
start=-1;
//First get the number of samples and sample rate.
getline(file,row,'-');//throw away first part
file >> samples; //acquired samples.
cout << "Number of samples = " << samples << endl;
getline(file,row,',');//skip
getline(file,row,',');//skip
file >> sample_rate; //acquired the sample rate
cout << "Sample rate = " << sample_rate << endl;
getline(file,row,',');//skip
getline(file,row,',');//skip
file >> ground;
cout << "Ground level = " << ground << endl << endl;
//Okay, now we just need to read the rest of the document
for(unsigned int i=0;i<samples;++i){
getline(file,row,',');//skip the "Data0" text
previous_data=data;
file >> data;
if(data<ground && previous_data>=ground){
//we've just passed ground and we're going upwards.
if(start==-1){
//is this the first time we've came across this zero crossing?
start=i;
}else{
zero_crossing++;
//this is a potential stop
end=i;
}
}
}
double mean_period = (end-start)/((double)zero_crossing);
double frequency = sample_rate / mean_period;
cout << "First occurance of a negative edge = " << start << endl;
cout << "Last occurance of a negative edge = " << end << endl;
cout << "Length between those two = " << end-start << endl;
cout << "Number of crossings detected = " << zero_crossing << endl;
cout << "Mean length per period = " << mean_period << endl;
cout << "Frequency = " << frequency << endl;
cout << endl << endl;
//cin.get();//pause, useful for when you drop a file onto the exe.
return 0;
}
Compiled with the following command: "g++ -std=c++11 main.cc", assuming you save the above code in a file called "main.cc".
I've tried to comment things that "look weird" or need some comments so it's easier to follow.
The algorithm is essentially: Detect zero crossings with a negative derivative. Record the first time and the last time it occurred and count how many times it occurred.
Subtract the first time from the last time to get the length of N periods. N periods being equal to the number of occurred zero crossings. Now you have the length of a period that has been averaged across all the detected periods.
Calculate the frequency by dividing the sample rate with the length of a period and present this data.
This is how it looks in action, on a Linux machine.
I'm not sure if I'm just bad but I couldn't drop a file onto the "a.out" file, so I couldn't test what I normally could do on Windows. But I left some "pause" commands in the code which you can uncomment in case you want to see the information.