NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » concise serial output?

March 10, 2012
by sask55
sask55's Avatar

I would like to send a series of packets of data from the micro to a PC over the serial port. Each individual packet of data consists of two consecutive one byte values followed by a four byte float type number variable. The time interval between successive packets will vary greatly from time to time, at times the frequency of the transmissions will be high.

I would like to use a format that is more compact and concise then something like printf_P(PSTR(,%d%d%8f),i,j,k). In this example i and j would be uint8 type variables k would be a float variable and a , is used to delimit the serial output, so that I can positively identify the begin of each individual packet at the PC. The printf function converting the one byte integer variable into one, two or three byte ASCII code is counter productive. I could also send the one byte data as char variables using %c.

Both of the one byte data variables that I am sending to the PC are actually bit wise information containing the pin states of various output pins from three stepper motor controller ICs. Therefore those two bytes are not used by the PC as numbers or as characters but are subjected to bitwise functions to determine the state of each individual bit within the bytes. Because of the nature of the information carried in these bytes they could conceivably be any value of the 256 possible in 8 bits ie the same value as any ACII code delimiter I may choose. Any suggestions how to format and send this type of data over the serial so as to limit the one byte data to one byte of serial transmission would be greatly appreciated..
I would like to send this data as compactly as possible while still maintaining some way to positively identify each individual set of data. I will require some reliable means to ensure that the data transmissions from the micro and the interpretations at the PC can not get out of sync.

March 11, 2012
by pcbolt
pcbolt's Avatar

@sask55

Three solutions come to mind right off the bat.

First, just bite the bullet and translate everything to ASCII, then you could use non-ASCII character(s) as "Start Tx" and/or "End Tx" token. (You might be able to get away with a simple "compression" system like the one used in URL coding.)

Second, set up a bi-directional protocol. Send a TX character to the PC, wait for an OK character from the PC, send a constant length packet, then wait for another OK character from the PC.

Third, use some kind of a checksum at the end of each packet.

March 11, 2012
by sask55
sask55's Avatar

In this project the communication is already fully Bidirectional. I am using the PC to control three stepper motors using three TB6560AHQ motor control chips. Each of the motor control chips receives data “instructions” from the PC that regulate the micro stepping mode, torque (max current level), movement direction, stepper clock sequences ect from the PC. All of these instructions are sent to the appropriate input pins on the motor controller chips from the PC thru a master and three slave micros. Each of the slave micros handles the input and output for one axis of movement on my mill. The three slave micros monitors the state of several output pins on the motor controller chips, as well as the output from a digital calliper and a couple of movement limit switches associated with that particular axis. Master slave communication is directed from the PC via the master serial port (uart). Motor control data regarding the desired pin state changes on the motor controller chips originate at the PC, are directed to the correct axis by the master chip and then set on the motor control chip by the slave micros. Motor function data and axis position data (calliper readings) are read by the slave chips and delivered to the master chip on the SPI at the next cycle of communication between the master and that slave.

I currently have the bidirectional communication working well between the master and the three slaves on SPI. I am using a simple two bit (LSBs) addressing type coding scheme to tag each data byte. Each of the two consecutive data bytes caries six bits of control or return information and two bits for axis or master control ID. I am hopping to tighten up the delay time between the PC sending a command code and the corresponding return code from the motor control chips as much as possible. The ongoing stream of control instructions to the stepper motors depend to some degree on the information returned from axis position and other parameters sent from the controller chips and or callipers. Depending on the micro stepping mode in use it can take as many as little as 800 or as many as 12800 motor control clock pulses to move the stepper one revolution. In order to maintain a high degree of actuate control and reasonable motor speed, frequent, compact and precise data transition is essential at every level. The ability to dedicate all of the control and returns communication to any direction or combination of directions is ideal. Letting the PC software direct which axis to control at any time (essentially ignoring the others) and have the ability to identify where the returning data is coming from should maximize the data throughput to an axis of interest at any time.

After reconsidering the nature of the data stream I believe that I may be able to identify some particular data byte that is impossible or at least very unlikely to occur. Something like the thermal protection (over heat) indicator pin and the controller MO signal pin going high at the same time. I could then send an ASCII character that has that specific bit value combination in its byte value, as a start or end token. That character should never randomly appear in the data stream. This approach would allow me to transmit the data bytes as one byte characters type bytes and still insure synchronizing interpretation of the serial data from the master to the PC.

I realize that much of this may not be very clear or understandable as I have described it. I think I have a solution that will compact my serial data flow as much as possible.

Thanks for the suggestions.

March 11, 2012
by pcbolt
pcbolt's Avatar

Cool. I was thinking more about the data compression and there is a solution that may work for you. If you have a data packet of 6 bytes (2 8-bit values and 1 32-bit float) you could split up the 32-bit variable into 4 8-bit values then "truncate" each of the 6 8-bit variables by stripping off the MSB (Most Significant Bit) giving 6 7-bit values. You can then add a 7th 7-bit value that contains the MSB of each of the previous values. Since a 7-bit value will only go from 0 to 127, you can use any "character" from 0x80 to 0xFF to act as an end/begin TX token.

For example,

i, j are uint8_t

  • i = 0x9B or 10011011b => send 00011011b or 0x1B (save 1 in bit0 of 7th variable)

  • j = 0x42 or 01000010b => send 01000010b or 0x42 (save 0 in bit1 of 7th variable)

k is float (32-bit)

  • break into k1,k2,k3,k4 (8-bits each) and apply the same pattern (k1 MSB stored in bit2, k2 MSB stored in bit3 etc)

Good luck on your project...sounds like you are learning a great deal. Hope you get a chance to post some pics when you get a chance, very interesting subject.

March 11, 2012
by sask55
sask55's Avatar

Thanks

Interesting idea, I may implement something along those lines

Darryl

Post a Reply

Please log in to post a reply.

Did you know that hobby servos are controlled through a particular kind of PWM (Pulse Width Modulation) signal? Learn more...