Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Post History

75%
+4 −0
Q&A Communication with microcontroller via usart - using strings a good idea?

Olin has posted a good answer regarding the pros and cons. To add to that, look at where your C code is going: if(strcmp...) else if (strcmp...) and so on. This is a common mistake in embedded C wh...

posted 1mo ago by Lundin‭  ·  edited 1mo ago by Lundin‭

Answer
#2: Post edited by user avatar Lundin‭ · 2026-08-10T09:13:47Z (about 1 month ago)
  • Olin has posted a good answer regarding the pros and cons. To add to that, look at where your C code is going: `if(strcmp...) else if (strcmp...)` and so on. This is a common mistake in embedded C when parsing strings, I've scolded a fair amount of programmers for writing super-inefficient code like that - with such `strcmp`chains you are essentially iterating over the same string over and over again. It is super-slow look-up and not ok, as addressed by any algorithm class in uni.
  • The proper production-quality version is to instead implement a binary search across a bunch of alphabetically sorted strings sitting in flash, "O(log n)". Standard C `bsearch` is probably good enough for most purposes. For more advanced situations you'd perhaps implement a hash map of some kind since those perform better when there is a large amount of data.
  • As for the _advantage_ of strings, it is that they are obviously more human-friendly and can get entered over an old school terminal, back in the days when we sill used terminals on PC. Something string-based like "AT commands" have been an industry standard for ages. If you need neither high performance nor safety, then why not.
  • Besides performance, the main arguments against using strings, or even UART, are all related to safety. If you don't need safety/data integrity, then fine. Otherwise:
  • - Whenever you send a protocol over UART, you ought to have at least a simple kind of checksum. Sure, you could use "parity" hardware checks, but this is a naive kind of safety that doesn't really catch a whole lot of errors.
  • In the realm of functional safety you'll come across the term "diagnostic coverage" meaning how large a percentage of all errors you are able to catch. If you consider that for one bit errors, two bit errors or burst errors, then mathematically both parity checks as well as simple checksums (add bytes together then invert/truncate etc) are immediately dismissed. The only thing good enough is CRC. And you can't send CRC as ASCII or that defeats how it works.
  • - In systems with lots of traffic you need means to synchronize the protocol. How does the receiver know it didn't start receiving in the middle of a protocol? Some unique characters are typically used for this. For example you could start the protocol with a bit sequence that is _not_ valid 7 bit ASCII like for example 0xAA. But then that too defeats all reasons to use strings to begin with, since it can't be trivially sent from a terminal.
  • - In safety-related systems, protocols can't be allowed to have completely variable lengths. Rather, you would design them to have a fixed maximum length.
  • - UART data link layer bit error checking is subpar - it starts off with a start byte then assumes everything in the data byte is clocked in at the expected baud rate from there. And then assumes the stop bits will end up where they should or otherwise it's a framing error, but what about the bits in between? Unlike for example Manchester encoding or CAN, where each and every bit length is checked individually.
  • Traditionally UART protocols with safety concerns were always built in the manner of: 1 or several synch bytes, a packet size, the payload, then at least CRC-16 at the end. That's not a format encouraging strings as payload.
  • On the hardware side, anything requiring a bit of safety/integrity should always use RS422/RS485. There isn't a reason why you wouldn't use that. RS232 is more error prone and therefore obsolete since many decades back, not to mention raw "TTL" UART which is very EMI-prone and should never be allowed to leave a PCB.
  • In general, I feel like UART is old, obsolete technology. Where safety matters it is replaced by CAN, which is superior in every single way. Where it doesn't, it is replaced by USB or Ethernet. The only thing UART has going for it still is the simplicity of implementation - you can cut down development times a fair bit compared to CAN, let alone USB or Ethernet. (Higher layer protocol stacks is another story and they tend to be quite complicated no matter what hardware layer you are going for.)
  • It used to be that every PC had a RS232 port and that was a big reason to still use UART, but that's no longer the case since a decade or two. If you need an icky USB-to-RS232 adapter (...that _never_ works), you may as well use an USB-to-CAN adapter or pure USB all the way. I think I started to abandon UART in new projects for bootloader-like stuff somewhere around ~2008, in favor of CAN. Good riddance.
  • Olin has posted a good answer regarding the pros and cons. To add to that, look at where your C code is going: `if(strcmp...) else if (strcmp...)` and so on. This is a common mistake in embedded C when parsing strings, I've scolded a fair amount of programmers for writing super-inefficient code like that - with such `strcmp`chains you are essentially iterating over the same string over and over again. It is super-slow look-up and not ok, as addressed by any algorithm class in uni.
  • The proper production-quality version is to instead implement a binary search across a bunch of alphabetically sorted strings sitting in flash, "O(log n)". Standard C `bsearch` is probably good enough for most purposes. For more advanced situations you'd perhaps implement a hash map of some kind since those perform better when there is a large amount of data.
  • As for the _advantage_ of strings, it is that they are obviously more human-friendly and can get entered over an old school terminal, back in the days when we sill used terminals on PC. Something string-based like "AT commands" have been an industry standard for ages. If you need neither high performance nor safety, then why not.
  • Besides performance, the main arguments against using strings, or even UART, are all related to safety. If you don't need safety/data integrity, then fine. Otherwise:
  • - Whenever you send a protocol over UART, you ought to have at least a simple kind of checksum. Sure, you could use "parity" hardware checks, but this is a naive kind of safety that doesn't really catch a whole lot of errors.
  • In the realm of functional safety you'll come across the term "diagnostic coverage" meaning how large a percentage of all errors you are able to catch. If you consider that for one bit errors, two bit errors or burst errors, then mathematically both parity checks as well as simple checksums (add bytes together then invert/truncate etc) are immediately dismissed. The only thing good enough is CRC. And you can't send CRC as ASCII or that defeats how it works.
  • - In systems with lots of traffic you need means to synchronize the protocol. How does the receiver know it didn't start receiving in the middle of a protocol? Some unique characters are typically used for this. For example you could start the protocol with a bit sequence that is _not_ valid 7 bit ASCII like for example 0xAA. But then that too defeats all reasons to use strings to begin with, since it can't be trivially sent from a terminal.
  • - In safety-related systems, protocols can't be allowed to have completely variable lengths. Rather, you would design them to have a fixed maximum length.
  • - UART data link layer bit error checking is subpar - it starts off with a start byte then assumes everything in the data byte is clocked in at the expected baud rate from there. And then assumes the stop bits will end up where they should or otherwise it's a framing error, but what about the bits in between? Unlike for example Manchester encoding or CAN, where each and every bit length is checked individually.
  • Traditionally UART protocols with safety concerns were always built in the manner of: 1 or several synch bytes, a packet size, the payload, then at least CRC-16 at the end. That's not a format encouraging strings as payload.
  • On the hardware side, anything requiring a bit of safety/integrity should always use RS422/RS485. There isn't a reason why you wouldn't use that. RS232 is more error prone and therefore obsolete since many decades back, not to mention raw "TTL" UART which is very EMI-prone and should never be allowed to leave a PCB.
  • In general, I feel like UART is old, obsolete technology. Where safety matters it is replaced by CAN, which is superior in every single way. Where it doesn't, it is replaced by USB or Ethernet. The only thing UART has going for it still is the simplicity of implementation - you can cut down development times a fair bit compared to CAN, let alone USB or Ethernet. (Higher layer protocol stacks is another story and they tend to be quite complicated no matter what hardware layer you are going for.)
  • It used to be that every PC had a RS232 port and that was a big reason to still use UART, but that's no longer the case since a decade or two. If you need an icky USB-to-RS232 adapter (...that _never_ works), you may as well use an USB-to-CAN adapter or pure USB all the way. I think I started to abandon UART in new projects for bootloader-like stuff somewhere around ~2008, in favor of CAN. Good riddance. But then I work pretty much exclusively with safety-related products only. One example of that since relays were mentioned would be relay control boards for industrial use.
#1: Initial revision by user avatar Lundin‭ · 2026-08-10T09:07:26Z (about 1 month ago)
Olin has posted a good answer regarding the pros and cons. To add to that, look at where your C code is going: `if(strcmp...) else if (strcmp...)` and so on. This is a common mistake in embedded C when parsing strings, I've scolded a fair amount of programmers for writing super-inefficient code like that - with such `strcmp`chains you are essentially iterating over the same string over and over again. It is super-slow look-up and not ok, as addressed by any algorithm class in uni.

The proper production-quality version is to instead implement a binary search across a bunch of alphabetically sorted strings sitting in flash, "O(log n)". Standard C `bsearch` is probably good enough for most purposes. For more advanced situations you'd perhaps implement a hash map of some kind since those perform better when there is a large amount of data.

As for the _advantage_ of strings, it is that they are obviously more human-friendly and can get entered over an old school terminal, back in the days when we sill used terminals on PC. Something string-based like "AT commands" have been an industry standard for ages. If you need neither high performance nor safety, then why not.

Besides performance, the main arguments against using strings, or even UART, are all related to safety. If you don't need safety/data integrity, then fine. Otherwise:

- Whenever you send a protocol over UART, you ought to have at least a simple kind of checksum. Sure, you could use "parity" hardware checks, but this is a naive kind of safety that doesn't really catch a whole lot of errors. 

  In the realm of functional safety you'll come across the term "diagnostic coverage" meaning how large a percentage of all errors you are able to catch. If you consider that for one bit errors, two bit errors or burst errors, then mathematically both parity checks as well as simple checksums (add bytes together then invert/truncate etc) are immediately dismissed. The only thing good enough is CRC. And you can't send CRC as ASCII or that defeats how it works.

- In systems with lots of traffic you need means to synchronize the protocol. How does the receiver know it didn't start receiving in the middle of a protocol? Some unique characters are typically used for this. For example you could start the protocol with a bit sequence that is _not_ valid 7 bit ASCII like for example 0xAA. But then that too defeats all reasons to use strings to begin with, since it can't be trivially sent from a terminal.

- In safety-related systems, protocols can't be allowed to have completely variable lengths. Rather, you would design them to have a fixed maximum length.

- UART data link layer bit error checking is subpar - it starts off with a start byte then assumes everything in the data byte is clocked in at the expected baud rate from there. And then assumes the stop bits will end up where they should or otherwise it's a framing error, but what about the bits in between? Unlike for example Manchester encoding or CAN, where each and every bit length is checked individually.

Traditionally UART protocols with safety concerns were always built in the manner of: 1 or several synch bytes, a packet size, the payload, then at least CRC-16 at the end. That's not a format encouraging strings as payload.

On the hardware side, anything requiring a bit of safety/integrity should always use RS422/RS485. There isn't a reason why you wouldn't use that. RS232 is more error prone and therefore obsolete since many decades back, not to mention raw "TTL" UART which is very EMI-prone and should never be allowed to leave a PCB.

In general, I feel like UART is old, obsolete technology. Where safety matters it is replaced by CAN, which is superior in every single way. Where it doesn't, it is replaced by USB or Ethernet. The only thing UART has going for it still is the simplicity of implementation - you can cut down development times a fair bit compared to CAN, let alone USB or Ethernet. (Higher layer protocol stacks is another story and they tend to be quite complicated no matter what hardware layer you are going for.)

It used to be that every PC had a RS232 port and that was a big reason to still use UART, but that's no longer the case since a decade or two. If you need an icky USB-to-RS232 adapter (...that _never_ works), you may as well use an USB-to-CAN adapter or pure USB all the way. I think I started to abandon UART in new projects for bootloader-like stuff somewhere around ~2008, in favor of CAN. Good riddance.