Hello everyone.
I am new to the Arduino, so please bear with me. The circuit I am using consists of an opamp with a specific frequency. Before, I used a handheld oscilloscope, which gave me the desired signal with the desired frequency (166.3kHz), as shown in the figure below.
Now, I want to replace the handheld oscilloscope with Arduino for obtaining the incoming signal frequency information. Initially, I wrote the below sketch to obtain the raw data through processing for 1 second (runcount =1000=1second).
unsigned long runcount = 0;
void setup()
{
Serial.begin(115200);
}
void loop() {
if (runcount < 1000) {
float val = analogRead(A0);
float Voltage = val * (5.0 / 1023.0);
Serial.println(Voltage);
runcount++;
}
}
After obtaining the raw data below, I draw the waveform in Excel, as shown below.
Now, the question is, does the waveform match the handheld oscilloscope, and most importantly, are the completed waveforms 25 in one sec, which means the obtained signal has a 25Hz frequency?
Could anyone please guide me if the data-obtaining process or the written sketch is incorrect?
You need to know the sample time taken by the analogRead and Serial.print loop, in order to calculate a frequency, and unfortunately that is variable, because Serial.print outputs a variable number of characters.
So, don't print in the loop. Collect 100 readings in an array, using millis() or micros() to time that action and then print the data.
It may not be available to you until you have spent a certain number of hours on the forum, reading posts, making posts etc. This is an anti-spammer measure.
160kHz is too fast for the "regular Arduino". (An Uno or Mega, etc.)
I see 1000 counts but I don't see 1 second.
You have to know the sample rate or the data is meaningless. There are ways to control it using internal registers/timers but I don't know the details.
The Audacity Website has a nice-easy introduction to sampling. (They are focused on audio, but the principals are the same.)
You need at-least two samples per cycle (one for the positive have of the wave and one for the negative half). An oscilloscope typically samples at 10X the signal frequency (or faster). The 'scope on my bench at work samples at 1.25GHz and it's rated for 100MHz.
If the sample rate is too slow you get aliasing (false frequencies).
analogRead() in a loop is "slow", and it takes time to make a calculation or print so that lowers your sample rate even more. You should do your calculations & printing after you collect the data.
The title of your thread mentions a signal coming through the serial port, but nothing you have written mentions anything about the serial port. So why the title?
Hint: if the data is not consistent the frequency will also not be constant. For the serial port it would be called baud not frequency. The serial data stream has ones and zeros a specified format, you need to know what format is being used. The scope is by far the best tool.
Sorry for my mistake. As per my understanding, a sequence of data will be coming through the serial port. The signal is fed to the A0 pin of the Arduino Uno.
I am trying to collect data from the serial port every microsecond, but I have not been successful yet. Can anyone help me with how to collect data from the serial port at a microsecond interval?
I'm very confused. What is this signal, and what are you trying to do with it?
What does the serial port have to do with this?
In this I'm assuming you're using an Uno or Nano, with ATmega328p MCU on board.
Your signal is 166 kHz, while the sampling frequency of the ADC is under 10 kHz. That's not going to work well. The values you get are an aliased signal. To use an ADC on a signal, the sample frequency should be at least double the signal frequency, i.e. 332 kHz in your situation.
If you need to measure the frequency, there are much more accurate methods of measuring this using the timers: you can use timer1 connected to the T1 pin (Arduino pin 5) as clock source, let it run for a specific period, and see how many pulses you got. You should get about 166,000 pulses per second, the timer overflows at 65535, so measure for say 300 ms, and see how many ticks the timer got.
Most accurate timing you get by using a timer interrupt, using e.g. timer0 or timer2. A simple millis() based timer would be good enough for a quick proof of concept.
Hello @wvmarle , the signal is coming from my sensor circuit, whose frequency is sensitive to a monitoring parameter. As changes occur in the monitoring parameter, the sensor circuit frequency also varies. I practically monitored frequency variation by changing my sensitive parameter on a handheld oscilloscope. Now, I need to replace the handheld oscilloscope with an Arduino. The signal is fed in A0, Now I am trying to monitor the serial port data.
It still not clear what serial port has to do with it? You receive your signal into A0 analog input, not to serial port.
Or do you consider any port, that able to receive data sequentially - as "serial"?
Hello @b707 . I am feeding the signal to the Arduino on port A0. I wrote a simple code as given above, and then I am receiving the voltage values on the serial monitor, which I believe is the serial port (If I am wrong, please forgive me because I have never used Arduino before and am learning now).
My target is to replace the handheld oscilloscope with Arduino (as elaborated above) and monitor frequency variations.
If what you're after is frequency variations on this signal, then indeed analog sampling is the wrong way to go. You're limited to <5 kHz this way.
As said, the Arduino can measure the frequency (using a digital pin - high/low signal) and print the value on the Serial monitor. You can measure frequencies up to fCLK/2 = 8 MHz. You just have to make sure the amplitude is high enough and within bounds, with the low points of the signal at 0-1.5V and the high points at 3-5V.
You seem to want to measure a signal with a base frequency around 166kHz, which is deviating. Analog readings won't suffice, as you've been told, because analog conversions on an Arduino Uno(you actually haven't said which Arduino you're using) max out around the 5-10 kHz range, and at that speed you can't do anything else anyway.
As for the Serial Port, you seem to be suggesting you'll send your frequency reading to your PC using Serial, where you'll be able to see the converted output (a number) on the Serial Monitor.
Is that correct?
It is time to stop all the words and provide a block diagram showing all the connections and pin numbers. Write on the connecting lines what the signal is.
OK: You are NOT reading data from a serial port, you are reading it from an analog input.
The 'scope shows a signal with a period of ABOUT 6uS = 160KHz
EXACTLY what do you need to know about this signal?
Its frequency?
Its amplitude?
The wave shape?
Hello @jremington . Yes, you are right I am reading analogy pin A0 (which is connected to my sensor) and displaying it on serial monitor. (I am using Arduino Uno)
If you are using the Arduino Uno R3 or related (classical Nano, etc.) limit the experiment to signals with frequency less than 5 kHz, as the default sample rate is 9.6 kHz.
With something like the Teensy 4.1, it is possible to record 166 kHz signals, but it will take some technical skills to set up the ADC correctly.