IR blaster for an AC unit

Share here your ideas for new projects

Moderators: meveric, mdrjr, odroid

IR blaster for an AC unit

Unread postby mad_ady » Mon Apr 24, 2017 5:37 pm

I've been thinking of a way to use an Odroid (XU4 or C1) to control an air conditioning (AC) unit (LG). The AC unit comes with a standard IR remote control (it's not a "smart" unit with Wifi), so I'll need to build an IR emitter and somehow clone the remote. Preliminary searches led me to this guide: https://github.com/zeroflow/ESPAircon/w ... ngineering which basically tells you that the AC's remote control sends the whole state (temperature, power status, cooling type, on/off timer, etc) each time you press a key. So, when you power on the AC you tell it all the parameters - the same thing when you power it off. This probably means that lirc might be unable to learn these codes, since it believes that each key has a unique code.

I will try to use lirc to record the IR codes from the existing remote to see if they can be captured.

Otherwise, plan B is to use the XProtolab Plain Oscilloscope to capture raw waveforms from the IR receiver data pin and store them as "wave" files. Next step is to decode the wave file and convert it to binary and see if I can decode the output (figure out which is temperature, which is power status, which is timer, etc).

If/when I can do all this, it's time to start working on an emitter. Lucky for me, I already have a fairly long (3m) IR repeater from my Samsung TV (https://forum.samygo.tv/viewtopic.php?t=11030) which should be able to do the job. I'll just have to figure out what parameters are safe for it (what voltage can be applied on the IR diodes, what current) and wire something up. I don't have any data-sheets for the components, but from guesses and internet searches it looks like most IR diodes work with about 1.6V and have a maximum current of about 50mA. The plan is to hook it up to a XU4 which is in a 3m proximity to the AC, since all other devices are away from line of sight and might be behind closed doors.

To emit the IR data I could probably use the LIRC_ODROID module (like here viewtopic.php?f=24&t=2426 or http://odroid.com/dokuwiki/doku.php?id= ... io_blaster) or I'll have to do it "by hand" and replay the wave file recorded or turn on/off the gpio with the correct sequence and frequency - but this might be more tricky.

I started this thread as a place to ask for help when I get stuck and also document each step and most failures :).

Wish me luck!
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Tue Apr 25, 2017 6:16 am

The Android application irplus has codes for most devices, you may be able to get what you need from it.

https://play.google.com/store/apps/deta ... oid.irplus

What is the exact model of your AC?
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue Apr 25, 2017 2:51 pm

Well, I can't seem to find the AC's manual or order information and I don't know the exact model. The remote however has the part number akb73456113 and is compatible with the following AC units:
P24EL, P18EL, P12RL, P09RL, P24RL, P18RL,
P24EL.NS2, P18EL.NS2, P12RL.NSB, P09RL.NSB,
P24RL.NSB, P18RL.NSB,
LG SILVERDEC09.SET, LG SILVERDEC12.SET,
LG SILVERDEC18.SET, LG SILVERDEC24.SET,
NEW SILVER DECO, SILVERDECO,
LG NEWSILVER12.SET, LG NEWSILVER09.SET,
LG NEWSILVER18.SET, LG NEWSILVER24.SET,


Unfortunately my phone doesn't have an IR blaster, so I can't install the app you suggested. But if you can install it, can you check if it supports any of the models above? I will try the LIRC approach and see if it can learn the codes.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Tue Apr 25, 2017 4:00 pm

Sure, looking now.

This is exported and contains lirc_raw codes

https://db.tt/WSelOZpCEK

This is the buttons it contains

http://i.imgur.com/8Xfxz19.png
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby crazyquark » Tue Apr 25, 2017 6:30 pm

I used a usb irtoy2 to capture codes and replay them for my AC unit.
crazyquark
 
Posts: 203
Joined: Thu Jan 15, 2015 4:22 pm
languages_spoken: english, french, romanian
ODROIDs: C1,C1+,C2,XU4

Re: IR blaster for an AC unit

Unread postby rooted » Tue Apr 25, 2017 8:28 pm

I'm not sure you can capture these codes, at least I have never captured any this complex.

I have no experience with an irtoy2, checking it out now.

*edit*
The irtoy2 is cool, as long as the device is RC5 based it would likely work.

@mad_ady
This will allow you to install it and get the codes yourself.

https://play.google.com/store/apps/deta ... .irpluslan

It could also be a cool weekend project to setup.

This one is equally cool and could also be a nice weekend project, it uses audio and the headphone jack.

https://play.google.com/store/apps/deta ... irpluswave
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue Apr 25, 2017 9:08 pm

I appreciate your guys help, but you're doing all the work and leaving me without the fun :D

I managed to get lirc to capture the codes in raw mode, but the problem is the code sends the whole state, so, for instance if you want to send the AC the code to set temperature to 20C with fan set to max is going to be a different than the code to set the temperature to 20C with fan set to low. It would be nice to be able to generate the correct code based on one's needs.

Here is a basic lircd.conf file with the POWER key and KEY_F8 - KEY-F17 mapped to temperatures 23-30
Code: Select all

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.0(default) on Tue Apr 25 14:51:10 2017
#
# contributed by
#
# brand:                       lg.conf
# model no. of remote control:
# devices being controlled by this remote:
#

begin remote

  name  lg.conf
  flags RAW_CODES
  eps            30
  aeps          100

  gap          16777215

      begin raw_codes

          name KEY_POWER
             8862    4178     461    1619     490     571
              489     569     442     558     467    1634
              467     558     467     585     465     577
              466     577     463     570     443     580
              463     590     443     591     443     614
              420     592     443    1631     445    1623
              444     592     443     613     437    1639
              445     606     443    1641     444     578
              463    1631     445    1623     445    1632
              445    1619     467    1625     441

          name BTN_MODE
             8823    4173     514    1564     503     553
              498     504     520     534     500    1565
              505     564     476     534     500     543
              500     542     499     543     496     547
              499     525     500    1601     501     507
              502     542     500     521     553     533
              477    1653     421    1584     501    1583
              509     541     502    1573     510     533
              501     534     500     562     486     517
              519    1590     500    1552     503

          name KEY_F8
             8849    4181     493    1576     494     592
              444     555     493     589     438    1600
              469     575     467     564     492     561
              466     568     466     575     468     557
              491     569     467    1608     468     573
              475     570     466     558     493    1596
              494     558     492     567     474     585
              442     577     467    1596     518     537
              466     576     466     565     517    1565
              519     566     444     567     467

          name KEY_F9
             8819    4191     463    1617     494     614
              420     582     498     529     505    1589
              445     573     485     539     491     593
              436     564     502     539     492     592
              459     567     476    1624     504     512
              491     562     467     656     377    1600
              470     567     466     582     451    1601
              468     604     430    1616     468     613
              444     583     476     558     443    1620
              503     524     504    1599     500

          name KEY_F10
             8787    4214     442    1646     469     572
              443     593     439     611     416    1659
              443     598     468     566     442     593
              468     577     489     557     443     601
              442     607     441    1642     418     632
              445     598     468     575     441    1625
              443     593     441     599     443     594
              438     595     438    1630     416     627
              440     593     440     619     415    1629
              441     592     441     600     443

          name KEY_F11
             8808    4215     502    1600     463     567
              472     587     443     555     492    1595
              468     576     465     558     491     564
              465     556     490     586     442     580
              454     568     466    1601     468     567
              467     590     444     591     443    1623
              468     577     466    1600     491     569
              466     583     468    1592     467     569
              466     590     442     579     457    1622
              469    1624     472     544     492

          name KEY_F12
             3803     295     252     370     334     450
              517     292     310     194    1422    4767
              436    1711     333     700     338     930
              154     605     387    1709     361     809
              207     807     258     648     361     681
              439     645     338     670     363     698
              363    1811     256     648     361     708
              352     647     386    1705     361     734
              308    1749     390     625     358     684
              362    1732     337     749     284     726
              308     647     282    1835     362    1723
              290     728     384

          name KEY_F13
             8846    4155     518    1558     514     542
              501     572     505     515     500    1563
              544     510     500     542     501     523
              549     511     498     533     518     551
              502     556     483    1555     531     523
              499     546     493     577     502    1535
              502    1587     503     563     471     588
              458     557     487    1560     522     542
              500     541     501    1721     376     553
              470     598     435     556     502

          name KEY_F14
             8789    4210     498    1589     512     533
              442     590     459     625     419    1622
              461     592     443     633     413     578
              460     584     458     602     447     620
              423     606     469    1590     468     609
              428     583     464     579     443    1631
              474    1621     442     590     476     572
              445     621     408    1622     466     611
              433     597     475    1619     427     621
              456     552     564     491     455

          name KEY_F15
             8779    4216     505    1531     494     597
              441     638     448     510     492    1597
              503     525     517     537     499     546
              501     529     500     532     518     539
              510     527     517    1580     504     531
              520     522     547     503     511    1565
              505    1572     503     523     519    1573
              503     540     503    1556     519     555
              479     534     551    1513     504     556
              477     565     502    1521     522

          name KEY_F16
             8791    4208     525    1546     465     574
              467     613     433     625     413    1612
              475     569     462     613     421     589
              472     573     443     612     440     620
              439     625     405    1639     456     576
              463     586     457     578     467    1624
              441    1629     447    1609     500     555
              446     625     417    1612     471     582
              446     598     443    1622     475     586
              447    1609     475     594     440

          name KEY_F17
             8866    4188     518    1542     520     567
              444     581     500     544     467    1596
              519     544     466     567     467     575
              467     558     516     567     444     555
              518     536     466    1624     469     574
              468     564     518     523     518    1567
              469    1607     470    1600     473    1593
              470     565     469    1614     470     570
              463     568     470    1584     521     535
              467    1598     470    1623     470

      end raw_codes

end remote



I'm not sure if I can convert the raw codes to a bitstring to try to see what fields are being sent (identify the fields based on the changes between them).
I think I'm going to hook up the oscilloscope to the IR pins and try to capture the waveform for the fun of it :D

The oscilloscope might not be needed. mode2 seems to do the job:
Code: Select all
root@kbd:~# mode2 -d /dev/lirc0
space 16777215
pulse 8879
space 4157
pulse 528
space 1588
pulse 482
space 522
pulse 519
space 534
pulse 501
space 566
pulse 477
space 1562
pulse 521
space 557
pulse 477
space 566
pulse 476
space 551
pulse 499
space 551
pulse 498
space 543
pulse 500
space 530
pulse 520
space 558
pulse 477
space 1562
pulse 521
space 542
pulse 500
space 543
pulse 499
space 522
pulse 519
space 535
pulse 500
space 1581
pulse 503
space 542
pulse 500
space 534
pulse 500
space 545
pulse 500
space 1563
pulse 502
space 543
pulse 499
space 1555
pulse 521
space 535
pulse 500
space 522
pulse 519
space 534
pulse 500
space 1585
pulse 500

I wonder if I can turn it into a waveform graph :) And also some hex. Need to read more on mode2...

Edit2: There was a project that did just that, but it seems to have dissapeared from the face of the internet: https://sourceforge.net/p/lirc/mailman/ ... /12852339/
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Tue Apr 25, 2017 9:33 pm

Oddly enough the app can show the waveform, at least on a device with an IR blaster.

This is the left power button, see the graph at the bottom.

http://i.imgur.com/YAY2BL6.png
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue Apr 25, 2017 11:03 pm

I've stumbled over this: https://bbs.nextthing.co/t/installing-l ... i-p/2449/4

With the raw codes captured by lirc and sox (with that guy's script) I generated this waveform:

Image

The on/off data is modulated on top of a carrier frequency (I suspect I need to tweak this to be 38k instead of 192k as the script defaults):

Image

At least now I have a visualization and I can think about comparing signals.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Thu Apr 27, 2017 10:00 pm

Ok, I had a bit of time and I was able to hook up the Xprotolab-Plain to the IR GPIO input pin of the IR receiver of the C2 (it's the outer most pin, closest to the edge of the board). I had to learn how to set triggers and how to capture the signal, and ran a capture through lirc's "mode2" and the oscilloscope.
The signal looks like this:
Code: Select all
     8925     4111      502     1555      519      662
      384      526      518      545      497     1563
      521      580      450      599      456      519
      602      456      499      549      499      544
      499      533      517      543      497      546
      494      529      518      544      485     1573
      497      556      498      517      494     1563
      518      543      495     1588      495      563
      484      570      469     1789      294     1586
      489      576      487     1572      494

I captured the signal for the state "on, 24 degrees, maximum fan" both ways. I converted the output from mode2 (which lists raw lirc codes of pause and signal) into a wave file with the script in the above post and compared the wave file to the output of the oscilloscope.

Tada:

- recreated wavefile
Image

- oscilloscope reading at 5ms/div (screenshot is truncated, but the signal was readable on the scope:
Image

- oscilloscope reading at 10ms/div (sampling rate is too low and some symbols merge):
Image

A bit length is about 500us, so, for the whole signal (including the "silence" at the beginning) we would have about 50ms of "signal". That would mean about 100 bits of data, or if we exclude the silence period (which I doubt carries any information), we're left with 41ms or 82 bits of data.

I won't be using the oscilloscope to extract the waveform, but it was a nice tool to use to validate that the data that was recorded through mode2 looks "ok".
Next steps:
1. Record signals with mode2 for all the states that I want/need to use (all temperature/fan speed combinations)
2. Look for a gnu-radio tool to convert the waveform into bits/hex
3. Just for fun - compare the codes based on the known state that was sent to identify where the bits are stored in the IR signal
4. Think about how the emitter would look like/work.
5. Implement the hardware + test
6. Profit!
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Thu Apr 27, 2017 10:17 pm

Good work mad_ady.

I've been meaning to look at the Xprotolab, what do you think about it?
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Thu Apr 27, 2017 10:37 pm

I think it's nice for a hobbyist. I certainly don't have the skills to push it to the limit. But I like the fact that it has UART (and other protocol) detection so I got it to find UART ports on other boards (e.g. hook up the relevant pins, reboot remote board, look for UART signals). It also comes with some clamps that you can use to latch to various pins (which is cool).

Image
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Fri Apr 28, 2017 8:27 am

Thumbs up ^^^

I don't have much need for a full blown oscilloscope but I often find myself needing to measure PWM, it might fit the bill.
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue May 02, 2017 7:54 pm

Ok, I tried to make some more progress on two fronts:
1. I mapped the keys I needed (on/off, temperature 18-30, fan low/medium/high/cycle) and put them in this repository: https://github.com/mad-ady/lg-ac-remote-lirc. I was too lazy to map them by hand so I wrote a small script to ask me to put the remote in a state and press a key and it would record the mode to that file. Took less than a minute to map the 48 codes I needed. I will probably use these for replay, but I still want to see the waveform and map the protocol (for fun)
2. I found some tools to handle OOK decoding (On-Off-Keying) (https://github.com/Sc00bz/DemodulateOOK), but they require wave files where the ones are represented as a high volume section, not a sine waveform as it is now. So, I'm working with sox trying to generate a flat signal in the time spectrum instead of a sine wave: https://superuser.com/questions/1205200 ... ave-signal

I'll work on concatenating the codes in a lirc file and then I will look at the hardware part of the project. See what I have and what I'm missing.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed May 03, 2017 8:02 pm

Some more progress report. I managed to convince sox to generate a square wave and was able to convert the lirc raw-codes to wave files. Then, I took the wavefiles and ran them through an ook-demodulator and got a hex string back. I ran the hex string through bc and converted it to binary and put all codes in an easy to read CSV file (Excel FTW!). The results are on my git mentioned above.

And now, a case study - looking for the on/off bit. We are looking at two remote signals, one for ON in the state "24C, low fan", and one for OFF in the "24C, low fan" state. The purpose of the exercise is to identify which bit(s) changed:

  • off-24-low, hex: 008AA2A88AAAAAA28AA0, bin: 10001010 10100010 10101000 10001010 10101010 10101010 10100010 10001010 10100000
    Image
  • on-24-low, hex: 008AA2AAA8AA2A2AAA80, bin: 10001010 10100010 10101010 10101000 10101010 00101010 00101010 10101010 10000000
    Image
One thing to mention is that the hex-binary conversion is done with bc and leading zeros are lost. If you are to take a close look at the differences you'll notice that there are 6 bits which are different. Unfortunately, the bits are widespread throughout the message indicating they are not (all) part of a CRC. Possible causes:
1. wrong demodulation - maybe it isn't OOK
2. the remote also has a "current time" setting which might get sent to the AC on each key press. This means that part of the message will differ between all messages.
3. read errors?

I'll continue to scratch my head over the meaning of the bits. Maybe I should print them out and overlay them to see what the pattern means...
Image
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue May 09, 2017 6:00 pm

Ok, summer is approaching, so I need to finish this project :)

I think I finished the software side (without decoding the actual codes - :( ), but I need to get started on the hardware side.
So, if I start with the standard schematic from here http://odroid.com/dokuwiki/doku.php?id= ... io_blaster and I modify it with my blaster configuration (which contains 5 leds in paralel) I end up with this schematic:
Image

The problem is - I don't have the specs of the IR diodes in my blaster, but I'd say they have to be close to regular IR diodes (https://cdn-shop.adafruit.com/datasheet ... asheet.pdf), so that would mean a peak current of ~100mA, usual current of 20mA and a voltage drop of ~1.2-1.5V.
So, I need to calculate the value of R2 and what actual current I will be needing - because the diodes are in paralel. So, R2 should support a current of 50mA*5 = 250mA. I'm not sure what the voltage drop on the NPN transistor (collector-emmitor) is, but - is R2 necessary for the XU4? If yes, what value (and power rating) should it have?
R1's role is to ensure a 0.6V drop on the base-emmitor of the transistor, so I guess I can use any value (e.g. 330ohm?) because the current is weak on the GPIO port.

I'll be using a KSP2222A transistor, which I think is appropriate for the job).

I'd like the input of somebody with hands-on knowledge (like @odroid or @phaseshifter), so that I can proceed further :)
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby odroid » Tue May 09, 2017 7:50 pm

Yes, R1 can be 270~1Kohm.
R2 can be 4.7ohm or less. Measure the voltage drop on R2 with a volt-meter when you tinkering the IR LEDs to find an optimal value.
User avatar
odroid
Site Admin
 
Posts: 24992
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue May 09, 2017 8:27 pm

Thank you for the feedback @odroid. I made an order for 4.7 ohm resistors (together with other stuff) and I'll build it early next week. Will keep you posted.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby rooted » Wed May 10, 2017 3:43 am

mad_ady wrote:Thank you for the feedback @odroid. I made an order for 4.7 ohm resistors (together with other stuff) and I'll build it early next week. Will keep you posted.

Good luck, I have a feeling it will turn out great.
User avatar
rooted
 
Posts: 3653
Joined: Fri Dec 19, 2014 9:12 am
Location: Gulf of Mexico, US
languages_spoken: english
ODROIDs: C1
C1+
C2
XU3 Lite
XU4
VU7+
HiFi Shield 2
Smart Power (original)

Re: IR blaster for an AC unit

Unread postby mad_ady » Fri May 19, 2017 6:20 pm

Ok, this week has been the hardest - the physical build. I tried the original design with the 4.7 ohm resistor (which was actually 6 ohm built from 4 20ohm resistors in parallel) and an assortment of wires and connectors - and - it didn't work. My test plan was to flip the GPIO to 1 and see if the leds light up (when viewed through a camera). Turns out my 1.8 VDD pin on my test XU3 didn't output 1.8V. Don't know why. So, I changed the design a bit and connected to the 5V pin (PIN1) and replaced the R2 resistor with a 80 ohm resistor (made from 4 330 ohm resistors in parallel - from the tinkering kit). With this design one can use the same circuit on the C series as well (not tested yet). This time I built it on a breadboard and tested it, and eureka - it lit up! Next I rebuilt the hardware variant, but again - I got nothing. I replaced and measured various parts and it turns out that the audio jack connector I was using to connect to the IR leds (since they have an audio jack by design) was faulty/not reliable. So I changed that as well. Now when I manually turn the GPIO on, the leds light up. I'm really bad at this... :)

Next, the software part. I'm using kernel 4.9 on the XU3 and I compiled my own kernel with this commit cherry-picked: https://github.com/hardkernel/linux/com ... b6af56c6ff
I can manually insert the kernel module and it seems to load just fine:

Code: Select all
# modprobe lirc_dev
# modprobe lirc_odroid gpio_out_pin=24 softcarrier=1 invert=1
# dmesg
...
[   33.401581] lirc_dev: IR Remote Control driver registered, major 245
[   49.181104] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   49.192967] lirc_odroid lirc_odroid.0: lirc_dev: driver lirc_odroid registered at minor = 0
[   49.200118] lirc_odroid: driver registered!



Lirc starts without incident as well. But - when I try to send a key code I get a crash:
Code: Select all
root@odroid:~# irsend SEND_ONCE lg.conf on-24-min
root@odroid:~# dmesg
...
[   33.401581] lirc_dev: IR Remote Control driver registered, major 245
[   49.181104] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   49.192967] lirc_odroid lirc_odroid.0: lirc_dev: driver lirc_odroid registered at minor = 0
[   49.200118] lirc_odroid: driver registered!
[  300.431749] lirc_odroid is opened
[  300.433852] Unable to handle kernel NULL pointer dereference at virtual address 00000020
[  300.441926] pgd = ec544000
[  300.444571] [00000020] *pgd=b5ea8835
[  300.448166] Internal error: Oops: 17 [#1] PREEMPT SMP ARM
[  300.453356] Modules linked in: lirc_odroid(C) lirc_dev netconsole fuse cpufreq_conservative cpufreq_ondemand cpufreq_userspace cpufreq_powersave smsc95xx exynos_gpiomem ipv6
[  300.468792] CPU: 4 PID: 1582 Comm: lircd Tainted: G         C      4.9.28+ #1
[  300.475879] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[  300.481951] task: ec529f40 task.stack: ed052000
[  300.486483] PC is at lirc_dev_fop_open+0xc4/0x18c [lirc_dev]
[  300.492106] LR is at set_use_inc+0x10/0x18 [lirc_odroid]
[  300.497384] pc : [<bf0b4bd8>]    lr : [<bf0ba088>]    psr: 600f0013
               sp : ed053df0  ip : 00000000  fp : 00000000
[  300.508810] r10: ed053f74  r9 : ed053ed0  r8 : 00000000
[  300.514012] r7 : edc8ac00  r6 : ec4c96f0  r5 : ed244480  r4 : 00000000
[  300.520513] r3 : 00000000  r2 : 00000000  r1 : eedb83a8  r0 : 00000000
[  300.527013] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[  300.534116] Control: 10c5387d  Table: 6c54406a  DAC: 00000051
[  300.539836] Process lircd (pid: 1582, stack limit = 0xed052210)
[  300.545725] Stack: (0xed053df0 to 0xed054000)
[  300.550070] 3de0:                                     bf0ba674 ed10d500 ec4c96f0 edc8ac00
[  300.558223] 3e00: 00000000 ed053ed0 ed053f74 c021c5d0 00000006 00000000 edc8ac00 ec4c96f0
[  300.566366] 3e20: edc8ac08 c021c52c 00000000 c0215644 00000000 ed053e94 00000002 00000000
[  300.574511] 3e40: 00000000 ed053ed0 ed053f74 c02254cc 00000000 c022172c ed053e80 00000006
[  300.582658] 3e60: edc8ac00 00000041 00000001 ed053f28 ed053f50 c0930154 00000000 c0226820
[  300.590799] 3e80: 00000000 00000000 00000000 00000002 ec4c96f0 c262fd90 ed737908 c2189550
[  300.598945] 3ea0: ec4c96f0 00000001 00000002 00000007 ed053f74 00000001 fffff000 c0107884
[  300.607094] 3ec0: ed052000 00000000 00000000 c02271a4 c262fd90 ed737908 5bc85782 00000005
[  300.615237] 3ee0: ed2f0015 00000001 00000000 c2189550 ec4c96f0 00000101 00000002 000019c0
[  300.623380] 3f00: 00000000 00000000 00000000 ed053f10 00000000 00000000 591eb6e3 239e60b6
[  300.631528] 3f20: 00000002 ed2f0000 00000007 c266f100 c266f118 00000000 00000400 c0235038
[  300.639671] 3f40: ed2f0000 00000000 ffffff9c 00000002 ffffff9c c0107884 00000007 ffffff9c
[  300.647818] 3f60: ed2f0000 c0216a58 0000002c 0f500000 00000000 00000002 591e0000 00000006
[  300.655968] 3f80: 00000100 00000001 591eb6e3 0004e1a4 00048138 0004814c 00000005 c0107884
[  300.664109] 3fa0: ed052000 c01076c0 0004e1a4 00048138 bee4cf6a 00000002 bee4c9e0 00002000
[  300.672257] 3fc0: 0004e1a4 00048138 0004814c 00000005 bee4cbc8 000463d0 00048138 00000000
[  300.680399] 3fe0: 00000000 bee4c9dc 00022807 b6d6be36 000f0030 bee4cf6a 00000000 00000000
[  300.688600] [<bf0b4bd8>] (lirc_dev_fop_open [lirc_dev]) from [<c021c5d0>] (chrdev_open+0xa4/0x178)
[  300.697497] [<c021c5d0>] (chrdev_open) from [<c0215644>] (do_dentry_open+0x1fc/0x2fc)
[  300.705288] [<c0215644>] (do_dentry_open) from [<c02254cc>] (path_openat+0x348/0xf14)
[  300.713086] [<c02254cc>] (path_openat) from [<c02271a4>] (do_filp_open+0x60/0xc4)
[  300.720537] [<c02271a4>] (do_filp_open) from [<c0216a58>] (do_sys_open+0x114/0x1c4)
[  300.728171] [<c0216a58>] (do_sys_open) from [<c01076c0>] (ret_fast_syscall+0x0/0x3c)
[  300.735867] Code: e12fff32 e2504000 1a000023 e595808c (e5984020)
[  300.742256] ---[ end trace be171f60b6608eab ]---


I'm guessing that the lirc_odroid patch will need adjusting for kernel 4.9, right?
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Mon May 22, 2017 5:27 pm

Until the 4.9 lirc_odroid driver gets fixed, I'm working on alternatives.

Plan A: use a spare C2 to transmit IR. I've made the hardware adjustments and tested the IR diodes (they light up under a camera when toggling the GPIO manually). Next, I'm working on making lirc transmit with the built-in lirc_odroid module. Here I've had mixed results. I'm loading the module with:
Code: Select all
sudo service lirc stop
modprobe lirc_dev
modprobe lirc_odroid gpio_out_pin=249 softcarrier=1 invert=0
sudo service lirc restart


The /etc/lirc/hardware.conf file lists the following:
Code: Select all
# /etc/lirc/hardware.conf
#
#Chosen Remote Control
REMOTE="None"
REMOTE_MODULES="meson-ir"
REMOTE_DRIVER="default"
REMOTE_DEVICE="/dev/lirc0"
REMOTE_SOCKET=""
REMOTE_LIRCD_CONF=""
REMOTE_LIRCD_ARGS="--uinput"
#Chosen IR Transmitter
TRANSMITTER="odroid blaster"
TRANSMITTER_MODULES="lirc_odroid lirc_dev"
TRANSMITTER_DRIVER=""
TRANSMITTER_DEVICE="/dev/lirc0"
TRANSMITTER_SOCKET=""
TRANSMITTER_LIRCD_CONF=""
TRANSMITTER_LIRCD_ARGS=""
#Disable kernel support.
#Typically, lirc will disable in-kernel support for ir devices in order to
#handle them internally.  Set to false to prevent lirc from disabling this
#in-kernel support.
#DISABLE_KERNEL_SUPPORT="true"

#Enable lircd
START_#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD="false"

#Try to load appropriate kernel modules
LIRCD="true"
LOAD_MODULES="true"

# Default configuration files for your hardware if any
LIRCMD_CONF=""

#Forcing noninteractive reconfiguration
#If lirc is to be reconfigured by an external application
#that doesn't have a debconf frontend available, the noninteractive
#frontend can be invoked and set to parse REMOTE and TRANSMITTER
#It will then populate all other variables without any user input
#If you would like to configure lirc via standard methods, be sure
#to leave this set to "false"
FORCE_NONINTERACTIVE_RECONFIGURATION="false"
START_LIRCMD=""


dmesg lists the following (the first errors are from missing parameters for lirc_odroid at boot time:
Code: Select all
root@kbd:~# dmesg | grep lirc
[   23.929955] lirc_dev: IR Remote Control driver registered, major 230
[   23.939766] rc rc0: lirc_dev: driver ir-lirc-codec (meson-ir) registered at minor = 0
[   23.960382] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   23.961189] lirc_odroid: cant claim gpio pin 0
[   23.961201] lirc_odroid: init port fail!
[   23.961204] lirc_odroid[lirc_odroid_exit]
[   24.573147] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   24.574542] lirc_odroid: cant claim gpio pin 0
[   24.574557] lirc_odroid: init port fail!
[   24.574561] lirc_odroid[lirc_odroid_exit]
[  305.003140] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[  305.004354] lirc_odroid lirc_odroid.0: lirc_dev: driver lirc_odroid registered at minor = 1
[  305.004369] lirc_odroid: driver registered!
[  305.198954] input: lircd as /devices/virtual/input/input5
[  430.014254] input: lircd as /devices/virtual/input/input6


irsend can list the configured key presses:
Code: Select all
root@kbd:~# irsend LIST lg.conf ""
irsend: 0000000000000001 on-21-low
irsend: 0000000000000002 on-19-high
irsend: 0000000000000003 on-23-high
irsend: 0000000000000004 on-27-med
irsend: 0000000000000005 on-26-high
irsend: 0000000000000006 on-22-high
irsend: 0000000000000007 on-30-low
irsend: 0000000000000008 on-24-low
irsend: 0000000000000009 on-27-high
irsend: 000000000000000a on-18-cycle
irsend: 000000000000000b on-29-med
irsend: 000000000000000c on-30-med
irsend: 000000000000000d on-20-cycle
irsend: 000000000000000e on-25-high
irsend: 000000000000000f on-26-cycle
irsend: 0000000000000010 on-29-high
irsend: 0000000000000011 on-28-low
irsend: 0000000000000012 on-24-cycle
irsend: 0000000000000013 on-20-med
irsend: 0000000000000014 on-28-high
irsend: 0000000000000015 on-20-high
irsend: 0000000000000016 off-24-min
irsend: 0000000000000017 on-26-low
irsend: 0000000000000018 on-22-low
irsend: 0000000000000019 on-29-low
irsend: 000000000000001a on-22-med
irsend: 000000000000001b on-25-low
irsend: 000000000000001c on-19-med
irsend: 000000000000001d on-21-med
irsend: 000000000000001e on-28-med
irsend: 000000000000001f on-24-med
irsend: 0000000000000020 on-28-cycle
irsend: 0000000000000021 on-24-high
irsend: 0000000000000022 on-25-cycle
irsend: 0000000000000023 on-19-cycle
irsend: 0000000000000024 on-30-high
irsend: 0000000000000025 on-18-low
irsend: 0000000000000026 on-23-cycle
irsend: 0000000000000027 on-27-cycle
irsend: 0000000000000028 on-27-low
irsend: 0000000000000029 on-19-low
irsend: 000000000000002a on-21-high
irsend: 000000000000002b on-18-med
irsend: 000000000000002c on-23-low
irsend: 000000000000002d on-29-cycle
irsend: 000000000000002e on-20-low
irsend: 000000000000002f on-21-cycle
irsend: 0000000000000030 on-23-med
irsend: 0000000000000031 on-26-med
irsend: 0000000000000032 on-18-high
irsend: 0000000000000033 on-22-cycle
irsend: 0000000000000034 on-25-med
irsend: 0000000000000035 on-30-cycle


But when I try to send I get this error:
Code: Select all
root@kbd:~# irsend SEND_ONCE lg.conf on-24-max
irsend: command failed: SEND_ONCE lg.conf on-24-max
irsend: hardware does not support sending


The thing is - I did get it to work once. The leds would even blink for a split second, but I was only able to send one message before lirc needed restarting. So - I might have messed up lirc config. I will restore the stock lirc configuration and try again.

Plan B: parse the lirc pulse-space data and toggle the gpio manually from user space. I'm not sure if I have enough accuracy from user-space to generate 500us pulses through GPIO on the XU4, but I think with affinity set to a big core and process priority set to high, I might have a chance.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby odroid » Mon May 22, 2017 5:34 pm

We will try the IR blaster function on XU4 kernel 4.9 within a few days.
User avatar
odroid
Site Admin
 
Posts: 24992
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID

Re: IR blaster for an AC unit

Unread postby mad_ady » Mon May 22, 2017 5:54 pm

Ok, I redid the /etc/lirc/hardware.conf like this:
Code: Select all
# /etc/lirc/hardware.conf
#
#Chosen Remote Control
REMOTE="None"
REMOTE_MODULES=""
REMOTE_DRIVER=""
REMOTE_DEVICE=""
REMOTE_SOCKET=""
REMOTE_LIRCD_CONF=""
REMOTE_LIRCD_ARGS=""

#Chosen IR Transmitter
TRANSMITTER="odroid blaster"
TRANSMITTER_MODULES="lirc_odroid lirc_dev"
TRANSMITTER_DRIVER=""
TRANSMITTER_DEVICE="/dev/lirc0"
TRANSMITTER_SOCKET=""
TRANSMITTER_LIRCD_CONF=""
TRANSMITTER_LIRCD_ARGS=""

#Disable kernel support.
#Typically, lirc will disable in-kernel support for ir devices in order to
#handle them internally.  Set to false to prevent lirc from disabling this
#in-kernel support.
#DISABLE_KERNEL_SUPPORT="true"

#Enable lircd
START_LIRCD="true"

#Don't start lircmd even if there seems to be a good config file
#START_LIRCMD="false"

#Try to load appropriate kernel modules
LOAD_MODULES="true"

# Default configuration files for your hardware if any
LIRCMD_CONF=""

#Forcing noninteractive reconfiguration
#If lirc is to be reconfigured by an external application
#that doesn't have a debconf frontend available, the noninteractive
#frontend can be invoked and set to parse REMOTE and TRANSMITTER
#It will then populate all other variables without any user input
#If you would like to configure lirc via standard methods, be sure
#to leave this set to "false"
FORCE_NONINTERACTIVE_RECONFIGURATION="false"
START_LIRCMD=""


Also, I made the modules load with the correct parameters at startup (@odroid, please add this step to the wiki as well):
Code: Select all
root@kbd:~# cat /etc/modprobe.d/lirc.conf
options lirc_odroid gpio_out_pin=249 softcarrier=1 invert=0


And now, after a reboot, I can send multiple commands without lirc locking up:
Code: Select all
root@kbd:~# dmesg | grep lirc
[   16.181978] lirc_dev: IR Remote Control driver registered, major 230
[   16.207962] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   16.209033] lirc_odroid lirc_odroid.0: lirc_dev: driver lirc_odroid registered at minor = 0
[   16.209040] lirc_odroid: driver registered!
[  286.513276] lirc_odroid is opened
[  286.514757] lirc_odroid is closed
[  307.536364] lirc_odroid is opened
[  307.543263] lirc_odroid is closed
[  310.813686] lirc_odroid is opened
[  310.823298] lirc_odroid is closed
[  324.470092] lirc_odroid is opened
[  324.470189] lirc_odroid - SET_SEND_CARRIER 38000
[  324.470204] lirc_odroid - SET_SEND_DUTY_CYCLE 50
[  324.523130] lirc_odroid is closed
[  464.108689] lirc_odroid is opened
[  464.109732] lirc_odroid - SET_SEND_CARRIER 38000
[  464.109752] lirc_odroid - SET_SEND_DUTY_CYCLE 50
[  464.161512] lirc_odroid is closed
[  585.147392] lirc_odroid is opened
[  585.149215] lirc_odroid - SET_SEND_CARRIER 38000
[  585.149282] lirc_odroid - SET_SEND_DUTY_CYCLE 50
[  585.202649] lirc_odroid is closed
[  626.154934] lirc_odroid is opened
[  626.157321] lirc_odroid - SET_SEND_CARRIER 38000
[  626.157407] lirc_odroid - SET_SEND_DUTY_CYCLE 50
[  626.212186] lirc_odroid is closed


The command I used (I had it wrong in my previous post):
Code: Select all
irsend SEND_ONCE lg.conf on-24-high


Now, this seems to work (it generates pulses), but I haven't tried it yet on my AC unit. I will try to do so in the following days/next week. But - I tried a dry run - generate the code and compare it with the remote's code with the oscilloscope. The codes look similar, but not identical (original code is further up):
Image

I'm guessing that the reason the codes are not identical is that my code is a replay of an older state which might include current date/time, while the remote has slightly different settings with regard to date/time. I'm hoping the relevant settings are correct (temperature, etc).

I'll let you guys know.

P.S. Thanks @odroid!
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Mon May 22, 2017 6:07 pm

Hmm, I tried the same procedure on a different C2 and the module can't load because it can't claim gpio 249:
Code: Select all
adrianp@jumphost:~> dmesg | grep lirc
[   15.321395] lirc_dev: IR Remote Control driver registered, major 230
[   15.327452] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   15.328345] lirc_odroid: cant claim gpio pin 249
[   15.328365] lirc_odroid: init port fail!
[   15.328370] lirc_odroid[lirc_odroid_exit]
[   17.754356] Modules linked in: lirc_dev w1_gpio wire meson_gpiomem gxbb_wdt nfsd nfs_acl ipv6 autofs4 raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq raid1 raid0 multipath linear md_mod

How can I find which module keeps that GPIO busy? It's not critical - it seems gpio 238 is free:
Code: Select all
   
root@jumphost:~# cd /sys/class/gpio/
root@jumphost:/sys/class/gpio# echo 249 > export
-su: echo: write error: Device or resource busy
root@jumphost:/sys/class/gpio# echo 238 > export
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby joy » Wed May 24, 2017 6:17 pm

You can use the node, /sys/kernel/debug/gpio to get a list of the mapped gpios.

Code: Select all
root@odroid64:~# cat /sys/kernel/debug/gpio
GPIOs 122-135, platform/c1109880.pinmux, ao-bank:
 gpio-125 (amlsd               ) out lo   
 gpio-127 (?                   ) in  lo   
 gpio-135 (blue:heartbeat      ) out hi   

GPIOs 136-255, platform/c1109880.pinmux, banks:
 gpio-150 (rst_pin             ) in  hi   
 gpio-165 (amlsd               ) out hi   
 gpio-180 (amlsd               ) in  hi   
 gpio-223 (amlsd               ) out lo   
 gpio-224 (sysfs               ) in  hi   
 gpio-249 (sysfs               ) in  hi   
Last edited by joy on Wed May 24, 2017 6:34 pm, edited 2 times in total.
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed May 24, 2017 6:23 pm

Thanks! It was one-wire:
Code: Select all
adrianp@jumphost:~> sudo cat /sys/kernel/debug/gpio
GPIOs 122-135, platform/c1109880.pinmux, ao-bank:
 gpio-125 (amlsd               ) out lo   
 gpio-127 (?                   ) in  lo   
 gpio-135 (blue:heartbeat      ) out lo   

GPIOs 136-255, platform/c1109880.pinmux, banks:
 gpio-150 (rst_pin             ) in  hi   
 gpio-165 (amlsd               ) out hi   
 gpio-180 (amlsd               ) in  hi   
 gpio-223 (amlsd               ) out lo   
 gpio-238 (lirc_odroid ir/out  ) out lo   
 gpio-249 (w1                  ) in  hi
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby joy » Wed May 24, 2017 6:35 pm

On C2, I confirmed the operation as the wiki describes so could you try it first?
http://odroid.com/dokuwiki/doku.php?id= ... io_blaster
And don't forget the IO voltage of C2 is 3.3V. ;)

And on XU4 4.9, I will check it.
Please give me a few days.
I got the same errors with XU4 4.9. :(
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed May 24, 2017 7:09 pm

For my C2 I had played with 1wire before, so my image is not stock.
The hardware I built works with both 1.8 and 3.3V because this voltage is used only for the transistor's base. The rest of the circuit plugs into 5V
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Mon May 29, 2017 5:31 am

Ok, I managed to set up the blaster at home on a C2 and tested it with my AC unit.
Unfortunately my tests failed:
* first, the AC unit was unplugged - I'm an idiot :)
* signals still failed to turn on the unit with the blaster 30 cm away from the receiver
* signals still failed with the blaster 1 cm away - I thought that would rule out low current or too narrow radiation cone from the ir leds.

Oh, forgot to mention, I see the leds blink when viewed with a camera, so the hardware works.

Now, I'm not sure where the problem is, but:
1. I could have recorded the wrong codes/truncated codes. I will try with codes provided by rooted to rule this out.
2. I may be sending the codes wrong. I have the lirc module loaded with
Code: Select all
options lirc_odroid gpio_out_pin=238 softcarrier=1 invert=0

If I use invert=1 the ir leds are mostly on. Not sure what softcarrier does
* is it possible that the AC IR receiver expects a different wavelength than the transmitter sends? Can I find this out somehow with household items? (e.g. by comparing colors?)
* Would it be fesable for me to bypass the kernel driver and toggle the gpio from userspace? I'm not sure how accurate the timings might be if I use sleep.

Any other ideas?
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby tobetter » Wed May 31, 2017 3:08 am

When I look at your schematic, 5 IR array, I can't see a circuit to generate modulation frequency which is 38kHz. Most or all IR remote controller are based on the modulation frequency, as I know, and receiver module have a filter inside. Based on my understanding, I suspect that this is missing and I guess you should use IR transmitter module which generate 38kHz itself or connect IR LED to PWM pin instead of GPIO. So let PWM generates 38kHz as much as equvalent to length of signal high. I don't tries this with LIRC, I suspect that 'softcarrier' is to set modular frequency.
tobetter
 
Posts: 2079
Joined: Mon Feb 25, 2013 10:55 am
Location: Kitchener, ON, Canada
languages_spoken: Korean, English
ODROIDs: X, X2, U2, U3, XU3, C1

Re: IR blaster for an AC unit

Unread postby tobetter » Wed May 31, 2017 3:33 am

I've quickly look at the driver code of LIRC and found that there is 'LIRC_SET_SEND_CARRIER' which seems to seet carrier frequency via ioctl from a userspace. But in the driver the frequency is already set 38000, if that is the case maybe you can debug the function 'send_pulse_softcarrier', if modular frequency is generated, the shape of pulse on GPIO would be completely different with what you measured in IR receiver.
tobetter
 
Posts: 2079
Joined: Mon Feb 25, 2013 10:55 am
Location: Kitchener, ON, Canada
languages_spoken: Korean, English
ODROIDs: X, X2, U2, U3, XU3, C1

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed May 31, 2017 3:08 pm

Thanks for your input, @tobetter. I was worried that the ciruit I was using was sending just the pulses, without the 38kHz carrier wave. In fact, I don't see how it would be able to send a sine wave, since the GPIO used is digital.

In the mean-time I managed to test the receiver with publicly available codes (posted by @rooted in the second or 3rd post). And - they worked! I was able to turn the AC unit on/off with the same hardware setup. Also, I seem to have been able to set temperature (I haven't tested it yet, but the unit beeps when receiving the command). The fan speed commands don't seem to do anything through (they beep, but the fan spins the same way). So, it seems I have captured the raw codes in a wrong way. I'm a bit stumped by this - all my efforts have been in vain and I have learned nothing from this failure.

More digging shall be needed.

But, the good news is the hardware setup works, there is enough power to drive the leds, and the signal doesn't need to be a modulated sine wave!

Oh, there is one problem though. On the C2, I am able to send only one code. When I send a second code with irsend, it times out when communicating with lirc. If I restart lirc, the second code gets sent (even if irsend had timed out!). I am able to send codes provided that I restart lirc after each code is sent. Maybe there is a problem in the odroid_lirc module, not signalling the end of the code to lirc?
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby tobetter » Wed May 31, 2017 3:20 pm

mad_ady wrote:Thanks for your input, @tobetter. I was worried that the ciruit I was using was sending just the pulses, without the 38kHz carrier wave. In fact, I don't see how it would be able to send a sine wave, since the GPIO used is digital.

In the mean-time I managed to test the receiver with publicly available codes (posted by @rooted in the second or 3rd post). And - they worked! I was able to turn the AC unit on/off with the same hardware setup. Also, I seem to have been able to set temperature (I haven't tested it yet, but the unit beeps when receiving the command). The fan speed commands don't seem to do anything through (they beep, but the fan spins the same way). So, it seems I have captured the raw codes in a wrong way. I'm a bit stumped by this - all my efforts have been in vain and I have learned nothing from this failure.

More digging shall be needed.

But, the good news is the hardware setup works, there is enough power to drive the leds, and the signal doesn't need to be a modulated sine wave!

Oh, there is one problem though. On the C2, I am able to send only one code. When I send a second code with irsend, it times out when communicating with lirc. If I restart lirc, the second code gets sent (even if irsend had timed out!). I am able to send codes provided that I restart lirc after each code is sent. Maybe there is a problem in the odroid_lirc module, not signalling the end of the code to lirc?

Good to hear your hardware works... :lol: But a little bit strange it works without 38kHz. It could be...but... :mrgreen:
tobetter
 
Posts: 2079
Joined: Mon Feb 25, 2013 10:55 am
Location: Kitchener, ON, Canada
languages_spoken: Korean, English
ODROIDs: X, X2, U2, U3, XU3, C1

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed May 31, 2017 3:27 pm

I'm guessing the receivers in most modern hardware are not too strict about the 38KHz carrier.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby joy » Wed Jun 14, 2017 8:43 pm

mad_ady wrote:Lirc starts without incident as well. But - when I try to send a key code I get a crash:
Code: Select all
root@odroid:~# irsend SEND_ONCE lg.conf on-24-min
root@odroid:~# dmesg
...
[   33.401581] lirc_dev: IR Remote Control driver registered, major 245
[   49.181104] lirc_odroid: module is from the staging directory, the quality is unknown, you have been warned.
[   49.192967] lirc_odroid lirc_odroid.0: lirc_dev: driver lirc_odroid registered at minor = 0
[   49.200118] lirc_odroid: driver registered!
[  300.431749] lirc_odroid is opened
[  300.433852] Unable to handle kernel NULL pointer dereference at virtual address 00000020
[  300.441926] pgd = ec544000
[  300.444571] [00000020] *pgd=b5ea8835
[  300.448166] Internal error: Oops: 17 [#1] PREEMPT SMP ARM
[  300.453356] Modules linked in: lirc_odroid(C) lirc_dev netconsole fuse cpufreq_conservative cpufreq_ondemand cpufreq_userspace cpufreq_powersave smsc95xx exynos_gpiomem ipv6
[  300.468792] CPU: 4 PID: 1582 Comm: lircd Tainted: G         C      4.9.28+ #1
[  300.475879] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[  300.481951] task: ec529f40 task.stack: ed052000
[  300.486483] PC is at lirc_dev_fop_open+0xc4/0x18c [lirc_dev]
[  300.492106] LR is at set_use_inc+0x10/0x18 [lirc_odroid]
[  300.497384] pc : [<bf0b4bd8>]    lr : [<bf0ba088>]    psr: 600f0013
               sp : ed053df0  ip : 00000000  fp : 00000000
[  300.508810] r10: ed053f74  r9 : ed053ed0  r8 : 00000000
[  300.514012] r7 : edc8ac00  r6 : ec4c96f0  r5 : ed244480  r4 : 00000000
[  300.520513] r3 : 00000000  r2 : 00000000  r1 : eedb83a8  r0 : 00000000
[  300.527013] Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
[  300.534116] Control: 10c5387d  Table: 6c54406a  DAC: 00000051
[  300.539836] Process lircd (pid: 1582, stack limit = 0xed052210)
[  300.545725] Stack: (0xed053df0 to 0xed054000)
[  300.550070] 3de0:                                     bf0ba674 ed10d500 ec4c96f0 edc8ac00
[  300.558223] 3e00: 00000000 ed053ed0 ed053f74 c021c5d0 00000006 00000000 edc8ac00 ec4c96f0
[  300.566366] 3e20: edc8ac08 c021c52c 00000000 c0215644 00000000 ed053e94 00000002 00000000
[  300.574511] 3e40: 00000000 ed053ed0 ed053f74 c02254cc 00000000 c022172c ed053e80 00000006
[  300.582658] 3e60: edc8ac00 00000041 00000001 ed053f28 ed053f50 c0930154 00000000 c0226820
[  300.590799] 3e80: 00000000 00000000 00000000 00000002 ec4c96f0 c262fd90 ed737908 c2189550
[  300.598945] 3ea0: ec4c96f0 00000001 00000002 00000007 ed053f74 00000001 fffff000 c0107884
[  300.607094] 3ec0: ed052000 00000000 00000000 c02271a4 c262fd90 ed737908 5bc85782 00000005
[  300.615237] 3ee0: ed2f0015 00000001 00000000 c2189550 ec4c96f0 00000101 00000002 000019c0
[  300.623380] 3f00: 00000000 00000000 00000000 ed053f10 00000000 00000000 591eb6e3 239e60b6
[  300.631528] 3f20: 00000002 ed2f0000 00000007 c266f100 c266f118 00000000 00000400 c0235038
[  300.639671] 3f40: ed2f0000 00000000 ffffff9c 00000002 ffffff9c c0107884 00000007 ffffff9c
[  300.647818] 3f60: ed2f0000 c0216a58 0000002c 0f500000 00000000 00000002 591e0000 00000006
[  300.655968] 3f80: 00000100 00000001 591eb6e3 0004e1a4 00048138 0004814c 00000005 c0107884
[  300.664109] 3fa0: ed052000 c01076c0 0004e1a4 00048138 bee4cf6a 00000002 bee4c9e0 00002000
[  300.672257] 3fc0: 0004e1a4 00048138 0004814c 00000005 bee4cbc8 000463d0 00048138 00000000
[  300.680399] 3fe0: 00000000 bee4c9dc 00022807 b6d6be36 000f0030 bee4cf6a 00000000 00000000
[  300.688600] [<bf0b4bd8>] (lirc_dev_fop_open [lirc_dev]) from [<c021c5d0>] (chrdev_open+0xa4/0x178)
[  300.697497] [<c021c5d0>] (chrdev_open) from [<c0215644>] (do_dentry_open+0x1fc/0x2fc)
[  300.705288] [<c0215644>] (do_dentry_open) from [<c02254cc>] (path_openat+0x348/0xf14)
[  300.713086] [<c02254cc>] (path_openat) from [<c02271a4>] (do_filp_open+0x60/0xc4)
[  300.720537] [<c02271a4>] (do_filp_open) from [<c0216a58>] (do_sys_open+0x114/0x1c4)
[  300.728171] [<c0216a58>] (do_sys_open) from [<c01076c0>] (ret_fast_syscall+0x0/0x3c)
[  300.735867] Code: e12fff32 e2504000 1a000023 e595808c (e5984020)
[  300.742256] ---[ end trace be171f60b6608eab ]---

I'm guessing that the lirc_odroid patch will need adjusting for kernel 4.9, right?

Hello mad_ady,
Sorry for very late response for the kernel fault of xu4 kernel 4.9.

I found the clue of the internal error
and it's now available to use IR blaster with GPIO on XU4 kernel 4.9.

It's caused by the WARN routine of lirc_buffer_clear in lirc_dev_fop_open during lirc device open.
https://github.com/hardkernel/linux/blo ... _dev.h#L43
Code: Select all
static inline void lirc_buffer_clear(struct lirc_buffer *buf)
{
   unsigned long flags;

   if (kfifo_initialized(&buf->fifo)) {
      spin_lock_irqsave(&buf->fifo_lock, flags);
      kfifo_reset(&buf->fifo);
      spin_unlock_irqrestore(&buf->fifo_lock, flags);
   } else
      WARN(1, "calling %s on an uninitialized lirc_buffer\n",
           __func__);
}

There are some updates in media lirc drivers of kernel 4.9 version compared with 3.10
and in the following routine, there is a limited condition to check available buffer allocation state in lirc_register_driver function.
Only available LIRC_CAN_REC.
https://github.com/hardkernel/linux/blo ... dev.c#L363
Code: Select all
int lirc_register_driver(struct lirc_driver *d)
{
   int minor, err = 0;

   minor = lirc_allocate_driver(d);
   if (minor < 0)
      return minor;

   if (LIRC_CAN_REC(d->features)) {
      err = lirc_allocate_buffer(irctls[minor]);
      if (err)
         lirc_unregister_driver(minor);
   }

   return err ? err : minor;
}
EXPORT_SYMBOL(lirc_register_driver);

In case of lirc_odroid gpio blaster driver, there are only SEND-related capabilities,
so the buffer allocation is skipped with the condition.
Code: Select all
driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
           LIRC_CAN_SET_SEND_CARRIER |
           LIRC_CAN_SEND_PULSE;

So I added one more condition of LIRC_CAN_SEND.

I've confirmed IR TX operation is working well
with HK's remote controller key value and the hardware environment described in the following wiki page.
http://odroid.com/dokuwiki/doku.php?id= ... io_blaster
- IR Receiver : ODROID-C2
- IR Transmitter : ODROID-XU4 with kernel 4.9 and patches

I attached the patches so if you're available and want to check it,
please check it.

1. xu4_lirc_patch_2_fix_lirc_buffer_allocation_fault.diff
Code: Select all
From 5b2affbf8473c024feb14c5559aa8d5f0d8ed431 Mon Sep 17 00:00:00 2001
From: Joy Cho <joy.cho@hardkernel.com>
Date: Wed, 14 Jun 2017 19:51:56 +0900
Subject: [PATCH] media/rc: add LIRC_CAN_SEND for the buffer allocation to support IR TX

Change-Id: I854ac738c13e2aea5443f1abf3e54117dd596437
---

diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 6ebe895..bdcaa67 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -360,7 +360,7 @@
    if (minor < 0)
       return minor;
 
-   if (LIRC_CAN_REC(d->features)) {
+   if (LIRC_CAN_REC(d->features) || (LIRC_CAN_SEND(d->features))) {
       err = lirc_allocate_buffer(irctls[minor]);
       if (err)
          lirc_unregister_driver(minor);


2. xu4_lirc_patch_1_add_odroid_gpio_irblaster.diff
Code: Select all
From 7579c602541d40d3228d66d54387f2714fab5f17 Mon Sep 17 00:00:00 2001
From: Joy Cho <joy.cho@hardkernel.com>
Date: Fri, 02 Jun 2017 11:33:01 +0900
Subject: [PATCH] staging/media: add odroid IR blaster driver with GPIO

Change-Id: I801d1e3f769e9c10c2fb19d8da5cda66a9ee2675
---

diff --git a/arch/arm/configs/odroidxu3_defconfig b/arch/arm/configs/odroidxu3_defconfig
index ca94dcb..dfda0c9 100644
--- a/arch/arm/configs/odroidxu3_defconfig
+++ b/arch/arm/configs/odroidxu3_defconfig
@@ -4583,7 +4583,14 @@
 CONFIG_STAGING_MEDIA=y
 # CONFIG_I2C_BCM2048 is not set
 # CONFIG_MEDIA_CEC is not set
-# CONFIG_LIRC_STAGING is not set
+CONFIG_LIRC_STAGING=y
+# CONFIG_LIRC_IMON is not set
+# CONFIG_LIRC_PARALLEL is not set
+# CONFIG_LIRC_SASEM is not set
+# CONFIG_LIRC_SERIAL is not set
+# CONFIG_LIRC_SIR is not set
+# CONFIG_LIRC_ZILOG is not set
+CONFIG_LIRC_ODROID=m
 
 #
 # Android
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index 6879c46..e5b5250 100644
--- a/drivers/staging/media/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
@@ -63,4 +63,17 @@
    help
      Driver for the Zilog/Hauppauge IR Transmitter, found on
      PVR-150/500, HVR-1200/1250/1700/1800, HD-PVR and other cards
+
+config LIRC_ODROID
+   tristate "GPIO based IR Transmitter for ODROID"
+   depends on LIRC
+   help
+     Say Y if you want to use GPIO-based IR transmitter
+     connected on one of expansion connectors
+     of ODROID-XU3/4 and C1/C2.
+
+     To compile this driver as a module, choose M here: the
+     module will be called lirc_odroid.
+
+     If unsure, say N.
 endif
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index 5430adf..b72cdc2 100644
--- a/drivers/staging/media/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
@@ -10,3 +10,4 @@
 obj-$(CONFIG_LIRC_SERIAL)   += lirc_serial.o
 obj-$(CONFIG_LIRC_SIR)      += lirc_sir.o
 obj-$(CONFIG_LIRC_ZILOG)   += lirc_zilog.o
+obj-$(CONFIG_LIRC_ODROID)   += lirc_odroid.o
diff --git a/drivers/staging/media/lirc/lirc_odroid.c b/drivers/staging/media/lirc/lirc_odroid.c
new file mode 100644
index 0000000..29c6dd0
--- /dev/null
+++ b/drivers/staging/media/lirc/lirc_odroid.c
@@ -0,0 +1,443 @@
+/*
+ * lirc_odroid.c
+ *
+ * lirc_odroid - Modified version from lirc_gpioblaster.c of OpenWrt.
+ *               taken from https://wiki.openwrt.org/doc/howto/lirc-gpioblaster
+ *
+ * Copyright (C) 2014 Qball Cow <qball@gmpclient.org>,
+ * Copyright (C) 2012 Aron Robert Szabo <aron@reon.hu>,
+ *                    Michael Bishop <cleverca22@gmail.com>
+ *
+ *  This driver has been modified to support ODROID-XU3/4 and C1/C2
+ *  and only supports IR transmitter.
+ *      Modified by Joy Cho <joy.cho@hardkernel.com>
+ *
+ *  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 2 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.
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/time.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/spinlock.h>
+#include <media/lirc.h>
+#include <media/lirc_dev.h>
+#include <linux/gpio.h>
+
+#define LIRC_DRIVER_NAME "lirc_odroid"
+
+#define RBUF_LEN 256
+#define LIRC_TRANSMITTER_LATENCY 50
+
+#ifndef MAX_UDELAY_MS
+#define MAX_UDELAY_US 5000
+#else
+#define MAX_UDELAY_US (MAX_UDELAY_MS*1000)
+#endif
+
+/* module parameters */
+/* set the default GPIO output pin */
+static int gpio_out_pin=24;
+/* enable debugging messages */
+static bool debug;
+
+/* softcarrier option : default on */
+static bool softcarrier = 1;
+/* 0 = do not invert output, 1 = invert output */
+static bool invert;
+
+/* forward declarations */
+static long send_pulse(unsigned long length);
+static void send_space(long length);
+static void lirc_odroid_exit(void);
+
+static struct platform_device *lirc_odroid_dev;
+static struct lirc_buffer rbuf;
+/* Fix spinlock bad magic issue */
+static spinlock_t lock = __SPIN_LOCK_UNLOCKED(lock);
+
+/* initialized/set in init_timing_params() */
+static unsigned int freq = 38000;
+static unsigned int duty_cycle = 50;
+static unsigned long period;
+static unsigned long pulse_width;
+static unsigned long space_width;
+
+static void safe_udelay(unsigned long usecs)
+{
+   while (usecs > MAX_UDELAY_US) {
+      udelay(MAX_UDELAY_US);
+      usecs -= MAX_UDELAY_US;
+   }
+   udelay(usecs);
+}
+
+static unsigned long read_current_us(void)
+{
+   struct timespec now;
+   getnstimeofday(&now);
+   return (now.tv_sec * 1000000) + (now.tv_nsec/1000);
+}
+
+static int init_timing_params(unsigned int new_duty_cycle,
+   unsigned int new_freq)
+{
+   /* Time unit of all parameters is microseconds unit.
+    * It's available for the case when base frequency is smaller
+    * than 1MHz.
+    */
+   duty_cycle = new_duty_cycle;
+   freq = new_freq;
+   period = 1000000L / freq;
+
+   /* duty cycle in percentage unit, duty_cycle 50 means 50% */
+   pulse_width = period * duty_cycle / 100;
+   space_width = period - pulse_width;
+
+   pr_info("in init_timing_params, freq=%d pulse=%ld, space=%ld\n",
+      freq, pulse_width, space_width);
+
+   return 0;
+}
+
+static long send_pulse_softcarrier(unsigned long length)
+{
+   int flag;
+   unsigned long actual, target;
+   unsigned long actual_us, initial_us, target_us;
+
+   actual = 0; target = 0; flag = 0;
+
+   actual_us = read_current_us();
+   /* length from lircd.conf is in us unit */
+   while (actual < length) {
+      if (flag) {
+         gpio_set_value(gpio_out_pin, invert);
+         target += space_width;
+      } else {
+         gpio_set_value(gpio_out_pin, !invert);
+         target += pulse_width;
+      }
+
+      initial_us = actual_us;
+      target_us = actual_us + (target - actual);
+
+      /*
+       * Note - we've checked in ioctl that the pulse/space
+       * widths are big enough so that d is > 0
+       */
+      if  ((int)(target_us - actual_us) > 0)
+         udelay(target_us - actual_us);
+
+      actual_us = read_current_us();
+      actual += (actual_us - initial_us);
+      flag = !flag;
+   }
+
+   return actual-length;
+}
+
+static long send_pulse(unsigned long length)
+{
+   if (length <= 0)
+      return 0;
+
+   if (softcarrier) {
+      return send_pulse_softcarrier(length);
+   } else {
+      gpio_set_value(gpio_out_pin, !invert);
+      safe_udelay(length);
+      return 0;
+   }
+}
+
+static void send_space(long length)
+{
+   gpio_set_value(gpio_out_pin, invert);
+   if (length <= 0)
+      return;
+   safe_udelay(length);
+}
+
+static int init_port(void)
+{
+   int ret;
+
+   if (gpio_request(gpio_out_pin, LIRC_DRIVER_NAME " ir/out")) {
+      pr_info(LIRC_DRIVER_NAME ": cant claim gpio pin %d\n",
+         gpio_out_pin);
+      ret = -ENODEV;
+      goto exit_init_port;
+   }
+
+   gpio_direction_output(gpio_out_pin, invert);
+   gpio_set_value(gpio_out_pin, invert);
+
+   return 0;
+
+exit_init_port:
+   gpio_free(gpio_out_pin);
+   return ret;
+}
+
+/* called when the character device is opened */
+static int set_use_inc(void *data)
+{
+   pr_info(LIRC_DRIVER_NAME " is opened\n");
+   return 0;
+}
+
+static void set_use_dec(void *data)
+{
+   pr_info(LIRC_DRIVER_NAME " is closed\n");
+}
+
+/*
+ * Header space pulse
+ * + pre_data space pulse pairs
+ * + key_codes space pulse pairs
+ */
+static ssize_t lirc_write(struct file *file, const char *buf,
+   size_t n, loff_t *ppos)
+{
+   int i, count;
+   unsigned long flags;
+   long delta = 0;
+   int *wbuf;
+
+   count = n / sizeof(int);
+   if (n % sizeof(int) || count % 2 == 0)
+      return -EINVAL;
+
+   wbuf = memdup_user(buf, n);
+   if (IS_ERR(wbuf))
+      return PTR_ERR(wbuf);
+   spin_lock_irqsave(&lock, flags);
+
+   /* refer to space and pulse duration for 'one','zero'
+      space first and then pulse */
+   for (i = 0; i < count; i++) {
+      if (i%2)
+         send_space(wbuf[i] - delta);
+      else
+         delta = send_pulse(wbuf[i]);
+   }
+   /* set default level after transmission */
+   gpio_set_value(gpio_out_pin, invert);
+
+   spin_unlock_irqrestore(&lock, flags);
+
+   kfree(wbuf);
+
+   return n;
+}
+
+static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+   int result;
+   __u32 value;
+
+   switch (cmd) {
+   case LIRC_GET_SEND_MODE:
+      return -ENOIOCTLCMD;
+      break;
+
+   case LIRC_SET_SEND_MODE:
+      result = get_user(value, (__u32 *) arg);
+      if (result)
+         return result;
+      /* only LIRC_MODE_PULSE supported */
+      if (value != LIRC_MODE_PULSE)
+         return -ENOSYS;
+      break;
+
+   case LIRC_GET_LENGTH:
+      return -ENOSYS;
+      break;
+
+   case LIRC_SET_SEND_DUTY_CYCLE:
+      result = get_user(value, (__u32 *) arg);
+      pr_info(LIRC_DRIVER_NAME " - SET_SEND_DUTY_CYCLE %d\n", value);
+      if (result)
+         return result;
+      if (value <= 0 || value > 100)
+         return -EINVAL;
+      return init_timing_params(value, freq);
+      break;
+
+   case LIRC_SET_SEND_CARRIER:
+      result = get_user(value, (__u32 *) arg);
+      pr_info(LIRC_DRIVER_NAME " - SET_SEND_CARRIER %d\n", value);
+      if (result)
+         return result;
+      if (value > 500000 || value < 20000)
+         return -EINVAL;
+      return init_timing_params(duty_cycle, value);
+      break;
+
+   default:
+      return lirc_dev_fop_ioctl(filep, cmd, arg);
+   }
+   return 0;
+}
+
+static const struct file_operations lirc_fops = {
+   .owner      = THIS_MODULE,
+   .write      = lirc_write,
+   .unlocked_ioctl   = lirc_ioctl,
+   .read      = lirc_dev_fop_read,
+   .poll      = lirc_dev_fop_poll,
+   .open      = lirc_dev_fop_open,
+   .release   = lirc_dev_fop_close,
+   .llseek      = no_llseek,
+};
+
+static struct lirc_driver driver = {
+   .name      = LIRC_DRIVER_NAME,
+   .minor      = -1,
+   .code_length   = 1,
+   .sample_rate   = 0,
+   .data      = NULL,
+   .add_to_buf   = NULL,
+   .rbuf      = &rbuf,
+   .set_use_inc   = set_use_inc,
+   .set_use_dec   = set_use_dec,
+   .fops      = &lirc_fops,
+   .dev      = NULL,
+   .owner      = THIS_MODULE,
+};
+
+static struct platform_driver lirc_odroid_driver = {
+   .driver = {
+      .name   = LIRC_DRIVER_NAME,
+      .owner  = THIS_MODULE,
+   },
+};
+
+static int __init lirc_odroid_init(void)
+{
+   int result;
+
+   /* Init read buffer. */
+   result = lirc_buffer_init(&rbuf, sizeof(int), RBUF_LEN);
+   if (result < 0)
+      return -ENOMEM;
+
+   result = platform_driver_register(&lirc_odroid_driver);
+   if (result) {
+      pr_info("lirc register returned %d\n", result);
+      goto exit_buffer_free;
+   }
+
+   lirc_odroid_dev = platform_device_alloc(LIRC_DRIVER_NAME, 0);
+   if (!lirc_odroid_dev) {
+      result = -ENOMEM;
+      goto exit_driver_unregister;
+   }
+
+   result = platform_device_add(lirc_odroid_dev);
+   if (result)
+      goto exit_device_put;
+
+   return 0;
+
+exit_device_put:
+   platform_device_put(lirc_odroid_dev);
+
+exit_driver_unregister:
+   platform_driver_unregister(&lirc_odroid_driver);
+
+exit_buffer_free:
+   lirc_buffer_free(&rbuf);
+
+   return result;
+}
+
+static void lirc_odroid_exit(void)
+{
+   pr_info(LIRC_DRIVER_NAME "[%s]\n", __func__);
+   gpio_free(gpio_out_pin);
+   platform_device_unregister(lirc_odroid_dev);
+   platform_driver_unregister(&lirc_odroid_driver);
+   lirc_buffer_free(&rbuf);
+}
+
+static int __init lirc_odroid_init_module(void)
+{
+   int result;
+
+   result = lirc_odroid_init();
+   if (result)
+      return result;
+
+   result = init_port();
+   if (result < 0) {
+      pr_info(LIRC_DRIVER_NAME ": init port fail!\n");
+      goto exit_odroid;
+   }
+
+   /* check if the module received valid gpio pin numbers */
+   driver.features = LIRC_CAN_SET_SEND_DUTY_CYCLE |
+           LIRC_CAN_SET_SEND_CARRIER |
+           LIRC_CAN_SEND_PULSE;
+
+   driver.dev = &lirc_odroid_dev->dev;
+   driver.minor = lirc_register_driver(&driver);
+
+   if (driver.minor < 0) {
+      pr_info(LIRC_DRIVER_NAME ": device registration failed with %d\n",
+         result);
+      result = -EIO;
+      goto exit_odroid;
+   }
+
+   pr_info(LIRC_DRIVER_NAME ": driver registered!\n");
+
+   return 0;
+
+exit_odroid:
+   lirc_odroid_exit();
+
+   return result;
+}
+
+static void __exit lirc_odroid_exit_module(void)
+{
+   lirc_odroid_exit();
+
+   lirc_unregister_driver(driver.minor);
+   pr_info(LIRC_DRIVER_NAME ": cleaned up module\n");
+}
+
+module_init(lirc_odroid_init_module);
+module_exit(lirc_odroid_exit_module);
+
+MODULE_DESCRIPTION("GPIO based IR Transmitter driver for Odroid XU3/4 and C1/C2");
+MODULE_AUTHOR("Joy Cho <joy.cho@hardkernel.com>");
+MODULE_LICENSE("GPL");
+
+module_param(gpio_out_pin, int, S_IRUGO);
+MODULE_PARM_DESC(gpio_out_pin, "GPIO output/transmitter pin number");
+
+module_param(softcarrier, bool, S_IRUGO);
+MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
+
+module_param(invert, bool, S_IRUGO);
+MODULE_PARM_DESC(invert, "Invert output (0 = off, 1 = on, default off");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging messages");
Attachments
xu4_lirc_patch_2_fix_lirc_buffer_allocation_fault.diff.zip
(695 Bytes) Downloaded 47 times
xu4_lirc_patch_1_add_odroid_gpio_irblaster.diff.zip
(4.56 KiB) Downloaded 44 times
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby joy » Wed Jun 14, 2017 8:53 pm

And if you've confirmed your hardware with C2 and 38KHz center frequency,
it must work with the hardware and XU4, I think.

The center frequency of this lirc_odroid driver is fixed as 38KHz, too.
I'm not sure if you've already tried them by adjusting the driver code.

If you need other conditions, please let us know.
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed Jun 14, 2017 8:59 pm

Thank you joy!
I will give it a try on a development xu4 and an oscilloscope on the gpio pin (for now), but I plan on moving it to production in a couple of weeks (need to get knee surgery in a week and will have a bit of time to play during recovery).

I see the second patch adds the original code that was on the 3.10 kernel, right? And the first patch fixes it.

Regarding the carrier frequency - I'm actually not sure how that works. Is the GPIO generating a sine wave with a 38kHz frequency? That's not what I see with an oscilloscope. Also, my setup doesn't have any component that can do a 38KHz modulation (apart from the diodes themselves - assuming that the diodes can produce a 38kHz signal by themselves). So - from what I can infer - the GPIO turns on/off with a low frequency - and the receiver is able to receive it. Most likely the receiver doesn't have a pass-band filter around 38kHz and can pick up other signals as well.
So, yes, I was able to use the C2 to inject the ir codes with the same hardware, but I'm able to only inject one command after which lirc seems to hang and needs to be restarted as a process. Afterwards I can inject a different command.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby tobetter » Wed Jun 14, 2017 9:42 pm

@mad_ady, maybe I am wrong. As I remember the carrirer freq 38kHz is not sine wave, it's the bit pulse of same duration for the pulse of IR protocol, for example, if the pulse width is 10ms then in 10ms there are many pulses with 38kHz. Actually how I did very long time ago is to use NE555 for carrier freq and reset it with IR bit stream. Eventually single IR transmit LED is connected to NE555 with low resistor , so it can reach more far.

Anyway, sorry to hear you need knee surgery, take care of yourself.
tobetter
 
Posts: 2079
Joined: Mon Feb 25, 2013 10:55 am
Location: Kitchener, ON, Canada
languages_spoken: Korean, English
ODROIDs: X, X2, U2, U3, XU3, C1

Re: IR blaster for an AC unit

Unread postby mad_ady » Wed Jun 14, 2017 10:31 pm

Well, if it's not a sine wave, then the gpio could flip at 38kHz and I wouldn't see it on my oscilloscope because I didn't use the correct time base. It would make sense. I'll see if I can view a 38kHz square signal with my USB oscilloscope :)

Update: You were right, @tobetter - the carrier had a square wave. I had no idea, thanks for enlightening me :)
Image

I'm guessing the kernel module takes care of generating the 38kHz on/off pattern for the duration of a "1".
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby joy » Thu Jun 15, 2017 9:25 am

mad_ady wrote:Well, if it's not a sine wave, then the gpio could flip at 38kHz and I wouldn't see it on my oscilloscope because I didn't use the correct time base. It would make sense. I'll see if I can view a 38kHz square signal with my USB oscilloscope :)

Update: You were right, @tobetter - the carrier had a square wave. I had no idea, thanks for enlightening me :)
Image

I'm guessing the kernel module takes care of generating the 38kHz on/off pattern for the duration of a "1".

No, the output signal is not sine wave, but should be the square signal form, as tobetter pointed out. (Thank you, Dennis!)
And you already found the correct signal example. :)
Also refer to the following link.
https://www.laser.com/dhouston/ir-rf_fundamentals.html

And one more about 'softcarrier',
it means the filling signals, so softcarrier should be on as '1' in this driver.
Code: Select all
module_param(softcarrier, bool, S_IRUGO);
MODULE_PARM_DESC(softcarrier, "Software carrier (0 = off, 1 = on, default on)");
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby joy » Thu Jun 15, 2017 9:52 am

mad_ady wrote:I see the second patch adds the original code that was on the 3.10 kernel, right? And the first patch fixes it.

Yes, right.
It's the same driver with the 3.10 kernel. Just gpio port initial value is different.
And another patch can fix the kernel panic with kernel 4.9 lirc dev.
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby mad_ady » Thu Jun 15, 2017 4:40 pm

Thanks joy. Yes, that document cleared up my misconceptions, thanks.
I was able to use the HK Oscilloscope to actually see the pulse trains, which is neat:
Image
This means one more thing - since the Oscilloscope is doing sampling when using a higher time base, I can't use it to reconstruct the signal - since I would be sampling a square wave signal with a period of about 25us. So, all my oscilloscope screenshots above are worthless. Well, at least I learned something new - where not to use the oscilloscope.

I also tried joy's patches and - they work on kernel 4.9.30! Yay! The only thing missing is enabling the module in the kernel config:
Code: Select all
CONFIG_LIRC_STAGING=Y
CONFIG_LIRC_ODROID=Y

Also, two chunks didn't apply correctly and I had to add them manually (for the Makefile and the KConfig).

When using the module I can send a pulse, I can see it on the oscilloscope, but when I send the second pulse with irsend, I get an "irsend: timeout" error. After 1-2 seconds, I can see the pulse on the oscilloscope - so it probably gets sent. If I send another one, again, it can take up to 5 seconds for it to send and I get a irsend: timeout error. If I restart lirc, the first code gets sent immediately. I noticed the same behavior with the C2 as well - not sure where the problem is. I can live with it - for my use case I can simply restart lirc after every command.
So - joy - you can push your patches in the 4.9 kernel and I'll be testing them on real hardware in the following weeks.
Thanks!
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby joy » Thu Jun 15, 2017 6:29 pm

mad_ady wrote:Thanks joy. Yes, that document cleared up my misconceptions, thanks.
I was able to use the HK Oscilloscope to actually see the pulse trains, which is neat:

This means one more thing - since the Oscilloscope is doing sampling when using a higher time base, I can't use it to reconstruct the signal - since I would be sampling a square wave signal with a period of about 25us. So, all my oscilloscope screenshots above are worthless. Well, at least I learned something new - where not to use the oscilloscope.

Thank you for checking the patches and sharing your status, mad_ady! :)
I think I can also try to catch the signals using my oscilloscope, maybe next week,
and it can be helpful to confirm the signals and analyze them as a reference.
( I've captured the signals before when I built-up lirc_odroid driver for odroid-c2 first.
so I tried to find the pictures but it seems I deleted them all. :( )

mad_ady wrote:I also tried joy's patches and - they work on kernel 4.9.30! Yay! The only thing missing is enabling the module in the kernel config:
Code: Select all
CONFIG_LIRC_STAGING=Y
CONFIG_LIRC_ODROID=Y

Also, two chunks didn't apply correctly and I had to add them manually (for the Makefile and the KConfig).

When using the module I can send a pulse, I can see it on the oscilloscope, but when I send the second pulse with irsend, I get an "irsend: timeout" error. After 1-2 seconds, I can see the pulse on the oscilloscope - so it probably gets sent. If I send another one, again, it can take up to 5 seconds for it to send and I get a irsend: timeout error. If I restart lirc, the first code gets sent immediately. I noticed the same behavior with the C2 as well - not sure where the problem is. I can live with it - for my use case I can simply restart lirc after every command.
So - joy - you can push your patches in the 4.9 kernel and I'll be testing them on real hardware in the following weeks.
Thanks!

I've encountered the same error, "irsend: timeout" on odrid-c2 before, but now I can't reproduce it nor recall the cause.

Can I check some to make sure?
(1) Do you still have the same error with C2 every initial stage?
(2) And on XU4 kernel, same issue?

If you have the same issue till you try it on real hardware and XU4 in following weeks, please let us know.

And as you mentioned, I will merge the patches in xu4 kernel 4.9 and share the release version here.

Thanks!
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby joy » Tue Jun 20, 2017 4:36 pm

Hi, :)
The version, 4.9.33-42 has been released
and the related patches are also included since the version.

Code: Select all
root@odroid:~# uname -a
Linux odroid 4.9.33-42 #1 SMP PREEMPT Tue Jun 20 05:17:06 UTC 2017 armv7l armv7l armv7l GNU/Linux
joy
 
Posts: 336
Joined: Fri Oct 02, 2015 1:44 pm
languages_spoken: english
ODROIDs: ODROID-C1+, XU4, X

Re: IR blaster for an AC unit

Unread postby mad_ady » Tue Jun 20, 2017 8:38 pm

Thank you! I've compiled it and IR seems to work. Thanks for your effort!
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Thu Jun 29, 2017 10:48 pm

Ok, I've moved the IR blaster over to the "production" XU4 and injecting IR signals totally works. Thank you for your help!

Back to my original problem regarding the scancodes I recorded, if you remember I managed to get it to work with @rooted's irplus codes, but not with mine. This time I tested it by injecting the codes I had recorded but I sent them when the unit was on. And it seems my codes work as well! Except I didn't specifically record a "power on" signal, thinking it would exist in every packet. It seems it doesn't (the off command I recorded works just fine).

So, instead of re-recording the codes I will be using the codes from irplus. I will also record a few additional signals for Jet Mode, Swing, Silent operation and Ionizer.

Next (maybe tomorrow), I will try to build a script that can control it through mqtt and integrate it in my Home Automation setup.
I'll keep you posted.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby mad_ady » Fri Jul 07, 2017 8:24 pm

Ok, some feedback. I created the mqtt script and integrated the AC unit into Home Assistant. I had to add some automations for things like - when Jet mode is on, set temperature slider to 18C and Fan mode to High, so that it reflects reality.

The mqtt agent and Home Assistant code is here:
https://github.com/mad-ady/home-assista ... t-agent.py
https://github.com/mad-ady/home-assista ... onfig.yaml
https://github.com/mad-ady/home-assista ... tions.yaml

Here's a screenshot of the user interface:
Image

And here it is in action:
https://youtu.be/zGRlhILVRCQ
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby odroid » Sat Jul 08, 2017 9:35 am

Nice Web UI :o
Very useful project since it is very hot here Korea too. :D
User avatar
odroid
Site Admin
 
Posts: 24992
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID

Re: IR blaster for an AC unit

Unread postby mad_ady » Sat Jul 08, 2017 1:19 pm

The best thing about the web ui is that I had nothing to do with it! It comes with Home Assistant.
User avatar
mad_ady
 
Posts: 2746
Joined: Wed Jul 15, 2015 5:00 pm
Location: Bucharest, Romania
languages_spoken: english
ODROIDs: XU4, C1+, C2

Re: IR blaster for an AC unit

Unread postby odroid » Sat Jul 08, 2017 2:09 pm

Yeah~ The Home Assistant is very useful open-source project for Home Automation.
https://home-assistant.io/
User avatar
odroid
Site Admin
 
Posts: 24992
Joined: Fri Feb 22, 2013 11:14 pm
languages_spoken: English
ODROIDs: ODROID

Next

Return to The Ideas

Who is online

Users browsing this forum: No registered users and 2 guests