Go Down

Topic: Is the eye able to see flashes at 30kHz? (Read 798 times) previous topic - next topic

adrian_h

I'm trying to test out a IR receiver and determine what frequency works best.  I tried this code and determined that it was an IR transistor.  But something was making me think... I was seeing the LED flash (I was testing it using a regular red LED) up to 37kHz.  As I understand it, our eyes are not capable of seeing things flash beyond 60Hz or 100Hz due to persistence of vision.  This makes me think that I am doing something wrong in my code.  Here it is:
Code: [Select]
#include<TimerOne.h>

template<class T> inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
static char const endl = '\n';

static int const inputPin = 0;
static int const outputPin = 10;

long inc = 500;
unsigned long freq = 30e3;  // 30kHz
void setup()
{
  analogReference(EXTERNAL);
  pinMode(outputPin, OUTPUT);
  Timer1.initialize(1e9/freq/2); // /2 because each interrupt is to toggle LED, doubling the frequency to call interrupt.
  Timer1.attachInterrupt(callback);
  Serial.begin(9600);
  Serial << "Freq = " << freq << "Hz - Period = " << 1e9/freq << "us" << endl;
}

int ledStatus = 0;
void callback()
{
  digitalWrite(outputPin, ledStatus = !ledStatus);
}

void loop()
{
  //delay(1000);
  if (freq > 56e3)
  {
    inc = -500;
  }
  else if (freq < 30e3)
  {
    inc = +500;
  }
  freq += inc; // increase by 0.5kHz
 
  Timer1.setPeriod(1e9/freq/2);
  analogRead(inputPin); // this extra is because I found elsewhere that the first read may not work properly
  long x = 0;
  for (int i = 0; i < 10000; ++i)
  {
    x += analogRead(inputPin);
  }
  Serial << "Freq = " << freq << "Hz - Period = " << 1e9/freq << "us" << " - " << x/10000 << endl;
}


It uses the TimerOne library I got here: http://playground.arduino.cc/code/timer1

Can someone confirm that I'm doing this right or tell me if a flicker can be seen up to 37kHz?

Thanks,


Adrian
I'm a programmer dammit, not an engineer! :D
Like this post?  Please give me some karma for it.  Thanks! :)

SurferTim

It is your persistence of vision that allows you to see it. I've run the D13 led about as fast as this thing will run it, and I still see the led lit abut half bright. A television runs your eyeballs about as fast as they can work. Remember, an analog tv is just one little tiny spot moving across the screen in a hurry.

majenko

Nothing to do with your LED flashing, but:
Code: [Select]

  analogRead(inputPin); // this extra is because I found elsewhere that the first read may not work properly

That is only true when you are taking readings from multiple analog inputs - the first reading from the second channel may still have some small left over charge in the sample and hold capacitor from the first channel.  If you're only using one analog channel then there is no other channel to interfere with it.

As for the LED, if you are seeing the LED as just on all the time (not flickering) then it is toggling too fast for you to see - but you still see it because some of the time it's on.  That's how PWM works.  The greater the percentage of time it's on, the brighter it looks.

If you're actually seeing it flashing on and off, then yes, you must be doing something wrong.  Try changing your 1e9 to 1e9UL.
Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

el_supremo

You should also change 56e3 to 56e3UL.

Pete

MarkT



If you're actually seeing it flashing on and off, then yes, you must be doing something wrong.  Try changing your 1e9 to 1e9UL.


No, don't do that.  Its not wise to suggest (broken) advice that's wrong which you could easily have tested first:
Quote
sketch_mar18a.ino:6:22: error: invalid suffix "UL" on floating constant
sketch_mar18a.ino:15:11: error: invalid suffix "UL" on floating constant


There is no problem at all use 1e9 (a floating point constant) and casting it implicitly to long.

The flickering is probably due to timer1 interrupts and timer0 interrupts colliding every so often.
[ I won't respond to messages, use the forum please ]

majenko

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

adrian_h


It is your persistence of vision that allows you to see it. I've run the D13 led about as fast as this thing will run it, and I still see the led lit abut half bright. A television runs your eyeballs about as fast as they can work. Remember, an analog tv is just one little tiny spot moving across the screen in a hurry.

Of course it'll be half as bright, you are basically doing PWM, having it on only half the time.  I'm referring to the flicker.


Nothing to do with your LED flashing, but:
Code: [Select]

  analogRead(inputPin); // this extra is because I found elsewhere that the first read may not work properly

That is only true when you are taking readings from multiple analog inputs - the first reading from the second channel may still have some small left over charge in the sample and hold capacitor from the first channel.  If you're only using one analog channel then there is no other channel to interfere with it.

Dunno, I was having some problem with another test that only used one analog input.  I wasn't sure why it did it, but it did.  100us isn't going to hurt me that much anyway in this case.


As for the LED, if you are seeing the LED as just on all the time (not flickering) then it is toggling too fast for you to see - but you still see it because some of the time it's on.  That's how PWM works.  The greater the percentage of time it's on, the brighter it looks.

If you're actually seeing it flashing on and off, then yes, you must be doing something wrong.  Try changing your 1e9 to 1e9UL.

Thanks, I know that about PWM, but I was seeing the LED flicker at 30-37kHz.  I was thinking that I shouldn't see it flicker at such a high rate and that it should be solid, but just half as bright as an always on LED.

Also, I did try replacing all of the constant doubles with constant longs with the same result.

Any other ideas?


Adrian
I'm a programmer dammit, not an engineer! :D
Like this post?  Please give me some karma for it.  Thanks! :)

Veco

The simple answer is: No.

Think about mains power, which dependent on where you live runs at 50/60Hz. If you've seen LED bulbs run on mains, AC Christmas lights for example, because the cheaper types only run 50% of the time, you can notice the flicker, but only just. However the effect becomes far more noticeable when either the bulb or you are moving. This is due to persistence of image.

At 37kHz you wouldn't see anything but a dimmed light.

It's far more likely that the flicker you're seeing is due to other factors, such as code or hardware not being up to the task of switching it that fast.

Nick Gammon


As I understand it, our eyes are not capable of seeing things flash beyond 60Hz or 100Hz due to persistence of vision. 


Do you mean, despite persistence of vision?

I have a gadget running right now that flashes an LED (once) at 2/1000 of a second, in other words 500 Hz. It is clearly visible. You can see camera flashes that are probably 1/1000 of a second, right?
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Nick Gammon

But if you mean, continual flashes at 30 KHz, not you won't see that (the flashing). After all, movies are made at around 30 Hz.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

PaulS

Quote
There is no problem at all use 1e9 (a floating point constant) and casting it implicitly to long.

Of course, expressing it as 1.0e9 makes it clear that it IS a floating point value, not a mistake.

MarkT



It's far more likely that the flicker you're seeing is due to other factors, such as code or hardware not being up to the task of switching it that fast.


As I said its probably some sort of strobing with timer0 interrupts.

Adding this line to setup() will disable timer0 interrupts - if this makes the flicker go away
then it proves it.   Note that doing this will stop delay(), millis() and micros() from working
as they depend on timer0 interrupts.

Code: [Select]
  TIMSK0 = 0x00 ;


In normal use there is a timer0 interrupt every 1.024ms and if it coincides with timer1 interrupt
it will delay the timer1 interrupt and throw the timing out leading to unequal duty cycles
occasionally.
[ I won't respond to messages, use the forum please ]

michinyon

You need to consider that the infrared detector responds to infrared light  and you need to consider
the frequency of the light being emitted by the transmitter and being detected by the receiver.

In this context,  the 30 kHz ( ballpark ) flashing of the device message pulses is not relevant.  The
frequency of the actual light waves doing the transmission is much higher,   many gigahertz,
whatever the speed of light divided by the wavelength around 1000 nm is.

adrian_h




It's far more likely that the flicker you're seeing is due to other factors, such as code or hardware not being up to the task of switching it that fast.


As I said its probably some sort of strobing with timer0 interrupts.

Adding this line to setup() will disable timer0 interrupts - if this makes the flicker go away
then it proves it.   Note that doing this will stop delay(), millis() and micros() from working
as they depend on timer0 interrupts.

Code: [Select]
  TIMSK0 = 0x00 ;


In normal use there is a timer0 interrupt every 1.024ms and if it coincides with timer1 interrupt
it will delay the timer1 interrupt and throw the timing out leading to unequal duty cycles
occasionally.


Tried this, doesn't help.  The flicker is not sporadic but continuous between 30-37kHz.


But if you mean, continual flashes at 30 KHz, not you won't see that (the flashing). After all, movies are made at around 30 Hz.


That's what I thought.  In fact this should be alternating on and off at 60-74kHz.  Doesn't feel right. (BTW, k is lower case for SI units)



As I understand it, our eyes are not capable of seeing things flash beyond 60Hz or 100Hz due to persistence of vision.


Do you mean, despite persistence of vision?

I have a gadget running right now that flashes an LED (once) at 2/1000 of a second, in other words 500 Hz. It is clearly visible. You can see camera flashes that are probably 1/1000 of a second, right?

Sorry, meant flicker not flash.

So is my code wrong?  Wish I had an oscilloscope. :(
I'm a programmer dammit, not an engineer! :D
Like this post?  Please give me some karma for it.  Thanks! :)

Nick Gammon


Doesn't feel right. (BTW, k is lower case for SI units)


Looks like you are right. I've been in the habit of capitalizing it after seeing people write mHz when they mean MHz.

So my (incorrect) rule of thumb is: capitalize things that are multipliers greater than one.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

Go Up