Could anyone show me how to using millis function to find the sampling rate of my analog signal? Currently I'm recording PPG signal from analog circuit by arduino and using Python to store it in a txt file, but i'm confusing with the sampling rate of the signal.
your sampling rate (in Hz) is how many samples you recorded in 1 second
- record the value of millis() or micros() before you start sampling
- record the value of millis() or micros() after the last sample
The difference ∆t is how long (in ms or µs) it tool to record your N samples
samples | duration |
---|---|
N | ∆t (converted to s) |
F (Hz) | 1s |
getting the value of F in Hz is just a simple math then (F = N/ ∆t)
-
Create an unsigned long variable called startTime and give it a value of 0
-
At the start of the loop function print out the value of startTime - millis(0) - the first time you do this it will be zero.
-
Transfer the contents of the millis counter to your startTime variable.
-
Do a sample and store it.
-
the time it took will be displayed at the start of the next iteration of the loop function.
-
You can do other maths on this figure to get the sample rate or frequency of conversion.
Some things for you to consider.
- What Arduino are you using? Sample rate, and sample bit count, vary.
- Conversion to float values costs you time. Consider if you can store the raw conversion counts, scaling the data later
- If you're sampling at a high rate, you need to transfer the data somewhere, or you'll quickly fill the Arduino's limited memory, which leads to the following considerations
- do you need to keep every sample, or will an average of n, or a rolling average value, suffice
- where is the data going - SD card, serial output, Wifi, ???
- SD is nice, but incurs some overheads, and you need to consider whether you're storing continuously, or in 'packages' that align to some file format, size, etc.
- Serial/Ethernet/Wifi all let you remote the storage, but all have bandwidth limitations, and complexity issues for the newbie
Your initial post hints at answers to some of this, but it's not clear if your current experimenting, etc. is part of your target application, or just a means of figuring out what the Arduino will do. Certainly, if your running an Uno and transmitting it by Serial to a PC with a python app storing the data to disk(how I interpret what you said), you need to know certain details about Serial. Please confirm what it is you're doing in more detail, and we can elaborate.
Actually, I'm using an Arduino UNO to convert the analog signal to digital, then I used Python (which uses PyQt and Pyserial) to create a GUI to store the data on .txt file on the computer. My PPG signal has the bandwidth from 0.3-5Hz and I don't know how to set the accurate sampling rate. My teacher told me to use the millis function instead of delay to figure out the sampling rate of the ADC and i was really confused to that. (According to some documents, I can set the sampling frequency equal to 2-2.5 times the bandwidth of my signal). Sorry if there is any confusion because i'm a newbie :')
Yes you can, but that is not the bandwidth but the sample time. However, that doesn't help you because it only applies a multiplier on something you don't know.
If you do what I said in post #3 the sample rate and the storage are automatically taken into consideration and you will get the true sample rate.
Do you actually know what the bandwidth means? Look it up on line it is not what you think it is.
Do what he says, he sounds like he knows what he is taking about.
yes i understand what you said, and i'm trying to do it. Thanks very much, i will test it then. <3
Actually, I'm using an Arduino UNO to convert the analog signal to digital, then I used Python (which uses PyQt and Pyserial) to create a GUI to store the data on .txt file on the computer.
Okay, so you're using Serial to transfer the data. Thanks for confirming that. More on that in a minute. PLEASE share your code as it currently exists.
My PPG signal has the bandwidth from 0.3-5Hz and I don't know how to set the accurate sampling rate.
Right. so per Nyquist, you need to sample at >2 times that, for discerning the primary rate. but is that all you want, the pulse rate? Or are you interested in information content of the waveform? Because that will require many more samples per beat.
You do seem confused about time vs frequency, but there may be a translation issue here - please elaborate about what you're really seeking.
Your Arduino Uno is capable of much more than 10 KILO Hertz sampling, given the right conditions. But you need to determine what sample rate you really require.
Regarding Serial, remember - you may be able to acquire data at a given rate, but Serial can be slow, so you need to know how to fix that. Tell us more.
unsigned long startTime = 0;
unsigned long time = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
time = startTime - millis();
Serial.print(time);
int sensorValue = analogRead(A2);
startTime = millis();
Serial.print(time);
}
this is my arduino code to find the time interval of recording signal
def start_logging(self):
self.arduino = serial.Serial(self.serial_port, self.baud_rate)
self.start_button.setEnabled(False)
self.stop_button.setEnabled(True)
self.timer.start(20) # Adjust the interval (milliseconds) as needed for faster recording
and this is a part of my Python code
Actually, I want to detect the information of the waveform to extract its feature for some applications as SpO2, Blood pressure, etc.
sorry for some translation issue.
this is slow and might become a throttling factor, try 1000000 or 2000000 bauds
Not the way I showed, because the serial print is not part of the timing, so it can be any speed you like.
When it comes to using it in the project you will not need to print out every sample anyway.
Please show your code. I'm confused about "set the accurate sample rate" versus "find out the sample rate". If you show how you are tried to use delay(), maybe it would make more sense.
For "set the accurate sample rate" using millis(), use the Blink Without Delay example.
I meant a throttling factor for the loop() to actually loop (print will become blocking at some point thus limiting the number of analogRead() which could be done.)
Agreed.
millis() will always be bigger than startTime so time will stay "0".
What does your Serial.print show?
no it will become a very large number (unsigned long maths)
I'd assumed this was some work left for the OP to solve
Thanks , I missed the roll over.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.