Serial communication, Uno and Python. Issues with no of samples and sampling

So I'm sampling a signal on the Arduino Uno and then I send it through the virtual serial port to Python. I can sample the signal successfully at some settings but that will not do for my project!

I'm using the digitalReadFast to achieve a higher sampling rate. You can read more about how it works and where to get it here:

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1267553811/all

Anyhow this is the arduino code.

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */

 int outPin = A0;
 int u = A1;
 const int no_Sample = 870; //870 seems to be optimal
 int value[no_Sample];
 int i = 0;
 int k = 0;

 
#include <digitalWriteFast.h>

void setup() {                
  pinModeFast2(outPin, OUTPUT);     
  //pinModeFast2(inPin, INPUT);
  Serial.begin(9600);
}

void loop() {
   
       for (i=0;i<no_Sample;i++) 
       {
         value[i]=digitalReadFast(A1);  
       }
  
       for (i=0;i<no_Sample;i++)
       {
         Serial.print(value[i]);
       }
 
    delay(125);
    

}

And this is the python code.

import matplotlib
import serial
import time

from pylab import *
from numpy import *
matplotlib.interactive(True)


#create a serial obj with a baud rate of 9600 #
ser = serial.Serial('/dev/tty.usbmodemfd131',9600)

collected_val = []
i = 0
no_Sample = 870

time.sleep(1)

k = 0
j = 0

while( i < no_Sample) :
	collected_val.append(ser.read()) #reads one byte#
	i = i + 1
		
	
print(collected_val)

plot(collected_val)
show()
grid(True)

ser.close()
raw_input("Press return to close this window...")

So what I'm doing is basicly collecting 870 samples from a signal generated by my signal generator. I'm able to get pretty decent plots for frequencies way over my intended one which is approx 2 kHz. However, I need to sample very fast to be able to detect small variations in the duty cycle.

Here is a plot where i sample a 2 kHz square wave(duty cycle 50%ish)

Looks quite good does not it? :slight_smile:

So for so good, right? Lets say I want a smaller amount of samples. Say 500. This is what I get then..

Not expected, same signal is generated. Don't bother the signal being plotted to 870, forgot to change that!

So what can I do to solve this? I should also add that 870 samples is quite close to the maximum values that I'm able to store before the Uno goes bananas. I should also add that I've tried different duty cycles etc with no of samples set to 870 and all have looked good.

So I suppose I'm not sampling very smart although it works for some specific cases. About the number of samples affecting the signals, what might cause this?

Oh I'm using the Uno rev 3.

Thanks in advance

/Elskurkos

I voted no. Hope that helps.

(Right next to Start New Poll was Start New Thread.)

         Serial.print(value[i]);

Sends the value as a string.

	collected_val.append(ser.read()) #reads one byte#

Is that byte as in character?

Since the Arduino's digital pins return 0 or 1, using a 16 bit variable to hold one bit seems overkill. value could (and should) be an array of type byte.

Converting the byte to a string to send is also wasteful. Use Serial.write() to send the value in binary. Must faster.

Okey than I know how to start a topic :slight_smile:

Yes, afaik.

What you say make sense :slight_smile: Did read the values as analog before, have not changed it.

Thanks.

Any ideas what might cause the the odd sampling?

However, I need to sample very fast to be able to detect small variations in the duty cycle.

You don't have to sample, there is a better approach to measure duty cycle precisely.

  1. Using Input Capture TIMER1 feature;
  2. Interrupt driven subroutine, and measure period/duty by any TIMER0/1/2.
    Unfortunately, AFAIK, arduino doesn't have function for first option, so you have to write control register directly, or go with pulseIn
    http://arduino.cc/en/Reference/PulseIn

Thanks for your reply!

I will check that out.