Take the 2-minute tour ×
Raspberry Pi Stack Exchange is a question and answer site for users and developers of hardware and software for Raspberry Pi. It's 100% free, no registration required.

I trying to toggle one of my GPIO pins at a specific frequency, at the kHz range.

I set up the wiringPi Library, the blinking example seems to work just fine.So I modified the code, so it will oscillat at 35 Khz, but the output frequency is about 5.5 kHz. However when I ran the code with no delay at all the output frequency was 0.5 Mhz. Note that I don't output anything to the screen.

I guess that that this related to the definition of sleeping function "suspends the execution of the calling thread", so returning the thread to the foreground might take some time.

How can I define the precise sleeping time?

  • I tired to use usleep as well an nanosleep, but same problem.
  • All the above was done done via an SSH, as I mentioned, no output was sent during execution
  • The pi is running an Apache server, but I guess it doesn't have a big affect on it

Here is the code I used

#include <wiringPi.h>
#include <stdio.h>
#include <time.h>

int main (void){
  int pin = 7;

  struct timespec time;
  time.tv_sec = 0;
  time.tv_nsec = 14000L;

  if (wiringPiSetup() == -1)
    exit (1);

  pinMode(pin, OUTPUT);

  while(1){
    digitalWrite(pin, 1);
    nanosleep(&time,&time);
    digitalWrite(pin, 0);
    nanosleep(&time,&time);
  }

  return 0;
}
share|improve this question

2 Answers 2

What you are trying to achieve is almost impossible using operating system. It's really hard to have some hard real time user space mechanism inside operating system. You can try with some RT systems (I don't know if there are some RPi ports) or real time application interface (RTAI, Xenomai, RT Linux) and write some RT module.

nanosleep() suspends the execution of the calling thread until either at least the time specified in *req has elapsed

this means that your timer will least at least time specified, but it could take longer to invoke the timer signal.

share|improve this answer
    
As I suspected :/ , What do you think about a blocking function for a specific time? for instance: while( currentTime() - startTime < delay ); Or should I consider external controlled square wave generator such as 555? –  Kirill Kulakov Dec 8 '12 at 15:34
    
I would consider writing kernel module and if that will not give what you want then try external generator. Some usefull info could be found here: mjmwired.net/kernel/Documentation/timers/timers-howto.txt. Take a look especially at usleep_range function. –  codewarrior Dec 8 '12 at 15:44
    
Since I'm not familiar with writing kernel modules, I'd go with an external oscillator, I'll try the usleep_range() method –  Kirill Kulakov Dec 8 '12 at 21:34
up vote 0 down vote accepted

As @codewarrior said that the nanosleep() will suspend the thread for at least the specified time, so I decided to block the thread rather than return the CPU time to the OS.

Here is my implantation of a precise delay function:

#include <sys/time.h>

void udelay(long us){
    struct timeval current;
    struct timeval start;

    gettimeofday(&start, NULL);
    do {
        gettimeofday(&current, NULL);
    } while( ( current.tv_usec*1000000 + current.tv_sec ) - ( start.tv_usec*1000000 + start.tv_sec ) < us );
}
share|improve this answer
    
This is not "best" solution in case of performance. If you will try to controll more than one pin you could encounter serious limitations. –  codewarrior Dec 8 '12 at 18:18
    
Yes, I know, but I'm using it just one pin for a few millisecond to transmit (modulated IR) a signal.So performance should be an issue here –  Kirill Kulakov Dec 8 '12 at 21:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.