Generated PPM signal is noisy

Hello there. To describe my question, first please see a comparison of PPM signal from Arduino and RC transmitter. The first one is from Arduino while the other one is from transmitter.


My purpose is to generate PPM signal from Arduino and then input into trainer port of RC transmitter.

The implementation is simple without additional circuit. Use a PPM Generator code from other guys and modify the loop() part based on my need. Then input into oscilloscope to check the signal.

As you can see, compared with transmitter, the signal from Arduino is kind of noisy with spikes appearing around rising edge and falling edge.

Is it the problem from PPM code? Or just for a software method, the signal is always poor than hardware one?

Thank you~

Image from Original Post so we don't have to download it. See this Image Guide

...R

You need to show a clear diagram of the wiring of the circuit from which you captured that image. And post the program that produced the image. My guess is that the noise is due to the circuit rather than the Arduino.

Also post the equivalent picture for the signal from the transmitter.

What are you using to capture the image?

If you are referring to the spikes and the jitter in the signal then "noise" is a good word.

...R

Robin2:
You need to show a clear diagram of the wiring of the circuit from which you captured that image. And post the program that produced the image. My guess is that the noise is due to the circuit rather than the Arduino.

Also post the equivalent picture for the signal from the transmitter.

What are you using to capture the image?

If you are referring to the spikes and the jitter in the signal then "noise" is a good word.

...R

Thanks for your reply. While it seems I can't remove my attachment other than the image will be lost in Post as well as your 1st post. Sorry :stuck_out_tongue:

I updated my question and maybe you can check.

For the future don't make changes to earlier Posts - just add the new information in a new Reply.

You have not responded to the other requests in Reply #1

...R

Robin2:
For the future don't make changes to earlier Posts - just add the new information in a new Reply.

You have not responded to the other requests in Reply #1

...R

Ah, understood.

PIN10 and GND to oscilloscope.

As for code, here you go.

//this programm will output a PPM signal

//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 10  //set the number of chanels
#define default_servo_value 1500  //set the default servo value
#define PPM_FrLen 26500  //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300  //set the pulse length
#define onState 1  //set polarity: 1 is positive, 0 is negative
#define sigPin 10  //set PPM signal pin on the arduino
//////////////////////////////////////////////////////////////////


/*this array holds the servo values for the ppm signal
 change theese values in your code (usually servo values are between 1000 and 2000)*/
int ppm[chanel_number];
char command;
int value = 20;

void setup(){  
  //initialize default ppm values
  for(int i=0; i<chanel_number; i++){
    if(i == 2){
      ppm[i] = 1000;
    }
    else{
      ppm[i]= default_servo_value;
    }
  }
  //initialize serial port
  Serial.begin(9600);

  pinMode(sigPin, OUTPUT);
  digitalWrite(sigPin, !onState);  //set the PPM signal pin to the default state (off)
}

void loop(){
  //when no keyboard input
  while(!Serial.available()){
    ppmWrite();
  }
  //when keyboard input
  while(Serial.available()){
    if(Serial.available() > 0){
      char command = Serial.read();
      Serial.println("Command received.");
      if(command == 'w'){
        Serial.println("Command:forward.");
        if(ppm[1] < 2000){
          ppm[1] += value;
          Serial.print("Channal2: ");
          Serial.println(ppm[1],DEC);
        }
        else{
          Serial.println("Cannot increase anymore.");
        }
      }
      else if(command == 's'){
        Serial.println("Command:backward.");
        if(ppm[1] > 1000){
          ppm[1] -= value;
          Serial.print("Channal2: ");
          Serial.println(ppm[1],DEC);
        }
        else{
          Serial.println("Cannot decrease anymore.");
        }
      }
      else if(command == 'a'){
        Serial.println("Command:turn left.");
        if(ppm[0] < 2000){
          ppm[0] += value;
          Serial.print("Channal1: ");
          Serial.println(ppm[0],DEC);
        }
        else{
          Serial.println("Cannot increase anymore.");
        }
      }
      else if(command == 'd'){
        Serial.println("Command:turn right.");
        if(ppm[0] > 1000){
          ppm[0] -= value;
          Serial.print("Channal1: ");
          Serial.println(ppm[0],DEC);
        }
        else{
          Serial.println("Cannot decrease anymore.");
        }
      }
      else if(command == 'q'){
        Serial.println("Command:shift left.");
        if(ppm[3] < 2000){
          ppm[3] += value;
          Serial.print("Channal4: ");
          Serial.println(ppm[3],DEC);
        }
        else{
          Serial.println("Cannot increase anymore.");
        }
      }
      else if(command == 'e'){
        Serial.println("Command:shift right.");
        if(ppm[3] > 1000){
          ppm[3] -= value;
          Serial.print("Channal4: ");
          Serial.println(ppm[3],DEC);
        }
        else{
          Serial.println("Cannot decrease anymore.");
        }
      }
      else if(command == 'u'){
        Serial.println("Command:Up.");
        if(ppm[2] < 2000){
          ppm[2] += value;
          Serial.print("Channal3: ");
          Serial.println(ppm[2],DEC);
        }
        else{
          Serial.println("Cannot increase anymore.");
        }
      }
      else if(command == 'j'){
        Serial.println("Command:down.");
        if(ppm[2] > 1000){
          ppm[2] -= value;
          Serial.print("Channal3: ");
          Serial.println(ppm[2],DEC);
        }
        else{
          Serial.println("Cannot decrease anymore.");
        }
      }
    }
  }
}

void ppmWrite(){  //generate PPM signal
  static unsigned long lastFrLen;
  static unsigned long lastServo;
  static unsigned long lastPulse;
  static boolean PPM_run;
  static boolean pulse;
  static boolean pulseStart = true;
  static byte counter;
  static byte part = true;

  if(micros() - lastFrLen >= PPM_FrLen){  //start PPM signal after PPM_FrLen has passed
    lastFrLen = micros();
    PPM_run = true;
  }

  if(counter >= chanel_number){
    PPM_run = false;
    counter = 0;
    pulse = true;  //output the last pulse
  }

  if(PPM_run){
    if (part){  //output the pulse
      pulse = true;
      part = false;
      lastServo = micros();
    }
    else{  //wait till servo signal time (values from the ppm array) has passed
      if(micros() - lastServo >= ppm[counter]){
        counter++;  //do the next channel
        part = true;
      }
    }
  }

  if(pulse){
    if(pulseStart == true){  //start the pulse
      digitalWrite(sigPin, onState);
      pulseStart = false;
      lastPulse = micros();
    }
    else{  //will wait till PPM_PulseLen has passed and finish the pulse
      if(micros() - lastPulse >= PPM_PulseLen){
        digitalWrite(sigPin, !onState);
        pulse = false;
        pulseStart = true;
      }
    }
  }
}

I'm way out of my depth when it comes to electronic circuits but it looks like you have no load on your circuit. What happens to your oscilloscope trace if you put a resistor (maybe 4k7) between the PWM signal and GND?

...R

See what happens if you put a 100 microFarad electrolytic capacitor and a 100 nanoFarad ceramic capacitor in parallel, and put that 'parallel' pair of capacitors across your 5V pin of your arduino and ground of arduino....... and make sure the 'positive' terminal of the electrolytic capacitor is on the 5V side (not the ground side). It is possible that the noise is coming from your power supply.

Southpark:
It is possible that the noise is coming from your power supply.

I second that.
Was your laptop running on mains power. And the scopemeter?
Could be a laptop-scope mains power groundloop.
Try unplugging the laptop charger.

Don't know if you should worry about that much hash on a digital signal.
Leo..

Ringing around transitions like that is a symptom of stray inductance in the wiring to the 'scope,
or of a scope-probe that's not had its trimmer set correctly.

[in other words its an artifact of the measurement, probably]