Here is a module, someone wrote a long time ago... You should be able to get an idea how to control this tuner from this code. Hopefully the protocol is the same..
MODULE_NAME='Rotel RT1080' (DEV dvTuner, DEV vdvTuner)
(*{{PS_SOURCE_INFO(PROGRAM STATS) *)
(***********************************************************)
(* FILE CREATED ON: 07/22/2002 AT: 11:10:23 *)
(***********************************************************)
(* FILE_LAST_MODIFIED_ON: 08/14/2002 AT: 14:28:20 *)
(***********************************************************)
(* ORPHAN_FILE_PLATFORM: 1 *)
(***********************************************************)
(***********************************************************)
(*}}PS_SOURCE_INFO *)
(***********************************************************)
(***********************************************************)
(* System Type : Netlinx *)
(***********************************************************)
(* REV HISTORY: *)
(***********************************************************)
(***********************************************************)
(* DEVICE NUMBER DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_DEVICE
(*
dvTuner Real Tuner RS232 Port
vdvTuner Virtual Tuner Device
*)
(***********************************************************)
(* CONSTANT DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_CONSTANT
FEEDBACK1 = 1
TUNER_QUEUE = 2
TunerQueueMAX = 10
(* ROTEL TUNER *)
MAX_PRESETS = 30
TUNER_DIRECT = 10
TUNER_UP = 12
TUNER_DN = 13
TUNER_SAVE = 14
TUNER_BAND = 15
TUNER_REFRESH = 16
(***********************************************************)
(* DATA TYPE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_TYPE
(***********************************************************)
(* VARIABLE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_VARIABLE
CHAR TunerQueue[TunerQueueMAX][20]
INTEGER TunerQueueHead
INTEGER TunerQueueTail
INTEGER TunerQueueIsReady
INTEGER TunerQueueHasItems
INTEGER nPresetLock
FLOAT fTEMP
FLOAT fFrequency
CHAR cTunerBuffer[1000]
INTEGER nTunerSend
CHAR cStationInfo[20]
INTEGER nTunerBand // 32 = FM 0 = AM
INTEGER nCurPreset
LONG lTimeArray[1]
(***********************************************************)
(* LATCHING DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_LATCHING
(***********************************************************)
(* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *)
(***********************************************************)
DEFINE_MUTUALLY_EXCLUSIVE
(***********************************************************)
(* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *)
(***********************************************************)
(* EXAMPLE: DEFINE_FUNCTION <RETURN_TYPE> <NAME> (<PARAMETERS>) *)
(* EXAMPLE: DEFINE_CALL '<NAME>' (<PARAMETERS>) *)
DEFINE_CALL 'CHECK TUNER QUEUE'
{
IF (TunerQueueHasItems AND TunerQueueIsReady)
{
OFF[TunerQueueIsReady]
IF (TunerQueueTail = TunerQueueMax)
TunerQueueTail = 1
ELSE
TunerQueueTail = TunerQueueTail + 1
IF (TunerQueueTail = TunerQueueHead)
OFF[TunerQueueHasItems]
SEND_STRING dvTuner, TunerQueue[TunerQueueTail]
WAIT 1 'TUNER1 QUEUE'
ON[TunerQueueIsReady]
}
}
DEFINE_CALL 'ADD TO TUNER QUEUE' (CHAR cCMD[])
{
IF (TunerQueueHead = TunerQueueMAX)
{
IF (TunerQueueTail <> 1)
{
TunerQueueHead = 1
TunerQueue[TunerQueueHead] = cCMD
ON[TunerQueueHasItems]
}
}
ELSE IF (TunerQueueTail <> TunerQueueHead + 1)
{
TunerQueueHead = TunerQueueHead + 1
TunerQueue[TunerQueueHead] = cCMD
ON[TunerQueueHasItems]
}
}
DEFINE_FUNCTION CHAR[6] SEND_TO_TUNER(INTEGER nFUNC)
{
LOCAL_VAR cSTRING[6]
cSTRING = "$FE,$03,$21,$10" // STRING HEADER
SWITCH(nFUNC)
{
CASE 0: // zero button
{
cSTRING = "cSTRING,$07,$3B"
}
CASE 1: // one button
{
cSTRING = "cSTRING,$0F,$43"
}
CASE 2: // two button
{
cSTRING = "cSTRING,$00,$34"
}
CASE 3: // 3 button
{
cSTRING = "cSTRING,$01,$35"
}
CASE 4: // 4 button
{
cSTRING = "cSTRING,$02,$36"
}
CASE 5: // 5 button
{
cSTRING = "cSTRING,$03,$37"
}
CASE 6: // 6 button
{
cSTRING = "cSTRING,$0E,$42"
}
CASE 7: // 7 button
{
cSTRING = "cSTRING,$04,$38"
}
CASE 8: // 8 button
{
cSTRING = "cSTRING,$05,$39"
}
CASE 9: // 9 button
{
cSTRING = "cSTRING,$06,$3A"
}
CASE TUNER_DIRECT: // direct button
{
cSTRING = "cSTRING,$27,$5B"
}
CASE 11: // preset tune button
{
cSTRING = "cSTRING,$09,$3D"
}
CASE TUNER_UP: // preset + button
{
cSTRING = "cSTRING,$19,$4D"
}
CASE TUNER_DN: // preset - button
{
cSTRING = "cSTRING,$18,$4C"
}
CASE TUNER_SAVE: // MEMORY SET BUTTON
{
cSTRING = "cSTRING,$0D,$41"
}
CASE TUNER_BAND: // TOGGLE BAND
{
cSTRING = "cSTRING,$0B,$3F"
}
CASE TUNER_REFRESH: // GET UPDATED STATION INFO
{
cSTRING = "cSTRING,$FF,$33"
}
}
RETURN cSTRING
}
DEFINE_CALL 'TUNER PRESET' (INTEGER nPreset)
{
IF(!nPresetLock)
{
IF(nPreset>9 && nPreset<=MAX_PRESETS)
{
CALL 'ADD TO TUNER QUEUE' ("SEND_TO_TUNER(nPreset/10)")
CALL 'ADD TO TUNER QUEUE' ("SEND_TO_TUNER(nPreset%10)")
}
ELSE IF(nPreset>0 && nPreset<=9)
{
CALL 'ADD TO TUNER QUEUE' ("SEND_TO_TUNER(nPreset)")
IF(nPreset<4) // TUNER WILL WAIT 3 SECS FOR A SECOND DIGIT IF POSSIBLE
{
TIMELINE_PAUSE(TUNER_QUEUE)
ON[nPresetLock]
WAIT 30 'PRESET LOCKOUT'
{
TIMELINE_RESTART(TUNER_QUEUE)
OFF[nPresetLock]
}
}
}
}
}
(***********************************************************)
(* STARTUP CODE GOES BELOW *)
(***********************************************************)
DEFINE_START
TunerQueueHead = 1
TunerQueueTail = 1
TunerQueueIsReady = 1
TunerQueueHasItems = 0
CREATE_BUFFER dvTuner,cTunerBuffer
lTimeArray[1] = 100
TIMELINE_CREATE(FEEDBACK1,lTimeArray,1,TIMELINE_RELATIVE,TIMELINE_REPEAT)
lTimeArray[1] = 300
TIMELINE_CREATE(TUNER_QUEUE,lTimeArray,1,TIMELINE_RELATIVE,TIMELINE_REPEAT)
(***********************************************************)
(* THE EVENTS GOES BELOW *)
(***********************************************************)
DEFINE_EVENT
DATA_EVENT[dvTuner]
{
ONLINE:
{
SEND_COMMAND dvTuner,"'SET BAUD 4800,N,8,1 485 DISABLE'"
SEND_COMMAND dvTuner,"'CHARD-20'"
}
}
TIMELINE_EVENT[FEEDBACK1]
{
LOCAL_VAR I
//BONUS CHANNEL FEEDBACK
//PRESET STATES
FOR(I=1;I<=MAX_PRESETS;I++)
{
[vdvTuner,I] = nCurPreset = I
}
//TUNER BAND
//FM
[vdvTuner,31] = nTunerBand
//AM
[vdvTuner,32] = (!nTunerBand)
}
TIMELINE_EVENT[TUNER_QUEUE]
{
CALL 'CHECK TUNER QUEUE'
}
DATA_EVENT[vdvTuner]
{
COMMAND:
{
LOCAL_VAR cMsg[42]
cMsg = DATA.TEXT
SELECT
{
ACTIVE(FIND_STRING(cMsg,'BAND=',1)):
{
REMOVE_STRING(cMsg,'BAND=',1)
SELECT
{
ACTIVE(FIND_STRING(cMsg,'AM',1)):
{
IF(nTunerBand)
{
nCurPreset = 0 // THESE BECOME UNKNOWN
fFrequency = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_BAND))
}
}
ACTIVE(FIND_STRING(cMsg,'FM',1)):
{
IF(!nTunerBand)
{
nCurPreset = 0 // THESE BECOME UNKNOWN
fFrequency = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_BAND))
}
}
ACTIVE(FIND_STRING(cMsg,'T',1)):
{
nCurPreset = 0 // THESE BECOME UNKNOWN
fFrequency = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_BAND))
}
}
}
ACTIVE(FIND_STRING(cMsg,'BAND?',1)):
{
IF(nTunerBand)
{
SEND_STRING vdvTuner,"'BAND=FM'"
}
ELSE
{
SEND_STRING vdvTuner,"'BAND=AM'"
}
}
ACTIVE(FIND_STRING(cMsg,'TUNE=',1)):
{
REMOVE_STRING(cMsg,'TUNE=',1)
SELECT
{
ACTIVE(FIND_STRING(cMsg,'+',1)): // TUNE +
{
nCurPreset = 0 // THESE BECOME UNKNOWN
fFrequency = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_UP))
}
ACTIVE(FIND_STRING(cMsg,'-',1)): // TUNE -
{
nCurPreset = 0 // THESE BECOME UNKNOWN
fFrequency = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_DN))
}
ACTIVE(FIND_STRING(cMsg,'.',1)): // TUNE FM
{
IF(!nTunerBand)
{
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_BAND))
}
fTEMP = ATOF(cMsg)
IF(LENGTH_STRING(cMsg) >= 4) // CHECK FOR VALID FM RANGE
{
IF((LENGTH_STRING(cMsg)= 5) && (fTEMP <= 108.0))
{
nCurPreset = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_DIRECT))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(1))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[3]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[5]")))
fFrequency = fTEMP
}
ELSE IF((LENGTH_STRING(cMsg)= 4) && (fTEMP >= 87.5))
{
nCurPreset = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_DIRECT))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[1]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[2]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[4]")))
fFrequency = fTEMP
}
}
}
ACTIVE(1): // TUNE AM
{
IF(nTunerBand)
{
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_BAND))
}
fTEMP = ATOF(cMsg)
IF((LENGTH_STRING(cMsg) = 3) && (fTEMP <= 990) && (fTEMP >= 580))
{
nCurPreset = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_DIRECT))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[1]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[2]")))
fFrequency = fTEMP
}
ELSE IF((LENGTH_STRING(cMsg) = 4) && (fTEMP <= 1710) && (fTEMP >= 1000))
{
nCurPreset = 0
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_DIRECT))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[1]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[2]")))
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(ATOI("cMsg[3]")))
fFrequency = fTEMP
}
}
}
}
ACTIVE(FIND_STRING(cMsg,'TUNE?',1)):
{
SEND_STRING vdvTuner,"'TUNE=',FTOA(fFrequency)"
}
ACTIVE(FIND_STRING(cMsg,'PRESET=',1)):
{
REMOVE_STRING(cMsg,'PRESET=',1)
SELECT
{
ACTIVE(FIND_STRING(cMsg,'+',1)): // PRESET +
{
IF(nCurPreset<MAX_PRESETS)
{
nCurPreset++
}
ELSE
{
nCurPreset=1
}
CALL 'TUNER PRESET' (nCurPreset)
SEND_STRING vdvTuner,"'PRESET=',ITOA(nCurPreset)"
fFrequency = 0
}
ACTIVE(FIND_STRING(cMsg,'-',1)): // PRESET -
{
IF(nCurPreset>1)
{
nCurPreset--
}
ELSE
{
nCurPreset=MAX_PRESETS
}
CALL 'TUNER PRESET' (nCurPreset)
SEND_STRING vdvTuner,"'PRESET=',ITOA(nCurPreset)"
fFrequency = 0
}
ACTIVE(1): // GOTO PRESET
{
nCurPreset=ATOI(cMsg)
IF(nCurPreset>MAX_PRESETS) // CHECK OUR RANGE
{
nCurPreset=MAX_PRESETS
}
IF(nCurPreset<1)
{
nCurPreset=1
}
CALL 'TUNER PRESET' (nCurPreset)
SEND_STRING vdvTuner,"'PRESET=',ITOA(nCurPreset)"
fFrequency = 0
}
}
}
ACTIVE(FIND_STRING(cMsg,'PRESET?',1)): // CHECK PRESET #
{
IF(nCurPreset)
{
SEND_STRING vdvTuner,"'PRESET=',ITOA(nCurPreset)"
}
ELSE
{
SEND_STRING vdvTuner,"'PRESET=UNKNOWN'"
}
}
ACTIVE(FIND_STRING(cMsg,'STATION?',1)): // GET STATION DATA FROM TUNER
{
SEND_STRING vdvTuner,"'STATION=',cStationInfo"
}
ACTIVE(FIND_STRING(cMsg,'STORE=',1)): // STORE CURRENT STATION AS PRESET #
{
REMOVE_STRING(cMsg,'STORE=',1)
nCurPreset=ATOI(cMsg)
IF(nCurPreset>MAX_PRESETS) // CHECK OUR RANGE
{
nCurPreset=MAX_PRESETS
}
IF(nCurPreset<1)
{
nCurPreset=1
}
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_SAVE))
CALL 'TUNER PRESET' (nCurPreset)
SEND_STRING vdvTuner,"'PRESET=',ITOA(nCurPreset)"
}
}
}
}
(***********************************************************)
(* THE ACTUAL PROGRAM GOES BELOW *)
(***********************************************************)
DEFINE_PROGRAM
WAIT 50 'POLL TUNER INFO'
{
CALL 'ADD TO TUNER QUEUE' (SEND_TO_TUNER(TUNER_REFRESH))
}
IF(LENGTH_STRING(cTunerBuffer))
{
LOCAL_VAR nPos, nLen, nFDSearch, cMsg[42], cStationTemp[20]
nPos = FIND_STRING(cTunerBuffer,"$FE",1)
nLen = LENGTH_STRING(cTunerBuffer)
IF(nPos)
{
// Drop any leading garbage
cTunerBuffer=RIGHT_STRING(cTunerBuffer,nLen-nPos+1)
IF(FIND_STRING(cTunerBuffer,"$FE",2)) (* IS THERE MORE THAN 1 MESSAGE IN THE BUFFER *)
{
cMsg = LEFT_STRING(cTunerBuffer,FIND_STRING(cTunerBuffer,"$FE",2)-1)
REMOVE_STRING(cTunerBuffer,cMsg,1)
}
ELSE IF(nLen > cTunerBuffer[2]) (* DO WE HAVE A WHOLE MESSAGE YET *)
{
cMsg = cTunerBuffer
// we already checked for the start of another message so we don't need anything in the buffer now
CLEAR_BUFFER cTunerBuffer
}
IF(LENGTH_STRING(cMsg))
{
IF(LENGTH_STRING(cMsg)>cMsg[2])
{
nFDSearch = 1
WHILE(FIND_STRING(cMsg,"$FD",nFDSearch))
{
nFDSearch = FIND_STRING(cMsg,"$FD",nFDSearch)
cMsg[nFDSearch] = cMsg[nFDSearch] + cMsg[nFDSearch+1]
cMsg = "LEFT_STRING(cMsg,nFDSearch),RIGHT_STRING(cMsg,LENGTH_STRING(cMsg)-nFDSearch-1)" (* DROP ONE FROM THE MIDDLE *)
nFDSearch++
}
IF((cMsg[3] = $21) && (cMsg[4] = $20) && (LENGTH_STRING(cMsg) = 21))
{
IF(nTunerBand <> (cMsg[7] & 32)) // IF THE BAND CHANGED, REPORT IT
{
IF(nTunerBand)
{
SEND_STRING vdvTuner,"'BAND=AM'"
}
ELSE
{
SEND_STRING vdvTuner,"'BAND=FM'"
}
}
nTunerBand = (cMsg[7] & 32)
cStationTemp = MID_STRING(cMsg,10,9) // ROTEL TUNER SENDS $1E INSTEAD OF LOWER CASE 'z'
IF(cStationTemp[9] = $1E)
{
cStationTemp[9] = 'z'
}
IF(cStationTemp<>cStationInfo)
{
cStationInfo=cStationTemp
SEND_STRING vdvTuner,"'STATION=',cStationInfo"
}
}
}
CLEAR_BUFFER cMsg
}
}
}
(***********************************************************)
(* END OF PROGRAM *)
(* DO NOT PUT ANY CODE BELOW THIS COMMENT *)
(***********************************************************)
Here's a large pdf with a whole bunch of Rotel rs-232. perhaps one of them will work for you.
Great file, i have it also, it is completly ok except device ID. It is 23, everything other is OK and it is working.
EXAMPLE
SEND_STRING dvROTEL,"$FE,$03,$23,$10,$01,$37" //power on
SEND_STRING dvROTEL,"$FE,$03,$23,$10,$02,$38" //power off
SEND_STRING dvROTEL,"$FE,$03,$23,$10,$08,$3E" //tune up
SEND_STRING dvROTEL,"$FE,$03,$23,$10,$09,$3F" //tune down
1. $FE .......................................START
2. $03 ........................................COUNT
3. $23 ........................................DEVICE ID
4. $10 ........................................TYPE OF COMMAND
5. $09 ........................................COMMAND
6. $3F ........................................CHECKSUM (2+3+4+5 in hex)
Comments
Here is a module, someone wrote a long time ago... You should be able to get an idea how to control this tuner from this code. Hopefully the protocol is the same..
Great file, i have it also, it is completly ok except device ID. It is 23, everything other is OK and it is working.
EXAMPLE
1. $FE .......................................START
2. $03 ........................................COUNT
3. $23 ........................................DEVICE ID
4. $10 ........................................TYPE OF COMMAND
5. $09 ........................................COMMAND
6. $3F ........................................CHECKSUM (2+3+4+5 in hex)
Commands you can use from PDF file !