# Async serial custom analyzer

**URL:** <https://discuss.saleae.com/t/async-serial-custom-analyzer/837>\
**Category:** Extensions\
**Created:** [December 17, 2020, 6:13pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837 "2020-12-17T18:13:03Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 17, 2020, 6:13pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/1 "2020-12-17T18:13:03Z")

</div>

First off, I am a NOOB regarding Python. But I don’t think that what I want to do should be too hard and I am an intermediate programmer in general. That being said here is what I am working on…

I have a small PIC processor that spits out debug bytes real time at 500kbaud. The bytes are location markers in the code on the PIC, and sometimes have a 1 or 2 byte payload, but usually not. I’ve used this for debugging for quite a while so I can debug while the chip is running real time. I have always used the Logic to watch and translate the serial line to decimal, then I would manually go to the table that translates the numbers into human readable labels to see what was going on.

I would like to write an extension to do the translation for me instead. I went through the Async example. I want to bring in decimal data instead of ASCII. Then I figure I can use a tuple table of my labels to print out what they mean. Once I get that down I can decide what to do with the bytes that have payloads.

So, I may have several questions, but my first is: In the example it was bringing in data with:  
ch = frame.data[‘data’].decode(‘ascii’)

What is the frame.data when it comes in? If the analyzer is set to decimal can I just use the frame.data directly? Like:  
debug\_code = frame.data[‘data’]

Then I could output:

#Shortened List for the example  
DebugMessageList = ( # This is actually a tuple, not a list, but who knows what a tuple is?  
“UnUsed”,  
“Initialize\_Variables”, # 1  
“Version\_Load”, # 2  
“Begin\_BT\_Setup”) # 3

…

```
result_types = {
    'format':'{{DebugMessageList[debug_code]}}'

```

I know this is dumbed down, but is this headed the right direction? I am trying not to write a book here!

---

<div class="post-metadata">

**Author:** ![huffman](https://avatars.discourse-cdn.com/v4/letter/h/71e660/32.png) [@huffman](https://discuss.saleae.com/u/huffman)\
**Post date:** [December 17, 2020, 6:37pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/2 "2020-12-17T18:37:35Z")

</div>

Hi @awolfe!

> But I don’t think that what I want to do should be too hard and I am an intermediate programmer in general.

Agreed! Any feedback you have about pain points is helpful. The goal is to make the process smooth and easy, but admittedly we aren’t there yet.

> What is the frame.data when it comes in? If the analyzer is set to decimal can I just use the frame.data directly?

The documentation at [https://support.saleae.com/extensions/analyzer-frame-types/serial-analyzer](https://support.saleae.com/extensions/analyzer-frame-types/serial-analyzer) should give some insight into the actual values in `frame.data`. `frame.data` is a dictionary whose contents depend on the analyzer being used. In this case, the serial analyzer has 3 fields: `data`, `error`, and `address`.

`data` will always be the Python type `bytes`. The type of this field is _not_ affected by what you set in the application, but I can see where that is confusing (we’ll work on making this more clear).

In your case, it sounds like the values are always a single byte. For that, you can do `debug_code = frame.data['data'][0]` to get the first byte in the data. If you have multiple bytes that you want to convert to an int, you can use `int.from_bytes(frame.data['data'], 'big')` (or ‘little’, depending on the endianness)

For the format string, you can only access values in the AnalyzerFrame that you return from your `decode` function. The simplest solution here is to put the debug string in the frame itself:

```auto
        return AnalyzerFrame('debug', frame.start_time, frame.end_time, {
            'debug_msg': DebugMessageList[debug_code]
        })

```

Technically you don’t need to provide a format string - the default is to list out the values in the frame - but if you do want a custom format, you can do this:

```auto
result_types = {
    'debug':'{{data.debug_msg}}'

```

Hope that helps! Please let me know if you have any more questions.

Ryan

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 17, 2020, 10:05pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/3 "2020-12-17T22:05:01Z")

</div>

Thanks for the info! That was helpful…  
 ![image](https://canada1.discourse-cdn.com/flex030/uploads/saleae/original/1X/f8bef09055df984e74af25cbc35a6efea278dbd3.png)

I now have some output… I’ll see if I have any questions in the next step.

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 18, 2020, 5:56pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/4 "2020-12-18T17:56:51Z")

</div>

@huffman I am continuing to refine this. I have it showing the debug message directly now by just using the following return:

> return AnalyzerFrame(DebugMessageList[debug\_code], frame.start\_time, frame.end\_time, {})

As I was testing it I was noticing a couple things. The data shows up in the data table if I select it to, but sometimes it misses data for some reason. Here is an example:

 ![image](https://canada1.discourse-cdn.com/flex030/uploads/saleae/original/1X/a7952aa33b7fc122ea9ded9d53dc827fd718591e.png)

Leave\_Shutoff should be in the table directly above Start\_Motor\_Forward, but it isn’t for some reason.

The other thing is that even though there is select box for it to be sent to the terminal window, that doesn’t seem to be working. Is that expected?

In general it is working great and I am now working on adding the instances where there are payload bytes along with particular debug messages.

Thanks for the cool tools!

---

<div class="post-metadata">

**Author:** ![huffman](https://avatars.discourse-cdn.com/v4/letter/h/71e660/32.png) [@huffman](https://discuss.saleae.com/u/huffman)\
**Post date:** [December 18, 2020, 6:17pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/5 "2020-12-18T18:17:50Z")

</div>

> I have it showing the debug message directly now by just using the following return:

Great idea! I didn’t think about using the debug msg as the frame type.

> Leave\_Shutoff should be in the table directly above Start\_Motor\_Forward, but it isn’t for some reason.

That’s a bug, I’ve reported it internally. Thanks!

> The other thing is that even though there is select box for it to be sent to the terminal window, that doesn’t seem to be working. Is that expected?

Yes, currently terminal support for HLAs is limited. Any `print(...)` statements in your python script will show up in the terminal, though. You could do that in your `decode(...)` function.

> In general it is working great and I am now working on adding the instances where there are payload bytes along with particular debug messages.

Awesome! Let us know if you have more questions.

Ryan

---

<div class="post-metadata">

**Author:** ![timreyes](https://yyz2.discourse-cdn.com/flex030/user_avatar/discuss.saleae.com/timreyes/32/108_2.png) [@timreyes](https://discuss.saleae.com/u/timreyes)\
**Post date:** [December 18, 2020, 9:29pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/6 "2020-12-18T21:29:18Z")

</div>

@awolfe Thanks for reporting that bug with the Data Table. We’re looking into it right now but could use your help. Would you mind sending over the following?

- Your HLA files
- A capture file (.sal format) that shows the Data Table issue

If they are files you don’t want to make public here, you can also send it over using the link below. Your files and message would go to me directly through a support ticket.

> **[Submit a request – Saleae](https://contact.saleae.com/hc/en-us/requests/new)**

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 18, 2020, 10:20pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/7 "2020-12-18T22:20:50Z")

</div>

I am just heading out for the Christmas holiday. I will be back in on the 28th. I saved a copy of the changes I have made since earlier (they were a ways from working yet), and undid back to where it was when I posted last…

In the zip is the extension:  
[Signature Board Debug.zip](https://discuss.saleae.com/uploads/short-url/zD0WbGQqqUpKxmNjYlnee5nsrnT.zip) (4.8 KB)

Here is the capture file:  
[Async Serial Data.sal](https://discuss.saleae.com/uploads/short-url/6UaMvBJz3smRhfyeKg00qjTquIN.sal) (58.4 KB)

I hope that helps.  
Hope you all have a Merry Christmas!

---

<div class="post-metadata">

**Author:** ![timreyes](https://yyz2.discourse-cdn.com/flex030/user_avatar/discuss.saleae.com/timreyes/32/108_2.png) [@timreyes](https://discuss.saleae.com/u/timreyes)\
**Post date:** [December 18, 2020, 10:32pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/8 "2020-12-18T22:32:41Z")

</div>

Thanks for sending those over! We’ll be taking a look at this bug in the meantime. Hope you have a Merry Christmas as well!

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 28, 2020, 9:59pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/9 "2020-12-28T21:59:56Z")

</div>

> [@huffman](#):
>
> Please let me know if you have any more questions.

Hi Ryan,

I have worked on this some more today… I am stuck, and it is probably a simple newbie issue. I want to keep a byte count, for when a debug message has a payload. I need to initialize the byte count before I start incrementing it. However, the compiler is complaining about where I am initializing it. I have tried moving it around some, but I don’t want it to initialize every time I receive a byte. I want it to initialize when the analyzer begins to analyze all the data in the stream. I included the entire module so maybe you could get a better idea of what I am trying to accomplish.

When you get a chance, please check out the attached code. Here is the compile error. ![image](https://canada1.discourse-cdn.com/flex030/uploads/saleae/original/1X/bc326f671c8fb9554e743dcb64a835e4660c3a50.png)

[Signature Board Debug.zip](https://discuss.saleae.com/uploads/short-url/kCDECzvJUkYIV2NLbaHhSzpVk2L.zip) (5.4 KB)

Thanks for your help!

---

<div class="post-metadata">

**Author:** ![huffman](https://avatars.discourse-cdn.com/v4/letter/h/71e660/32.png) [@huffman](https://discuss.saleae.com/u/huffman)\
**Post date:** [December 28, 2020, 10:25pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/10 "2020-12-28T22:25:20Z")

</div>

Hi @awolfe,

In Python you will need to use `self.byte_count` to access class and instance variables, like this: `self.byte_count = self.byte_count + 1`.

I’d also recommend checking out [https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables](https://docs.python.org/3/tutorial/classes.html#class-and-instance-variables) for information on class and instance variables. You are using a class variable, which is generally fine for HighLevelAnalyzers, but only because Logic2 runs each analyzer in a separate environment, so they aren’t sharing the same `byte_count` value. But, if you end up creating other classes, you’ll want to know the difference.

Hope that helps! And excited to see that you are making progress!

Ryan

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 30, 2020, 6:10pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/11 "2020-12-30T18:10:46Z")

</div>

Hi @huffman,

I’ve got it mostly working for what I wanted for now, but I just got this error on a new capture: ![image](https://canada1.discourse-cdn.com/flex030/uploads/saleae/original/1X/210c1d04782937d4ffd470c959be40d5c52d2a9c.png)

I assume it is because there is a power on event in the data stream and it is not handling it correctly. Do I need to handle that somewhere in my code and how? I have again attached the latest code and the capture that caused the error.  
[Signature Board Debug.zip](https://discuss.saleae.com/uploads/short-url/6ky0xeenKE8khq2eHs4oLR3SWSl.zip) (5.9 KB) [Async Serial Data 2.sal](https://discuss.saleae.com/uploads/short-url/7I019nrKsShK90cUm35ENNYeQK4.sal) (47.4 KB)

Thanks for all your help!

---

<div class="post-metadata">

**Author:** ![rani](https://yyz2.discourse-cdn.com/flex030/user_avatar/discuss.saleae.com/rani/32/343_2.png) [@rani](https://discuss.saleae.com/u/rani)\
**Post date:** [December 30, 2020, 6:16pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/12 "2020-12-30T18:16:56Z")

</div>

From a quick look, it seems like you returned a `Set` as data (line 157). I don’t think this type is supported

---

<div class="post-metadata">

**Author:** ![awolfe](https://avatars.discourse-cdn.com/v4/letter/a/8edcca/32.png) [@awolfe](https://discuss.saleae.com/u/awolfe)\
**Post date:** [December 30, 2020, 6:28pm UTC](https://discuss.saleae.com/t/async-serial-custom-analyzer/837/13 "2020-12-30T18:28:04Z")

</div>

You are right. Thank you!
