Square Wave Signal noise 20HZ - 200 HZ

I am making a pulse generator for a camera speed control. The signal is in frames per second and is from 20 frames per second to 200 Frames per second.

The pulse is a 1 degree (1/360th) of the Frequency period.

I am using an Arduino Nano 3.0 from Gravitech.

I have no bypass capacitors on my 9V battery or on the board.

here is a picture of two channels (A and B from two separate digital IO pins). They are 3 degrees offset from each other. My Rigol DS1052E shows lots of noise and not quite a square wave here. I'm wondering if the input leads or some other factor is causing the signal noise.

Here is a picture of my output on the scope for a 30 HZ signal ...

Any help in getting these to be very square would be great.

IMG_0567.jpg

Hmmm. looks unusual, brent...

what is the load on this?? Those periods of slope are funny..

what's your code?? Are you doing anything else with the pins like Pinmode inside your loop??

What does the trace from the calibration output on the scope look like?

Can we see the code?

One possible explanation for the shapes is that you are changing the pin mode from input to output. Are you using direct port manipulation and have got the code wrong or have you not set those pins to be an output in the setup function?

Here is the relevant code:

pinModeFast(sync1, OUTPUT);
pinModeFast(sync2, OUTPUT);
pinModeFast(onled, OUTPUT);
pinModeFast(outled, OUTPUT);

while (digitalReadFast(buttonmode) == 0){ // as long as the mode button is off.

// put out our pulse
digitalWriteFast(outled, HIGH);
digitalWriteFast(onled, LOW); // invert the ON LED
digitalWriteFast(sync1, HIGH);
if (offset == 0)
digitalWrite(sync2, HIGH);
delayMicroseconds(p1);

// now turn off and wait.
digitalWrite(outled, LOW);
digitalWrite(onled, HIGH); // invert the ON LED
digitalWrite(sync1, LOW);
if (offset == 0)
digitalWriteFast(sync2, LOW);
delayMicroseconds(d1); // do the remainder
for ( int x = 0; x < nd1; x++){ // loop over 16000 n times.
delayMicroseconds(16000 - loopcomp); // subtract a fixed compensation from the delay for loop overhead
}
if (offset != 0){
// put out our 2nd pulse
digitalWriteFast(sync2, HIGH);
delayMicroseconds(p1);

// now turn off and wait
digitalWriteFast(sync2, LOW);
delayMicroseconds(d2); // do the remainder
for ( int x = 0; x < nd2; x++){ // loop over 16000 n times.
delayMicroseconds(16000 - loopcomp); // subtract a fixed compensation from the delay for loop overhead
}
}

} // end while button not on.

The connection from my project box to the scope is a simple shielded coax cable (about 8 feet long). There are two outputs... one on Sync1 and one on Sync2.

I changed to use the regular digitalWrite and here is channel B alone (the same picture as before is what I get).

It just seems like the coax is acting like a big capacitor.

I guess I'll have to test the signal with a probe lead directly.

IMG_0002.jpg

Please post code using the # icon.
Also posting part of the code is not much, experience shows that it is the bit you know is right where the fault lies. If the code is too long try and simplify it so that it just shows the fault, often that helps you spot what is wrong.
Again to me that trace looks like a high output being switched to an input. If it were capacitance it would show on the rise time as well.

#include <string.h>
#include <SoftwareSerial.h>
#include <avr/pgmspace.h>
#include <EEPROM.h>


const int buttonmode = 6;      // the mode button is attached to
const int buttonbacklight = 3; // backlight button
const int buttondown = 5;        // the up button
const int buttonup = 4;      // the down button
const int buttonenter = 2;     // the enter button
const int outled = 10;
const int sync1 = 8;
const int sync2 = 9;
const int onled = 7;


const int LCDtxpin = 12;
const int LCDrxpin = 11;

const int pulsedegree = 1;

int debounce = 10; // debounce millisec delay

int repeatmillis = 80;

SoftwareSerial LCDSerial = SoftwareSerial(LCDrxpin, LCDtxpin);

unsigned int num16;  // make this working var visible to other routines.
// 
byte framerate = 30;
byte loopcomp = 0;  // loop compensation microseconds
byte staticcomp = 0;  // static overhead compensation
byte backlight = 0;  // state of the backlight button.
unsigned int offset = 0; // degrees offset

unsigned long p1;  // pulse width
unsigned long d1;  // delay width
unsigned int nd1;  // number of 16000
unsigned long d2;  // remainder of delay2
unsigned int nd2;  // number or 16000
unsigned long totalmicros;  // total microseconds for this freq.

void setup()
{
  pinMode(buttonmode, INPUT);
  pinMode(buttonbacklight, INPUT);
  pinMode(buttonup, INPUT);
  pinMode(buttondown, INPUT);
  pinMode(buttonenter, INPUT);
  pinMode(sync1, OUTPUT);
  pinMode(sync2, OUTPUT);
  pinMode(onled, OUTPUT);
  pinMode(outled, OUTPUT);
  pinMode(LCDrxpin, INPUT);
  pinMode(LCDtxpin, OUTPUT);

  getvalues();
  LCDSetup();
  calcvalues();
}

void loop(){
  if (digitalRead(buttonmode) == 1){
        setparams();
  } else {
    calcvalues();
    runit();
  }
}




void runit()
{
  // delayMicroseconds can only handle just over 16,000 counts, so 
  // break this up into n x 16000 + a remainder. and delay with those parameters.
  //Serial.println("in");

  clearLCD();
  selectLineOne();
  LCDSerial.print("FPS: ");
  LCDSerial.print(framerate,DEC);
  selectLineTwo();
  LCDSerial.print("PHASE DEG: ");
  LCDSerial.print(offset,DEC);

  while (digitalRead(buttonmode) == 0){ // as long as the mode button is off.
  
      // put out our pulse
      digitalWrite(outled, HIGH);
      digitalWrite(onled, LOW);  // invert the ON LED
      digitalWrite(sync1, HIGH);
      if (offset == 0)
        digitalWrite(sync2, HIGH);
      else
        digitalWrite(sync2, LOW);
      delayMicroseconds(p1);
      
      // now turn off and wait.
      digitalWrite(outled, LOW);
      digitalWrite(onled, HIGH);  // invert the ON LED
      digitalWrite(sync1, LOW);
      if (offset == 0)
        digitalWrite(sync2, LOW);
      delayMicroseconds(d1);  // do the remainder
      for ( int x = 0; x < nd1; x++){  // loop over 16000 n times.
        delayMicroseconds(16000 - loopcomp);  // subtract a fixed compensation from the delay for loop overhead
      }
      if (offset != 0){
        // put out our 2nd pulse
        digitalWrite(sync2, HIGH);
        delayMicroseconds(p1);
        
        // now turn off and wait
        digitalWrite(sync2, LOW);
        delayMicroseconds(d2);  // do the remainder
        for ( int x = 0; x < nd2; x++){  // loop over 16000 n times.
          delayMicroseconds(16000 - loopcomp);  // subtract a fixed compensation from the delay for loop overhead
        }
     }
    
  }  // end while button not on.
 
}


// ------------  button functions

boolean buttonIn(int button){
  
  int isdown = digitalRead(button);
  if (isdown == 0){
    repeatmillis = 100;
    return false;
  }
  
  delay(debounce);
  isdown = digitalRead(button);
  if (isdown == 0){
    repeatmillis = 100;
    return false;
  }
    
  long starttime = millis();
  
  // 100 milliseconds max, and repeat 
  while (millis() - starttime < repeatmillis && digitalRead(button) == 1){
    // hangout
  }
  repeatmillis = 5;  // repeat-amatic rate
  return true;

}

// ----------- below here is all lcd stuff

There is nothing in that code that would cause that waveform to be produced. Have you tried just measuring the pulse with nothing else connected to it?

Does it behave any differently if you comment out the declaration "SoftwareSerial LCDSerial = .." and everything that uses LCDSerial? SoftwareSerial is #2 on my Arduino "do not use" list, Five things I never use in Arduino projects | David Crocker's Solutions blog.

you know... when I put the probe onto the outLED across the 330 ohm resistor, it's nice and square.... when I put it on the pin for the sync, it shows that decay curve.

I do have protection diodes to prevent signals from either sync output (they are on different cameras) to cause any havoc..

I wonder if my board (and the diodes on those outputs) are causing any issue.)

I'll have to tear it all down and look closely....

Weird.

The Radio Shack 1N4003 diode seems to be my problem.

I am isolating my A and B channels with diodes. So the signal is going through
Ground -> diode -> (negative signal to output and scope)
Arduino Output pin (Positive signal).

When I take signal from the Ground... the square wave is true.

I did not know that a Diode would act as a capacitor? Can I find an extremely low capacitance diode?

Brent

weird, why? :roll_eyes:

Try putting a load resistor (say 1k or 10k) between the positive and negative "output" points. Currently, the only load is your scope probe, which will be 1M or 10M.

Also consider using a signal diode such as the 1n4148 instead of a power diode like the 1n4003, unless you have a particular reason for using a power diode.

Sure, the diode is the problem...

The current goes ONE way and charges the cable up fast, but when the arduino output goes Low, it's not connected in the reverse connection and you get a capacitive discharge..

NOW we understand !

Yup... switching diodes didn't help... 10k resistor across the TTL level output does do better ... I'll play with the resistor value to get rid of the little spike I saw...

Thanks all!!

I am isolating my A and B channels with diodes.

That is not the way to isolate things. It won't work (as you have found out)