< async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"">

Sunday, December 29, 2013

Wirelessly send strings to 8*8 led matrix with NRF24L01 Transceiver- scrolling tweets

Using wireless connectivity in arduino project is really cool and can be easily achived with small cost effective nrf2401 modules. Most of the examples shows sending integer or float values but the module can send or receive strings and floats. Here is a small project which is based on a serial chat from Stanley. In this case am sending a set of strings from an arduino attached to a raspberry pi ( you could directly attach an nrf24l01 to the pi, more on it later) and the string (for eg tweets from a local news paper) will be wirelessly send to my scrolling 8*8 led matrix placed on the kitchen.




There are two parts. One arduino with nrf module is connected to a raspberry pi and receives the strings over serial and is achieved with python serial as follows (basic block is shown)

#!/usr/bin/python
import serial
import sys
ser = serial.Serial('/dev/ttyACM0', 9600)
ser.write("string goes here.......")


Sources - Raspberry-serial-arduino transmit part (it can receive as well!)

/* credits to Author : Stanley Seow
e-mail : [email protected] 
modified for dotmatrix led 
This will send a string from the Raspberry pi or PC to a remote NRF24l01 connected 8*8 led matrix
On the raspberry pi you can use pyserial to write to the arduino

Connecting the rf module is same as my previos post

See here http://blog.riyas.org/2013/12/working-quick-start-guide-for-nrf24l01.html

*/

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
RF24 radio(9,10);
const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };
boolean stringComplete = false;  
static int dataBufferIndex = 0;
boolean stringOverflow = false;
char charOverflow = 0;
char SendPayload[31] = "";
char RecvPayload[31] = "";
char serialBuffer[31] = "";

void setup(void) {
 
  Serial.begin(9600);
  analogReference(INTERNAL);
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
  radio.printDetails(); 
  delay(500);

}

void loop(void) {   
  
  nRF_receive();
  serial_receive();
  
} 
void serialEvent() {
  while (Serial.available() > 0 ) {
      char incomingByte = Serial.read();
      
      if (stringOverflow) {
         serialBuffer[dataBufferIndex++] = charOverflow;  // Place saved overflow byte into buffer
         serialBuffer[dataBufferIndex++] = incomingByte;  // saved next byte into next buffer
         stringOverflow = false;                          // turn overflow flag off
      } else if (dataBufferIndex > 31) {
         stringComplete = true;        // Send this buffer out to radio
         stringOverflow = true;        // trigger the overflow flag
         charOverflow = incomingByte;  // Saved the overflow byte for next loop
         dataBufferIndex = 0;          // reset the bufferindex
         break; 
      } 
      else if(incomingByte=='\n'){
          serialBuffer[dataBufferIndex] = 0; 
          stringComplete = true;
      } else {
          serialBuffer[dataBufferIndex++] = incomingByte;
          serialBuffer[dataBufferIndex] = 0; 
      }          
  } 
} 

void nRF_receive(void) {
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    RecvPayload[0] = 0;  // Clear the buffers
  }  

} 

void serial_receive(void){
  
  if (stringComplete) {
        strcat(SendPayload,serialBuffer);      
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        bool ok = radio.write(&SendPayload,strlen(SendPayload));
        stringComplete = false;
        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  
        SendPayload[0] = 0;
        dataBufferIndex = 0;
        
  } 
}    


Here is the led matrix receiver
 Library Timed action can be downloaded here (and details are here )

/*
Serial string receiving arduino with an 8*8 led matrix to show the text
wiring of nrf24l01 is same as the buddy program
Credits to: 
nRF Serial Chat by Stanley Seow

*/

//#include <LiquidCrystal.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"


#include <HCDotMatrix.h>
#include <TimedAction.h>

/* Led matrix related code starts here depends on direct drive/ shift register or serial control of 8*8 led matrix i used the one from hobby component*/
HCDotMatrix HCDotMatrix(5,6,4,17,16,15,14,8,7,3,2);
int TextPosition;
/* Used to control the scroll speed. */
int ScrollCounter = 0;
char charBuf[31]= "------";
TimedAction scrollerAction = TimedAction(20,scroller);
/* Led matrix related code ends here */

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;
} 

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}


RF24 radio(9,10);

const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };

boolean stringComplete = false;  // whether the string is complete
static int dataBufferIndex = 0;
boolean stringOverflow = false;
char charOverflow = 0;

char SendPayload[31] = "";
char RecvPayload[31] = "";
char serialBuffer[31] = "";

void setup(void) {
 
  Serial.begin(9600);
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
  radio.printDetails();
  delay(500);

}

void loop(void) {
  
  nRF_receive();
  serial_receive();
  scrollerAction.check(); 
  
} 

void serialEvent() {
  while (Serial.available() > 0 ) {
      char incomingByte = Serial.read();
      
      if (stringOverflow) {
         serialBuffer[dataBufferIndex++] = charOverflow;  // Place saved overflow byte into buffer
         serialBuffer[dataBufferIndex++] = incomingByte;  // saved next byte into next buffer
         stringOverflow = false;                          // turn overflow flag off
      } else if (dataBufferIndex > 31) {
         stringComplete = true;        // Send this buffer out to radio
         stringOverflow = true;        // trigger the overflow flag
         charOverflow = incomingByte;  // Saved the overflow byte for next loop
         dataBufferIndex = 0;          // reset the bufferindex
         break; 
      } 
      else if(incomingByte=='\n'){
          serialBuffer[dataBufferIndex] = 0; 
          stringComplete = true;
      } else {
          serialBuffer[dataBufferIndex++] = incomingByte;
          serialBuffer[dataBufferIndex] = 0; 
      }          
  } // end while()
} // end serialEvent()

void nRF_receive(void) {
  
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    Serial.print("R:");
    Serial.print(RecvPayload);
    Serial.println();
    RecvPayload[0] = 0;  // Clear the buffers
  }  

} // end nRF_receive()

void serial_receive(void){
  
  if (stringComplete) {
        
        strcat(SendPayload,serialBuffer);
              
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        bool ok = radio.write(&SendPayload,strlen(SendPayload));
        stringComplete = false;

        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  
        SendPayload[0] = 0;
        dataBufferIndex = 0;
        
  } // endif
} // end serial_receive()  


/* put the text showing routine specific to your led matrix drive here and assign to recvpayload */

void scroller()
{
    
  /* Stores the position index for the portion of text to diplay */
    ScrollCounter++;
  
  /* Has enough time passed to move the text by one position ?*/
  if (ScrollCounter >= 10)
  {
    /* Have we got to the end of the text (24 characters x 8 pixels wide)? 
       If so go back to the start.*/
       
    if (TextPosition > (8*31))
      TextPosition = 0;
   
    /* Output a string to the matrix buffer and specify the display 
       column position */
     
    HCDotMatrix.print(RecvPayload,TextPosition); //RecvPayload charBuf
     
    TextPosition++;
    ScrollCounter = 0;
  }
  
  /* Refresh the display. This must be run continuously */
  HCDotMatrix.UpdateMatrix();
  
  
}


Remove Raspbmc web browser- getting rid of Arora Web Browser and removing it from Program shortcuts in raspbmc

I really love to use raspbmc, a port of xbmc for raspberry pi. I run it on a raspberry pi attached to an lcd screen to watch youtube and other media files on a big screen by sending it by flipping the media files from a smart phone / tablet. With the recent update, there is a new feature, an integrated web browser called Arora, which runs on the pi with a different kernel. So we need a reboot to switch between xbmc and the web-browser. As am a bit obsessive of removing stuffs which i don't use / like it, i need to completely get rid of the  web-browser and its shortcut on the home screen. I also dont have a keyboard or mouse attached to my raspbmc, hence the browser is useless for me and accidentl launch of browser kills the ssh access to the pi :(

So you can remove it either from the Program shortcuts alone or can completely get rid of it. Here is the solutions

Fix the boot configuration

I initially encountered a problem where on rebooting the raspberry the browser always comes back rendering the xbmc in accessible. I realized that the browser is a totally different entity rather than a simple plugin

So first step is to fix the reboot loop. Place your sdcard in a computer and edit the config.txt and make it look like the following (no word like browser should be there :)).

Important lines are the last two! ( for correct booting)  and remove these words like ramfsaddr=-1
cmdline=browser.cmdline
kernel=browser.img 
ramfsfile=browser.rfs

and keep the following lines or add if it is missing

 arm_freq=800  
 force_turbo=1  
 disable_overscan=1  
 gpu_mem=128  
 start_file=start_x.elf  
 fixup_file=fixup_x.dat  

With this at least you will be back to xbmc and if ssh is enabled, now you can access the system and fix the rest

Now let us remove the Arora Browser, whic is taking up  spot in home menu

We need to edit /opt/xbmc-bcm/xbmc-bin/share/xbmc/addons/skin.confluence/720p/IncludesHomeMenuItems.xml and remove the lines whic is behind that menu.

 cd /opt/xbmc-bcm/xbmc-bin/share/xbmc/addons/skin.confluence/720p  
 sudo nano IncludesHomeMenuItems.xml   

search for (ctrl+w) and remove the part marked red as shown below. Then save the file (ctrl+x, press y, if you make a mistake in deleting, just ctrl+z and redo). You may also make a back up before editing this file by typing


 sudo cp IncludesHomeMenuItems.xml IncludesHomeMenuItems.xml.bak  
 and can be restored with  
 sudo mv IncludesHomeMenuItems.xml.bak IncludesHomeMenuItems.xml   

Remove the entry in red to get rid of the Arora

      <include name="HomeAddonItemsPrograms">  
           <item>  
                <label>$INFO[system.addontitle(script.raspbmc.settings)]</label>  
                <onclick>RunAddon(script.raspbmc.settings)</onclick>  
                <icon>$INFO[system.addonicon(script.raspbmc.settings)]</icon>  
                <thumb>-</thumb>  
           </item>  
           <item>  
                <label>$INFO[system.addontitle(script.raspbmc.browserlaunch)]</label>  
                <onclick>RunAddon(script.raspbmc.browserlaunch)</onclick>  
                <icon>$INFO[system.addonicon(script.raspbmc.browserlaunch)]</icon>  
                <thumb>-</thumb>  
           </item>  
           <item>  
                <label>$INFO[system.addontitle(Skin.String(HomeProgramButton3))]</label>  
                <onclick>RunAddon($INFO[Skin.String(HomeProgramButton3)])</onclick>  
                <icon>$INFO[system.addonicon(Skin.Strin  
If you are obsessed to remove all raspbmc browser things :) do the following steps (be careful with the steps so that you wont screw up your xbmc installation) 1) Remove the addon: script.raspbmc.browserlaunch (first ssh in to the raspbmc)
 sudo rm -rf ~/.xbmc-current/xbmc-bin/share/xbmc/addons/script.raspbmc.browserlaunch  

2)remove starter script for browser
 sudo rm /scripts/browser.sh   

2)Remove boot files for Arora browser (make sure you fixed your config.txt as shown in the beginning)
 cd /boot  
 sudo rm browser.*  

Friday, December 27, 2013

Watch youtube on tv with raspberry pi and raspbmc

In my previous post, i showed how to set up a low budget media center on a raspberry pi using raspbmc. This is a small post to set up youtube and live streams after installing the raspbmc. See the video below, which shows how to enable the addon on raspbmc or xbmc.

 

After installing this and enabling, to control your media player from your smartphone, on google play store for Yatse xbmc remote (Android here) Once it is installed, while you browse a youtube video or other streams, there will be an option to send the video to your xbmc and hence appears on your tv screen.

Turn tv into smart tv-cheap smart tv conversion using raspberry pi

These days we rely too much on internet and media files for entertainments and news. Often people watch recorded TV programs from you-tube or other video sharing sites and many tv channels have a good presence on social media which allows it easier to watch a show if you miss it at the time of telecast. It is also possible to watch live streams from the tv channels which is often helpful when you live at a different corner of the world than your home country.

Some of you might have bought an hdtv and uses it while hooked on to a laptop or tablet and this forms one of the simplest ways to convert the tv to a smarter one. But it is often inconvenient if you dont have multiple computers at home. Here am going to present a simple way to use a raspberry pi , a cheap 35$ computer board to make an always on, low power consuming (~1W) media player box. This makes it possible to  watch live streams for example to watch youtube on tv. This is also a simple tv to smart tv conversion technique. You can also send videos from your smartphone to big screen (TV/lcd or led) with the flip of a finger.


This is achieved by getting one of the raspberry pi boards. It has all the good things we need. An hdmi port to connect to most of the TV sets. There is an audio jack and a video output which can be used with an old model tv sets. There is an ethernet port which can be connected to your router. To make it active, we need to install a software on it which can be obtained from raspbmc, which installs an xbmc media center on your raspberry pi. XBMC has a lot of cool features like sending youtube videos from smartphones with a  youtube addon and similar features are available for hulu and other media sharing sites. Live streams can be handled with livestreams addon. More on these addons and xbmc can be read here. If you need any tips or helps which cannot be located else where (see my postd on adding a remote control), place a comment below.


 There are devices like Apple TV, Rokus and Android boxes which can turn your tv in to a smart tv. This guide is for those who like to have a more flexible and tinkerable solution. It is also convenient for those who bought a raspberry pi and doesn't know what to do with it  

Thursday, December 26, 2013

Online led matrix font generator with binary and hex codes for Arduino

If you are looking for the nokia lcd (bitmap to hex codes for 84X48 lcd with PCD8544, it can be accessed at the link here Nokia LCD Hex Generator
Scrolling text patterns on 8x8 led matrix displays from one of the common and favorite Arduino projects. It is necessary to set the led pixels in binary or hex to the corresponding led to being kept on. Example sketch can be viewed here
Here is an easy to use, web-based online font generator. click on the matrix to toggle the led status to on or off and get the hex codes.

8x8 ONLINE LED HEX/ BINARY PATTERN GENERATOR FOR ARDUINO

 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0
Binary values:

Hex values:


This can be used to generate fonts and patterns for using with arduino sketches. Insert the generated codes in the font or pattern definitions in the sketch. Both forms will work and the hex form will keep the source code small and neat. For example, see the following direct drive sketch. To generate a pattern , click on the grid and toggle it to on (1). Once you are done with the font / pattern, copy the binary values or hex values to your sketch.



8X16 and DYNAMIC ONLINE LED BINARY CODE PATTERN GENERATOR FOR BIGGER DISPLAYS like 16 X 8
To make a bigger one for e.g a 16 X 8 matrix, just fill 16 in the columns and 8 in the rows field and click update

Rows: Columns:
Binary values:


Wednesday, December 25, 2013

Broadcast FM reception with gnuradio and Funcube Dongle [quick start with funcube and gnuradio]

I recently got a fun-cube pro plus sdr dongle. As i dont have an external antenna, i need to test the device with wide band fm broadcast stations (Although funcube pro is not really meant for that purpose) So i hooked up the device with my sophisticated antenna (see the image below :)) and connected to the gnuradio. My search for an example gnuradio sketch ended up in vain. I tried some of the receiver layouts, which was mainly for narrow band fm,which i realized at a later time point.
Things turns so simple when you have an example sketch to start with. So i was forced to test with a windows only, powerful sdr software (sdr#). But using gnuradio and linux offers a lot more flexibility and learning oppurtunities. To start with, connect the dongle to usb port and place an antenna, a piece of wire in to the sma connector.


Now open gnu radio companion and load the following grc file (all files can be downloaded from github by clicking here)

Currently it didnt control your frequency, so you need to get the Qthid Funcube Dongle Controller software from funcube website (here)

here is a snapshot of what you get (click on image to view a bigger version)



If you dont have a funcubedongle, you can still try the sample capture file and the attached grc files.

Download the complete sources from github

Hope this will help some one :)

Note: As of v3.7.4 of gnu radio, you may get an error stating that -Error: Block key "blks2_wfm_rcv" not found in Platform - grc(GNU Radio Companion). This is because in newer versions, they have moved it under modulators, WBFM receiver. Set the quad rate to 192000 and audio decimation to 48. Instead og the grc code below, if you use the version from git, i have updated it to the latest.

Sunday, December 22, 2013

[working] Quick start guide for nRF24L01 on Arduino

Making your sensors wireless is always a convenient solution to avoid cabling hassle. The available, cheap 2.4ghz transceiver are a good solution. They have a small wireless chip which makes two way communications between two arduinos or any other micro-controllers much easier.  They are available in different form factors and the commonly available ones are shown in the figure. When you get the parts it is always thrilling to test it out in the shortest possible time. After searching for nrf24l01 arduino tutorials, i ended up with a lot of information's and a huge chunk of codes with a lot of wrong information/misguidance for beginners. So i planned to write one short and quick start guide for using nrf24l01 module with arduino uno and a working sketch to test.

So in short the radio module needs to be connected to arduino board as follows

nRF24L01 Arduino PIN
GND GND
3V3 (VCC) 3V3 (IMPORTANT!!)
CE 9
CSN 10
SCK 13
MOSI 11
MISO 12

Now let us have a look at the pin connections for commonly available nrf24l01 module. See the picture where two most commonly seen variants are shown. One of them has 10 pins (2 grounds (GND) and two vcc (3v3)



Now install RF24 library which makes things easy. Download it from here To install this, unzip the files and rename the folder to RF24 (from RF24-master) and place this folder in your arduino libraries folder (mine was at Desktop/arduino-1.0.5/libraries/) and restart the arduino ide. Now the library is ready to go. There are examples and i was unable to understand them at the first time. So am giving some sketch (basically from the same source) which you can upload and test without thinking too much.

Wireless scanner
----------------------

It just need only one module to test. It acts like a poormans scanner (from Mark) and shows the signals around.  Paste this script in arduino ide and upload it to the uno board. Open the serial monitor by pressing the small magnifier button on the ide and set baud rate to 57600 (else you will see some gibberish text)




#include <SPI.h>

// Poor Man's Wireless 2.4GHz Scanner
//
// uses an nRF24L01p connected to an Arduino
// 
// Cables are:
//     SS CSN) -> 10
//     MOSI     -> 11
//     MISO     -> 12
//     SCK      -> 13
// 
// and CE       ->  9
//
// created March 2011 by Rolf Henkel
//

#define CE  9

// Array to hold Channel data
#define CHANNELS  64
int channel[CHANNELS];

// greyscale mapping 
int  line;
char grey[] = " .:-=+*aRW";

// nRF24L01P registers we need
#define _NRF24_CONFIG      0x00
#define _NRF24_EN_AA       0x01
#define _NRF24_RF_CH       0x05
#define _NRF24_RF_SETUP    0x06
#define _NRF24_RPD         0x09

// get the value of a nRF24L01p register
byte getRegister(byte r)
{
  byte c;
  
  PORTB &=~_BV(2);
  c = SPI.transfer(r&0x1F);
  c = SPI.transfer(0);  
  PORTB |= _BV(2);

  return(c);
}

// set the value of a nRF24L01p register
void setRegister(byte r, byte v)
{
  PORTB &=~_BV(2);
  SPI.transfer((r&0x1F)|0x20);
  SPI.transfer(v);
  PORTB |= _BV(2);
}
  
// power up the nRF24L01p chip
void powerUp(void)
{
  setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x02);
  delayMicroseconds(130);
}

// switch nRF24L01p off
void powerDown(void)
{
  setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)&~0x02);
}

// enable RX 
void enable(void)
{
    PORTB |= _BV(1);
}

// disable RX
void disable(void)
{
    PORTB &=~_BV(1);
}

// setup RX-Mode of nRF24L01p
void setRX(void)
{
  setRegister(_NRF24_CONFIG,getRegister(_NRF24_CONFIG)|0x01);
  enable();
  // this is slightly shorter than
  // the recommended delay of 130 usec
  // - but it works for me and speeds things up a little...
  delayMicroseconds(100);
}

// scanning all channels in the 2.4GHz band
void scanChannels(void)
{
  disable();
  for( int j=0 ; j<200  ; j++)
  {
    for( int i=0 ; i<CHANNELS ; i++)
    {
      // select a new channel
      setRegister(_NRF24_RF_CH,(128*i)/CHANNELS);
      
      // switch on RX
      setRX();
      
      // wait enough for RX-things to settle
      delayMicroseconds(40);
      
      // this is actually the point where the RPD-flag
      // is set, when CE goes low
      disable();
      
      // read out RPD flag; set to 1 if 
      // received power > -64dBm
      if( getRegister(_NRF24_RPD)>0 )   channel[i]++;
    }
  }
}

// outputs channel data as a simple grey map
void outputChannels(void)
{
  int norm = 0;
  
  // find the maximal count in channel array
  for( int i=0 ; i<CHANNELS ; i++)
    if( channel[i]>norm ) norm = channel[i];
    
  // now output the data
  Serial.print('|');
  for( int i=0 ; i<CHANNELS ; i++)
  {
    int pos;
    
    // calculate grey value position
    if( norm!=0 ) pos = (channel[i]*10)/norm;
    else          pos = 0;
    
    // boost low values
    if( pos==0 && channel[i]>0 ) pos++;
    
    // clamp large values
    if( pos>9 ) pos = 9;
   
    // print it out
    Serial.print(grey[pos]);
    channel[i] = 0;
  }
  
  // indicate overall power
  Serial.print("| ");
  Serial.println(norm);
}

// give a visual reference between WLAN-channels and displayed data
void printChannels(void)
{
  // output approximate positions of WLAN-channels
  Serial.println(">      1 2  3 4  5  6 7 8  9 10 11 12 13  14                     <");
}

void setup()
{
  Serial.begin(57600);
  
  Serial.println("Starting Poor Man's Wireless 2.4GHz Scanner ...");
  Serial.println();

  // Channel Layout
  // 0         1         2         3         4         5         6
  // 0123456789012345678901234567890123456789012345678901234567890123
  //       1 2  3 4  5  6 7 8  9 10 11 12 13  14                     | 
  //
  Serial.println("Channel Layout");
  printChannels();
  
  // Setup SPI
  SPI.begin();
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setBitOrder(MSBFIRST);
  
  // Activate Chip Enable
  pinMode(CE,OUTPUT);
  disable();
  
  // now start receiver
  powerUp();
  
  // switch off Shockburst
  setRegister(_NRF24_EN_AA,0x0);
  
  // make sure RF-section is set properly 
  // - just write default value... 
  setRegister(_NRF24_RF_SETUP,0x0F); 
  
  // reset line counter
  line = 0;
}

void loop() 
{ 
  // do the scan
  scanChannels();
  
  // output the result
  outputChannels();
  
  // output WLAN-channel reference every 12th line
  if( line++>12 )
  {
    printChannels();
    line = 0;
  }
}

Now let us make two module speaking to each other. This is from the rf24 examples folder. Make two sets where the first one sends the signal, second the second one receives and send it back to first and the time taken for the loop is shown. When i tried the examples, i didn't set the order of which module to transmit and which one to receive and i was wondering why it was not working! So to make simple i made two sketches which are 99.9% similar except in the rad and write variables. Upload SKETCH1 to the first one which is kept connected to a computer and keep arduino serial monitor open. The second one is on an arduino which is kept far from the computer and can be powered with a 9volt battery. The second one receives the signal and relays it back to the first one and the response can be viewed on a PC. So to make it simple, load sketch2 to an arduino with nrf24l module and then keep it away from pc with a 9v battery attached. Then load sketch1 to the next arduino and open its serial monitor to see the response.

 SKETCH2 (for the arduino which will send pback the response, battery powered)

/*
 Copyright (C) 2011 J. Coliz <[email protected]>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example for Getting Started with nRF24L01+ radios. 
 *
 * This is an example of how to use the RF24 class.  Write this sketch to two 
 * different nodes.  Put one of the nodes into 'transmit' mode by connecting 
 * with the serial monitor and sending a 'T'.  The ping node sends the current 
 * time to the pong node, which responds by sending the value back.  The ping 
 * node can then see how long the whole cycle took.
 */

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;
} 

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 

RF24 radio(9,10);

//
// Topology
//

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  
//

// The various roles supported by this sketch
typedef enum { role_ping_out = 1, role_pong_back } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};

// The role of the current running sketch
role_e role = role_pong_back;
int led = 8;

void setup(void)
{

  Serial.begin(57600);
  analogReference(INTERNAL);
  radio.begin();
  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15); 
  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);
  //
  // Start listening
  //
  radio.startListening();
  //
  // Dump the configuration of the rf unit for debugging
  //
  radio.printDetails();
}

void loop(void)
{
  //
  // Ping out role.  Repeatedly send the current time
  //      

  if (role == role_ping_out)
  {
    // First, stop listening so we can talk.
    radio.stopListening();

    // Take the time, and send it.  This will block until complete
    unsigned long time = millis();
    
    bool ok = radio.write( &time, sizeof(unsigned long) );

    // Now, continue listening
    radio.startListening();

    // Wait here until we get a response, or timeout (250ms)
    unsigned long started_waiting_at = millis();
    bool timeout = false;
    while ( ! radio.available() && ! timeout )
      if (millis() - started_waiting_at > 200 )
        timeout = true;

    // Describe the results
    if ( timeout )
    {
      //printf("Failed, response timed out.\n\r");
    }
    else
    {
      // Grab the response, compare, and send to debugging spew
      unsigned long got_time;
      radio.read( &got_time, sizeof(unsigned long) );

      // Spew it
      //printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
    }

    // Try again 1s later
    delay(1000);
  }

  //
  // Pong back role.  Receive each packet, dump it out, and send it back
  //

  if ( role == role_pong_back )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      unsigned long got_time;
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( &got_time, sizeof(unsigned long) );     
        
    // Delay just a little bit to let the other unit
    // make the transition to receiver
    delay(20);
        
      }

      // First, stop listening so we can talk
      radio.stopListening();

      // Send the final one back.
      radio.write( &got_time, sizeof(unsigned long) );
      //printf("Sent response.\n\r");

      // Now, resume listening so we catch the next packets.
      radio.startListening();
    }
  }

}


 SKETCH1 (for the arduino connected to the computer with serial monitor and this keeps transmitting to the arduino with SKETCH2 loaded and listen for the reply)

/*
 Copyright (C) 2011 J. Coliz <[email protected]>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * Example for Getting Started with nRF24L01+ radios. 
 *
 * This is an example of how to use the RF24 class.  Write this sketch to two 
 * different nodes.  Put one of the nodes into 'transmit' mode by connecting 
 * with the serial monitor and sending a 'T'.  The ping node sends the current 
 * time to the pong node, which responds by sending the value back.  The ping 
 * node can then see how long the whole cycle took.
 */

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;
} 

void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}


//
// Hardware configuration
//

// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 

RF24 radio(9,10);

//
// Topology
//

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };

//
// Role management
//
// Set up role.  This sketch uses the same software for all the nodes
// in this system.  Doing so greatly simplifies testing.  
//

// The various roles supported by this sketch
typedef enum { role_ping_out = 1, role_pong_back } role_e;

// The debug-friendly names of those roles
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};

// The role of the current running sketch
role_e role = role_pong_back;

void setup(void)
{
  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/GettingStarted/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);
  printf("*** PRESS 'T' to begin transmitting to the other node\n\r");

  //
  // Setup and configure rf radio
  //

  radio.begin();

  // optionally, increase the delay between retries & # of retries
  radio.setRetries(15,15);
  radio.openWritingPipe(pipes[1]);
  radio.openReadingPipe(1,pipes[0]);
  
  //
  // Start listening
  //

  radio.startListening();

  //
  // Dump the configuration of the rf unit for debugging
  //

  radio.printDetails();
}

void loop(void)
{
  //
  // Ping out role.  Repeatedly send the current time
  //

  if (role == role_ping_out)
  {
    // First, stop listening so we can talk.
    radio.stopListening();

    // Take the time, and send it.  This will block until complete
    unsigned long time = millis();
    printf("Now sending %lu...",time);
    bool ok = radio.write( &time, sizeof(unsigned long) );
    
    if (ok)
      printf("ok...");
    else
      printf("failed.\n\r");

    // Now, continue listening
    radio.startListening();

    // Wait here until we get a response, or timeout (250ms)
    unsigned long started_waiting_at = millis();
    bool timeout = false;
    while ( ! radio.available() && ! timeout )
      if (millis() - started_waiting_at > 200 )
        timeout = true;

    // Describe the results
    if ( timeout )
    {
      printf("Failed, response timed out.\n\r");
    }
    else
    {
      // Grab the response, compare, and send to debugging spew
      unsigned long got_time;
      radio.read( &got_time, sizeof(unsigned long) );

      // Spew it
      printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
    }

    // Try again 1s later
    delay(1000);
  }

  //
  // Pong back role.  Receive each packet, dump it out, and send it back
  //

  if ( role == role_pong_back )
  {
    // if there is data ready
    if ( radio.available() )
    {
      // Dump the payloads until we've gotten everything
      unsigned long got_time;
      bool done = false;
      while (!done)
      {
        // Fetch the payload, and see if this was the last one.
        done = radio.read( &got_time, sizeof(unsigned long) );

        // Spew it
        printf("Got payload %lu...",got_time);

    // Delay just a little bit to let the other unit
    // make the transition to receiver
    delay(20);
      }

      // First, stop listening so we can talk
      radio.stopListening();

      // Send the final one back.
      radio.write( &got_time, sizeof(unsigned long) );
      printf("Sent response.\n\r");

      // Now, resume listening so we catch the next packets.
      radio.startListening();
    }
  }

  //
  // Change roles
  //

  if ( 1 )
  {
    char c = toupper(Serial.read());
    if ( 1 )
    {
      printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");

      // Become the primary transmitter (ping out)
      role = role_ping_out;
      radio.openWritingPipe(pipes[1]);
      radio.openReadingPipe(1,pipes[0]);
    }
    
  }
}

Saturday, December 21, 2013

Build a low cost remote temperature monitoring system for home or server room temperature monitoring

Often we need a simple way to log and look at the temperature at the basement or the room while staying away from the property. This may often help to save a couple of water pipes getting frozen or server room getting heated up. Here i will show a simple way to start with a wired solution and later it can be upgraded to a wireless solution. It is easy to buy one system and install it. But it is fun to build one :)

We need a couple of things to start. An LM35 temperature sensor and a micro-controller with an ethernet  module. Here am going to use an ATMEGA328 (arduino uno prototyping board) with an Ethernet shield. (There are more options out there if you have a raspberry pi, so that the need for ethernet shield can be replaced with a wireless link to raspberry pi)

Connecting the hardware is easy and can be figured out from the pictures below. Sensor has 3 pins and connect them to ground, vcc (5 volt) and the output to the analogue input pins of the micro controller.

                                                                         

And here is the PIN connections for LM38

 

Now the interesting part is the firmware for the device to upload the temperature to a web-service. To make things easy for the beginners, am going to use a cloud based serial data logging service. Exosite.com offers a simple and easy to set up solution with beautiful charting. You can see my temperature logger in action at this link. Firmware for connecting to exosite can be seen here.

Modified source for LM35 is given below. dont forget to connect the Ethernet shield and the cable. After the source, an updated version of my logger which uses raspberry pi and tempo-db together with highchart ( a nice charting tool) is used to log and plot the temperature data from a set of sensors

Complet source can be downloaded as a zip file from here

/*
It uses parts of code from exocite and their libraries. 
Create an account there and use that api key for CIK
Set the mac adress for ethernet shield
Replace writeParam = "number="; with the data name of your device in exocite

This is modified to use LM38 temperature sensor and uses ANALOGUE PIN 5 on arduino uno

The original file can be seen at https://raw.github.com/exosite-garage/arduino_exosite_library/master/examples/TemperatureMonitor/TemperatureMonitor.ino

Credit goes to exocite and please see the above link

For more details on setting up and instructions see 

http://blog.riyas.org/2013/12/build-low-cost-remote-temperature.html

*/
  
  
#include <SPI.h>
#include <Ethernet.h>
#include <Exosite.h>
 

 
/*==============================================================================
* Configuration Variables
*
* Change these variables to your own settings.
*=============================================================================*/
String cikData = "0000000000000000000000000000000080000000";  // <-- FILL IN YOUR CIK HERE! (https://portals.exosite.com -> Add Device)
byte macData[] = {0xDE, 0xAD, 0xBE, 0xEE, 0xEE, 0xFF};        // <-- FILL IN YOUR Ethernet shield's MAC address here.

// User defined variables for Exosite reporting period and averaging samples
#define REPORT_TIMEOUT 30000 //milliseconds period for reporting to Exosite.com
#define SENSOR_READ_TIMEOUT 5000 //milliseconds period for reading sensors in loop
#define LM35Pin 14

/*==============================================================================
* End of Configuration Variables
*=============================================================================*/

class EthernetClient client;
Exosite exosite(cikData, &client);

//
// The 'setup()' function is the first function that runs on the Arduino.
// It runs completely and when complete jumps to 'loop()' 
//
void setup() {
  Serial.begin(9600);
  analogReference(INTERNAL);
  Serial.println("Boot");
  Serial.println("Starting Exosite Temp Monitor");
  Ethernet.begin(macData);
  // wait 3 seconds for connection
  delay(3000); 
 
}
 
//
// The 'loop()' function is the 'main' function for Arduino 
// and is essentially a constant while loop. 
//
void loop() {
  static unsigned long sendPrevTime = 0;
  static unsigned long sensorPrevTime = 0; 
  static float tempC;
  char buffer[7];
  String readParam = "";
  String writeParam = "";
  String returnString = "";  
   
  Serial.print("."); // print to show running
 
 // Read sensor every defined timeout period
  if (millis() - sensorPrevTime > SENSOR_READ_TIMEOUT) {
    Serial.println();
    Serial.println("Requesting temperature...");
    tempC =  analogRead(LM35Pin) / 9.31;
    Serial.print("Celsius:    ");
    Serial.print(tempC);
    Serial.println(" C ..........DONE");   
    sensorPrevTime = millis();
  }
 
  // Send to Exosite every defined timeout period
  if (millis() - sendPrevTime > REPORT_TIMEOUT) {
    Serial.println(); //start fresh debug line
    Serial.println("Sending data to Exosite...");
    
    readParam = "";        //nothing to read back at this time e.g. 'control&status' if you wanted to read those data sources
    writeParam = "number="; //parameters to write e.g. 'temp=65.54' or 'temp=65.54&status=on'
    
    String tempValue = dtostrf(tempC, 1, 2, buffer); // convert float to String, minimum size = 1, decimal places = 2
    
    writeParam += tempValue;    //add converted temperature String value
    
    //writeParam += "&message=hello"; //add another piece of data to send

    if ( exosite.writeRead(writeParam, readParam, returnString)) {
      Serial.println("Exosite OK");
      if (returnString != "") {
        Serial.println("Response:");
        Serial.println(returnString);
      }
    }
    else {
      Serial.println("Exosite Error");
    }
 
    sendPrevTime = millis(); //reset report period timer
    Serial.println("done sending.");
  }
  delay(1000); //slow down loop
}
Here is some example for setting up exocite

Thursday, December 12, 2013

Infrared remote controlled (TV remote) bash script on raspberry pi (or raspbmc) with irexec

After my post on using any TV remote to control raspberry pi based xbmc (raspbmc), i made this post to complete the purpose of the previous post; where one of the aim was to execute a command/script to restart the xbmc at the click of remote control. In this way the xbmc can be forcefully restarted (for instance when xbmc freezes and become unresponsive to http/android/iphone based remote controls) .

To achieve this irexec program is used which can be run as a demon. It looks staraight forward but in my case , irexec fails to start on system reboots. So it needs to be added to the startup and can be done by upstart in newer debian distros.

 sudo nano /etc/init/irexec.conf  

And then add the following lines there

 #<---start----------->  
 # irexec Daemon  
 #  
 description     "irexec daemon"  
 author      "None"  
 start on (started eventlircd)  
 stop on (xbmc-do-stop or runlevel [!2345])  
 exec irexec /home/pi/.lircrc  
 respawn  
 #<---end----------->  

This will keep irexec running. But wait a second, before this we need to tell irexec, what to do. So edit its configuration file

 nano /home/pi/.lircrc  

and add the following lines (you can change the scripts based on this example to what ever you need)

 #<---start here----------->  
 begin  
  prog = irexec  
 # remote = mceusbou   
  button = KEY_BLUE  
  config = /home/pi/rebootxbmc.sh  
 end  
 begin  
  prog = irexec  
 # remote = mceusbou  
  button = KEY_MENU  
  config = /home/pi/auto2.sh  
 end  
 #<---ends here----------->  

Note that config= followes your script to get executed and button should be the one you need to map

For instance below is an example script (rebootxbmc.sh) which helps to reboot the xbmc and contains the following lines (make sure you chmod +x rebootxbmc.sh)

 #!/bin/bash   
 # Kill XBMC and restart   
 echo "XBMC running, force restart."   
 sudo -u root initctl stop xbmc   
 #Optional logging for troubleshooting. Remove the hash to enable  
 #echo $(date) ": XBMC-live stop executed" >> /home/xbmc/.restart-log.log   
 sleep 2   
 sudo -u root initctl start xbmc   
 #Optional logging for troubleshooting. Remove the hash to enable  
 echo $(date) ": XBMC-live RESTART executed" >> /home/pi/rebootxbmc.log   
 exit  

But a  before it does its job we need to do something more! As xbmc restart needs sudo (super user), we need to set this script to run with higher privilege.

 sudo visudo  

and append following line to the end of the file (remember end of the file! don't look at the stuff above :)

 pi ALL=(ALL) NOPASSWD:/home/pi/rebootxbmc.sh  

where pi is the username.


Shutting down the Monitor/LCD  by turning the hdmi off in raspberry pi

This can be achieved by mapping the following script to the remote buttons.

So add the following to  

 nano /home/pi/.lircrc  
begin
 prog = irexec
# remote = mceusbou
 button = KEY_M
 config = /home/pi/off.sh
end
begin
 prog = irexec
# remote = mceusbou
 button = KEY_LANGUAGE
 config = /home/pi/on.sh


and then we need the on.sh (/home/pi/on.sh)  and off.sh (/home/pi/off.sh) 

on.sh


#!/bin/bash
/opt/vc/bin/tvservice -p
sudo initctl start xbmc

off.sh 


#!/bin/bash
sudo initctl stop xbmc
/opt/vc/bin/tvservice -o

Single button to toggle on /off using IR remote

Instead of using seperate buttons to turn on or off, it is possible to use the following script which basically toggle between on and off positions.

#!/bin/bash
if [ `sudo /sbin/initctl status xbmc | grep running | wc -l` = 1 ]
then
sudo initctl stop xbmc
/opt/vc/bin/tvservice -o
echo $(date -u) "Off" >> /home/pi/tvlog.txt
else
/opt/vc/bin/tvservice -p
sudo initctl start xbmc
echo $(date -u) "On" >> /home/pi/tvlog.txt
fi


end

Sunday, December 8, 2013

Using any TV remote to control raspberry pi - xbmc (raspbmc)

If you are using your raspberry pi as a media player (using raspbmc/xbmc), it is often convenient to use the same TV remote control (infra red remote) to handle most of the features rather than using the wifi remote on a smart phone or tablet. It is also more child or girl friend,wife or grandma friendly. Often the raspbmc/xbmc freezes and it is very convenient for the non techie family member to press the magic button on an ir remote to gracefully restart the xbmc rather than pulling the powercord for the raspberry pi.

Even for me, it is inconvenient to ssh in to the raspberry pi and do a

 sudo initctl stop xbmc  
 sudo initctl start xbmc  
or more violently,
 sudo reboot xbmc  
Think of doing this, with out turning on the ssh program and typing it on a smartphone with wifi on :), so i mapped some extra buttons on the TV remote to do all these.

And here is my TV remote where i used some of the buttons for the built in DVD  player functions which i do not use and are mapped for XBMC


I used the record button to restart the xbmc, but it is possible to map any tv remote button for the purpose as long as it wont produce any valid result on the TV, while it is used with hdmi input.

If you are starting from scratch with a brand new raspberry pi, you need to install an operating system to use it as a media player. The easiest solution is raspbmc.

To get infrared remote receiver, the cheapest solution is to use the GPIO pins. Installation instructions can be seen here. If you search for HX1838  you can spot a reasonable ir sensor. Take care while hooking it on to the pi, so that you wont damage the board.


Raspbmc has the required softwares built in to it. You just need to configure it (in raspbmc settings menu)and it usually works out of the box with those small remotes like the one shown below


If you are happy with having two or more remotes, the process is simple and almost done.

For non raspbmc (starting from scratch ) users 
CLICK FOR DETAILS


 Now let us test the installation and the remote control. Reboot the pi and stop the lirc and fire up a small program which shows the signals from ir remote

 sudo /etc/init.d/lirc stop  
 mode2 -d /dev/lirc0  

If things are fine ,something like pulse and some numbers pops up in the console/ssh window. Next step is to use a program called irrecord to make a config file which contains the fingerprints for each buttons in your remote by recording the infrared pulses from your remote
 irrecord -d /dev/lirc0 ~/lircd.conf   
 sudo cp lircd.conf /etc/lirc/lircd.conf   
Next step is to run  a script using irexec to reboot/restart the xbmc with a specific keypress. Often mapping the keys to correct xbmc function is needed and is achieved with Lircmap.xml file placed at (home/pi/.xbmc/userdata). More details will follow in my next post [click here]. Please post a comment , if you face any difficulties.

A sample lircd.conf

 # Please make this file available to others  
 # by sending it to <[email protected]>  
 #  
 # this config file was automatically generated  
 # using lirc-0.9.0-pre1(default) on Fri Oct 25 21:47:45 2013  
 #  
 # contributed by   
 #  
 # brand:            /home/pi/lircd.conf.new  
 # model no. of remote control:   
 # devices being controlled by this remote:  
 #  
 begin remote  
  name /home/pi/lircd.conf.new  
  flags RAW_CODES|CONST_LENGTH  
  eps      30  
  aeps     100  
  gap     114780  
    begin raw_codes  
      name KEY_RECORD  
        1147   624  1147   660  2015   681  
        1093   700  1087   705  1077  1626  
        998   798   988   821  1855   825  
        958  1729   953   837   938  
      name KEY_PLAY  
        1142   635  2004   692  1095   702  
        1091   705  1094   705  1035  1667  
        1876  1705   980   816  1862   823  
        947  1748   924  
      name KEY_PAUSE  
        1139   667  1099   688  1988   715  
        1082   699  1078   785   953  1686  
        987   804   985   806  1872   817  
        961   833   955  1738   934  
      name KEY_STOP  
        1134   655  1123   669  1996   698  
        1087   712  1079   737  1000  1674  
        1886  1739   951   819  1858   825  
        945   839   935  
      name KEY_PREVIOUS  
        1161   622  2033   662  1112   686  
        1103   687  1088   705  1085  1614  
        1891  1714   979   823   947   827  
        1851  1741   928  
      name KEY_NEXT  
        1116   673  1084   707  1946   766  
        984   806   978   811   968  1719  
        1844  1744   933   865   910   892  
        890   907  1776  
      name KEY_FASTFORWARD  
        1173   621  2052   633  1148   647  
        1136   655  1117   677  1089  1600  
        1926  1685   982   806   972   818  
        1844   850   950  
      name KEY_REWIND  
        1169   668  1088   663  2006   683  
        1089   699  1089   707  1083  1623  
        1883  1712   968   822  1848  1747  
        928   847   925  
      name KEY_RED  
        1151   640  2010   685  1093   709  
        1077   719  1070   709  1157  1551  
        991   802   982   819  1864  1717  
        954   835   943   846   940  
      name KEY_GREEN  
        1179   609  1140   652  2015   684  
        1088   698  1088   705  1081  1616  
        1013   788   986   808  1864  1733  
        949   836  1824  
      name KEY_YELLOW  
        1183   608  2048   657  1121   658  
        1146   646  1121   673  1090  1628  
        1057   724  1015   783  1884   805  
        965  1725  1835  
      name KEY_MENU  
        1172   621  2020   666  1120   680  
        1100   700  1081   700  1114  1595  
        1003   786  1883  1724   958   819  
        963   838  1814  
      name KEY_BLUE  
        1166   622  1165   627  2029   668  
        1103   683  1107   685  1088  1599  
        1177   679   951   802  1876  1713  
        1845   836   947  
      name KEY_ENTER  
        1149   632  2033   656  1136   660  
        1110   687  1091   703  1085  1611  
        1894  1707  1862  1718   956   831  
        948   844   933  
    end raw_codes  
 end remote  

Re mapping the IR remote keys for xbmc under Raspbmc

If we need to use a specific key on the remote control for a different function on the raspbmc/xbmc we need to remap the keys. For e.g. we can remap the record button on a tv remote to stop button on raspbmc and so on. For this, create a file called Lircmap.xml and keep it at  ~/.xbmc/userdata

An example file is given below nano ~/.xbmc/userdata/Lircmap.xml

<lircmap>
       <remote device="devinput">
               <stop>KEY_RECORD</stop>
               <play>KEY_PLAY</play> 
               <pause>KEY_PAUSE</pause> 
               <stop>KEY_STOP</stop> 
               <left>KEY_PREVIOUS</left> 
               <right>KEY_NEXT</right> 
               <up>KEY_FASTFORWARD</up> 
               <down>KEY_REWIND</down> 
               <back>KEY_RED</back> 
               <start>KEY_GREEN</start> 
               <mute>KEY_YELLOW</mute> 
               <close>KEY_BLUE</close> 
           <select>KEY_ENTER</select>              
       </remote>
 </lircmap>

Notes on Recording and debugging irremotes with irrecord/lirc

A simple log of recording an irremote and debugging the keypresses with irw
pi@raspbmc:~$ sudo /etc/init.d/lirc stop
[ ok ] Stopping remote control daemon(s): LIRC:.
pi@raspbmc:~$ sudo lircd  -d /dev/lirc0 
pi@raspbmc:~$ irw
00000000e17a28d7 00 KEY_BACK philipsxbmc
00000000e17a28d7 01 KEY_BACK philipsxbmc
00000000e17a28d7 02 KEY_BACK philipsxbmc

Routines
========
pi@raspbmc:~$ irrecord -d /dev/lirc0 ~/newconf.conf

irrecord -  application for recording IR-codes for usage with lirc

Copyright (C) 1998,1999 Christoph Bartelmus([email protected])

This program will record the signals from your remote control
and create a config file for lircd.


A proper config file for lircd is maybe the most vital part of this
package, so you should invest some time to create a working config
file. Although I put a good deal of effort in this program it is often
not possible to automatically recognize all features of a remote
control. Often short-comings of the receiver hardware make it nearly
impossible. If you have problems to create a config file READ THE
DOCUMENTATION of this package, especially section "Adding new remote
controls" for how to get help.

If there already is a remote control of the same brand available at
http://www.lirc.org/remotes/ you might also want to try using such a
remote as a template. The config files already contain all
parameters of the protocol used by remotes of a certain brand and
knowing these parameters makes the job of this program much
easier. There are also template files for the most common protocols
available in the remotes/generic/ directory of the source
distribution of this package. You can use a template files by
providing the path of the file as command line parameter.

Please send the finished config files to <[email protected]> so that I
can make them available to others. Don't forget to put all information
that you can get about the remote control in the header of the file.

Press RETURN to continue.


Now start pressing buttons on your remote control.

It is very important that you press many different buttons and hold them
down for approximately one second. Each button should generate at least one
dot but in no case more than ten dots of output.
Don't stop pressing buttons until two lines of dots (2x80) have been
generated.

Press RETURN now to start recording.
................................................................................
Found const length: 108501
Please keep on pressing buttons like described above.
................................................................................
Space/pulse encoded remote control found.
Signal length is 67.
Found possible header: 9047 4522
Found trail pulse: 562
Found repeat code: 9040 2245
Signals are space encoded.
Signal length is 32
Now enter the names for the buttons.

Please enter the name for the next button (press <ENTER> to finish recording)
KEY_0

Now hold down button "KEY_0".

=========================


end