11 years, 4 months ago.

RS-232 8 byte word

I need to receive an 8 byte word that has 4 different functions. How do I break down or interpret the received word and assign the function to a GPIO (Out 0/1)

Function 1 : F9 FF FF FF FF A1 C2 00

Function 2: F9 FF BF FF FF A1 42 00

Function 3: F9 FF 7F FF FF A1 C2 00

Function 4: F9 FF E8 99 DF A1 66 00

Receiving function 2-4 will turn on a respective relay Receiving function 1 will turn off all relays

Baud Rate is 2400 one stop bit, no parity

I can read the data in but need to interpret bytes 3-7 for the functions

Any help is greatly appreciated

3 Answers

11 years, 4 months ago.

Have you written some sort of program yet?
Try buffering them, and then lookup in the buffer afterwards:

char buffer[8];
char function1[] = {F9, FF, FF, FF, FF, A1, C2, 00}; // Array for function
char function2[] = {F9, FF, BF, FF, FF, A1, 42, 00};
char function3[] = {F9, FF, 7F, FF, FF, A1, C2, 00};
char function4[] = {F9, FF, E8, 99, DF, A1, 66, 00};

Serial serial(p9, p10);

void serial_interrupt(){
   if(serial.readable()){          // check availability
      buffer[i] = serial.getc();   // copy the serial input to buffer
      i++;                         // increment buffer value
   }
}

int main() {
   int i = 0;
   serial.attach(&serial_interrupt(), Serial::RxIrq);
   while(true){
      if(!memcmp(buffer, function1, 8)){
         // do stuff in here.  
         i = 0;                       // doing this prevents buffer overflow, i.e. you reset i, to point to buffer[0] again.  
      }
      if(buffer == ....)
                                      // And so on, you get the idea.
   }
}

Accepted Answer
11 years, 4 months ago.

One addition:

Obviously all "packets" start with 0xf9. It would be a good idea to check incoming data in serial_interrupt() for this byte to be the first, and reset i on match. Christians Code would work well if the first incoming byte is guaranteed to be 0xf9, otherwise the buffer will never hold a proper packet, the memcmp will never match and i will never be reset, causing buffer to overflow.

Thus:

unsigned char d;
if(serial.readable()){          // check availability
      d = serial.getc()
      if (d == 0xf9) {
             buffer[0] = d;
             i = 1;
      } else {
             buffer[i] = d;   // copy the serial input to buffer
             i++;              // increment buffer value
      }
}

If it is not your only intention to do that job, it might be a good idea to place the memcmp within interrupt, checking when i becomes 7 and always resetting i in that case, so it will never overflow.

11 years, 4 months ago.

Christian and Rainer

First off than you for helping me here. I'm not a programmer by trade so please forgive my naiveté. With the code you have provided I keep getting an "identifier "i" is not identified" on the compile

The following communicates fine as a start, meaning reads proper data.

  1. include "mbed.h"

Serial pc(USBTX, USBRX); Serial uart(p9, p10); Connect TX to RX (p9 to p10) or can also use USB and type back in the number printed out in a terminal window

DigitalOut uart_activity(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); assign led function

int main() { uart.baud(2400); while(1) { if(pc.readable()) { uart.putc(pc.getc()); pc_activity = !pc_activity } uart_activity = 0; turn off rx led if(uart.readable()) { pc.putc(uart.getc()); uart_activity = !uart_activity; wait(0.01); Turn on LED 1 when data recieved void Tx_interrupt(); void Rx_interrupt(); void send_line(); void read_line();

Circular buffers for serial TX and RX data - used by interrupt routines const int buffer_size = 255; might need to increase buffer size for high baud rates char tx_buffer[buffer_size]; char rx_buffer[buffer_size];

} } }

What follows is giving me the problems. The data is garbled, like a baud rate error, and I keep getting errors. What am I trying to do? Receive the commands via RS-232 then turn a set of GPIO functions on/off. In the program I was hoping to print the command on Cool Term and illuminate an LED when the functions occur. The GPIOs will be driving relays which in turn power a 3 axis motor system.

  1. include "mbed.h"

Serial pc(USBTX, USBRX); Serial uart(p9, p10); Connect TX to RX (p9 to p10) or can also use USB and type back in the number printed out in a terminal window

DigitalOut uart_activity(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DigitalOut led4(LED4); assign led function

int main() { uart.baud(2400); while(1) { if(pc.readable()) { uart.putc(pc.getc()); pc_activity = !pc_activity } uart_activity = 0; turn off rx led if(uart.readable()) { pc.putc(uart.getc()); uart_activity = !uart_activity; wait(0.01); Turn on LED 1 when data recieved void Tx_interrupt(); void Rx_interrupt(); void send_line(); void read_line();

Circular buffers for serial TX and RX data - used by interrupt routines const int buffer_size = 255; might need to increase buffer size for high baud rates char tx_buffer[buffer_size]; char rx_buffer[buffer_size];

} } }

Any help would be welcome , thanks Thom

Are you sure of the data bits, stop bits, and so on?

posted by Christian Lerche 22 Dec 2012