Article Index

Phased Pulses

As a simple example of using the bcm2835 output functions lets try to write a short program that pulses two lines - one high and one low and then one low and one high i.e. two pulse trains out of phase by 180 degrees.

The simplest program to do this job is: 

#include "bcm2835.h"
#include <stdio.h>
#include <unistd.h>
int main()
{
 bcm2835_init();
 bcm2835_gpio_context pin15 = bcm2835_gpio_init(15);
 bcm2835_gpio_dir(pin15, bcm2835_GPIO_OUT_HIGH);
 bcm2835_gpio_context pin31 = bcm2835_gpio_init(31);
 bcm2835_gpio_dir(pin31, bcm2835_GPIO_OUT_LOW);
 for (;;) {
  bcm2835_gpio_write(pin15, 0);
  bcm2835_gpio_write(pin31, 1);
  bcm2835_gpio_write(pin15, 1);
  bcm2835_gpio_write(pin31, 0);
 }
 return bcm2835_SUCCESS;
}

Notice that there is no delay in the loop so the pulses are produced at the fastest possible speed. 

Using a logic analyzer reveals that the result isn't what you might expect:

 

At this high speed the pulses aren't perfectly regular and come in two sizes but you can also see that the pulse trains are not 180 degrees out of phase. The top train switches on and the bottom train takes about half a pulse before it switches on - the intent is for both actions to occur at the same time.

The point is that it does take quite a long time to access and change the state of an output line. 

Of course if we include a delay to increase the pulse width then the delay caused by accessing the GPIO lines in two separate actions isn't so obvious:

 

 

In this case the loop now n=1000 busy wait loops:

volatile int i;
for(;;)
{
 bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, HIGH);
 bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, HIGH);
 for(i=0;i<1000;i++){};
 bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_07, LOW);
 bcm2835_gpio_write(RPI_BPLUS_GPIO_J8_11, LOW);
 for(i=0;i<1000;i++){};
}

You will notice that the pulses are now roughly 10 microseconds wide and they are changing at what looks like nearer to being the same time - of course they aren't.

There is still a lag, but in many applications it might not be important. In other applications it could be crucial.

For example, if the two pulse trains were driving different halves of a motor controller bridge there would be a significant time when both were high - so shorting the power supply. It might only be for 10 microseconds but over time it could well damage the power supply.  Of course, any sensible, cautious, engineer wouldn't feed a motor control bridge from two independently generated pulse trains unless they were guaranteed not to switch both sides of the bridge on at the same time. 

A better way to generate in phase pulses is to use a multi function and a mask. 

For example if you change the first program to:

bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_07, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(RPI_BPLUS_GPIO_J8_11, BCM2835_GPIO_FSEL_OUTP);uint32_t mask=(1 << RPI_GPIO_P1_07) | (1 << RPI_GPIO_P1_11);
for(;;)
{
 bcm2835_gpio_set_multi (mask);
 bcm2835_gpio_clr_multi (mask);
}

Then the two GPIO lines do change at the same time even at the highest speed:

 

It is clear that if you want to synchronize the changing of GPIO lines you should use the multi functions and a mask. 

Can We Do Better?

If by better you mean faster - probably not enough to make it worth the effort. There is some overhead in calling a function but this is tiny. How to directly address the GPIO without the use of a library is covered in a later chapter but more for educational reasons than to increase the speed of operation.

A more interesting question is whether it is possible to increase the accuracy of the pulses. 

This might be possible by turning off interrupts and using internal timers but it would interfere with the normal operation of Linux and again probably isn't going to be worth it. 

 

 

 

Now On Sale!

You can now buy a print or ebook edition of Raspberry Pi IoT in C from Amazon.

 

For Errata and Listings Visit: IO Press

 

 

This our ebook on using the Raspberry Pi to implement IoT devices using the C programming language. The full contents can be seen below. Notice this is a first draft and a work in progress. 

Chapter List

  1. Introducing Pi (paper book only)

  2. Getting Started With NetBeans In this chapter we look at why C is a good language to work in when you are creating programs for the IoT and how to get started using NetBeans. Of course this is where Hello C World makes an appearance.

  3. First Steps With The GPIO
    The bcm2835C library is the easiest way to get in touch with the Pi's GPIO lines. In this chapter we take a look at the basic operations involved in using the GPIO lines with an emphasis on output. How fast can you change a GPIO line, how do you generate pulses of a given duration and how can you change multiple lines in sync with each other? 

  4. GPIO The SYSFS Way
    There is a Linux-based approach to working with GPIO lines and serial buses that is worth knowing about because it provides an alternative to using the bcm2835 library. Sometimes you need this because you are working in a language for which direct access to memory isn't available. It is also the only way to make interrupts available in a C program.

  5. Input and Interrupts
    There is no doubt that input is more difficult than output. When you need to drive a line high or low you are in command of when it happens but input is in the hands of the outside world. If your program isn't ready to read the input or if it reads it at the wrong time then things just don't work. What is worse is that you have no idea what your program was doing relative to the event you are trying to capture - welcome to the world of input.

  6. Memory Mapped I/O
    The bcm2835 library uses direct memory access to the GPIO and other peripherals. In this chapter we look at how this works. You don't need to know this but if you need to modify the library or access features that the library doesn't expose this is the way to go. 

  7. Near Realtime Linux
    You can write real time programs using standard Linux as long as you know how to control scheduling. In fact it turns out to be relatively easy and it enables the Raspberry Pi to do things you might not think it capable of. There are also some surprising differences between the one and quad core Pis that make you think again about real time Linux programming.

  8. PWM
    One way around the problem of getting a fast response from a microcontroller is to move the problem away from the processor. In the case of the Pi's processor there are some builtin devices that can use GPIO lines to implement protocols without the CPU being involved. In this chapter we take a close look at pulse width modulation PWM including, sound, driving LEDs and servos.

  9. I2C Temperature Measurement
    The I2C bus is one of the most useful ways of connecting moderately sophisticated sensors and peripherals to the any processor. The only problem is that it can seem like a nightmare confusion of hardware, low level interaction and high level software. There are few general introductions to the subject because at first sight every I2C device is different, but here we present one.

  10. A Custom Protocol - The DHT11/22
    In this chapter we make use of all of the ideas introduced in earlier chapters to create a raw interface with the low cost DHT11/22 temperature and humidity sensor. It is an exercise in implementing a custom protocol directly in C. 

  11. One Wire Bus Basics
    The Raspberry Pi is fast enough to be used to directly interface to 1-Wire bus without the need for drivers. The advantages of programming our own 1-wire bus protocol is that it doesn't depend on the uncertainties of a Linux driver.

  12. iButtons
    If you haven't discovered iButtons then you are going to find of lots of uses for them. At its simples an iButton is an electronic key providing a unique coce stored in its ROM which can be used to unlock or simply record the presence of a particular button. What is good news is that they are easy to interface to a Pi. 

  13. The DS18B20
    Using the software developed in previous chapters we show how to connect and use the very popular DS18B20 temperature sensor without the need for external drivers. 

  14. The Multidrop 1-wire bus
    Some times it it just easier from the point of view of hardware to connect a set of 1-wire devices to the same GPIO line but this makes the software more complex. Find out how to discover what devices are present on a multi-drop bus and how to select the one you want to work with.

  15. SPI Bus
    The SPI bus can be something of a problem because it doesn't have a well defined standard that every device conforms to. Even so if you only want to work with one specific device it is usually easy to find a configuration that works - as long as you understand what the possibilities are. 

  16. SPI MCP3008/4 AtoD  (paper book only)

  17. Serial (paper book only)

  18. Getting On The Web - After All It Is The IoT (paper book only)

  19. WiFi (paper book only)

 

 

Related Articles

Real Raspberry Pi - Getting Started And Custom NOOBS

    

 

comments powered by Disqus