0

I've been working on decoding a UART-like signal, and while I've made some progress, I've hit a roadblock. I have a portion of the code that's currently working, but I believe there might be a better solution out there.

Problem: I'm using a logic analyzer to capture and decode the signal, but every attempt to decode it using the analyzer's built-in software has failed. From my calculations and observations, I believe the bit rate to be 46000 bps, but I can't seem to get a consistent and accurate decoding.

Logic Analyzer Message:

Binary: 1111 0110 1010 1010 1010 1010 1010 1010

Decode (I think): 366,252,252,252 enter image description here

Decoded Message (as per my code):

Red - 0000 0001 1010 1010 1010 1010 1010 1010

 1           252           252           252

Green - 0000 0010 1010 1010 1010 1010 1010 1010

 2           252           252           252

Blue - 0000 0011 1010 1010 1010 1010 1010 1010

 3           252           252           252

White - 0000 0100 1010 1010 1010 1010 1010 1010

4           252           252           252

My Current Code:

const int txPin = 3;  
const unsigned int defaultLowDuration = 16;

void setup() {
  pinMode(txPin, OUTPUT);
  digitalWrite(txPin, HIGH);
  Serial.begin(9600);  // initialize serial communication
  Serial.println("Enter four integers separated by commas (e.g. 5,47,0,153):");
}

void loop() {
  if (Serial.available()) {
    String input = Serial.readStringUntil('\n');
    int nums[4];
    int index = 0;
    for (int i = 0; i < input.length(); i++) {
      int val = 0;
      while (i < input.length() && isDigit(input[i])) {
        val = val * 10 + input[i] - '0';
        i++;
      }
      nums[index++] = val;
      if (index == 4) break;
    }
    
    if (index == 4) {
      sendIntegersAsBinary(nums[0], nums[1], nums[2], nums[3]);
      Serial.println("Signal sent. Enter another set of numbers or reset.");
    } else {
      Serial.println("Invalid input. Please enter four integers separated by commas.");
    }
  }
}

void sendIntegersAsBinary(int a, int b, int c, int d) {
  // Start bit
  digitalWrite(txPin, LOW);
  delayMicroseconds(50);  //rounded up from 76.5us
  
  // Sending 4 integers, 8 bits each
  sendIntegerAsBinary(a);
  sendIntegerAsBinary(b);
  sendIntegerAsBinary(c);
  sendIntegerAsBinary(d);

  // Stop bit
  digitalWrite(txPin, HIGH);
  delayMicroseconds(16);  // given defaultLowDuration
}

void sendIntegerAsBinary(int num) {
  for (int i = 8; i >= 0; i--) {
    bool bitToSend = (num >> i) & 0x01;
    sendBit(bitToSend, bitToSend ? 14 : 16);
    if(bitToSend){
      sendBit(0, 0 ? 14 : 16);
    }
  }
}

void sendBit(bool bit, unsigned int duration) {
  if (bit) {
    digitalWrite(txPin, HIGH);
  } else {
    digitalWrite(txPin, LOW);
  }
  delayMicroseconds(duration);
  
  digitalWrite(txPin, HIGH);  // return to default state
  delayMicroseconds(defaultLowDuration);
}

I'm hoping for insights into:

  1. Improvements or optimizations to my code.
  2. Any recommended methods or software to better utilize the logic analyzer for decoding.
  3. General troubleshooting tips or common pitfalls with UART-like decoding. I appreciate any advice or guidance you can provide. Has anyone else experienced a similar issue, and if so, how did you resolve it?

enter image description here

enter image description here

enter image description here

enter image description here

Thank you in advance!

10
  • A normal Arduino serial transmission for example has 8 data bits, no parity bits and one stop bit. Your serial stream does not appear to have any similar structure and is unlikely to be recognised by a standard analyser. What board are you using? The int data type can be 2 or 4 bytes depending on this. As a test, send "Hello World" using Serial.print at 9600 baud to your logic analyser and see what you get.
    – 6v6gt
    Sep 18 at 5:37
  • why are you using octal base?
    – jsotola
    Sep 18 at 5:53
  • The different widths do not match in integer multiples, and the assumed baud rate is non-standard. Why do you think that this is the common asynchronous serial protocol? Would you mind to edit your question and add a capture with better resolution and measured timing values? Since the later 2/3 looks repetitively, a zoomed part would suffice. Sep 18 at 6:35
  • 3
    This question is very unclear. What has your Arduino code to do with this signal? Is the signal coming from the Arduino or from a device that uses an unknown protocol? How could you decode 1010 1010 to 252? Why did you write “Red”, “Green”, “Blue” and “White”? Could this be the WS2812 protocol (short pulse = 0, long pulse = 1)? Sep 18 at 7:51
  • 1
    @EdgarBonet 10101010 is 252 in octal ... 10 101 010 ... very confusing when you are dealing with more than 8 bits
    – jsotola
    Sep 20 at 0:48

0

Browse other questions tagged or ask your own question.