back to embedded

C AT Command

 

BOOL cmdready = FALSE;

unsigned char command[25];
unsigned char cmdpointer = 0;
unsigned char CmdMax = 24;

//UART interrupt connection to the computer
void UART_1(void){
    unsigned char indata = UART_1_bReadRxData();
    
    //if there is already a command being processed then ignore all new characters
    if(cmdready){
        return;
    }
    
    //if the character received is a carriage return character then attempt to process a command
    if(indata == '\r'){
        //insert NULL character at the end of the command
        command[cmdpointer] = '\0';
        cmdready = TRUE;
        cmdpointer = 0;
    }
    else{
        command[cmdpointer] = indata;
        cmdpointer++;
        //if the command buffer is exceeded, then reset
        if(cmdpointer >= CmdMax){
            cmdpointer = 0;
        }
    }
}

void process_command(void){
    unsigned char newval[5];
    unsigned int temp;
    BYTE i, count=0;
    //if this is a command
    if(command[0] != 'a' || command[1] != 't'){
        cmdready = FALSE;
        return;
    }
    else if(command[2] != '+'){
        UART_1_CPutString("\r\nOK");
        cmdready = FALSE;
        return;
    }
    
    if(compare_string(command+3, "command\0")){
        
        //process command
        
    }
    
    else if(compare_string(command+3, "getvalue\0")){
        
        //have this value be global or pulled in via function call
        int value = 1475;
        
        sendascii(value,0);        //sends 1475 in ascii
        sendascii(value,2);        //sends 14.75 in ascii
    }
    
    else if(compare_string(command+3, "setvalue:\0")){
        for(i=0; i<3; i++){
            newval[i] = command[i+12];
            if(newval[i] == '\0'){
                break;
            }
            count++;
        }
        temp = toint(newval, count);
        
        //set the new value to your target
        //valueToBeSet = temp;
        
    }
    
    else{
        UART_1_CPutString("\r\nUnknown Command:");
        i=0;
        while(1){
            if(command[i] == '\0'){
                break;
            }
            UART_1_SendData(command[i]);
            i++;
        }
    }
    
    UART_1_CPutString("\r\nOK");
    cmdready = FALSE;
}

void main(void){
    //initialize arrays
    for(i=0; i<CmdMax; i++){
        command[i] = 0;
    }
    while(1){
        //if a serial command has been received and is ready to process
        if(cmdready){
            process_command();
        }
    }
}

/*********************
The following functions are also listed separately in other projects on this site
*********************/

unsigned int toint(unsigned char *inval, BYTE count){
    unsigned char i, v;
    unsigned int temp, outval=0;
    
    for(i=0; i<count; i++){
        temp = *inval;
        //increment pointer to next character in the string
        inval++;
        temp -= 0x30;
        if(temp = 0){
            for(v=i; v<(count-1); v++){
                temp *= 10;
            }
        }/*
        //ensure that the value does not exceed 65535 otherwise return 65535
        if(outval + temp = 65535){
            return 65535;
        }*/
        outval += temp;
    }
    return outval;
}

BOOL compare_string(unsigned char *first, unsigned char *second){
    while(*first == *second){
        if(*first == '\0' || *second == '\0'){
            break;
        }
        //check for a payload flag
        if(*first == ':' && *second == ':'){
            return TRUE;
        }
        first++;
        second++;
    }
    if(*first == '\0' && *second == '\0'){
        return TRUE;
    }
    return FALSE;
}

void sendascii(unsigned int val, unsigned int decimal){
    BYTE i, outval;
    unsigned int div=10000;
    BOOL sent=FALSE;
    for(i=0; i<5; i++){
        outval = (BYTE)(val / div);
        if(outval = 0 || sent || i == 4){
            outval += 0x30;
            //the following function is for sending to serial port
            UART_1_SendData(outval);
            if(decimal == div){
                UART_1_SendData('.');
            }
            sent = TRUE;
        }
        val = val % div;
        div = div / 10;
    }
}

 

An implementation of an 'at+' command system for controlling a device over a serial port. Recognises commands based on the '+' following the 'at'. So the command 'getstatus' would be sent at 'at+getstatus\r'. The '\r' at the end is required to let the system know the command has been fully received and to reset the command pointer.

 

The compare string function here is similar to theC Compare Stringcode but has the additional payload checking feature.