lördag 22 november 2014

iRobot Roomba IR-remote: Send CLEAN command


Intro

The cheaper models of iRobot Roomba -I have model 620- doesn't come with a scheduler. So you have to manually reach down and push the clean-button for it to start clean your house.
Roomba provides an infrared remote control to start up the cleaner. That is what we going to mimic here.

I have summarized 2 articles that I've found from the internet according this remote. The other is Virtual Wall with 12F683 and the other is "Tiny Remote" for Roomba, which uses other PIC and doesn't have source code written in C. Links to both you can find at the bottom of this article.

Roombas IR-remote works on 38Khz carrier and the bits for 1 and 0 are following:


The code consist of 8 bits and for CLEAN it is following: 10001000
For more codes refer to "Tiny Remote" site.


The software

When powering up the circuit, the program sends "CLEAN"-command 5 times, with 32ms delay between commands and then falls asleep. I did some experiment with different scenarios, anything from having it send the code once and looping it for infinite time. When sending once, Roomba didn't always react to the command. And to send it longer period, it became confused and sometimes stopped and started again the cleaning cycle. Also the delay between the code had some strange behaviors, so putting up 8 bits times 4ms = 32ms, did the thing. With another words the code and delay between them are equal length. Whole 5 times cycle takes therefore 5x32ms + 4x32ms (last delay doesn't count) = 288ms.

The code is pretty forward and easy to follow. Here is flow chart to explain how it works:


And the code itself:
 /*   
  * File:  main.c  
  * Author: Juice  
  *  
  * Created on den 18 november 2014, 23:58  
  */  
 #include <xc.h>  
 #ifndef _XTAL_FREQ  
  #define _XTAL_FREQ 2000000  
 #endif  
 #define PWM_OFF CCP1CON = 0x10  
 #define PWM_ON CCP1CON = 0x1c  
 #define BURST_COUNT 2         // How many IR bursts to send (repeat of pattern 1000)  
 #define LOOP_COUNT 5          // How many times to send code  
 int bit_high(void) //Subroutine for bit 1 = 3ms on, 1ms off  
 {  
        PWM_ON;  
       __delay_us(3000);  
       PWM_OFF;  
       __delay_us(1000);  
 }  
 int bit_low(void) //Subroutine for bit 0 = 1ms on, 3ms off  
 {  
        PWM_ON;  
       __delay_us(1000);  
       PWM_OFF;  
       __delay_us(3000);  
 }  
 int main(void)  
 {  
   int i;  
   int l;  
   OSCCON = 0x51;           // Internal 2MHz osc.  
   ADCON0 = 0;             // all pins digital  
   ANSEL = 0;             // all pins digital  
   CMCON0 = 7;             // Comparators off.  
   TRISIO = 0;             // all output  
   GPIO = 0;              // all pins low  
   PR2 = 0b00001100 ;         // Set up PWM for roughly 38kHz  
   T2CON = 0b00000100 ;  
   CCPR1L = 0b00000110 ;  
   PWM_OFF;  
   PSA = 0;              // Don't use Timer0 prescalar  
   WDTCON = 0b00010000;        // Prescalar = 1000 = 8192 = 272ms  
   l = LOOP_COUNT;  
   while( l-- )  {          // how many times to send code.  
                     // sending 2 times 1000, since code is 10001000  
     i = BURST_COUNT;  
     while( i-- )  
     {     
       bit_high();         // send the first 1  
       int x;           // loop 3 times bit_low  
       for ( x = 0; x < 3; x++ ) {  
         bit_low();       //send 0  
        }  
     }  
     __delay_ms(32);         // delay between commands 3+1ms=4ms for one bit. 8bit * 4ms = 32ms.  
   }  
  asm("sleep") ;            // Put processor to sleep.  
  }  

To edit the code and compile, you need MPLAB X IDE v2.25 and MPLAB® XC8 Compiler v1.33B (Links at the bottom of this article.).

For those who doesn't need to edit the source code, here is ready compiled HEX-file for flashing: Roomba_clean.HEX

And for flashing the PIC, there are many hardwares to choose from. One of the cheapest and probably most popular is the K150 USB PIC Programmer, which you can purchase for example from Ebay.


The hardware


Parts list:
  • Microship PIC 12F683 8-Pin Flash-Based, 8-Bit CMOS Microcontroller
  • R1 Resistor 330ohm 0.25W
  • R2 Resistor 40ohm 0.25W
  • R3 Resistor 100ohm 0.25w * see text below
  • C1 Capacitor 100nF
  • T1 Transistor 2N3904 (I tested with BC549, 550, 560. The PIC is also cabable to power up LED directly, but with this setup we push around 85mA thru the IR-LED, to provide enough range to the system.)
  • D1 IR-LED 940nm
It can be build easily on small Veroboard. Nothing critical here.
Mount the C1 as near as possible to the PIC pins 1 and 8 (Decoupling capacitor).
The input voltage can be between 3-5,5V. Reduce the R2 slightly (~22-27 ohms) if using 3V.







Bonus: Tellstick


For Tellstick users this circuit can be powered from USB wall charger and compatible receiver (Nexa etc.).
The R3 might be needed to drain the wall charger capacitors out. Otherwise it can take few minutes before the circuit powers off and you can start it again. (In case Roomba won't start and you like to repeat the command.)

Tellsdus Live! event handler. In swedish, but pretty straightforward.

Just create event on Tellstick to shutdown the receiver few seconds after it turns on.

Thats it!
Please feel free to comment and even link/show your own project in case this was any help at all!

P.S För svenska besökare kan jag även tänka mig att sälja färdigflashad PIC för en billig peng.


References / Thanks to:
http://www.enide.net/webcms/?page=tiny-remote
http://misc.ws/2014/08/09/diy-virtual-wall-for-roomba-part-two/
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010115
http://www.microchip.com/pagehandler/en-us/family/mplabx/
http://www.microchip.com/pagehandler/en-us/devtools/mplabxc/home.html



Inga kommentarer:

Skicka en kommentar