Creating a Transmit Queue
Greetings,
I need to queue my commands to a slow serial device. I knew that sooner or later I would run into this.
Are there any generic methods for this? All of my commands end with a CR, so picking them from an outgoing buffer should be simple.
Thank you.
I need to queue my commands to a slow serial device. I knew that sooner or later I would run into this.
Are there any generic methods for this? All of my commands end with a CR, so picking them from an outgoing buffer should be simple.
Thank you.
0
Comments
DATA_EVENT[vdvSERIAL] // VIRTUAL DEVICE { COMMAND: { LOCAL_VAR BUFFER[100] STACK_VAR REPLY[100] WHILE (FIND_STRING (DATA.TEXT,"13",1)) { Reply = "Buffer, REMOVE_STRING (DATA.TEXT,"13",1)" CLEAR_BUFFER Buffer WAIT_UNTIL(RESPONSE='ACCEPTED') // SOMETHING TO SAY IT'S GOOD TO SEND A COMMAND SEND_STRING dvREAL_DEVICE,"Reply,13" } Buffer = "Buffer,DATA.TEXT" } } BUTTON_EVENT[dvTP,1] { PUSH: SEND_COMMAND vdvSERIAL,"'COMMAND',13" }The logic should be there, but it's late and I'm programming off the top of my head. Need brain food (Taco Bell!!!)
DEFINE_CONSTANT tlHandleQueue = 1000 DEFINE_VARIABLE VOLATILE long SendRate[] = {2000} // 2 second VOLATILE char cBuffer[200] = '' VOLATILE char cQueue[200] = '' DEFINE_CALL 'Add to Queue' (char cCmd[10]) { cQueue = "cQueue,cCmd,$0D" } DEFINE_CALL 'Send' (char cCmd[10]) { SEND_STRING dvDEV,"cCmd" } DEFINE_START CREATE_BUFFER dvDEV,cBuffer TIMELINE_CREAT (tlHandleQueue,SendRate,1,TIMELINE_RELATIVE,TIMELINE_REPEAT) DEFINE_EVENT TIMELINE_EVENT[tlHandleQueue] { IF (LENGTH_STRING(cQueue)) { STACK_VAR char cCmd[10] cCmd = REMOVE_STRING(cQueue,"$0D",1) CALL 'Send' (cCmd) } } DATA_EVENT[vdvDEV] { COMMAND: { STACK_VAR char cCMD[100] STACK_VAR integer nFunc IF(FIND_STRING(DATA.TEXT,'=',1)) cCMD = REMOVE_STRING(DATA.TEXT,'=',1) ELSE cCMD = DATA.TEXT SWITCH(cCMD) { CASE 'POWER=': { nFunc = ATOI(DATA.TEXT) IF (nFunc = 1) CALL 'Add to Queue' ("$43,$30,$30") ELSE { CALL 'Add to Queue' ("$43,$30,$31") } CALL 'Add to Queue' ("$43,$52,$30") BREAK } CASE 'STATUS?': { CALL 'Add to Queue' ("$43,$52,$30") BREAK } } } }I know its an old post, but I like this nice simple and elegant way to handle a queue.
thanks for sharing.
PROGRAM_NAME='Queue' (***********************************************************) (* System Type : NetLinx *) (***********************************************************) (* REV HISTORY: *) (***********************************************************) (***********************************************************) (* CONSTANT DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_CONSTANT // MAX STUFF #IF_NOT_DEFINED MAX_CMD_LENGTH MAX_CMD_LENGTH = 50; #END_IF #IF_NOT_DEFINED MAX_QUEUE_ITEMS MAX_QUEUE_ITEMS = 4; #END_IF (***********************************************************) (* DATA TYPE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_TYPE STRUCTURE _QUEUE { CHAR cQueue[MAX_QUEUE_ITEMS][MAX_CMD_LENGTH]; CHAR cLastCommandSent[MAX_CMD_LENGTH]; CHAR cQueueHead; CHAR cQueueTail; CHAR cQueueBusy; CHAR cQueueHasItems; CHAR cQueueReady; } (***********************************************************) (* LATCHING DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_LATCHING (***********************************************************) (* MUTUALLY EXCLUSIVE DEFINITIONS GO BELOW *) (***********************************************************) DEFINE_MUTUALLY_EXCLUSIVE (***********************************************************) (* SUBROUTINE/FUNCTION DEFINITIONS GO BELOW *) (***********************************************************) (**************************************) (* Call Name: PushQueue *) (* Function: Adds comamnd to the queue*) (* Return: n/a *) (**************************************) DEFINE_FUNCTION ENQueue(_QUEUE uQueue,Char cCmd[]) { IF (uQueue.cQueueHead = MAX_LENGTH_ARRAY(uQueue.cQueue)) { IF (uQueue.cQueueTail <> 1) { uQueue.cQueueHead = 1; uQueue.cQueue[uQueue.cQueueHead] = cCmd; ON[uQueue.cQueueHasItems]; } } ELSE IF (uQueue.cQueueTail <> uQueue.cQueueHead + 1) { uQueue.cQueueHead++; uQueue.cQueue[uQueue.cQueueHead] = cCmd; ON[uQueue.cQueueHasItems]; } } (**************************************) (* Call Name: PopQueue *) (* Function: Removes from the queue *) (* Return: CHAR[] *) (**************************************) DEFINE_FUNCTION CHAR[MAX_CMD_LENGTH] DEQueue(_QUEUE uQueue) { IF (GetQueueReady(uQueue) == TRUE) { SetQueueReady(uQueue,FALSE); IF (uQueue.cQueueTail = MAX_LENGTH_ARRAY(uQueue.cQueue)) uQueue.cQueueTail = 1; ELSE uQueue.cQueueTail++; IF (uQueue.cQueueTail = uQueue.cQueueHead) OFF[uQueue.cQueueHasItems]; uQueue.cLastCommandSent = uQueue.cQueue[uQueue.cQueueTail]; RETURN uQueue.cLastCommandSent; } } (**************************************) (* Call Name: PeekQueue *) (* Function: Shows Item from the queue*) (* Return: CHAR[] *) (**************************************) DEFINE_FUNCTION CHAR[MAX_CMD_LENGTH] PeekQueue(_QUEUE uQueue) { STACK_VAR INTEGER nLastTail; nLastTail = uQueue.cQueueTail IF (nLastTail = MAX_LENGTH_ARRAY(uQueue.cQueue)) nLastTail = 1 ELSE nLastTail = nLastTail + 1 RETURN uQueue.cQueue[nLastTail]; } (**************************************) (* Call Name: ForceQueueReady *) (* Function: Forces Queue Ready *) (* Return: n/a *) (**************************************) DEFINE_FUNCTION SetQueueReady(_QUEUE uQueue,CHAR bBool) { IF (bBool == TRUE) { ON[uQueue.cQueueReady]; OFF[uQueue.cQueueBusy]; } ELSE { OFF[uQueue.cQueueReady]; ON[uQueue.cQueueBusy]; } } (**************************************) (* Call Name: InitQueue *) (* Function: Setup Queue *) (* Return: n/a *) (**************************************) DEFINE_FUNCTION InitQueue(_QUEUE uQueue) { uQueue.cQueueHead = 1; uQueue.cQueueTail = 1; uQueue.cQueueBusy = FALSE; uQueue.cQueueReady = TRUE; } (**************************************) (* Call Name: GetQueueReady *) (* Function: Forces Queue Ready *) (* Return: n/a *) (**************************************) DEFINE_FUNCTION CHAR GetQueueReady(_QUEUE uQueue) { IF (uQueue.cQueueHasItems && uQueue.cQueueBusy == FALSE) RETURN TRUE; ELSE RETURN FALSE; } (**************************************) (* Call Name: GetQueueEmpty *) (* Function: Test if Queue is Empty *) (* Return: n/a *) (**************************************) DEFINE_FUNCTION CHAR GetQueueEmpty(_QUEUE uQueue) { IF (uQueue.cQueueHasItems == FALSE) RETURN TRUE; ELSE RETURN FALSE; }Nothing wrong with your example. Just a include file we use here at AMX full of helper functions. I thought it would be helpful...
BTW - the above example that I had - certainly not what I use now.