unknown 'error' message in Diagnostcs - processor taking too long to boot up!
My processor is taking a good 6-8 mins to boot up, and I believe I've narrowed the fault down to one of my modules (after commenting out each module, compiling, uploading, checking processor boot time), but can't quite work out what part of my module is causing the problem.
During boot up I telnet to the processor as early as possible and poll the processor with "show buffer".
Without my suspected faulty module, the Interpreter maxes out at about 188 and then clears back to zero once all devices are online pretty quickly.
When my module is running, the interpreter will get up to about 600 over about 6-8 minutes, before eventually clearing back to zero.
In diagnostics I also repeatedly get this message which I don't get when I run the code without my module:
"CIMessageRouter - Unknown ObjectID 30"
Does anyone know what this relates to? Knowing this could help me narrow down the fault in my code.
I've spoke to AMX tech support here in the UK, but they are not allowed access to these diagnostic messages.... apparently only guys in the AMX development team in the USA are allowed knowledge of them!
thanks
During boot up I telnet to the processor as early as possible and poll the processor with "show buffer".
Without my suspected faulty module, the Interpreter maxes out at about 188 and then clears back to zero once all devices are online pretty quickly.
When my module is running, the interpreter will get up to about 600 over about 6-8 minutes, before eventually clearing back to zero.
In diagnostics I also repeatedly get this message which I don't get when I run the code without my module:
"CIMessageRouter - Unknown ObjectID 30"
Does anyone know what this relates to? Knowing this could help me narrow down the fault in my code.
I've spoke to AMX tech support here in the UK, but they are not allowed access to these diagnostic messages.... apparently only guys in the AMX development team in the USA are allowed knowledge of them!
thanks
Comments
module_name='SMC_Arcam_T32_v0_9' (dev dv, dev vdvArray[], char presetXMLFile[]) /******************************************************************************************* * System Type : NetLinx * * Program By : Mark Bertenshaw (MJB) * * Rev. History : * 02/06/09: v0.7 - MJB - Initial Build (based on SMC_Arcam_DT91 module, hence version) * 23/07/09: v0.8 - MJB - Added read/write to disc of preset structure in XML format * 26/10/10: v0.9 - MJB - XML file IO name now passed into module, and general code update *******************************************************************************************/ /******************************************************************************************* * Device Information : * * Proven for: Arcam T32 DAB/FM/AM/SIRIUS tuner, running software v1.98 * * Connector Type: Arcam : D-Sub 9pin female (cross) - AMX : D-Sub 9pin female * pin 2 : Rx - pin 2 : Rx * pin 3 : Tx - pin 3 : Tx * pin 4 : Gnd - pin 5 : Gnd * * Communication Format * Baud rate: 38400bps * data length: 8 bits * Parity: None * Stop bit: 1 bit * Flow control: None *******************************************************************************************/ /******************************************************************************************* * Sample coding required for including this module with multiple touch panels: * * define_device * dvArcamDT91 = 05001:1:0 * * dvTP1_ArcamT32 = 10001:1:0 * dvTP2_ArcamT32 = 10002:1:0 * * vdvTP1_ArcamT32 = 33001:1:0 * vdvTP2_ArcamT32 = 33001:1:0 * * define_variable * dev TP_ArcamT32Array[] = { dvTP1_ArcamT32, dvTP2_ArcamT32 } * dev vTP_ArcamT32Array[] = { vdvTP1_ArcamT32, vdvTP2_ArcamT32 } * * define_start * define_module 'SMC_Arcam_T32_v0_7' m_SMC_Arcam_T32 (dvArcamT32, vTP_ArcamT32Array) * * define_program * // for example: * // when feedback is required for dvTP1, use command: * // combine_devices(vTP_ArcamT32Array[1],TP_ArcamT32Array[1]]) * // when feedback is no longer needed, use command: * // uncombine_devices(vTP_ArcamT32Array[1]) *******************************************************************************************/ /******************************************************************************************* * Device Definitions *******************************************************************************************/ define_device /******************************************************************************************* * Constant Definitions *******************************************************************************************/ define_constant ver = '0.9 26/10/10 - MJB' // The Version of this module // timeline IDs tlTx = 1 // timeline to manage command transmission tlCommsReady = 2 // timeline to manage commsReady flag tlUpdateStatus = 3 // timeline to update status after pre-defined time tlPowerOn = 4 // timeline to pause module whilst arcam powers on tlPowerOff = 4 // timeline to pause module whilst arcam powers off // other zone = $01 /******************************************************************************************* * data Type Definitions *******************************************************************************************/ define_type structure _arcamT32 { integer debug // Are debug messages required or not char commStack[500] char commTx[500] char commRx[500] char passThru[1000] // String of passThru command requested integer commsReady // Is device ready to receive commands integer tlTxActive // is timeline running integer tlCommsReadyActive // is timeline running integer tlUpdateStatusActive // is timeline running integer tlPowerOnActive // is timeline running integer tlPowerOffActive // is timeline running integer Power // Power status (0 or 1 only) integer stationType // 0=FM, 1=AM, 2=DAB, 3=SIRIUS, 4=AUX char stationName[200] // Current station name char stationGenre[200] // Current station genre char stationInfo[200] // Current station info char fmFreq[20] // Tuned FM (or AM) frequency integer fmStereoMono // FM in Stereo or Mono (0 = Stereo, 1 = Mono) integer fmRDSDisabled // is FM RDS disabled (0 = no, 1 = yes) integer signalStrength // Current station signal strength (1-16) integer dabMPEG // Current station DAB MPEG mode (0-3) integer dabBitrate // Current station DAB data rate (0 - 224kb/s) integer dabScan // DAB scanning status (0/1/2) integer presetCurrent // Currently selected Preset station integer presetType[50] // 0=FM, 1=AM, 2=DAB, 3=SIRIUS char presetName[50][200] // Preset Name from list char vRS232[2] // The rs232 protocol version char vSoftware[2] // The main software version char vDAB[2] // The DAB version } /******************************************************************************************* * Variable Definitions *******************************************************************************************/ define_variable non_volatile _arcamT32 arcamT32 // Status of Device integer PresetStore_Called // Tracks whether a Preset Store command has been called integer vdvArray_Channels_Sub_101_150[] = { 001,002,003,004,005,006,007,008,009,010,011,012,013,014,015,016,017,018,019,020,021,022,023,024,025,026,027,028,029,030, 031,032,033,034,035,036,037,038,039,040,041,042,043,044,045,046,047,048,049,050,051,052,053,054,055,056,057,058,059,060, 061,062,063,064,065,066,067,068,069,070,071,072,073,074,075,076,077,078,079,080,081,082,083,084,085,086,087,088,089,090, 091,092,093,094,095,096,097,098,099,100, 151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180, 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210, 211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240, 241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 } integer vdvArray_Channels_101_150[] = { 101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120, 121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140, 141,142,143,144,145,146,147,148,149,150 } // timeline timings long tlTxTime[] = {100} // 1/10 sec timeline - looping long tlCommsReadyTime[] = {10000} // 10 sec timeline long tlUpdateStatusTime[] = {30000} // 30 sec timeline long tlPowerOnTime[] = {4000} // 4 sec timeline long tlPowerOffTime[] = {4000} // 4 sec timeline /******************************************************************************************* * Latching Definitions *******************************************************************************************/ define_latching /******************************************************************************************* * Mutually Exclusive Definitions *******************************************************************************************/ define_mutually_exclusive /******************************************************************************************* * Module and Include Definitions *******************************************************************************************/ /******************************************************************************************* * Subroutines/Functions *******************************************************************************************/ define_function char[17] devToString(dev dv) { return "format('%d',dv.number),':',format('%d',dv.port),':',format('%d',dv.system)" } define_function virtualCommandParse (char vdvArrayCommand[500]) { local_var char Instruction[100], Identifier[1], DataPt1[100], DataPt2[100], DataPt3[100] local_var integer CmdData // Seperate Rx command into component sections.... select { active(find_string(vdvArrayCommand,'?',1)): // A data request Identifier { Instruction = remove_string(vdvArrayCommand,'?',1) // Instruction is all data before Identifier } active(find_string(vdvArrayCommand,'=',1)): // A data request Identifier { Instruction = remove_string(vdvArrayCommand,'=',1) // Instruction is all data before Identifier } } Identifier = right_string(Instruction,1) // Set value of Identifier Instruction = left_string(Instruction,length_string(Instruction)-1) // Remove Identifier from Instruction if(Instruction = "'passThru'") // Do not parse rest of data if arcamT32.arcamT32.passThru command is Rx { arcamT32.passThru = "vdvArrayCommand" do_push(vdvArray[],246) } else { if(find_string(vdvArrayCommand,':',1)) // if remaining data is split by ':' { DataPt1 = remove_string(vdvArrayCommand,':',1) // DataPt1 is all data before ':' DataPt1 = left_string(DataPt1,length_string(DataPt1)-1) // Remove ':' from Instruction if(find_string(vdvArrayCommand,':',1)) // if remaining data is again, split by ':' { DataPt2 = remove_string(vdvArrayCommand,':',1) // DataPt2 is all data before ':' DataPt2 = left_string(DataPt2,length_string(DataPt2)-1) // Remove ':' from Instruction DataPt3 = vdvArrayCommand // Remaining data is required for Instruction } else { DataPt2 = vdvArrayCommand // Remaining data is required for Instruction } } else { DataPt1 = vdvArrayCommand // Remaining data is required for Instruction } // Process each command dependant on Instruction, then Identifier.... switch(Instruction) { case 'version': { send_string vdvArray,"'version=',Ver" } case 'debug': { switch(Identifier) { case '?': { send_string vdvArray,"'debug=',itoa(arcamT32.debug)" // Send integer value select // Send text value { active(arcamT32.debug = 0): { send_string vdvArray,"'debug=off'" } active(arcamT32.debug = 1): { send_string vdvArray,"'debug=on'" } } } case '=': { select { active((DataPt1 = '0')OR(DataPt1 = 'off')): { arcamT32.debug = 0 } active((DataPt1 = '1')OR(DataPt1 = 'on')): { arcamT32.debug = 1 } active((DataPt1 = '3')OR(DataPt1 = 'toggle')): { arcamT32.debug = !arcamT32.debug } } } } } } } } define_function txCommand(integer comm) { local_var char StringToSend[30] // Local string to create, which gets transmitted to device StringToSend = "''" // Clear StringToSend initially as a precautionary measure switch (comm) { case 001: { StringToSend = "$21,$01,$00" } // Insert code for FM : Stereo case 002: { StringToSend = "$21,$01,$01" } // Insert code for FM : Mono case 003: { StringToSend = "$20,$01,$F1" } // Insert code for DAB : Erase current station list case 004: { StringToSend = "$20,$01,$F0" } // Insert code for DAB : Scan for new stations case 005: { StringToSend = "$16,$01,$01" } // Insert code for FM/AM Freq : Increase case 006: { StringToSend = "$16,$01,$00" } // Insert code for FM/AM Freq : Decrease case 007: { StringToSend = "$22,$01,$00" } // Insert code for FM RDS : Enable case 008: { StringToSend = "$22,$01,$01" } // Insert code for FM RDS : Disabled case 022: // Insert code for Next station { switch(arcamT32.stationType) { case 01: StringToSend = "$26,$01,$F0" // FM/AM case 03: StringToSend = "$08,$02,$11,$50" // DAB (using RC5 simulate command for "right") } } case 023: // Insert code for previous station { switch(arcamT32.stationType) { case 01: StringToSend = "$26,$01,$F1" // FM case 03: StringToSend = "$08,$02,$11,$51" // DAB (using RC5 simulate command for "left") } } case 027: { StringToSend = "$00,$01,$01" } // Insert code for Power On case 028: { StringToSend = "$00,$01,$00" } // Insert code for Power Off case 031: { StringToSend = "$24,$01,$00" } // Insert code for Source : FM case 032: { StringToSend = "$24,$01,$01" } // Insert code for Source : AM case 033: { StringToSend = "$24,$01,$02" } // Insert code for Source : DAB case 034: { StringToSend = "$24,$01,$03" } // Insert code for Source : SIRIUS case 035: { StringToSend = "$24,$01,$04" } // Insert code for Source : AUX case 044: { StringToSend = "$08,$02,$11,$7D" } // Insert code for system menu case 045: { StringToSend = "$08,$02,$11,$56" } // Insert code for up case 046: { StringToSend = "$08,$02,$11,$55" } // Insert code for down case 047: { StringToSend = "$08,$02,$11,$51" } // Insert code for left case 048: { StringToSend = "$08,$02,$11,$50" } // Insert code for right case 049: { StringToSend = "$08,$02,$11,$57" } // Insert code for ok case 051: case 052: case 053: case 054: case 055: // Insert code for Preset Data Request : 1 - 50 case 056: case 057: case 058: case 059: case 060: case 061: case 062: case 063: case 064: case 065: case 066: case 067: case 068: case 069: case 070: case 071: case 072: case 073: case 074: case 075: case 076: case 077: case 078: case 079: case 080: case 081: case 082: case 083: case 084: case 085: case 086: case 087: case 088: case 089: case 090: case 091: case 092: case 093: case 094: case 095: case 096: case 097: case 098: case 099: case 100: { StringToSend = "$1B,$01,type_cast(comm-50)" } case 101: case 102: case 103: case 104: case 105: // Insert code for Preset select : 1 - 50 case 106: case 107: case 108: case 109: case 110: case 111: case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127: case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143: case 144: case 145: case 146: case 147: case 148: case 149: case 150: { StringToSend = "$17,$01,type_cast(comm-100)" } case 151: case 152: case 153: case 154: case 155: // Insert code for Preset Store : 1 - 50 case 156: case 157: case 158: case 159: case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: case 170: case 171: case 172: case 173: case 174: case 175: case 176: case 177: case 178: case 179: case 180: case 181: case 182: case 183: case 184: case 185: case 186: case 187: case 188: case 189: case 190: case 191: case 192: case 193: case 194: case 195: case 196: case 197: case 198: case 199: case 200: { StringToSend = "$25,$01,type_cast(comm-150)" } // Status Request commands case 210: { StringToSend = "$00,$01,$F0" } // Insert code for Power Request case 211: { StringToSend = "$24,$01,$F3" } // Insert code for Source current : request case 212: { StringToSend = "$03,$01,$F0" } // Insert code for FM data request : Genre case 213: { StringToSend = "$02,$01,$F0" } // Insert code for FM data request : RDS case 214: { StringToSend = "$15,$01,$F0" } // Insert code for current Tuner preset request case 215: { StringToSend = "$18,$01,$F0" } // Insert code for Station Name Request case 216: { StringToSend = "$16,$01,$F0" } // Insert code for FM Freq. Request case 217: { StringToSend = "$19,$01,$F0" } // Insert code for Program Type Request case 218: { StringToSend = "$1A,$01,$F0" } // Insert code for DLS/PDT Info Request case 219: { StringToSend = "$21,$01,$F0" } // Insert code for FM Stereo/Mono request case 220: { StringToSend = "$22,$01,$F0" } // Insert code for FM RDS enabled : request case 221: { StringToSend = "$04,$01,$F0" } // Insert code for software version request : RS232 case 222: { StringToSend = "$04,$01,$F1" } // Insert code for software version request : main case 223: { StringToSend = "$04,$01,$F3" } // Insert code for software version request : DAB // skip channels too.... case 246: { StringToSend = arcamT32.passThru } // Insert code for passThru } // Set DevicePowerTime to required value for Power on or Off switch (comm) { case 027: { if(!arcamT32.tlPowerOnActive) timeline_create(tlPowerOn, tlPowerOnTime, length_array(tlPowerOnTime), timeline_absolute, timeline_once) } case 028: { if(!arcamT32.tlPowerOffActive) timeline_create(tlPowerOff, tlPowerOffTime, length_array(tlPowerOffTime), timeline_absolute, timeline_once) } } // if station search/change commands are called, clear out data arrays switch(comm) { case 003: case 004: case 005: case 006: case 022: case 023: case 031: case 032: case 033: case 034: case 035: case 045: case 046: case 047: case 048: case 049: { arcamT32.fmFreq = "''" send_command vdvArray,"'^TXT-',itoa(61),',0,',arcamT32.fmFreq" arcamT32.stationName = "''" send_command vdvArray,"'^TXT-',itoa(62),',0,',arcamT32.stationName" arcamT32.stationGenre = "''" send_command vdvArray,"'^TXT-',itoa(63),',0,',arcamT32.stationGenre" arcamT32.stationInfo = "''" send_command vdvArray,"'^TXT-',itoa(64),',0,',arcamT32.stationInfo" // create timeline to request general update on status after period of time if(!arcamT32.tlUpdateStatusActive) timeline_create(tlUpdateStatus, tlUpdateStatusTime, length_array(tlUpdateStatusTime), timeline_absolute, timeline_once) } } // if a command has been called, transmit if(length_string(StringToSend)) { arcamT32.commTx = "$21,zone,StringToSend,$0D" // Modify StringToSend as required by device send_string dv,arcamT32.commTx // Send final command to device arcamT32.commsReady = 0 // commsReady will be set on rx of data from device if(!arcamT32.tlCommsReadyActive) timeline_create(tlCommsReady, tlCommsReadyTime, length_array(tlCommsReadyTime), timeline_absolute, timeline_once) } } define_function rxCommand () { local_var integer DataStartFound, DataEndFound, IntData, DataLength, x local_var char DataToProcess[500], zoneCode[1], CommandCode[1], AnswerCode[1], data[500], Data1[500], Data2[500], Data3[500] DataEndFound = find_string(arcamT32.commRx,"$0D",1) // Each Rx data shoud always end with $0D, find first instance of it.... while(DataEndFound>0) { DataToProcess = get_buffer_string(arcamT32.commRx,DataEndFound) // Remove first $0D and its preceeding data for processing DataToProcess = get_buffer_string(DataToProcess,length_string(DataToProcess)-1) // Remove $0D at end of DataToProcess DataStartFound = find_string(DataToProcess,"$21",1) // Each Rx data shoud always begin with $21, find first instance of it.... if(DataStartFound==0) // if no $21 is found, empty DataToProcess { DataToProcess = "''" } else { get_buffer_string(DataToProcess,DataStartFound) // Remove first $21 and its preceeding data, as uneeded zoneCode = get_buffer_string(DataToProcess,1) // Zone is next byte CommandCode = get_buffer_string(DataToProcess,1) // CommandCode is next byte AnswerCode = get_buffer_string(DataToProcess,1) // AnswerCode is next byte if(arcamT32.debug) { switch(answerCode) { case $00: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Status update'" case $82: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Zone invalid'" case $83: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Command not recognised'" case $84: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Parameter not recognised'" case $85: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Command invalid at this time'" case $86: send_string 0,"'Answer code from ArcamT32, (DPS ',devToString(dv),') = Invalid data length'" } } DataLength = type_cast(get_buffer_string(DataToProcess,1)) data = get_buffer_string(DataToProcess,DataLength) // data = Datalength of DataToProcess if(length_string(data)) // if there is data (in case answer code is failure) { switch(CommandCode) { case $00: arcamT32.Power = type_cast(data) // Power case $24: arcamT32.stationType = (type_cast(data))+1 // station Type case $12: // FM RDS Info { arcamT32.stationInfo = data send_command vdvArray,"'^TXT-',itoa(64),',0,',arcamT32.stationInfo" } case $22: arcamT32.fmRDSDisabled = type_cast(data) // is FM RDS disabled case $03: // FM Genre { arcamT32.stationGenre = data send_command vdvArray,"'^TXT-',itoa(63),',0,',arcamT32.stationGenre" } case $16: // current FM/AM frequency { Data1 = get_buffer_string(data,1) // Data1 is 1st byte Data2 = data // Data2 is 2nd and remaining byte arcamT32.fmFreq = "itoa(type_cast(Data1)),'.',itoa(type_cast(Data2))" send_command vdvArray,"'^TXT-',itoa(61),',0,',arcamT32.fmFreq" } case $21: arcamT32.fmStereoMono = type_cast(data) // FM Mono/Stereo case $18: // Station name { arcamT32.stationName = data send_command vdvArray,"'^TXT-',itoa(62),',0,',arcamT32.stationName" // check to see if any presets match current station for feedback purposes off[vdvArray,vdvArray_Channels_101_150] for(x=1;x<=50;x++) { if((arcamT32.stationName = arcamT32.presetName[x]) and(arcamT32.stationType = arcamT32.presetType[x])) { on[vdvArray,100+x] } } } case $23: // Radio signal info { Data1 = get_buffer_string(data,1) // Data1 is 1st byte Data2 = get_buffer_string(data,1) // Data2 is 2nd byte Data3 = data // Data3 is remaining data switch(Data1) { case $00: // fm frequency { arcamT32.fmFreq = "itoa(type_cast(Data2)),'.',itoa(type_cast(Data3))" send_command vdvArray,"'^TXT-',itoa(61),',0,',arcamT32.fmFreq" } case $01: // signal strength { arcamT32.signalStrength = type_cast(Data2) } case $02: // DAB bitrate { arcamT32.dabBitrate = type_cast(Data2) } case $03: // DAB mpeg mode { arcamT32.dabMPEG = type_cast(Data2) } } } case $19: // DAB Programme genre { arcamT32.stationGenre = data send_command vdvArray,"'^TXT-',itoa(63),',0,',arcamT32.stationGenre" } case $1A: // DLS info { arcamT32.stationInfo = data send_command vdvArray,"'^TXT-',itoa(64),',0,',arcamT32.stationInfo" } case $20: arcamT32.dabScan = type_cast(data) // DAB scanning status case $15: // current preset case $17: // preset selected { arcamT32.presetCurrent = type_cast(data) off[vdvArray,vdvArray_Channels_101_150] on[vdvArray,100+arcamT32.presetCurrent] } case $1B: // preset details { Data1 = get_buffer_string(data,1) // Data1 is 1st byte Data2 = get_buffer_string(data,1) // Data2 is 2nd byte Data3 = data // Data3 is remaining data arcamT32.presetType[type_cast(data1)] = type_cast(data2) arcamT32.presetName[type_cast(data1)] = Data3 presetWriteToXMLFile() } case $25: // preset stored { arcamT32.presetCurrent = type_cast(data) arcamT32.presetType[arcamT32.presetCurrent] = arcamT32.stationType arcamT32.presetName[arcamT32.presetCurrent] = arcamT32.stationName off[vdvArray,100+arcamT32.presetCurrent] send_command vdvArray,"'^TXT-',itoa(100+arcamT32.presetCurrent),',0,',arcamT32.stationName" wait 7 // turn preset bttn off for 7/10s to let user know preset is stored { off[vdvArray,vdvArray_Channels_101_150] on[vdvArray,100+arcamT32.presetCurrent] } presetWriteToXMLFile() } case $04: // software versions of arcamT32 (various) { Data1 = get_buffer_string(data,1) // Data1 is 1st byte Data2 = data // Data2 is remaining 2 bytes switch(Data1) { case $F0: arcamT32.vRS232 = Data2 case $F1: arcamT32.vSoftware = Data2 case $F3: arcamT32.vDAB = Data2 } } } } } DataEndFound = find_string(arcamT32.commRx,"$0D",1) // Does arcamT32.commRx contain more code to parse? else terminate WHILE loop } } define_function stackCommand (integer comm) { local_var integer x if(arcamT32.debug) send_string 0:1:0,"'arcamT32 : stacking command, ',itoa(comm),' ....for device, ',devToString(dv)" // Put at the top of the switch/case any command that requires specific coding before stacking in Queue switch(comm) { case 009: // power toggle { switch(arcamT32.power) { case 00: arcamT32.commStack = "arcamT32.commStack,27" // if currently off, send power on case 01: arcamT32.commStack = "arcamT32.commStack,28" // if currently on, send power off } } case 049: // after "enter" command (which selects a station { // ... request details on station again! arcamT32.commStack = "arcamT32.commStack,comm" do_push(vdvArray[1],211) do_push(vdvArray[1],212) do_push(vdvArray[1],213) do_push(vdvArray[1],214) do_push(vdvArray[1],215) do_push(vdvArray[1],216) do_push(vdvArray[1],217) do_push(vdvArray[1],218) } case 240: // Update all data { do_push(vdvArray[1],210) do_push(vdvArray[1],211) do_push(vdvArray[1],212) do_push(vdvArray[1],213) do_push(vdvArray[1],214) do_push(vdvArray[1],215) do_push(vdvArray[1],216) do_push(vdvArray[1],217) do_push(vdvArray[1],218) do_push(vdvArray[1],219) do_push(vdvArray[1],220) do_push(vdvArray[1],221) do_push(vdvArray[1],222) do_push(vdvArray[1],223) } case 250: { arcamT32.debug=!arcamT32.debug // debug (toggle) } case 252: // Update all text to vdvArray { send_command vdvArray,"'^TXT-',itoa(61),',0,',arcamT32.fmFreq" send_command vdvArray,"'^TXT-',itoa(62),',0,',arcamT32.stationName" send_command vdvArray,"'^TXT-',itoa(63),',0,',arcamT32.stationGenre" send_command vdvArray,"'^TXT-',itoa(64),',0,',arcamT32.stationInfo" for(x=1;x<=50;x++) { if(length_string(arcamT32.presetName[x])) { send_command vdvArray,"'^TXT-',itoa(100+x),',0,',arcamT32.presetName[x]" } else { send_command vdvArray,"'^TXT-',itoa(100+x),',0,push & hold',$0D,$0A,'to store preset'" } } } // All Commands that do not require any manipulation of the queue default: { arcamT32.commStack = "arcamT32.commStack,comm" // Add requested command to the end of the queue } } // create timeline to tx stacked commands if(!arcamT32.tlTxActive) timeline_create(tlTx, tlTxTime, length_array(tlTxTime), timeline_absolute, timeline_repeat) } define_function presetWriteToXMLFile() { stack_var slong slResult, slFile stack_var char sXMLString[50000] // Convert To XML slResult = variable_to_xml(arcamT32.presetName, sXMLString, 1, 0) // Save Structure To Disk – XML slFile = file_open(presetXmlFile, 2) slResult = file_write(slFile, sXMLString, length_string(sXMLString)) slResult = file_close(slFile) } define_function presetReadFromXMLFile() { stack_var slong slResult, slFile, slReturn stack_var char sXMLString[50000] // Read XML File slFile = file_open(presetXmlFile,1) slResult = file_read(slFile, sXMLString, 50000) slResult = file_close(slFile) // Convert To XML, and save to preset structure slReturn = xml_to_variable(arcamT32.presetName, sXMLString, 1, 0) } /******************************************************************************************* * Startup Code *******************************************************************************************/ define_start create_buffer dv,arcamT32.commRx arcamT32.commsReady = 1 presetReadFromXMLFile() wait 300 'Wait for processor' { do_push(vdvArray[1],240) // 'Update All data' command do_push(vdvArray[1],252) // update text to vdvArray device } /******************************************************************************************* * Event Handlers *******************************************************************************************/ define_event // Processing for all data events on physical port data_event[dv] { online: { send_command dv,'HSOFF' send_command dv,'XOFF' send_command dv,'RXON' send_command dv,'SET BAUD 38400,N,8,1 485 DISABLE' } string: { if(arcamT32.debug) send_string 0:1:0,"'rx data : ',data.text,' ....from device : ',devToString(dv)" // We've received data from device, comms can be assumed to be ok if(arcamT32.tlCommsReadyActive) timeline_kill(tlCommsReady) arcamT32.commsReady = 1 rxCommand() // Process incoming data from device } } data_event[vdvArray] { command: // send_command Instructions into this module from Mainline { virtualCommandParse(data.text) } } button_event[vdvArray,vdvArray_Channels_Sub_101_150] { push: { // Button channel number links directly to SNAPI defined channel number stackCommand(button.input.channel) if(arcamT32.debug) send_string 0:1:0,"'arcamT32: button_push ',itoa(button.input.channel),' from device ',devToString(button.input.device)" } hold[2,repeat]: { // The following commands require PUSH_HOLD processing.... switch(get_last(vdvArray_Channels_Sub_101_150)) { case 022: // station next case 023: // station previous case 005: // FM Freq increase case 006: // FM Freq decrease { stackCommand(button.input.channel) } } } } // Processing for button_events for preset store and select button_event[vdvArray,vdvArray_Channels_101_150] { push: { PresetStore_Called = 0 on[vdvArray,button.input.channel] } hold[30]: // Preset Store commands after 3 seconds { stackCommand (button.input.channel+50) PresetStore_Called = 1 } release: // if Preset store commands hasn't been called, then Preset select { if(!PresetStore_Called = 1) { stackCommand (button.input.channel) } } } timeline_event[tlTx] { // timeline manages tx commands stack_var char comm if(length_string(arcamT32.commStack)) { if(arcamT32.commsReady && !arcamT32.tlPowerOnActive && !arcamT32.tlPowerOffActive) { comm = get_buffer_char(arcamT32.commStack) if(arcamT32.debug) send_string 0:1:0,"'arcamT32 : command, ',comm,' ...retrieved from stacked commands for device, ',devToString(dv)" txCommand(comm) } } else { timeline_kill(tlTx) } } timeline_event[tlCommsReady] { // timeline used to force comms ready flag to ok arcamT32.commsReady = 1 do_push(vdvArray[1],210) // request power status } timeline_event[tlUpdateStatus] { // timeline used to request status from arcam do_push(vdvArray[1],240) } /******************************************************************************************* * Mainline code *******************************************************************************************/ define_program arcamT32.tlTxActive = timeline_active(tlTx) arcamT32.tlCommsReadyActive = timeline_active(tlCommsReady) arcamT32.tlUpdateStatusActive = timeline_active(tlUpdateStatus) arcamT32.tlPowerOnActive = timeline_active(tlPowerOn) arcamT32.tlPowerOffActive = timeline_active(tlPowerOff) // Feedback to vdvArray device.... [vdvArray,9] = arcamT32.power // Power status - toggle [vdvArray,27] = arcamT32.power // - on [vdvArray,28] = !arcamT32.power // - off [vdvArray,31] = (arcamT32.stationType==1) // Source - FM [vdvArray,32] = (arcamT32.stationType==2) // | - AM [vdvArray,33] = (arcamT32.stationType==3) // | - DAB [vdvArray,34] = (arcamT32.stationType==4) // | - SIRIUS [vdvArray,35] = (arcamT32.stationType==5) // `---------------- AUX [vdvArray,250] = arcamT32.debug // debug - toggle [vdvArray,251] = !arcamT32.commsReady // Comms Connected - on if comms is OKCommented out all of DEFINE_PROGRAM, and no change, but I have found out why the diagnostic message, "CIMessageRouter - Unknown ObjectID 30" keeps appearing.......
....... it's a response to me sending the command "SHOW BUFFERS" when connected via telnet to the processor!
just noticed it by running 2 telnet connections to the processor, one showing diagnostics (with command "SHOW MSG ALL") and the other telnet window where I could poll the command "SHOW BUFFERS".
sorry.....
There is still a noticabley long boot time of the processor when I include my Arcam module in code.
I'm using 3 instances of the module, which works fine once the processor is booted, but maybe this is the cause?
Even though AMX teaches this, you should be a little carefull with doing this, as it slows down the whole thing
These days AMX actually tells you to put as little as possible in 'define_program' and handle your feedback in your functions.
Our local Technical Representative recommends a maximum of 10 lines in define_program if you REALLY need it.
Snippet from the Netlinx Reference Guide:
I've put in bold what's really important.
I would also agree that you should not use the mainline for anything at all
The way the NetLinx system works: (see attachment)
I've only ever put channel feedback to devices in mainline (and recently tracking the state of timelines for debug purposes), but with some of my systems using a good 20 or more modules, and often with multiples of the same modules, this overloading of mainline can't be good as you say.
thanks for the advice guys.