PWM (Part 4)

Partย 1,ย 2,ย 3,ย 4

Here is a simple sketch which examplifies the use of the PlainPWM library. Be carefully at declaring port and pin properly. The rest is really easy: initialize the PWM object with the port name, pin index, base frequency and default duty cycle ratio. The loop will dim the led up and down endlessly.

/*

	PlainPWM library test
	Copyright (C) 2011 Didier Longueville

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

/* Include libraires */
#include 
/* Create object */
PlainPWM PWM;
/* Local variables */
uint8_t pin = PINB5;
volatile uint8_t *port = &PORTB;

void setup()
{  
	/* Initialize PWM */
	PWM.InitPWM(port, pin, 2000, 0);
};

void loop() 
{
	delay(2000);
	for (int8_t i = 1; i = 0; i--) {
		PWM.SetDutyCycle(i);
		delay(200);
	}	
};

Note: The delay(200); instruction allows your scope to show the flat signal while PWM is set to 0 or 100%

Here is an illustration of the measurements made from the example sketch

As you can see from the bottom indication from the DSO display, the measured frequency is very accurate to the setting!

The PlainPWM library is available as per Arduinoos policy.

20 Comments

  1. bernard says:

    Hello Mr. Didier,

    I have a problem, and I must say that i’m no expert in programming.

    I wish to control the hovering of the quadcopter, so that it flies at a constant height from ground. So I have a remote controller (FUTABA 7 channel) that will control the flight of the quadcopter. The radio receiver brand is also FUTABA and works with PCM – Pulse Code Modulation. So what I did was, I placed my Arduino at the output of the receiver box, so that the microcontroller can manipulate the signal that is sent to the quadcopter.

    With the hover control mode off, the signal that is received from the remote control should be the same as that to be sent to the gyroscope. So this signal basically goes into the microcontroller and comes out unchanged. Attached is my codes for your reference.

    Referring to the codes, line 46 reads the pulsewidth of the incoming signal (from the receiver module), and without any hover control, the signal that is to be sent out from the microcontroller to the quadcopter should be the same, according to lines 141-142. When I connect the output to an oscilloscope, the waveform seems fine. My issue is, the quadcopter doesn’t respond at all! Does PCM have any effect on this issue? Or is it my codes that’s giving the problem? Please help!!

    p/s: How do i attach images or schematics here?

  2. bernard says:

    So sorry, i forgot to paste my codes:

    #include

    // Initialising:
    // *************
    int Rx_pin = 7; // Pin 7 to read signal from the Quadrotor’s receiver
    int Usensor_pin = 4; // Pin 4 used to interface with the PING))) sensors
    int Con_pin = 6; // Pin 6 is used as the switch to turn on/off hover control
    float pw_in = 0; // Pulse width of the incoming signal from receiver box
    float pw_con; // Pulse width of the hover control switch signal
    float period = 0.0142; // Period of the incoming and outgoing signal (seconds)
    float period_m = 14200; // Period of the incoming and outgoing singal (microseconds)
    float freq = 1/period; // Frequency of the signal
    float duty_out; // Duty cycle of the outgoing signal
    float pw_sensor; // Pulse width of the sensor signal
    float alt_cm; // Altitude of quadcopter in centimetres
    float desired_pw; // Pulse width of the signal for desired height
    float desired_height;
    int flag; // flag counter

    // Create Object //
    PlainPWM PWM;

    // Declaring ports and pins //
    uint8_t Gyro_pin = PINB0; // This declares pin 8 as the output pin to the gyroscope.
    volatile uint8_t *port = &PORTB;

    // Setting up //
    void setup()
    { // Initialising PWM //
    PWM.InitPWM(port, Gyro_pin, freq , 0);
    // Establishing serial communication //
    Serial.begin(9600);
    };

    void loop()
    { // Variables for the sensor routine:

    // Reading the incoming pulse and calculating the pulse width //
    pw_in = pulseIn(Rx_pin, HIGH); // Value in microseconds
    Serial.print(“PW_in (no control):”);
    Serial.print(pw_in);
    Serial.println();
    delay(2000);

    // Reading the pulse width of control switch //
    pw_con = pulseIn(Con_pin, HIGH); // Value in microseconds
    // Serial.print(pw_con);
    // Serial.println();
    // delay(1000);
    //

    if (pw_con>1600 && pw_in>1200) // The hover control switch is turned ON // pw_in should be 1200
    {
    Serial.println();
    Serial.print(“Hover Control Initiated”);
    Serial.println();
    flag = 0;
    while (pulseIn(Con_pin, HIGH)>1600) // used to be 1600
    {
    if (flag == 1){

    // Triggering the Ultrasound Sensors to transmit an Echo

    // *****************************************************
    // The PING))) ultrasound sensors need to be triggered to transmit an echo for distance estimation.
    // The trigger command is a pulse (“010”) with a HIGH duration of at least 2 microseconds.
    // To ensure a clean pulse is sent, a LOW is transmitted first, followed by a 5 microseconds HIGH pulse:

    pinMode(Usensor_pin, OUTPUT);
    digitalWrite(Usensor_pin, LOW);
    delayMicroseconds(3);
    digitalWrite(Usensor_pin, HIGH);
    delayMicroseconds(5);
    digitalWrite(Usensor_pin, LOW);

    // Receiving a Signal from the Ultrasound Sensors
    // **********************************************
    // The mode of the Usensor_pin changes to ‘Input’. The distance measured by the PING))) ultrasound
    // sensors is translated into siganl pulse width. For the conversion and relationship between distance
    // and pulse width of the signal back to the microcontroller, please refer to Design Report.

    pinMode(Usensor_pin, INPUT);
    pw_sensor = pulseIn(Usensor_pin, HIGH); // Reading the input signal from the sensors
    alt_cm = pw_sensor/29.034/2; // Converting input signal pulsewidth into height in centimetres
    // Kindly refer to design document/report for conversion details

    if(pw_sensordesired_pw){
    duty_out = duty_out – 0.35;
    PWM.SetDutyCycle(duty_out);
    Serial.print(“Duty Cycle(above desired):”);
    Serial.print(duty_out);
    Serial.println();
    delay(2000);

    }

    }
    else{
    pinMode(Usensor_pin, OUTPUT);
    digitalWrite(Usensor_pin, LOW);
    delayMicroseconds(3);
    digitalWrite(Usensor_pin, HIGH);
    delayMicroseconds(5);
    digitalWrite(Usensor_pin, LOW);

    pinMode(Usensor_pin, INPUT);
    pw_sensor = pulseIn(Usensor_pin, HIGH); // Reading the input signal from the sensors
    desired_pw = pw_sensor;
    desired_height = pw_sensor/29.034/2;
    Serial.print(“Desired Height:”);
    Serial.print(desired_height);
    Serial.println();
    delay(2000);
    flag = 1;
    }
    }
    }

    else{
    // Outputting signal with the same pulse width as the incoming signal //
    // ************************************************************//
    duty_out = pw_in*100/period_m;
    PWM.SetDutyCycle(duty_out);
    Serial.print(“Duty Cycle (manual):”);
    Serial.print(duty_out);
    Serial.println();
    delay(2000);
    // ************************************************************//
    }
    };

  3. bernard says:

    the first line is #include in the codes

  4. Didier says:

    I have a few questions so far:
    Q1: Do I understand correctly that the FUTUBA R/C generates a PWM signal at 1 / 0.0142, so as to say approx. 70 Hz?
    Q2: Am I correct if I say that we could simplify your problem to: I want to mirror the FUTUBA signal to to the output of an Arduino

    It might be interesting that you post a link to some shematics. Just copy paste the URL to shematics that you have previously uplaoded to some private of some public (e.g. Flikr) place

  5. bernard says:

    Hello,

    Q1: Yes the frequency is at 70.4 Hz. But it is PCM instead of PWM.
    Q2: Yes, correct. I want to mirror the signal and also be able to manipulate it for hover control, as you can see in the codes.

    Alright, I will try to get something posted and when i’m done with it, i will post the URL here. Thanks! I will get back to you as soon as possible.

    • Didier says:

      After checking on the Internet, I understand that … I misunderstood the type of PCM that you are using. I found descriptions of various sorts of FUTABA PCM protocols (90, 512, 1024, …) Would you please post a link to the PCM protocol that you are using? Thanks.

  6. bernard says:

    Sorry for the delay! I’ve been having connection issues.

    The link below shows the components of the quadcopter:
    http://www.flickr.com/photos/71911276@N08/6489978633/in/photostream

    Connections are made between the FUTABA receiver and the gyroscope as shown below. Channel 3 of the receiver is THROTTLE, which is of interest as my project deals only with hover control. So, my intention is to place the microcontroller between Channel 3 of the receiver and the gyroscope so that i can manipulate the signals. (Blue wire – Signal; Red – Supply; White – Ground). The connections:
    http://www.flickr.com/photos/71911276@N08/6489973593/in/photostream

    If you are wondering what sort of signal is being communicated, I have included the link below. The signal coming out from the receiver is a pulse. The pulse width changes with the position of the throttle stick, from 1.1 ms (minimum) to 1.92ms (maximum). Basically, when not in hover control mode, I wish to duplicate this signal to be sent to the gyroscope. With hover control, i wish to manipulate the signal before sending. The frequency is 70.4 Hz, pardon me as I forgot to show in the photo. The link:
    http://www.flickr.com/photos/71911276@N08/6490053301/in/photostream

    The Duemilanove =D that I use:
    http://www.flickr.com/photos/71911276@N08/6489983487/in/photostream

    If you can see, i use pin8 to output the signal to the gyroscope (red wire). pin7 will be used to receive the signal from the FUTABA, as described in my codes. When probed with the oscilloscope, the signal at pin7 seems fine, but the signal at pin8 seems rubbished.

    Regarding the FUTABA’s PCM protocol, it is using PCM 1024. It’s a rather old product. =(

    I hope you can point out to me some mistakes! Thanks!

  7. bernard says:

    Could there be a problem with my codes? It still doesn’t work =(

    • Didier says:

      Hello Bernard,
      I could not find the specification that I was expecting from the links that you sent. I tried to collect information about the PCM1024 protocol, and all I managed to get is this diagram:

      http://didier.longueville.free.fr/arduinoos/wp-content/uploads/pcm_01.jpg

      which definetly shows that the FUTABA PCM 1024 protocol has nothing to do with PWM. May be I am completely out of scope, or your may misunderstand the principle of the interface that you try to set up. Any help from Arduinoos reader is welcome!

  8. bernard says:

    Hello!

    Hmm, but if the input to the microcontroller is a pulse, the codes above should output a pulse too, right? Have I made a mistake with the codes in anyway?

    Using a signal generator to mimic the input pulse, i obtained an output pulse at the same frequency, but the amplitude is halved. Any idea why that is happening?

    Is it possible for me to change the magnitude of the output pulse using your PWM function/library?

    I’m pretty sure the problem is with my codes. The FUTABA receiver box outputs an electrical pulse (in my opinion, the PCM protocol does not matter), and I think, as long as I can produce the same pulse, I should be able to get the output that i need, unless of course if there is a problem with the codes.

    Please let me know what you think =)
    Thanks!

  9. bernard says:

    Hello,

    Okay no problem =) Referring to your diagram, the signal that i get at the receiver end (labeled PWM) is this:
    http://www.flickr.com/photos/71911276@N08/6490053301/in/photostream

    The frequency is 70.4 Hz and the signal pulse width changes with the position of the throttle stick of the transmitter Tx. Pulse width range is 1.1 – 1.92 ms.

    Thanks!

  10. Didier says:

    Okay, we are making good progress.
    I want you to realize that you are responsible for the big mix up. in your post 08/12/2011 at 10:20, you wrote
    “Q1: Yes the frequency is at 70.4 Hz. But it is PCM instead of PWM.”

    The signal of interest IS PWM! ๐Ÿ˜‰ You owe me a bear (or two!)

    Now I can get into your code alright. Give me a little time to care about it.

  11. bernard says:

    Ahhh! Oh God. This is so embarrassing!

    You are right, the PCM protocol is only between the TX and RX. I was probably drinking =D I owe you three!

    Thanks! Glad that we see some light now. God bless!

  12. bernard says:

    Hello!

    I have tried to make it work again today, which makes me wonder whether i have used the right pins for the input and output. The pins that i have used are pins 7 (input) and 8 (output, which are digital pins on the Duemilanove.

    Should I have used other pins instead? Or is it the port? I noticed that the data type i have used (float) is different from the ones you have declared above (int8_t). Could that be the reason why it’s not working?

    Thanks =)

  13. faisal says:

    Hello,

    Where can I get the Library for PlainPWM.h? In your policy stated that I have to send an email and the purpose of the library coding. I have done that and still there’s no reply from you =(.
    I appreciate with your assist due this matter =)

    Thanks!

    • Didier says:

      Faisal,

      This is the header of your mail to me:
      On Tue, Feb 7, 2012 at 2:58 PM, faisal Irshad wrote: …

      Your claim for not receiving an answer on a next day basis for free stuff is unfair.

      In addition, you refer to my download policy which reads:
      … If I am talking to students, the answer is no again: why should they find the result of their equation without spending some time to understand it! While I admit that learning by running advanced code is quite an exciting experience, all will agree on the fact the fun is with making the thing happen!

      Sorry, I am not inclined to help you, except for encouraging you to:
      Be patient
      Study hard
      Keep visiting Arduinoss, and try your chance an other time in a communication different mode.

  14. faisal says:

    Thank you for your reply, I appreciate it ๐Ÿ™‚

    I will try to understand(actually I’ve understand a little bit =)) the codes that you have post in arduinoss. The coding is really good for my revision. It’s very concise and explain a lot!

    Sorry if I bugging you with this matter. My apologize

    I will accept your encouragement as my motivation! yeay!

    • Didier says:

      I am glad you take it well. I did not want offense you. Try your best (I am sure you will) , come back to Arduinoos with some results to share ๐Ÿ˜‰

  15. bernard says:

    Hello Mr. Didier,

    I am now able to generate the PWM at the frequency I desire. However, the amplitude is slightly too high for my application. Is there a way I can change the output voltage level?

    I encountered another problem. The blades seem to be jittering when i tried to control the quadcopter. I am thinking that it is probably due to the slight difference in the freq between the input and output signal. Is there a way to read the incoming signal’s frequency and outputs a signal with that measured frequency?

    Thanks for your guidance!

Leave a Reply

You must be logged in to post a comment.