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
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:
- Improvements or optimizations to my code.
- Any recommended methods or software to better utilize the logic analyzer for decoding.
- 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?
Thank you in advance!
1010 1010
to252
? Why did you write “Red”, “Green”, “Blue” and “White”? Could this be the WS2812 protocol (short pulse =0
, long pulse =1
)?