SilverLit RC driver

This short write-up to documents the SilverLit Remote Control vehicle protocol. It implementation, allows you to control your Arduino creation using the remote control that came with the SilverLit RC set. This set was sold through Costco and included a dump truck, flatbed, bulldozer or crane.

Protocol

I reverse engineered the protocol. The remote control first transmits a header burst of 38 kHz infrared light. The bits are then transferred as short or longer period with no IR light (space) followed by short burst of IR light (mark).

encoding
header 1.778 msec mark
13 bits data bits
1 bit stop bit

The bits are encoded as

bit value encoding
“0” 0,400 msec space, followed by 0.722 msec mark
“1” 1.037 msec space, followed by 0.722 msec mark

The data bits

bit(s) meaning
[12:11] vehicle identifier (00=dumptruck, 01=flatbed, 10=bulldozer, 11=crane)
[10:9] no special meaning. 11 when bit[7] is 0, otherwise 00
[8] 0 for backward
[7] 0 for forward
[6] 1 for right
[5] 1 for left
[4] 1 for down
[3] 1 for up
[2] 1 for light on
[1:0] checksum (see below)

The CRC is calculated as follows

checksum = bit[11:12] ^ bit[10] ^ bit[9:8] ^ bit[7:6] ^bit[5:4] ^ bit[3:2]

Note that bit 11 and 12 are reversed.

Implementation

I added a few lines to implement support for SilverLit remote vehicle/car protocol. The library was forked from Chris Young’s IRLib. His rewrite made it easy to add this new protocol. The library is available at

Note that you can’t have the original IRLib library installed because it will conflict.

Sources

  • SilverLit Infrared demo, spi_master.ino
    /*
     * Display codes coming from SilverLit remote control
     * Detect an IR receiver such as TSOP38238 to RECV_PIN (see https://learn.adafruit.com/using-an-infrared-library/hardware-needed)
     * Protocol details can be found at https://coertvonk.com/technology/embedded/arduino-ir-for-silverlit-rc-vehicles-12970
     * By Sander Vonk, 2015
     */
    
    #include <IRLib.h>
    
    int RECV_PIN = 11;
    
    IRrecv My_Receiver( RECV_PIN );
    IRdecode My_Decoder;
    unsigned int Buffer[RAWBUF];
    
    void setup()
    {
        Serial.begin( 9600 );
        My_Receiver.enableIRIn();
        My_Decoder.UseExtnBuf( Buffer );
    }
    
    
    void loop()
    {
        if ( My_Receiver.GetResults( &My_Decoder ) ) {
            My_Receiver.resume();
            if ( My_Decoder.decode() ) {
                unsigned long const data = My_Decoder.value;
    
                if ( (data & 0b111111100L) != 0b110000000L ) {  // don't display idle codes
    
                    char const * vehicle;
                    switch ( data >> 11 ) {
                        case 0: vehicle = "dumptruck "; break;
                        case 1: vehicle = "flatbed "; break;
                        case 2: vehicle = "bulldozer "; break;
                        case 3: vehicle = "crane "; break;
                    }
                    Serial.print( vehicle );
    
                    if ( bitRead( data, 8 ) == 0 ) Serial.print( "backward " );
                    if ( bitRead( data, 7 ) == 0 ) Serial.print( "forward " );
                    if ( bitRead( data, 6 ) == 1 ) Serial.print( "right " );
                    if ( bitRead( data, 5 ) == 1 ) Serial.print( "left " );
                    if ( bitRead( data, 4 ) == 1 ) Serial.print( "down " );
                    if ( bitRead( data, 3 ) == 1 ) Serial.print( "up " );
                    if ( bitRead( data, 2 ) == 1 ) Serial.print( "light " );
                    Serial.println();
                }
            }
        }
    }

The hardware setup uses the TSOP38238 as described in AdaFruit’s Receiving and Decoding IR.