Şener Delibaş
Şener Delibaş

Reputation: 1

Infrared Remote for Android with Android Studio

I have a homework, I have to make a remote for my Android phone. There is something I want to ask you if you can help me that would be very nice.

I am using Android Studio for doing my homework I researched and found some codes I have a problem at the function

transmit(frequency, pattern);     

I read the value with Arduino infrared receiver and I get the value 874140405. I don't know how to use this value and I don't know actually transmit function works. I saw in the internet there are a pattern arrays and in arrays a lot of values which I don't know what is this and what is the difference for other devices if you have a little time can you explain this for me or if you have another idea this can be useful for my homework can you help me?

Upvotes: 0

Views: 2263

Answers (2)

krevelen
krevelen

Reputation: 391

There are many sources available for converting Original Button Codes (OBCs) to Infrared patterns in the Pronto/NEC protocol, e.g. Remote Central.

My implementation in Kotlin with recent Android SDKs is as follows:

In my AndroidManifest.xml:

<manifest ...>
    <uses-permission android:name="android.permission.TRANSMIT_IR" android:required="false" />
    <uses-feature android:name="android.hardware.consumerir" />
</manifest>

In my MainActivity.kt:

class MainActivity : ... {

    private lateinit var irMgr: ConsumerIrManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        getSystemService(CONSUMER_IR_SERVICE)?.let {
            irMgr = it as ConsumerIrManager
        }
    }

    /**
     * [obc] is the **Original Button Code**, e.g. `152` (POWER OFF)
     * [carrierCycles] is the [Byte]-value for the **IR carrier frequency**, e.g. `0x6d` (= 38028 Hz)
     */
    fun doTransmitInfrared(obc: Int, carrierCycles: Byte = 0x6d) {
        if (!irMgr.hasIrEmitter()) return

        val wavelengthMicros = carrierCycles * MICROSECONDS_PER_CYCLE
        val frequencyHertz = (1_000_000 / wavelengthMicros).toInt()
        val bytes = encodeBurstPairs(obc)
        val pattern = bytes.wordsToMicroseconds(wavelengthMicros.toInt())
        println("Sending IR function: ${obc}, carrier frequency: $frequencyHertz Hz," +
                " total duration ${pattern.sum()} ${TimeUnit.MICROSECONDS}," +
                " pattern: ${bytes.encodeHex().chunked(4).joinToString(" ") { it }}")
        irMgr.transmit(frequencyHertz, pattern)
    }
}

In my Util.kt:

const val MICROSECONDS_PER_CYCLE = 0.241246
private val leadInBurstPair = 0x00AC00AB.toByteArray()
private val leadOutBurstPair = 0x00150689.toByteArray()
private val hexChars = "0123456789ABCDEF".toCharArray()

fun Int.toByteArray(n: Int = Int.SIZE_BYTES) =
    ByteArray(n) { (this shr ((n - 1 - it) shl 3)).toByte() }

fun ByteArray.encodeHex(): String =
    CharArray(size * 2) { i ->
        val unsigned = 0xff and this[i shr 1].toInt()
        val j = if (i and 1 == 0) unsigned / Char.SIZE_BITS else unsigned % Char.SIZE_BITS
        hexChars[j]
    }.concatToString()

/**
 * encode bits as little-endian pairs of 2-byte words, for IR burst ON and OFF durations
 */
fun ByteArray.toBurstPairs() =
    BitSet.valueOf(this).let { bits ->
        ByteArray(this.size * Byte.SIZE_BITS * 4) { i ->
            if (i % 2 == 0)
                0x00 // both ON and OFF duration start with `0x00`
            else if (i % 4 == 1)
                0x15 // the ON duration is always `0x15` (21 decimal)
            else if (bits.get(i / 4))
                0x41 // bit is TRUE / `1`, longer OFF duration (65)
            else
                0x16 // bit is FALSE / `0`, shorter OFF duration (22)
        }
    }

fun encodeBurstPairs(obc: Int, device: Int = 7, subDevice: Int = 7): ByteArray {
    return leadInBurstPair +
        byteArrayOf(
            device.toByte(),
            subDevice.toByte(),
            obc.toByte(),
            (0xFF - obc).toByte()
        ).toBurstPairs() +
        leadOutBurstPair
}

fun ByteArray.wordsToMicroseconds(wavelengthMicros: Int): IntArray {
    var offset = 0
    return IntArray(size / 2) { 
        ( (0xFF and this[offset++].toInt()) shl Byte.SIZE_BITS)
        + (0xFF and this[offset++].toInt()) * wavelengthMicros
    }
}

Upvotes: 1

Dr.Fre
Dr.Fre

Reputation: 1

The numbers that you see are supposed to be the IR signals. To use them, try to convert the signals to a hex value, then send the hex value to control other devices.

Upvotes: -2

Related Questions