Low sampling rate using Arduino Uno

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
I am working on Non-Intrusive Load Monitoring. I am measuring Voltages and Current Non-Intrusively. Voltage and Current Signals are the fed to Arduino Uno ADC. After converting them to digital form, the signals are sent to PC serial port. I receive the signal from serial port and apply feature extraction algorithms on voltage and current signals. Problem I am facing is I am achieving low sampling rate using Arduino Uno. I need minimum of 8K samples for some algorithms and I am receiving only 1K now. I have trouble figuring out that if the problem is with Arduino ADC sampling rate or Serial port latency is the issue. Kindly help me figure out the problem.
Thanks
 

LesJones

Joined Jan 8, 2017
3,303
What baud rate are you using and how many characters make up the serial data sent to the PC ? What amount of time are the 8K samples spread over ? (Or in other words what is the sample rate ?)

Les.
 

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
What baud rate are you using and how many characters make up the serial data sent to the PC ? What amount of time are the 8K samples spread over ? (Or in other words what is the sample rate ?)

Les.
Baud rate selected is 250000. I am sending a string. Attached file contains the code which is just reading from adc and writing on serial port. I need 8K samples per second.
 

Attachments

smooth_jamie

Joined Jan 4, 2017
107
I believe the maximum supported baud rate on the Arduino is115200bps

On an unrelated note, how are you monitoring voltage non-intrusively? (you can't monitor voltage using a current transformer?)

EDIT:
Whoops had to edit my answer after I saw your code
 

LesJones

Joined Jan 8, 2017
3,303
There is no point in me looking at your code. I am useless at "C" programming. I find assembler much easier. As your baud rate is 250000 you can send up to about 25000 characters per second. (Assuming there are no checksums or handshaking.) So that would only allow you to transmit 3 characters per reading. I realise now I did not word my question well I meant to say how many characters are sent for each reading. I have only looked at the data transfer side I have not looked at the data sheet for the ATMEG928P to see how fast the A to D converter can work.
Edit I should have said ATMEGA328P
Les.
 
Last edited:

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
I believe the maximum supported baud rate on the Arduino is115200bps

On an unrelated note, how are you monitoring voltage non-intrusively? (you can't monitor voltage using a current transformer?)

EDIT:
Whoops had to edit my answer after I saw your code
Using capacitive pickups to measure voltage. My problem is low sampling rate.
 

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
There is no point in me looking at your code. I am useless at "C" programming. I find assembler much easier. As your baud rate is 250000 you can send up to about 25000 characters per second. (Assuming there are no checksums or handshaking.) So that would only allow you to transmit 3 characters per reading. I realise now I did not word my question well I meant to say how many characters are sent for each reading. I have only looked at the data transfer side I have not looked at the data sheet for the ATMEG928P to see how fast the A to D converter can work.

Les.
Sampling time is 250 us.
 

Andrei Suditu

Joined Jul 27, 2016
51
Set the arduino to trigger adc in free_running mode and setup interrupt routine for buffer chaching those results then send them over the serial.Also the datasheet specifies the sampling rates regarding different precisions(8 bit faster 10 bit slower).The ADC needs about 13.5 ADC clock cycles to complete.The max spped recommended for 10 bit res is 1mhz clock.(not talking about you clock here).
So you get around 74khz sampling rates but you will have to set up buffers for reading them over serial.
I recommend reading the Atmegas 328p datasheet.
 

LesJones

Joined Jan 8, 2017
3,303
If one sample takes 250 uS then yoy will need at least two samples (One voltage and one current) per reading. That limits you to 2K samples per second.

Les.
 
Last edited:

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
Set the arduino to trigger adc in free_running mode and setup interrupt routine for buffer chaching those results then send them over the serial.Also the datasheet specifies the sampling rates regarding different precisions(8 bit faster 10 bit slower).The ADC needs about 13.5 ADC clock cycles to complete.The max spped recommended for 10 bit res is 1mhz clock.(not talking about you clock here).
So you get around 74khz sampling rates but you will have to set up buffers for reading them over serial.
I recommend reading the Atmegas 328p datasheet.
Can you tell me how to set up buffers.
 

AlbertHall

Joined Jun 4, 2014
11,402
At a baud rate of 250000, you can send 25000 characters per second. You are scaling the ADC values to a double which is a lot of characters and a decimal point. You can't get 8k samples per second if you do that. Even if you send the two byte integer values with no other characters, with two ADC readings per sample, and 8k samples that is 8000*2*2 = 32000 characters per second. Still can't do it.
You could pack 2 ten bit ADC readings into 3 bytes which would need 24000 characters per second. You might just be able to do that if both the arduino and the PC never make the serial link wait.
 

philba

Joined Aug 17, 2017
960
Converting to double takes a LOT of code. Just send the raw data to the pc and do the conversion to floating point there.

Test the ADC speed by timing a loop that reads 1K samples. hint: micros(). That will tell you if you have an acquisition problem.
 
Last edited:

Thread Starter

musabfarooq

Joined Mar 22, 2017
38
Converting to double takes a LOT of code. Just send the raw data to the pc and do the conversion to floating point there.

Test the ADC speed by timing a loop that reads 1K samples. hint: micros(). That will tell you if you have an acquisition problem.
Sending raw data means Serial.print(analogRead(A0));
 

philba

Joined Aug 17, 2017
960
Sending raw data means Serial.print(analogRead(A0));
yes, but it will take more than that. read AlbertHall's post.

note that print(int) does a conversion to ASCII which may send up to 5 characters (space + 4 numerics). Pack on the Arduino, send, unpack in a program (that you write) on the PC. There may be programs around that do this for you but you'll need to research that.
 

Andrei Suditu

Joined Jul 27, 2016
51
Also try eliminating Serial.println() if it is still to slow to transmit.However you will have to identifiy the high bytes and low bytes received.Also if it still does't work as intended you could use 8 bit resolution by sending only the high bytes.Modifiy this in adc_send and set ADLAR to 1 to left adjust the result eliminating the low bites.
Again datashhet page ~320
 

Attachments

Top