How to send 16bit struct over UART?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
anma_3885486
Level 1
Level 1
First question asked Welcome!

I have a small motor that moves upwards and downwards, the communication interface is RS232 and the baud rate is 19200. I am using a PSOC5 to send the data over UART and a SIPEX 3232 chip to covert the TTL to RS232. I know the motor uses a STM32F103 and it uses the communication structure shown below.  I also know the 16 bit integers are being split up into two bytes and being sent that way. The motor is currently sitting in its lowered position and I have yet to get it to respond to a lifting command. I am not sure how to properly send this data . Any help is much appreciated.  

Lift Command: 0x13, 0x12, 0x3, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x6C, 0x7, 0xDC, 0x5, 0xF4, 0x1, 0xA3, 0x0

0x13 is the start bit.

0x12 is the number of bytes to send.

the other 18 bytes are the 16 bit integers being split up. For example, 0x3 and 0x0 would be a 16 bit integer for the number 3. 

Communication structure

struct
{
    int16 update;
    struct 
    {
        int16 status;
        int16 error;
        int16 position;
        int16 current;
        int16 check; 
    }I;
    struct 
    {
        int16 command;
        int16 A;
        int16 B;
        int16 C;
        int16 D;
        int16 E;
        int16 F;
        int16 G;
        int16 check;
    }O;
}H1,H2;

Data to be sent to raise motor

Data: 0x13, 0x12, 0x3, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x6C, 0x7, 0xDC, 0x5, 0xF4, 0x1, 0xA3, 0x0

command = 3;        //3 raises motor,  1 lowers motor, 0 stops motor
A = 25;
B = 25;
C = 25;
D = 25;
E = 1900;
F = 1500;
G = 500;
check = 163;

This is my attempt to communicate with the motor however, this did not work 

#include "project.h"

struct
{
    int16 update;
    struct 
    {
        int16 status;
        int16 error;
        int16 position;
        int16 current;
        int16 check; 
    }I;
    struct 
    {
        int16 command;
        int16 A;
        int16 B;
        int16 C;
        int16 D;
        int16 E;
        int16 F;
        int16 G;
        int16 check;
    }O;
}H1,H2;
        

int main(void)
{
    UART_1_Start();
    /////////////////
    H1.O.command = 3;
    H1.O.A = 25;
    H1.O.B = 25;
    H1.O.C = 25;
    H1.O.D = 25;
    H1.O.E = 1900;
    H1.O.F = 1500;
    H1.O.G = 500;
    H1.O.check = 163;
    //////////////////
    uint8 hibyte1 = 0u;
    uint8 lowbyte1 = 0u;
    uint8 hibyte2 = 0u;
    uint8 lowbyte2 = 0u;
    uint8 hibyte3 = 0u;
    uint8 lowbyte3 = 0u;
    uint8 hibyte4 = 0u;
    uint8 lowbyte4 = 0u;
    uint8 hibyte5 = 0u;
    uint8 lowbyte5 = 0u;
    uint8 hibyte6 = 0u;
    uint8 lowbyte6 = 0u;
    uint8 hibyte7 = 0u;
    uint8 lowbyte7 = 0u;
    uint8 hibyte8 = 0u;
    uint8 lowbyte8 = 0u;
    uint8 hibyte9 = 0u;
    uint8 lowbyte9 = 0u;
    lowbyte1 = H1.O.command & 0xFF;
    hibyte1 = (H1.O.command >> 😎 & 0xFF;
    
    lowbyte2 = H1.O.A & 0xFF;
    hibyte2 = (H1.O.A >> 😎 & 0xFF;
    
    lowbyte3 = H1.O.B & 0xFF;
    hibyte3 = (H1.O.B >> 😎 & 0xFF;
    
    lowbyte4 = H1.O.C & 0xFF;
    hibyte4 = (H1.O.C >> 😎 & 0xFF;
    
    lowbyte5 = H1.O.D & 0xFF;
    hibyte5 = (H1.O.D >> 😎 & 0xFF;
    
    lowbyte6 = H1.O.E & 0xFF;
    hibyte6 = (H1.O.E >> 😎 & 0xFF;
    
    lowbyte7 = H1.O.F & 0xFF;
    hibyte7 = (H1.O.F >> 😎 & 0xFF;
    
    lowbyte8 = H1.O.G & 0xFF;
    hibyte8 = (H1.O.G >> 😎 & 0xFF;
    
    lowbyte9 = H1.O.check & 0xFF;
    hibyte9 = (H1.O.check >> 😎 & 0xFF;
    
    //////////////////
    
    for(;;)
    {
        
        UART_1_PutChar(0x13);
        UART_1_PutChar(0x12);
        UART_1_PutChar(lowbyte1);
        UART_1_PutChar(hibyte1);
        UART_1_PutChar(lowbyte2);
        UART_1_PutChar(hibyte2);
        UART_1_PutChar(lowbyte3);
        UART_1_PutChar(hibyte3);
        UART_1_PutChar(lowbyte4);
        UART_1_PutChar(hibyte4);
        UART_1_PutChar(lowbyte5);
        UART_1_PutChar(hibyte5);
        UART_1_PutChar(lowbyte6);
        UART_1_PutChar(hibyte6);
        UART_1_PutChar(lowbyte7);
        UART_1_PutChar(hibyte7);
        UART_1_PutChar(lowbyte8);
        UART_1_PutChar(hibyte8);
        UART_1_PutChar(lowbyte9);
        UART_1_PutChar(hibyte9);
      
    }
}

  

0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

anma,

I've simplified your code.

I've tested this code works to output your raise motor command sequence in this byte sequence:

0x13, 0x12, 0x3, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x6C, 0x7, 0xDC, 0x5, 0xF4, 0x1, 0xA3, 0x0

#include <project.h>
#include <stdio.h>


/* I don't see an advantage of using a union in this case. */
typedef struct
{
    int16 update;
    int16 status;
    int16 error;
    int16 position;
    int16 current;
    int16 check; 
}HI;
typedef struct
{
    int16 update;
    int16 command;
    int16 A;
    int16 B;
    int16 C;
    int16 D;
    int16 E;
    int16 F;
    int16 G;
    int16 check;
}HO;

/* This is a very simple way to initialize a static array.  This is set at compile-time.  
If this data never changes, you can place a 'const' keyword in front of 'HO' in the statement below.
This will force this HO struct to be stored in FLASH instead of RAM.
*/
HO raise_motor = { .update=0x1213, .command=3, .A=25, .B=25, .C=25, .D=25, .E=1900, .F=1500, .G=500, .check=163};

int main(void)
{
    UART_1_Start();
    /////////////////
/* Note:  This works for little-endian int16 output data to the UART 
	since the Cortex CPU is little-endian based for data storage 
	If the URT needs Big-Endian int16 data, the byte order needs to be swapped 
*/
    for(;;)
    {
        UART_1_PutArray((uint8 *)&raise_motor, sizeof(HO));		/* Pushes the data in raise_motor to UART */	
		CyDelay(100);
    }
}

 

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
2 Replies
Ekta_N
Moderator
Moderator
Moderator
750 replies posted First like given 250 solutions authored

Hello @anma_3885486 ,

Could you please let me know if you were successfully able to build the project?

1. For the following line: 

hibyte1 = (H1.O.command >>  & 0xFF;

I see that the end parenthesis is missing. 
Also, the  >>  right shift operator was followed by an operand, Similarly, the & operator should be preceded by an operator.
I understand that you are trying to separate the Higher 8 bits and lower 8 bits of a 16-bit value. You can try doing this (H1.O.command & 0xFF00) and then right-shift the bits.

2. Another way is to directly send the entire data using PutArray((uint8_t *)&H1.O). This function Places N bytes of data from a memory array into the TX buffer for transmission.

Thanks and Regards

Ekta

0 Likes
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

anma,

I've simplified your code.

I've tested this code works to output your raise motor command sequence in this byte sequence:

0x13, 0x12, 0x3, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x19, 0x0, 0x6C, 0x7, 0xDC, 0x5, 0xF4, 0x1, 0xA3, 0x0

#include <project.h>
#include <stdio.h>


/* I don't see an advantage of using a union in this case. */
typedef struct
{
    int16 update;
    int16 status;
    int16 error;
    int16 position;
    int16 current;
    int16 check; 
}HI;
typedef struct
{
    int16 update;
    int16 command;
    int16 A;
    int16 B;
    int16 C;
    int16 D;
    int16 E;
    int16 F;
    int16 G;
    int16 check;
}HO;

/* This is a very simple way to initialize a static array.  This is set at compile-time.  
If this data never changes, you can place a 'const' keyword in front of 'HO' in the statement below.
This will force this HO struct to be stored in FLASH instead of RAM.
*/
HO raise_motor = { .update=0x1213, .command=3, .A=25, .B=25, .C=25, .D=25, .E=1900, .F=1500, .G=500, .check=163};

int main(void)
{
    UART_1_Start();
    /////////////////
/* Note:  This works for little-endian int16 output data to the UART 
	since the Cortex CPU is little-endian based for data storage 
	If the URT needs Big-Endian int16 data, the byte order needs to be swapped 
*/
    for(;;)
    {
        UART_1_PutArray((uint8 *)&raise_motor, sizeof(HO));		/* Pushes the data in raise_motor to UART */	
		CyDelay(100);
    }
}

 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes