I've use a pic to create IR patterns to modulate frequencies (37kHz or 58kHz) to control different devices. I'd like to move as much as possible to a RPi. I will use a pic to generate the 37kHz or 58kHz, but would ike to be able to have the RPi control the 'on' and 'off' periods of the pic signals.

I would like to create a waveform where, a logical '1' could be descibed as 2-600us periods followed by 1 600us low period. A logical '0' would be described as a 600 us high, followed by a 600us low.

If this is too complex, I can always drop back and use a pic to receive a 'command string' via RS232 from the RPi to do the waveform generation.


  • Search on Raspberry Pi and pwm, the GPIO pins can also generate PWM. Maybe that way you can put all functionality into the RPi.
    – ikku
    Dec 28, 2012 at 16:21
  • On second thought, I fear that the RPi with Linux on it cannot handle the time constraints to manipulate the waveform. Interesting!
    – ikku
    Dec 28, 2012 at 16:36

2 Answers 2


I have managed to do this with the Python RPIO library. I set the PWM up with a 1 uSec pulse, and loaded the entire IR code into memory, doing the 36khz modulation in software. Since this is using DMA, the waveform is pretty good. The one issue I am having is that it does take about 4 seconds to get 2 seconds of DMA buffer loaded into memory.

So, it is possible without too many issues. The code is not pretty, but does work :-)

  out += [header[0]]
  out += [header[1]]

      for c in send:
        if c == "1":
      out += [one[0]]
      out += [one[1]]
      out +=  [zero[0]]
      out +=  [zero[1]]
  out +=  [ptail]
  #out +=  (chr(0xff) + chr(0xff))

  # Pulses => Out
  #print out

  out2 = [0]
  running = 0

  for number in out:
    running += number
    out2 += [running]

  # Running Pulses => Out
  print out2

  #for i in range(len(out2)/2):
  #  a = out2[i*2]
  #  b = out2[i*2+1]

  pw = 1000000 / (36000 * 2) 

  print "PW %d" % (pw)
  print time.time()

  # Setup PWM and DMA channel 0
  PWM.init_channel(0, subcycle_time_us=2000000)

  high = True
  for a,b in pairwise(out2):
    #print "%d %d %d" % (high, a, b)

    if high:
      #pulse = int (a / pw)
      #PWM.add_channel_pulse(0, 17, a, pw)

      pointer = a
      while True:
        pStart = pointer
        pStop = pointer + pw
        if pStop > b:
          pStop = b
          #print "End of Packet 1"
        PWM.add_channel_pulse(0, 17, pStart, pStop-pStart)
        pointer += pw * 2
        if pointer > b: # was pStart > b; One too many cycles
          #print "End of Packet 2"
    high = not high
  print time.time()

  time.sleep (30)

  # Stop PWM for specific GPIO on channel 0
  PWM.clear_channel_gpio(0, 17)

  # Shutdown all PWM and DMA activity

The PWM output is not really suitable to create arbitrary spaced high-low patterns. But have a look at the PCM audio output that can indeed do this and the frequency of 37kHz is in the range of the output capabilities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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