For a while I have been running XBMC 13.0 on CentOS-6. I turns out that there is a known issue in that version which prevents it from playing .m4a files.
The solution is to upgrade to 13.2 which for me means rebuilding a new RPM.
For you, that means downloading the new version from http://www.chrysocome.net/downloads/xbmc-13.2-1.el6.x86_64.rpm
And don't forget to get the deps from http://rpmfusion.org/ and EPEL.
Showing posts with label Digital ORB. Show all posts
Showing posts with label Digital ORB. Show all posts
Wednesday, November 5, 2014
Friday, May 23, 2014
Arduino IR Blaster
My IR blaster is built on a LeoStick which is an arduino compatible USB stick. I must be a sucker for punishment because I thought it would be easy to make one of the many IR libraries work on here and control my Samsung TV.
There were two problems with my plan. First, the defacto IR libraries don't allow me to use the necessary IO pins and second, Samsung IR codes are not supported.
Rather than detail what when wrong, I will present my solutions.
The first problem arises because the LeoStick has a green LED attached to Digital IO pin 9 which is the default PWM Timer used by Ken Shirriff's IR library. The solution is an updated fork of this library Chris Young which implements more Timer chips and enables selecting Digital IO pin 5. Do to that, edit IRLibTimer.h and find the section with the heading 'it's probably Leonardo' (the LeoStick is apparently compatible with the Leonardo). Comment out the default #define and uncomment the IR_USE_TIMER3. (I wonder why we can't select this at run time?). Based on the IRLib manual, I also installed my IR LED with whatever resistors I had on hand (470 ohm I think).
So, thanks to the hard work of these guys, I have got my LED working. Now, to make it talk Samsung protocol.
There were a few snippits of code in various forums but I had to piece that together into the format for IRLib. I have only added sending as I already have a list of codes from SamyGO and LIRC. The only code I wanted to use is TV_POWER 0xE0E040BF because once the TV is on, I can talk to it via the network.
I have submitted my changes as a GitHub pull request. If they are not accepted in the upstream library you can find them here https://github.com/jnewbigin/IRLib
The final piece to the puzzle is making the IR code send when I want it to. To keep this generic, I made my sketch read a hexadecimal code from the serial port. When it receives a code it just send it, thus allowing control over the time and the code. This could probably be integrated with LIRC but I am just using a simple shell command
echo 0xE0E040BF > /dev/ttyACM0
So here is my sketch. There is not much error detection in the serial reading but what is the worst that can go wrong?
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
* Version 1.3 January 2014
* Copyright 2014 by Chris Young http://cyborg5.com
* Based on original example sketch for IRremote library
* Version 0.11 September, 2009
* Copyright 2009 Ken Shirriff
* http://www.righto.com/
*
* Modified by John Newbigin to support Samsung and USB control May 2014
*/
#include <IRLib.h>
IRsend My_Sender;
void setup()
{
Serial.begin(9600);
}
void p(char *fmt, ... ){
char buf[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(buf, 128, fmt, args);
va_end (args);
Serial.print(buf);
}
// 0xE0E040BF = Power
void sendCode(unsigned long code)
{
p("Sending SAMSUNG 0x%08lx\n", code);
for (int i = 0; i < 3; i++)
{
My_Sender.send(SAMSUNG, code, 0);
delay(30);
}
}
unsigned long ir_code = 0;
void loop() {
while(Serial.available() <= 0)
{
delay(10);
}
int incomingByte = Serial.read();
int nibble = -1;
if(incomingByte == 10)
{
p("Got newline\n");
sendCode(ir_code);
ir_code = 0;
}
else if(incomingByte == 13)
{
// ignore
}
else if(incomingByte >= '0' && incomingByte <= '9')
{
nibble = incomingByte - '0';
p("Got digit %d\n", nibble);
}
else if(incomingByte >= 'a' && incomingByte <= 'f')
{
nibble = incomingByte - 'a' + 10;
p("Got hex digit %d\n", nibble);
}
else if(incomingByte >= 'A' && incomingByte <= 'F')
{
nibble = incomingByte - 'A' + 10;
p("Got hex digit %d\n", nibble);
}
else if(incomingByte = 'x')
{
p("Starting number\n");
ir_code = 0;
}
else
{
p("Got %d\n", incomingByte);
}
if(nibble >= 0)
{
ir_code<<= 4;
ir_code+= nibble;
p("Code is 0x%08lx\n", ir_code);
}
}
There were two problems with my plan. First, the defacto IR libraries don't allow me to use the necessary IO pins and second, Samsung IR codes are not supported.
Rather than detail what when wrong, I will present my solutions.
The first problem arises because the LeoStick has a green LED attached to Digital IO pin 9 which is the default PWM Timer used by Ken Shirriff's IR library. The solution is an updated fork of this library Chris Young which implements more Timer chips and enables selecting Digital IO pin 5. Do to that, edit IRLibTimer.h and find the section with the heading 'it's probably Leonardo' (the LeoStick is apparently compatible with the Leonardo). Comment out the default #define and uncomment the IR_USE_TIMER3. (I wonder why we can't select this at run time?). Based on the IRLib manual, I also installed my IR LED with whatever resistors I had on hand (470 ohm I think).
So, thanks to the hard work of these guys, I have got my LED working. Now, to make it talk Samsung protocol.
There were a few snippits of code in various forums but I had to piece that together into the format for IRLib. I have only added sending as I already have a list of codes from SamyGO and LIRC. The only code I wanted to use is TV_POWER 0xE0E040BF because once the TV is on, I can talk to it via the network.
I have submitted my changes as a GitHub pull request. If they are not accepted in the upstream library you can find them here https://github.com/jnewbigin/IRLib
The final piece to the puzzle is making the IR code send when I want it to. To keep this generic, I made my sketch read a hexadecimal code from the serial port. When it receives a code it just send it, thus allowing control over the time and the code. This could probably be integrated with LIRC but I am just using a simple shell command
echo 0xE0E040BF > /dev/ttyACM0
So here is my sketch. There is not much error detection in the serial reading but what is the worst that can go wrong?
/* Example program for from IRLib – an Arduino library for infrared encoding and decoding
* Version 1.3 January 2014
* Copyright 2014 by Chris Young http://cyborg5.com
* Based on original example sketch for IRremote library
* Version 0.11 September, 2009
* Copyright 2009 Ken Shirriff
* http://www.righto.com/
*
* Modified by John Newbigin to support Samsung and USB control May 2014
*/
#include <IRLib.h>
IRsend My_Sender;
void setup()
{
Serial.begin(9600);
}
void p(char *fmt, ... ){
char buf[128]; // resulting string limited to 128 chars
va_list args;
va_start (args, fmt );
vsnprintf(buf, 128, fmt, args);
va_end (args);
Serial.print(buf);
}
// 0xE0E040BF = Power
void sendCode(unsigned long code)
{
p("Sending SAMSUNG 0x%08lx\n", code);
for (int i = 0; i < 3; i++)
{
My_Sender.send(SAMSUNG, code, 0);
delay(30);
}
}
unsigned long ir_code = 0;
void loop() {
while(Serial.available() <= 0)
{
delay(10);
}
int incomingByte = Serial.read();
int nibble = -1;
if(incomingByte == 10)
{
p("Got newline\n");
sendCode(ir_code);
ir_code = 0;
}
else if(incomingByte == 13)
{
// ignore
}
else if(incomingByte >= '0' && incomingByte <= '9')
{
nibble = incomingByte - '0';
p("Got digit %d\n", nibble);
}
else if(incomingByte >= 'a' && incomingByte <= 'f')
{
nibble = incomingByte - 'a' + 10;
p("Got hex digit %d\n", nibble);
}
else if(incomingByte >= 'A' && incomingByte <= 'F')
{
nibble = incomingByte - 'A' + 10;
p("Got hex digit %d\n", nibble);
}
else if(incomingByte = 'x')
{
p("Starting number\n");
ir_code = 0;
}
else
{
p("Got %d\n", incomingByte);
}
if(nibble >= 0)
{
ir_code<<= 4;
ir_code+= nibble;
p("Code is 0x%08lx\n", ir_code);
}
}
Friday, January 17, 2014
NVIDIA GPU Temp
On my old TV setup I used nvclock to get the NVIDIA GPU temperature and graph it using rrdtool (along with other temperatures and fan speeds).
nvclock was always a bit of a hack and does not work any more (at least, it won't do anything useful for me).
I know the nvidia-settings tool can display the temperature (and much more information) so there must be a modern way to access this data. A quick google showed up the nvidia-smi tool.
Quick and dirty,
nvidia-smi -q | grep Temperature -A 1
will show the current temperature.
Temperature
Gpu : 72 C
Interestingly, the output can also be in XML format. Combined with some xslt magic, it is possible to get the temperature in a more structured way.
echo '<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='text'/>
<xsl:template match="/">
<xsl:for-each select="//gpu_temp">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
' > nvidia-temp.xml
nvidia-smi --dtd > nvsmi_device_v6.dtd
nvidia-smi -q -x | xsltproc nvidia-temp.xml -
Note: Your driver might be using a different dtd version. Adjust as required. (nvidia-smi --dtd | head -1 | cut -d ' ' -f 2 will give the correct name)
If you have multiple cards and want to know which card has which temperature then you can alter the xsl to format it as you require with something like
<xsl:value-of select="ancestor::gpu/@id"/> or <xsl:value-of select="ancestor::gpu/uuid"/>
eg
0000:04:00.0 Quadro K2000 31 C
0000:05:00.0 Quadro K2000 32 C
nvclock was always a bit of a hack and does not work any more (at least, it won't do anything useful for me).
I know the nvidia-settings tool can display the temperature (and much more information) so there must be a modern way to access this data. A quick google showed up the nvidia-smi tool.
Quick and dirty,
nvidia-smi -q | grep Temperature -A 1
will show the current temperature.
Temperature
Gpu : 72 C
Interestingly, the output can also be in XML format. Combined with some xslt magic, it is possible to get the temperature in a more structured way.
echo '<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='text'/>
<xsl:template match="/">
<xsl:for-each select="//gpu_temp">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
' > nvidia-temp.xml
nvidia-smi --dtd > nvsmi_device_v6.dtd
nvidia-smi -q -x | xsltproc nvidia-temp.xml -
Note: Your driver might be using a different dtd version. Adjust as required. (nvidia-smi --dtd | head -1 | cut -d ' ' -f 2 will give the correct name)
If you have multiple cards and want to know which card has which temperature then you can alter the xsl to format it as you require with something like
<xsl:value-of select="ancestor::gpu/@id"/> or <xsl:value-of select="ancestor::gpu/uuid"/>
eg
0000:04:00.0 Quadro K2000 31 C
0000:05:00.0 Quadro K2000 32 C
Friday, January 10, 2014
The new TV is almost here
Now that summer has hit, it is time to head indoors and tinker with the TV. Some clever planning when I last upgraded the disk in my CentOS-4 machine meant that the required partitions and space for CentOS-6 was available without having to alter anything.
That meant that installing CentOS-6 was relatively easy. (I did it the hard way and PXE booted off the work server via VPN). After a minimal install I configured the machine in puppet and managed to leverage most of my Linux SOE config.
After that was finished, I had a workstation but not a TV. Next step XBMC. That installed without any trouble but would not play any audio and the video kept going choppy. Not what I was expecting.
The choppy video was being caused by high load caused by the sosreport program. I don't know what crashed, and I don't much care. There is no point sending me an email about it.
I remember wrestling with this in the past without any satisfactory result. This time, rpm --erase sos did the trick. (I have to make sure puppet does not put it back.).
The audio seemed to be a problem with PulseAudio. I don't much care for this either. I have never needed it before and it does not appear to support S/PDIF / EC958 which I need so it has to go. Once again, no satisfactory instructions so rpm --erase alsa-plugins-pulseaudio seems required.
After a restart (I hate that!), all traces of pulseaudio are gone and XBMC is offering me S/PDIF again. Audio and video now working.
Next hurdle, Remote Controls. I have lots of experience with LIRC in the past because I had to make some modifications to the old version to get it to do everything I wanted. As hoped, there has been some improvement in this area but alas, also some steps backwards.
The first remote is a DVICO Fusion remote. This is a supported model but requires configuration in /etc/sysconfig/lirc and /etc/lirc/lircd.conf
/etc/sysconfig/lirc wants to know the device but it is a dynamically assigned USB HID device. This means UDEV rules ahead. It would be ideal if LIRC came with these but it seems not. Luckily I have my old EL4 rule but the new new udev uses a new format for rules. This was what I came up with in the end:
/etc/udev/rules.d/20-dvico.rules
SUBSYSTEM!="usb", GOTO="end"
KERNEL!="hiddev*", GOTO="end"
ATTRS{idVendor}=="0fe9", ATTRS{idProduct}=="9010", SYMLINK+="dvico"
LABEL="end"
Now I can configure lirc and it should work reliably (unless I have two receivers, which I do but I only use one!).
Copy the lircd.conf config file from the files supplied in lirc-remotes and that is ready to go.
It seems I still need to build a Lircmap.xml file for XBMC before it will work there. Lets hope I can find a sample on the internet. Writing XML by hand is not what I call fun.
The next challenge with LIRC is my IR Blaster which controls the stereo. This uses the kernel driver called lirc_serial. I understand that this is not an enterprise solution but if lirc_dev can be in the kernel, why no lirc_serial? Well, no worries, perhaps I'll find a package which has the driver. I do require that the driver will work after a kernel update so the atrpms package is no good. And is is only version 0.8 and I am using LIRC 0.9 (may not be an issue but I want them to match).
I guess I'll just build one myself. Enter a world of 'lirc_serial: disagrees about version of symbol' errors. Briefly, some lirc drivers are now in the EL6 kernel. lirc_serial depends on lirc_dev. The lirc_dev in the kernel is back ported so checking kernel version numbers for the correct API does not work reliably. Also, modversions seem to be cached so once the errors are fixed, the resulting module still does not work.
Finally, I abandoned the LIRC build scripts and went straight to the kernel Makefile. After tweaking a few #defines I had a working build. I then packages in into an elrepo style kmod package and now I have a working ilrc_serial driver (which you can download from http://www.chrysocome.net/download). LIRC does not come with the definition for Panasonic remotes but I have the old one on hand which still works (yay). The LIRC init script does not handle starting multiple instances so I will have to hack that up too. At least I can specify the location of the .pid file which I think was a show stopper in the old version.
The next job is to work out if I can use my IR Blaster to turn the TV on too. For a SMART TV, there are not many options for turning it on...
That meant that installing CentOS-6 was relatively easy. (I did it the hard way and PXE booted off the work server via VPN). After a minimal install I configured the machine in puppet and managed to leverage most of my Linux SOE config.
After that was finished, I had a workstation but not a TV. Next step XBMC. That installed without any trouble but would not play any audio and the video kept going choppy. Not what I was expecting.
The choppy video was being caused by high load caused by the sosreport program. I don't know what crashed, and I don't much care. There is no point sending me an email about it.
I remember wrestling with this in the past without any satisfactory result. This time, rpm --erase sos did the trick. (I have to make sure puppet does not put it back.).
The audio seemed to be a problem with PulseAudio. I don't much care for this either. I have never needed it before and it does not appear to support S/PDIF / EC958 which I need so it has to go. Once again, no satisfactory instructions so rpm --erase alsa-plugins-pulseaudio seems required.
After a restart (I hate that!), all traces of pulseaudio are gone and XBMC is offering me S/PDIF again. Audio and video now working.
Next hurdle, Remote Controls. I have lots of experience with LIRC in the past because I had to make some modifications to the old version to get it to do everything I wanted. As hoped, there has been some improvement in this area but alas, also some steps backwards.
The first remote is a DVICO Fusion remote. This is a supported model but requires configuration in /etc/sysconfig/lirc and /etc/lirc/lircd.conf
/etc/sysconfig/lirc wants to know the device but it is a dynamically assigned USB HID device. This means UDEV rules ahead. It would be ideal if LIRC came with these but it seems not. Luckily I have my old EL4 rule but the new new udev uses a new format for rules. This was what I came up with in the end:
/etc/udev/rules.d/20-dvico.rules
SUBSYSTEM!="usb", GOTO="end"
KERNEL!="hiddev*", GOTO="end"
ATTRS{idVendor}=="0fe9", ATTRS{idProduct}=="9010", SYMLINK+="dvico"
LABEL="end"
Now I can configure lirc and it should work reliably (unless I have two receivers, which I do but I only use one!).
Copy the lircd.conf config file from the files supplied in lirc-remotes and that is ready to go.
It seems I still need to build a Lircmap.xml file for XBMC before it will work there. Lets hope I can find a sample on the internet. Writing XML by hand is not what I call fun.
The next challenge with LIRC is my IR Blaster which controls the stereo. This uses the kernel driver called lirc_serial. I understand that this is not an enterprise solution but if lirc_dev can be in the kernel, why no lirc_serial? Well, no worries, perhaps I'll find a package which has the driver. I do require that the driver will work after a kernel update so the atrpms package is no good. And is is only version 0.8 and I am using LIRC 0.9 (may not be an issue but I want them to match).
I guess I'll just build one myself. Enter a world of 'lirc_serial: disagrees about version of symbol' errors. Briefly, some lirc drivers are now in the EL6 kernel. lirc_serial depends on lirc_dev. The lirc_dev in the kernel is back ported so checking kernel version numbers for the correct API does not work reliably. Also, modversions seem to be cached so once the errors are fixed, the resulting module still does not work.
Finally, I abandoned the LIRC build scripts and went straight to the kernel Makefile. After tweaking a few #defines I had a working build. I then packages in into an elrepo style kmod package and now I have a working ilrc_serial driver (which you can download from http://www.chrysocome.net/download). LIRC does not come with the definition for Panasonic remotes but I have the old one on hand which still works (yay). The LIRC init script does not handle starting multiple instances so I will have to hack that up too. At least I can specify the location of the .pid file which I think was a show stopper in the old version.
The next job is to work out if I can use my IR Blaster to turn the TV on too. For a SMART TV, there are not many options for turning it on...
Friday, November 1, 2013
XBMC on CentOS 6
After years of putting it off I have finally taken the plunge into XBMC.
My plan is to hook it up as a front end for the Digital ORB pvr.
RpmFusion have packages for XBMC version 11 for CentOS 6. This is a good start as many of the audio & video packages from RpmForge (which I am sure most CentOS 6 users have) are too old for XBMC.
Unfortunately there is no package for XBMC version 12 which apparently has much better pvr support. The bug database entry suggested that it would be relatively easy to fix... and it was https://bugzilla.rpmfusion.org/show_bug.cgi?id=2699
So now I have a relatively stable base to start my integration. Lets hope that I get it working before XBMC version 13 comes out and changes everything again.
If you want to run XBMC yourself, you will need my xbmc and taglib packages from http://www.chrysocome.net/downloads and any dependencies from rpmfusion and epel.
You can also get the Digital ORB from my downloads directory. It does come with instructions but has not been widely tested yet. Stay tuned.
My plan is to hook it up as a front end for the Digital ORB pvr.
RpmFusion have packages for XBMC version 11 for CentOS 6. This is a good start as many of the audio & video packages from RpmForge (which I am sure most CentOS 6 users have) are too old for XBMC.
Unfortunately there is no package for XBMC version 12 which apparently has much better pvr support. The bug database entry suggested that it would be relatively easy to fix... and it was https://bugzilla.rpmfusion.org/show_bug.cgi?id=2699
So now I have a relatively stable base to start my integration. Lets hope that I get it working before XBMC version 13 comes out and changes everything again.
If you want to run XBMC yourself, you will need my xbmc and taglib packages from http://www.chrysocome.net/downloads and any dependencies from rpmfusion and epel.
You can also get the Digital ORB from my downloads directory. It does come with instructions but has not been widely tested yet. Stay tuned.
Subscribe to:
Posts (Atom)