User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Using Python to generate IR pulses

Fri Jun 20, 2014 6:55 am

This is a continuation of http://www.raspberrypi.org/forums/viewt ... 91&t=79462 where the OP wants to generate IR remote control codes.

I'm aware that LIRC has support for this task.

I was interested in the technology so hooked up a TCRT5000 (10 for a GBP) close to a 38kHz IR receiver.

Using the following code I seem to be able to construct and transmit IR codes.

ir_tx.py

Code: Select all

#!/usr/bin/env python

import pigpio

class tx:

   """
   """

   def __init__(self, pi, gpio, carrier_hz):

      """
      Initialises an IR tx on a Pi's gpio with a carrier of
      carrier_hz.

      http://www.hifi-remote.com/infrared/IR-PWM.shtml
      """

      self.pi = pi
      self.gpio = gpio
      self.carrier_hz = carrier_hz
      self.micros = 1000000 / carrier_hz
      self.on_mics = self.micros / 2
      self.off_mics = self.micros - self.on_mics
      self.offset = 0

      self.wf = []
      self.wid = -1

      pi.set_mode(gpio, pigpio.OUTPUT)

   def clear_code(self):
      self.wf = []
      if self.wid >= 0:
         self.pi.wave_delete(self.wid)
         self.wid = -1

   def construct_code(self):
      if len(self.wf) > 0:
         pulses = self.pi.wave_add_generic(self.wf)
         print("waveform TOTAL {} pulses".format(pulses))
         self.wid = self.pi.wave_create()

   def send_code(self):
      if self.wid >= 0:
         self.pi.wave_send_once(self.wid)
         while self.pi.wave_tx_busy():
            pass

   def add_to_code(self, on, off):

      # is there room for more pulses?

      if (on*2) + 1 + len(self.wf) > 680: # 682 is maximum
         
         pulses = self.pi.wave_add_generic(self.wf)
         print("waveform partial {} pulses".format(pulses))
         self.offset = self.pi.wave_get_micros()

         # continue pulses from offset
         self.wf = [pigpio.pulse(0, 0, self.offset)]

      # add on cycles of carrier
      for x in range(on):
         self.wf.append(pigpio.pulse(1<<self.gpio, 0, self.on_mics))
         self.wf.append(pigpio.pulse(0, 1<<self.gpio, self.off_mics))

      # add off cycles of no carrier
      self.wf.append(pigpio.pulse(0, 0, off * self.micros))

if __name__ == "__main__":

   import time
   import pigpio
   import ir_tx

   pi = pigpio.pi()

   tx = ir_tx.tx(pi, 25, 38000)

   for x in range(1024):
      tx.clear_code()

      tx.add_to_code(96, 24) # lead-in burst code

      for b in range(10):

         if x & (1<<b): # 1 bit
            tx.add_to_code(48, 24) # 1 burst-code
         else:
            tx.add_to_code(24, 24) # 0 burst-code

      tx.add_to_code(24, 1024) # lead-out burst code

      tx.construct_code()

      tx.send_code()

   tx.clear_code()

   pi.stop()
Note, the waveform has to be broken up into chunks as the maximum message size to pigpio is currently 8192 bytes and each pulse uses 12 bytes.

The TCRT5000 is connected to gpio 25 via a 220 ohm resistor. The 38kHz receiver is connected to gpio 7. The TCRT5000 only has a range of a few centimetres but it is useful for testing (I don't have any other IR transmitters).
ir-tx-a.png
Overview
ir-tx-a.png (41.33 KiB) Viewed 14254 times
ir-tx-b.png
Two codes
ir-tx-b.png (40.96 KiB) Viewed 14254 times
ir-tx-c.png
Code detail
ir-tx-c.png (40.87 KiB) Viewed 14254 times

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Fri Jun 20, 2014 9:03 am

joan wrote:Note, the waveform has to be broken up into chunks as the maximum message size to pigpio is currently 8192 bytes and each pulse uses 12 bytes.
Hey man,
you know you have been elected my personal guru :), but this part is scaring me!
I was quite confident to have managed the script (i have tested it only "debugging" because i still have not the transmitter..) but the daikin code is something like 36bytes of data (lol) and 3 of 4 long pauses, for a total of "pulse time" of about 144ms (yes, i said ms)
this means A LOT of pulses

So, my question: is this limit something like "cycle to build the wave" or "cycle to send the wave"?
it seems to me (from your code) that it's the first case (and that's good, it's only programmin), but i'm not fully understanding your code..
Then i'll post also the code "micros style" :)
Thanks again a lot.

n.b.: it's not fully true that LIRC has support for this task..
Not for signals that long
Not for signals that are not "differential" but "full" (i'm not sending "temp + 1", i'm sending "temp = 20°C"
Non for signals that can be sent to different transmitters (i'm planning to control all of my splits, obviously :P)
At lease, AFAIK, not in a simple way :)

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Fri Jun 20, 2014 10:16 am

Assuming a 38kHz carrier equates to 76k pulses per second, or 0.144 * 76k = approx 11k pulses. pigpio as compiled supports a maximum of 12000 pulses. So it should work. However in the edge cases you might run out of DMA control blocks (as compiled a maximum of 25016).

You might need to change the source if you reach the limits (change #define PI_WAVE_BLOCKS 4 in pigpio.h to a larger number and recompile).


Starting from a empty waveform you use wave_add_generic to add pulses. They are added from time 0 in the waveform unless the first pulse is a delay in which case they are added offset by the delay time. I had to use that feature in the Python code because a full waveform contained too many pulses to fit into a single socket message.

The wave_create function takes all the added pulses and commits them to DMA blocks. Think of that as a compilation stage. As a side effect it also clear all pulses ready for the construction of a new waveform.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Fri Jun 20, 2014 10:21 pm

Hello,
i think your code cannot manage the case you need a ir pulse longer than 680 pulses (strange, but possible, case)
Btw, i converted your code to "microseconds" and.. it works!

Code: Select all

[email protected] ~ $ python daikin.py --debug wave
##### Start #####
Creating output with this values:
Power status:  1
Powerful status:  None
Temperature setpoint:  25
Fan speed:  auto
Operating mode: cool
Debug level:  wave
####   Config   ####
Gpio: 17
Carrier frequency: 32768
#### End config ####
####   Output   ####
waveform partial 680 pulses
waveform partial 1359 pulses
waveform partial 2037 pulses
waveform partial 2716 pulses
waveform partial 3394 pulses
waveform partial 4073 pulses
waveform partial 4751 pulses
waveform partial 5430 pulses
waveform partial 6108 pulses
waveform partial 6787 pulses
waveform partial 7465 pulses
waveform partial 8144 pulses
waveform partial 8823 pulses
waveform partial 9501 pulses
waveform partial 10180 pulses
waveform TOTAL 10241 pulses
Working time: 1.49 seconds
lot of pulses :)
i linked a red led (not ir) and the signal was received by my tsop1133 sensor, timings are similar to original remote control output, so i think i got it! But the AC doesn't receive it :) need to wait the ir led from DX..

to manage "long ir pulse" case, i checked available pulses and used them to make part of ir pulse, recursively call che same method for remaining part of the ir pulse.. it seems to work :)

thanks a lot (as always) i only haven't understood why the listening script (the same we were talking about in the other topic) is missing the first level (and inverting HIGH and LOW terms, but that's a bug..)
I tried to force the input LOW and enabled a pull down resistance waiting for the first rising edge, but no result.. really dunno, probably it's simply something about the initializazion of tick0 or tick1, but i need to think about it.. from the second to the 583rd level it's perfect :)

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Thu Jun 26, 2014 8:07 pm

Hello,

tell me please, how we can record ir codes and play it ?

Need simple ir recorder/player
I want use my A/C but LIRC can't decrypt IR signal.

i use this http://abyz.co.uk/rpi/pigpio/ex_ir_remote.html for capture codes, and have result:
./ir_remote
ir code is 998385107
ir code is 3627817467


but now i don't know how send this code to blaster :(

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Fri Jun 27, 2014 10:08 am

snaiperr wrote:Need simple ir recorder/player
I want use my A/C but LIRC can't decrypt IR signal.
if you need "only" to record and playback a signal, lirc is the way.
What do you mean with "can't decrypt ir signal"?

What remote are you using? for "simple" commands (i.e., tv) lirc is really really simple (if you don't find the lirc file for your remote, you have to "teach" signals to lirc).
Maybe for complex signals to playback (long signals, like AC remote) something can go wrong, but should be tested..

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 6:36 am

Hello! Thanks for answer!
i run
irrecord -d /dev/lirc0 ac_panasonic
....
Press RETURN now to start recording.
.........................................................................
irrecord: could not find gap.
irrecord: gap not found, can't continue


finish :(
can't control my A/C :(
IMAG0489.jpg
remote control
IMAG0489.jpg (14 KiB) Viewed 13247 times

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 7:03 am

When you used the ir_remote code as in
./ir_remote
ir code is 998385107
ir code is 3627817467
Did it give you the same number each time you pressed the same key, i.e. did a press of 1 always give the same ir_code, and a press of 9 always give the same (but different) ir_code?

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 7:33 am

i run ir_remonte and change temperature value from 30 to 25 and from 25 to 30
my result is:

Code: Select all

30*c
ir code is 998385107
ir code is 657076464

29*c
ir code is 998385107
ir code is 644467611

28*c
ir code is 998385107
ir code is 1005884619

27*c
ir code is 998385107
ir code is 3718221259

26*c
ir code is 998385107
ir code is 3711145608

25*c
ir code is 998385107
ir code is 4240554400

and go back to 30 =>

26*c
ir code is 998385107
ir code is 3711145608

27*c
ir code is 998385107
ir code is 3718221259
...the sames codes


if it is difficult to decipher the signal, I want to at least record and play back but don't know how

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 7:50 am

That is promising. It shows that the individual pulses which make up the IR code have repeatable timings.

The number being printed by ir_remote is a hash over the pulses and is designed to give a different number for each type of code. It doesn't give any information about the individual pulse times.

To transmit a code you need to know the individual pulses times.

Can you program? You'd need to change the code to print out the microseconds on/off for each pulse making up the hash.

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 8:03 am

we have software
mode2 - shows the pulse/space length of infrared signals

with this software we can "record" signals.

Maybe there is a software for play records from mode2 to IR blaster ?

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 8:38 am

If you know the pulse/spaces and the carrier you would need to send the pulse/spaces by adapting the software posted at the start of this thread.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 9:44 am

1) remember that what you receive from an ac remote is not like what you receive from a tv remote: it's not "volume up", it's "mode cooling, temp 25°, fan speed 2" and so on
2) if you want to decode it, you can use "mode 2" from lirc, or an example script from my guru joan that tells you "high" and "low" level of an input GPIO and then work on this (that's not so easy)
3) then, if you want to CREATE those signals, you can use the script joan posted at the start of this topic. Remember also that your ac will receive signals "modulated", so for the high level of your signal you have to modulate it on the carrier frequency

Btw, if you only want to "repeat" some signals (i.e.: specific configuration of your ac) in my opinion you only need to register the signal with lirc and transmit it again..

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 2:18 pm

pattagghiu wrote: Btw, if you only want to "repeat" some signals (i.e.: specific configuration of your ac) in my opinion you only need to register the signal with lirc and transmit it again..
when i try register the signal with lirc i have this error:

Code: Select all

irrecord: could not find gap.
irrecord: gap not found, can't continue

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Sat Jun 28, 2014 3:25 pm

snaiperr wrote:
pattagghiu wrote: Btw, if you only want to "repeat" some signals (i.e.: specific configuration of your ac) in my opinion you only need to register the signal with lirc and transmit it again..
when i try register the signal with lirc i have this error:

Code: Select all

irrecord: could not find gap.
irrecord: gap not found, can't continue
as said before, probably is because of the lenght of the signal..
Try doing something like this

http://absurdlycertain.blogspot.it/2013 ... ation.html

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 6:59 am

pattagghiu wrote:as said before, probably is because of the lenght of the signal..
Try doing something like this

http://absurdlycertain.blogspot.it/2013 ... ation.html
Thanks for solution!

I try record signals

Code: Select all

mode2 -d /dev/lirc0 -m  -r > temp21auto

Next step - i past data from temp21auto file to /etc/lirc/lircd.conf

Code: Select all

begin remote
name ac
flags RAW_CODES
eps 30
aeps 100

ptrail 0
repeat 0 0
gap 40991
#gap 1000

begin raw_codes

name testcode

....codes from temp21auto .....
  3499     1749      421      436      436
  1303      425      428      441      429      438
...

end raw_codes
end remote

Code: Select all

 /etc/init.d/lirc start
and

Code: Select all

 irsend SEND_ONCE ac testcode
Command sended, but a/c not want process this signal.

I run ir_remote, and run again irsend and then saw a very different result than with the remote

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 7:40 am

Have you got the pulse widths/pulse spaces of one of the codes you want to transmit? If so, could you post them within

Code: Select all

 
quotes? What frequency is the remote? 38kHz?

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 8:33 am

joan wrote:Have you got the pulse widths/pulse spaces of one of the codes you want to transmit? If so, could you post them within

Code: Select all

 
quotes? What frequency is the remote? 38kHz?

Code: Select all

     3509     1735      434      427      442     1283
      445      428      458      412      466      396
      445      437      430      428      439      434
      438      428      440      427      437      431
      440      428      439      428      440     1287
      441      428      442      431      450      418
      439      428      438      430      440      428
      440      427      440     1289      439     1287
      442     1290      442      425      444      426
      440     1288      441      426      441      426
      441      428      440      428      440      432
      442      449      418      428      440      427
      448      419      440      427      441      426
      441      428      443      430      439      428
      440      428      438      429      441      427
      441      427      440      427      441      463
      406      432      439      427      441      426
      441      426      439      430      441      428
      439      427      440      427      440      432
      442      426      441     1297      431     1283
      446      426      441      426      442      426
      442      426      441      429      442     9968
     3516     1730      439      428      440     1287
      442      429      434      431      439      428
      439      428      439      425      440      436
      442      425      444      425      440      427
      441      430      452      413      440     1287
      442      426      441      432      441      426
      441      427      452      416      441      426
      441      426      443     1285      442     1286
      443     1291      444      424      443      425
      441     1286      444      425      440      428
      440      428      440      427      440      433
      441      426      450      419      440      426
      440      428      439      428      451      418
      440      427      440      432      440     1287
      442      426      442      427      437      431
      440     1287      441     1287      442      426
      447      429      438      427      440     1284
      445      428      441      426      440     1286
      442     1287      441      429      439      432
      440      425      442      426      441      428
      440      427      441      426      441      428
      440      427      441     1305      441     1294
      438     1284      441     1287      441     1287
      442     1286      438     1291      443     1283
      444      432      440      426      441      427
      440      428      444      425      437      431
      439      428      439      427      440      433
      440      428      440      426      472      393
      437      438      437      429      439      425
      443      426      442      431      442      426
      440      428      439      428      440      426
      438      433      441      426      439     1285
      444      433      440      429      438     1287
      441      428      439     1290      441     1283
      443      428      440      427      441      432
      440      427      441      428      439      427
      443      426      440      426      438      431
      440      428      439      445      427      429
      439      428      440      428      440      427
      441      427      440      427      440      428
      440      433      439      428      441      426
      442      427      447      421      439      429
      440      434      432      426      441     1291
      445      427      441      427      440      428
      440      427      441      428      439      439
      429      427      440      434      439      427
      440     1288      440     1288      440      428
      440      429      438      428      440      427
      437      437      440      427      439      428
      441      427      441     1286      441      428
      441      427      440     1285      443      430
      440

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 11:36 am

The following Python will send an IR code based on the contents of a file.

The file must be called ir_tx_micros.py

Change

tx = ir_tx_micros.tx(pi, 25, 38000) # Pi, IR gpio, carrier frequency Hz.

to reflect the gpio you are using (25) and the carrier wave frequency (38000).

Invoke with ./ir_tx_micros.py name_of_data_file

Manually cut&paste. Don't use SELECT ALL.

Code: Select all

#!/usr/bin/env python

import pigpio

class tx:

   """
   """

   def __init__(self, pi, gpio, carrier_hz):

      """
      Initialises an IR tx on a Pi's gpio with a carrier of
      carrier_hz.

      http://www.hifi-remote.com/infrared/IR-PWM.shtml
      """

      self.pi = pi
      self.gpio = gpio
      self.carrier_hz = carrier_hz
      self.micros = 1000000 / carrier_hz
      self.on_mics = self.micros / 2
      self.off_mics = self.micros - self.on_mics
      self.offset = 0

      self.wf = []
      self.wid = -1

      pi.set_mode(gpio, pigpio.OUTPUT)

   def clear_code(self):
      self.wf = []
      if self.wid >= 0:
         self.pi.wave_delete(self.wid)
         self.wid = -1

   def construct_code(self):
      if len(self.wf) > 0:
         pulses = self.pi.wave_add_generic(self.wf)
         print("waveform TOTAL {} pulses".format(pulses))
         self.wid = self.pi.wave_create()

   def send_code(self):
      if self.wid >= 0:
         self.pi.wave_send_once(self.wid)
         while self.pi.wave_tx_busy():
            pass

   def add_to_code(self, on_micros, off_micros):
      """
      Add on micros of carrier followed by off micros of silence.
      """
      # Calculate cycles of carrier.
      on = (on_micros + self.on_mics) / self.micros

      # Is there room for more pulses?

      if (on*2) + 1 + len(self.wf) > 680: # 682 is maximum
         
         pulses = self.pi.wave_add_generic(self.wf)
         print("waveform partial {} pulses".format(pulses))
         self.offset = self.pi.wave_get_micros()

         # Continue pulses from offset.
         self.wf = [pigpio.pulse(0, 0, self.offset)]

      # Add on cycles of carrier.
      for x in range(on):
         self.wf.append(pigpio.pulse(1<<self.gpio, 0, self.on_mics))
         self.wf.append(pigpio.pulse(0, 1<<self.gpio, self.off_mics))

      # Add off_micros of silence.
      self.wf.append(pigpio.pulse(0, 0, off_micros))

if __name__ == "__main__":

   import sys
   import time

   import pigpio
   import ir_tx_micros

   if len(sys.argv) < 2:
      print("No pulse file specified.")
      exit()

   f = open(sys.argv[1], "r")
   p = f.read().split("\n")

   pulses = (len(p)/2) * 2

   pi = pigpio.pi() # Connect to local Pi.

   tx = ir_tx_micros.tx(pi, 25, 38000) # Pi, IR gpio, carrier frequency Hz.

   tx.clear_code()

   for x in xrange(0, pulses, 2):

      print(int(p[x]), int(p[x+1]))
      tx.add_to_code(int(p[x]), int(p[x+1]))

   tx.construct_code()

   tx.send_code()

   tx.clear_code()

   pi.stop()
The file contains a list of numbers, one per line. The first is micros of carrier on, the second micros of carrier off, the third micros of carrier on, the fourth micros of carrier off, etc.

There is no error checking. The file must contain an even number of numbers.

Your data becomes.

Code: Select all

3509
1735
434
427
442
1283
445
428
458
412
466
396
445
437
430
428
439
434
438
428
440
427
437
431
440
428
439
428
440
1287
441
428
442
431
450
418
439
428
438
430
440
428
440
427
440
1289
439
1287
442
1290
442
425
444
426
440
1288
441
426
441
426
441
428
440
428
440
432
442
449
418
428
440
427
448
419
440
427
441
426
441
428
443
430
439
428
440
428
438
429
441
427
441
427
440
427
441
463
406
432
439
427
441
426
441
426
439
430
441
428
439
427
440
427
440
432
442
426
441
1297
431
1283
446
426
441
426
442
426
442
426
441
429
442
9968
3516
1730
439
428
440
1287
442
429
434
431
439
428
439
428
439
425
440
436
442
425
444
425
440
427
441
430
452
413
440
1287
442
426
441
432
441
426
441
427
452
416
441
426
441
426
443
1285
442
1286
443
1291
444
424
443
425
441
1286
444
425
440
428
440
428
440
427
440
433
441
426
450
419
440
426
440
428
439
428
451
418
440
427
440
432
440
1287
442
426
442
427
437
431
440
1287
441
1287
442
426
447
429
438
427
440
1284
445
428
441
426
440
1286
442
1287
441
429
439
432
440
425
442
426
441
428
440
427
441
426
441
428
440
427
441
1305
441
1294
438
1284
441
1287
441
1287
442
1286
438
1291
443
1283
444
432
440
426
441
427
440
428
444
425
437
431
439
428
439
427
440
433
440
428
440
426
472
393
437
438
437
429
439
425
443
426
442
431
442
426
440
428
439
428
440
426
438
433
441
426
439
1285
444
433
440
429
438
1287
441
428
439
1290
441
1283
443
428
440
427
441
432
440
427
441
428
439
427
443
426
440
426
438
431
440
428
439
445
427
429
439
428
440
428
440
427
441
427
440
427
440
428
440
433
439
428
441
426
442
427
447
421
439
429
440
434
432
426
441
1291
445
427
441
427
440
428
440
427
441
428
439
439
429
427
440
434
439
427
440
1288
440
1288
440
428
440
429
438
428
440
427
437
437
440
427
439
428
441
427
441
1286
441
428
441
427
440
1285
443
430

snaiperr
Posts: 9
Joined: Thu Jun 26, 2014 7:54 pm

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 6:27 pm

Thanks a lot!

try run
./ir_tx_micros.py data > log

Code: Select all

Traceback (most recent call last):
  File "./ir_tx_micros.py", line 102, in <module>
    tx.add_to_code(int(p[x]), int(p[x+1]))
  File "/root/cond/ir_tx_micros.py", line 61, in add_to_code
    pulses = self.pi.wave_add_generic(self.wf)
  File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 1433, in wave_add_generic
    self._control, _PI_CMD_WVAG, 0, 0, len(pulses)*12, extents))
  File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 644, in _u2i
    raise error(error_text(v))
pigpio.error: 'waveform has too many pulses'

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 7:04 pm

snaiperr wrote:Thanks a lot!

try run
./ir_tx_micros.py data > log

Code: Select all

Traceback (most recent call last):
  File "./ir_tx_micros.py", line 102, in <module>
    tx.add_to_code(int(p[x]), int(p[x+1]))
  File "/root/cond/ir_tx_micros.py", line 61, in add_to_code
    pulses = self.pi.wave_add_generic(self.wf)
  File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 1433, in wave_add_generic
    self._control, _PI_CMD_WVAG, 0, 0, len(pulses)*12, extents))
  File "/usr/local/lib/python2.7/dist-packages/pigpio.py", line 644, in _u2i
    raise error(error_text(v))
pigpio.error: 'waveform has too many pulses'
pigpio.error: 'waveform has too many pulses'

The IR code is too long or the previous waveform wasn't properly cleared.

Try a

pigs wvclr

from the command line to make sure all waveforms are deleted.

The program has a limit of 12000 pulses. Each ms of carrier needs 76 pulses. So any code must be less than 158 ms long.

If you do have a long code you'd have to recompile the library to allow more pulses.

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 9:36 pm

joan wrote:The following Python will send an IR code based on the contents of a file.
Hey man :)
you know i never doubt about what you say, but can you explain this piece of code?

Code: Select all

pulses = (len(p)/2) * 2
how can you calculate pulses starting from ms if the frequency is never used? (it's only used in wave creation, but as far as your "add_to_code" needs pulses, i think you should use it also in __main__)

nice to read you again on ir signals :)

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Sun Jun 29, 2014 9:46 pm

pulses = (len(p)/2) * 2
The file is read and split at the newlines to give a list of numbers len(p) long. The quoted code is just a convoluted way of making sure an even number of numbers are processed (carrier on/ carrier off). If the file has an odd number of number the last is ignored.

e.g. 1000/2 * 2 = 1000, 1001/2 * 2 = 1000 (at least with integer arithmetic).

Massi
Posts: 1691
Joined: Fri May 02, 2014 1:52 pm
Location: Italy

Re: Using Python to generate IR pulses

Mon Jun 30, 2014 9:05 am

joan wrote:
pulses = (len(p)/2) * 2
The file is read and split at the newlines to give a list of numbers len(p) long. The quoted code is just a convoluted way of making sure an even number of numbers are processed (carrier on/ carrier off). If the file has an odd number of number the last is ignored.

e.g. 1000/2 * 2 = 1000, 1001/2 * 2 = 1000 (at least with integer arithmetic).
Stupid me, this morning i read your code again and i understood how it works in the send_to_code part
Sorry :)

last question: is there a python equivalent of this

Code: Select all

pigs wvclr

?
if the script fails after some loops (it happened to me while debugging :)) as you say the wave is not deleted so you get the "too many pulses error" the next time you run the script
When i was debugging i solved with a pigpiod restart, but if there's a way to fix it programmaticcally, why not?
have I to use a pi.wave_clear() just after the pi inizialization?

btw, snaiperr signal is shorter than mine and has a total pulse time lower than 103ms, so for sure the "too many pulses" error is not regarding this..

User avatar
joan
Posts: 14352
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Using Python to generate IR pulses

Mon Jun 30, 2014 10:42 am

Yes, the wave_clear() will do the job, it'll clear all waveforms. I try to avoid using it as I sometimes create waveforms from the command line which I don't want purged. wave_delete(wid) will delete all waveforms with id >= wid. wave_clear() is the equivalent of wave_delete(0). Really you should be able to delete individual waveforms but the software would get messy (copying DMA control blocks around) for a feature which would probably never be used.

Return to “Automation, sensing and robotics”