Serial Communication using ASCII

24 Apr 2011

Hey guys im working on getting an rfid reader to talk to my embed for a junior design project.

the way the software communicates with the reader is by serial ASCII or binary it sends out a command and the reader carries out an action and sends a response

i need the mbed to send a command and then recieve the response but i am not familiar with ASCII but here is how the software that came with the reader communicates with it.

/media/uploads/michaud85/reader.jpg

i need to send that request from the mbed and recieve the response then compare it to another response x amount of time later.

#include "mbed.h"
#include "Terminal.h"
#include <string>
using namespace std;

DigitalOut Led();
Terminal term(USBTX, USBRX);
Serial M9(p28, p27);
PwmOut servo(p21);

int main() {
   M9.baud(9600);
   string Present = " ";
   term.printf("Press 1 to see if readable\n\r");
       while(1){ 
       switch(term.getc()) {
            case '1': M9.printf("\r0002010100000\r"); 
                      if(M9.readable()){
                        term.printf("\rreadable");
                        M9.scanf("%s", Present);
                        term.printf("%s", Present);
                        }
                      else{
                        term.printf("not readable\r");
                        }
                      break;
                      }}}

All i get back as a response is readable. So i have no idea if im comminucating effectively. I would really apprectiate any help on how to send and recieve information using ASCII.

If theres any other info you need just let me know.

24 Apr 2011

Hi Michael,

Your logic looks close, but you might want to check the exact behaviour of scanf. It will do things like read characters until it sees whitespace for a string, which includes line feeds. See:

So it could be that your scanf logic isn't having the desired effect. To start with, you might want to check you are getting a (first) response at all, e.g.:

M9.printf("\r0002010100000\r");
while(1) {
   term.printf("char: %d\n", M9.getc());
}

You could then try something like the following:

char result[8];
M9.printf("\r0002010100000\r");
M9.scanf("\n%s\r\n", &result);
term.printf("result: %s\n", result);

Although it may skip the initial \n, so you may want to read that more explicitly (e.g. %*c to read but ignore a character). You can also do things like look at the return value of scanf to see how many things it found. Note, i'm using a standard c char array to store the result in here.

Hope that gets you closer.

Simon

27 May 2014

/* return the checksum character for the message in array subtract 32 from each character before taking modulo 95 sum add 32 to the final sum mes_len = message length

  • / char check_sum(char *array, char mes_len) { char i,sum;

for (i = 0, sum = 0; i < mes_len; i++) { sum += *array++ - 32; sum %= 95; } return(sum + 32); }

how to write this???

27 May 2014

What do you mean? It already is written.

27 May 2014

I'm not sure eactly what you are asking how to write. You posted a description of how to generate a checksum followed by the code that generates the checksum. There is nothing left to write for that.

Create your message to send as a char array. Then call the function check_sum passing it the array and the length of the message and it will return the checksum

e.g. (note I've made some guesses as to the format of the commands and where the checksum goes)

/*
return the checksum character for the message in array subtract 32 from each character before taking modulo 95 sum add 32 to the final sum mes_len = message length 
*/
char check_sum(char *array, char mes_len) {
 char i,sum;
 for (i = 0, sum = 0; i < mes_len; i++) {
    sum += *array++ - 32;
    sum %= 95; 
 }
return(sum + 32);
}

// fairly randomly picked size of buffer to create for the message. Change as needed.
#define MaxLen 32

void send_message() {
  char myMessage[MaxLen];
 
 // generate the command to send, use MaxLen-1 to allow space for the \r at the end
 int length = snprintf(myMessage,MaxLen-1,"\r00020101000");

  // snprintf puts a '\0' at the end of the string, replace that with the checksum. Don't include the leading \r in the checksum.
  myMessage[length] = check_sum(myMessage+1,length-1); 

 // Add a carriage return to the end
  myMessage[length+1] = '\r';                                                      


  // send the message
  int count = 0;
  while (count < (length+1)) {
    if (M9.writeable()) {
      M9.putc(myMessage[count]);
      count++;
    }
  }

}

Also when posting c code put <<code>> on it's own line before and <</code>> on it's own line afterwards, that will format the code and make it a lot more readable.