unstable signal from Arduino Uno board

Hi
I am using Arduino Uno Rev 3 to input and output signal.
I'm testing it right now.

What I'm doing is to input a 1kHz (bandwidth 1.5 microsecond) signal and hope I can output the same signal from the board.

Here is the code

int led = 13; //output
int laser = 2; //1kHz input signal
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
// initialize the inputs
pinMode(laser, INPUT);
}
void loop(){
if (digitalRead(laser) == HIGH ) {
digitalWrite(led,HIGH);
}else if (digitalRead(laser) == LOW ) {
digitalWrite(led,LOW);
}
}

I thought it is a simple code but the output signal is unstable.
Here is the video.

I connect the output signal to our oscilloscope.
The yellow one is the input 1kHz signal (which is from a laser source and it is stable)
The green one is the output signal from the board.
In the first video, it is unstable and blinking which means the board might not read all the input.

I also zoom in (shown in the second video). The output signal lags behind the input signal by about 10 microsecond and the bandwidth is broaden.

The 1kHz input signal is from a laser source which is a TTL sent through a BNC cable. And I cut that BNC cable to connect it to a solid wire by alligator clip(shown below)

I know it is not a good setup. It is just for a temporary test.
But I am still wondering if there is any other reason for the unstable output.
I guess even though our setting is not good, the output signal should not be that bad.

Below is the picture of our board

I am not not familiar with all these things.
Hope your advises.

Thanks.

1.5KHz is not 1.5uS period.
1/1000 = 1000uS

digitalRead and digitalWrite are kind of slow.
Try direct port manipulation instead:

void loop(){
while (1){ // do forever, without the 12uS or so that restarting loop imposes
if ((PIND & 0b00000100) ==1) { // D2 is high?
  PORTB = PORTB | 0b00100000; //make output D13 high
  }
  else { // pin is low if not high
  PORTB = PORTB & 0b11011111; // make output D13 low
  }
 }
}

You'll still have some lag, this should be less tho.

In your last picture where is your Arduino Ground connected to?

Hi CrossRoads,
Thanks for your code. I will try it.
Our signal is 1kHz and the bandwidth of the pulse is 1.5 microseconds.

Hi LarryD,
Should I connect the ground of the BNC cables together and insert it into the ground terminal block on the board?

If you are connecting the Arduino to an external circuit that provides an input to a digital pin you need a ground return for that signal. The Arduino has a ground pin on the power header.

Hi LarryD,

Could you explain it in more detail way. I am a little bit confused.
Is the ground pin besides the 13 digital pin?

I am not clear where should I connect the ground pin.

What do you mean in "you need a ground return for that signal" ?
In my setting, should I connect the ground pin to the oscilloscope or to the BNC ground(the outer stranded wire) of the output from the board??

Thanks,

See image:

Hi LarryD

Do you mean like this?

I insert a solid wire to the GND(NO. 7) and make the other end (the alligator clips) grounded (put it on a metal desk)

No.
You do not connect the GND pin of the Arduino to the metal surface.
GND (Arduino 0Volts) is not earth ground.

Hi LarryD,
Where should I connect the GND??

Lets start again.
If you have a coax cable with a 0 to +5V digital signal on it (1.5KHZ) connect the center of the cable to Arduino D2 pin.
Connect the shield of the coax to the Arduino GND pin. No other connection is needed.

I think CROSSROADS means:

void setup()
{
  pinMode(13,OUTPUT);
  pinMode(2,INPUT_PULLUP);
}

void loop(){
  while (1)
  { // do forever, without the 12uS or so that restarting loop imposes
//    if (PIND & ( 1 << 3 )) // D2 is high?                 the 3 should be a 2!
   if (PIND & ( 1 << 2 )) // D2 is high?
    {
      PORTB = PORTB | 0b00100000; //make output D13 high
    }
    else
    {
      PORTB = PORTB & 0b11011111; // make output D13 low
    }
  }
}

Sorry change the line as follows
if (PIND & ( 1 << 3 )) // D2 is high?
To
if (PIND & ( 1 << 2 )) // D2 is high?

Hi, to clarify things, your input is?

Pulse 1.5uS wide, (not bandwidth, its pulse width.)
Pulse sent at a rate of 1Khz, or every 1mS.

Is this correct?

Tom. Hope to help.... :slight_smile:

Hi all

Our signal is 1kHz(1 milisecond between each pulse) and the pulse width of each pulse is 1.5 microsecond.

LarryD
I upload the code you gave me and connect the GND as you suggested. The lagging issue was improved.

The yellow one is the input and the green one is the output.

However it still cannot catch all the input signals.
The output signal is still unstable.

The yellow one is the input and the green one is the output.
It seems like it will miss some pulses.

Do you have any other idea??

If your pulse width is 1.5 uS you are going to have trouble catching that.

Is it because of the speed of the board?
Or is there any other solution for catching this short pulse? get another high speed one?

You could feed the o/p of your device to a one shot set for say 100uS.
Feed this to the Arduino then feed the Arduino o/p to a second one shot set for 1.5uS
Then use the output of the second one shot as needed.

Edit. There will be a lag from I/P to O/P

Hi LarryD
What do you mean “o/p of your device?” The output signal from the board?
And in " a one shot set for say 100uS" do you mean to make our input be a 100us pulse width signal and send it to the Arduino board??

It is not necessary to output a 1.5us pulse width signal.

Actually, we want the rising edge of the output signal to trigger a CCD camera.
Thus, the pulse width of the output signal is not a big issue.

We want the rising edge of the output pulses synchronized with the input.
Therefore we do not want to miss any input pulse and rising edge of the output cannot lag behind the input more than 100ns.

Eventually we are going combine other input signals together(the signal we are discussing now is the fastest).

The code is this

int led = 13;  //external trigger from arduino to camera
int laser = 2;  //trigger from laser
int chopper = 4; //trigger from chopper
int camera = 7; //Shutter output from camera
int flag = 0;
// the setup routine runs once when you press reset:
void setup() {                
// initialize the digital pin as an output.
pinMode(led, OUTPUT);    
// initialize the inputs
pinMode(laser, INPUT);
pinMode(chopper, INPUT);
pinMode(camera, INPUT); 
}
// the loop routine runs over and over again forever:
void loop(){
if (digitalRead(laser) == HIGH && digitalRead(chopper) == HIGH && digitalRead(camera) == HIGH) {
flag=1;
  digitalWrite(led,HIGH);
  }else if (digitalRead(laser) == HIGH && digitalRead(camera) == HIGH && flag==1) {

digitalWrite(led,HIGH);
  }else if (digitalRead(laser) == LOW && digitalRead(camera) == HIGH && flag==1) {

digitalWrite(led,LOW);

  }else if (digitalRead(camera) == LOW){ 
  digitalWrite(led,LOW);
flag=0;
  }
}

the output cannot lag behind the input more than 100ns.

You are not going to achieve this with the Arduino.

You could feed the laser output to the One Shot (an integrated circuit SN74121 that is setup to give 100uS pulse).
The OneShot output triggers the CCD and would go to the Arduino input.

c5fang:
Is it because of the speed of the board?
Or is there any other solution for catching this short pulse? get another high speed one?

Since the signal is coming in on pin 2 you can use attachInterrupt and direct
port manipulation:

void setup ()
{
  pinMode (13, OUTPUT) ;
  attachInterrupt (0, handler, CHANGE) ;  // interrupt channel 0 is pin 2
}

void loop ()
{}

void handler ()
{
  if (PIND & 4)        // read pin 2
    PORTB |= 0x20 ;  // set pin 13
  else
    PORTB &= ~0x20 ; // reset pin 13
}

That's how to get high speed handling of external events - the interrupt handler
is only affected by other interrupts (such as timer0 overflow which is used to
implement millis() and delay()).