Shop OBEX P1 Docs P2 Docs Learn Events
Bell202 object, AX.25 and APRS - Page 2 — Parallax Forums

Bell202 object, AX.25 and APRS

2»

Comments

  • ke4pjwke4pjw Posts: 1,172
    edited 2011-06-14 19:46
    RvnPhnx wrote: »
    As the one who made the conversion from Jason's original, I'd like to know very much what is purported to be wrong with this. I will note that I have only tried DECODING packets with it, and that's not exactly the same process of encoding.

    This is an interesting read. http://web.archive.org/web/20060117083030/http://www.joegeluso.com/software/articles/ccitt.htm (The domain is no longer registered) It appears there is some controversy regarding the "correctness" of various CRC-CCITT 16 bit implementations.
  • leggsleggs Posts: 21
    edited 2011-06-15 08:37
    Has anybody confirmed that my modifications work? Has anybody transmitted and successfully decoded an AX.25 packet? Is anybody working on producing a complete usable object? I do not want to spend my time writing code that other people can probably do better. I am interested mainly in transmitting APRS packets, so if no one else is working on this, I will write code to transmit an APRS packet with custom text
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-15 11:54
    RvnPhnx wrote: »
    As the one who made the conversion from Jason's original, I'd like to know very much what is purported to be wrong with this. I will note that I have only tried DECODING packets with it, and that's not exactly the same process of encoding.
    RvnPhnx,

    I tried your routine, but I wasn't able to get the correct CRC with it. One problem I saw was that it accesses the buffer as words, which means it can only handle blocks with an even number of bytes. You increment the buffer pointer, key, by one after each access. You should increment by 2 to get to the next word. You only loop "len - 1" times, and it seems that it should loop "len" times, unless "len" includes the received CRC. Also, shouldn't the inner loop repeat 16 times instead of 15?

    I tried various corrections, but I couldn't get it to produce the right answer. I could have done a few more corrections, but then it would be essentially identical to the routine I posted.

    When you decoded packets, were you able to get the CRCs to match? Can you post a few samples of packets you were able to decode?

    Dave
  • ke4pjwke4pjw Posts: 1,172
    edited 2011-06-15 12:09
    leggs wrote: »
    Has anybody confirmed that my modifications work? Has anybody transmitted and successfully decoded an AX.25 packet? Is anybody working on producing a complete usable object? I do not want to spend my time writing code that other people can probably do better. I am interested mainly in transmitting APRS packets, so if no one else is working on this, I will write code to transmit an APRS packet with custom text

    I looked at your code last night. I like where you have placed everything on the assembly side. Our interests are aligned in that we both want to transmit APRS packets, however I don't think I will have time over the next couple of weeks to pick up the torch and run with it. I have quite a bit of knowledge at the APRS level. I built a .net packet parser from scratch and don't think it would be very difficult to do the same in spin for assembling the packets. (BTW, Mic-E documentation is horrendous in the way it's explained in the spec) I really appreciate you hard work on this! Your very close! Can't wait to build a PropTracker :)
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-06-15 12:46
    The code needs to be able to handle sending data bytes of $7e and $00. You also need to ensure that there is at least one flag character between blocks. When you write data to the FIFO there is no way to know where the block boundaries are. One way to do this would be to wait until the transmit FIFO is empty, and a flag character has been sent, before you load another frame into the FIFO.

    Or you could implement a blocking scheme inside the FIFO by using a magic word followed by a block count. The magic word is useful to check for buffer over-runs. You could use a single byte, such as $7e for the magic word. So a block of data such as {$12, $34, $56, $78} would look like {$7e, $04, $12, $34, $56, $78} in the FIFO. This way you could delineate block boundaries in the FIFO.
  • leggsleggs Posts: 21
    edited 2011-06-16 13:51
    At this stage I have got a sendPacket function working. It takes a string, which it puts in the information field of a UI AX.25 packet. So you could potentially send any telemetry or other info. If i call the function with a NMEA string straight from a gps, it shows up on the map in software such as UIView. So, a propTracker would be easy!

    There are so many different formats for AX.25 packets, that making a comprehensive object is too much work. It will work better if my code is simply altered for individual uses. I will make functions to send one or two useful, and generic, types of packets. Does anyone want anything specific? I have a lot of free time at the moment (university holidays).
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-19 17:28
    Dave Hein wrote: »
    The code needs to be able to handle sending data bytes of $7e and $00. You also need to ensure that there is at least one flag character between blocks. When you write data to the FIFO there is no way to know where the block boundaries are. One way to do this would be to wait until the transmit FIFO is empty, and a flag character has been sent, before you load another frame into the FIFO.

    Or you could implement a blocking scheme inside the FIFO by using a magic word followed by a block count. The magic word is useful to check for buffer over-runs. You could use a single byte, such as $7e for the magic word. So a block of data such as {$12, $34, $56, $78} would look like {$7e, $04, $12, $34, $56, $78} in the FIFO. This way you could delineate block boundaries in the FIFO.

    This is why I was focusing on implementing a KISS-compliant TNC. Unfortunately, I never managed to get a stable-enough decode going (largely, I suspect, due to audio-coupling issues) to get to the point of testing for valid CRC, so my KISS "packets" weren't anywhere near compliant.
    (It should probably be noted that I took the opposite track than most people, attempting to demodulate first as I considered that the hard part. I was also trying to decode live packets pulled "off the air"--144.390--so as to not get any falsely positive "good" decodes.)

    I have also been seriously considering implementing 6PACK, but I'll have the same problem as with KISS: A valid (standard) packet can still be 330 bytes long (excluding the flags, which many implementers have chosen to generate locally in the TNC, and do not pass back to the DTE in 6PACK & KISS), which is more buffer space than we have. This means two things:
    (1) Flags in the datastream must somehow be extracted from the stream (the function of KISS & 6PACK encapsulation) to allow 8-bit transparency, but as we don't have the space in the buffer (8-bit index) for a whole packet we need to somehow tie the transparent stream to the flags for decoding in SPIN (where we have more RAM available). We could in theory change the buffering to use a 9-bit index, but that increases code complexity. (Alas, some implementations choose to ignore the 256-byte size limit of the data field, so using the 9-bit index isn't really much of a fix either.)
    (2) We need some way to notify the SPIN wrapper that a new packet has started (remember, a single HDLC flag is enough to separate two packets, so we don't care about endings--an end is just the start of an invalid packet) so that we can handle the CRC appropriately.

    These issues also have converse versions in transmitting.

    The thought does occur to me that one need not keep the whole packet in queue, but that does change the way that we handle things a bit. In particular we need to teach it to send ABORT sequences, for instance. HMMMM.....
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-19 17:39
    Dave Hein wrote: »
    RvnPhnx,

    I tried your routine, but I wasn't able to get the correct CRC with it. One problem I saw was that it accesses the buffer as words, which means it can only handle blocks with an even number of bytes. You increment the buffer pointer, key, by one after each access. You should increment by 2 to get to the next word. You only loop "len - 1" times, and it seems that it should loop "len" times, unless "len" includes the received CRC. Also, shouldn't the inner loop repeat 16 times instead of 15?

    I tried various corrections, but I couldn't get it to produce the right answer. I could have done a few more corrections, but then it would be essentially identical to the routine I posted.

    When you decoded packets, were you able to get the CRCs to match? Can you post a few samples of packets you were able to decode?

    Dave

    As I was having what are most likely audio coupling issues, I wasn't getting to the point of having something worth trying a CRC on. That's part of why I was hoping for help from others testing the CRC code.
    IN any case, I looked back at Jason's original code, and I got the loop parameter scaling from there ("len-1" and bits-1, respectively)--if there's something wrong with that I'd suggest talking with him about it. (Then we might all learn something.) The error that I seem to have made is in setting up my input buffering to use words, which should cause a 50% failure rate at best as you've noted.
    I may try some others (including your own) if I get to that point. (Given some of the thoughts I had while composing my other post, I may try translating that to assembler.)
    After all, receiving is really the hard part; transmitting is definitely easier.
    Thanks for the code review.
  • RvnPhnxRvnPhnx Posts: 36
    edited 2011-06-19 17:56
    ke4pjw wrote: »
    This is an interesting read. http://web.archive.org/web/20060117083030/http://www.joegeluso.com/software/articles/ccitt.htm (The domain is no longer registered) It appears there is some controversy regarding the "correctness" of various CRC-CCITT 16 bit implementations.

    The only controversy I've been able to find is of the sort that there is "controversy" among scientists with regard to global warming. The CRC-CCITT polynomial is (and has been since definition) x^16+x^12+x^5+1. This can, depending on the innards of the CRC routine, be represented several ways.
    One of the biggest issues here is properly handling the fact that the data is sent LSB-first but the FCS is to be sent MSB-first. There are two ways to do this: calculate the FCS taking this into account, or change the code inserting the FCS into or pulling the FCS from the data stream. The former is notably more popular in my research.
    There is always room to screw up the implementation. I seem to know a lot about that! ;-)
  • leggsleggs Posts: 21
    edited 2011-08-12 05:43
    For those who are interested, this project is not dead.

    Part of my senior design project involves sending AX25 packets with the Propeller. I will put up a link to the complete project when it is done in a few weeks. The AX25 and APRS parts seem to work without problems.

    Should I post the code here for you guys to check before putting an APRS object in the OBEX?
  • ke4pjwke4pjw Posts: 1,172
    edited 2011-08-12 07:25
    leggs wrote: »
    For those who are interested, this project is not dead.

    Part of my senior design project involves sending AX25 packets with the Propeller. I will put up a link to the complete project when it is done in a few weeks. The AX25 and APRS parts seem to work without problems.

    Should I post the code here for you guys to check before putting an APRS object in the OBEX?

    I would love to get my grubby little hands on your code ASAP :D Fantastic work leggs!
  • CapdiamontCapdiamont Posts: 218
    edited 2011-08-12 12:47
    We have to wait weeks? I can't wait to see it. Good job!
  • CapdiamontCapdiamont Posts: 218
    edited 2011-08-12 13:41
    Is the circuit the same as in the bell document? I don't have the prop backpack.
  • leggsleggs Posts: 21
    edited 2011-09-01 03:23
    OK guys, because some of you are eager to start playing with APRS, here is my code. It still needs some polishing, and comments, before I add it to the OBEX. Play with it and give me any suggestions.

    AX25.spin is a modified version of the Bell202 modem object. The schematics are the same. I have modified it to add NRZI encoding and bitstuffing, as required by the AX.25 protocol.

    APRS Demo.spin will transmit an APRS packet every few seconds. It contains a random location's coordinates, and an altitude. The altitude increases with every packet sent. You should be able to decode and view the packets using AGWPE.

    Remember to replace my callsign with yours in the DAT section of ax25.spin

    The simplest way to create a tracker using this code is to call createPacket with the string straight from your GPS.

    Let me know if it works for you.

    Edit: You may have to adjust the transmit level (volume) setting in AX.25 just as with the Bell202 modem object.
  • leggsleggs Posts: 21
    edited 2011-09-12 10:37
    So, has anybody tried my code? Any interesting uses for it yet?
  • Jay KickliterJay Kickliter Posts: 446
    edited 2011-11-08 03:22
    I'm interested. On my phone now, so I can't check until later. Have you had any confirmed (like on aprs.fi) position reports?
    leggs wrote: »
    So, has anybody tried my code? Any interesting uses for it yet?
  • leggsleggs Posts: 21
    edited 2011-11-09 07:37
    I launched a near space balloon with a Propeller as the flight computer. It transmitted APRS packets using a 300mW radiometrix VHF transmitter module. Half the packets were sent without a digi path, and the other half were meant to go via repeaters. The direct packets were picked up by two different IGates, and appeared on aprs.fi. I also received them using AGWPE on my laptop from 50km away. There must be a small error in the digi path, because the packets did not seem to be repeated by digipeaters. However, APRS with the Propeller definitely works!
  • Jay KickliterJay Kickliter Posts: 446
    edited 2011-11-10 05:35
    That's awesome. I once tried to tackle the APRS specs but got overwhelmed, there seemed to be too many ways to do the same thing. What decisions did you have to make? Or, did you port this from existing code? Also, are you in the US, where did you ge thte Radiometrix? From what I understand, the Radiometrix input serial, so you didn't use Phil's code?
    leggs wrote: »
    I launched a near space balloon with a Propeller as the flight computer. It transmitted APRS packets using a 300mW radiometrix VHF transmitter module. Half the packets were sent without a digi path, and the other half were meant to go via repeaters. The direct packets were picked up by two different IGates, and appeared on aprs.fi. I also received them using AGWPE on my laptop from 50km away. There must be a small error in the digi path, because the packets did not seem to be repeated by digipeaters. However, APRS with the Propeller definitely works!
  • leggsleggs Posts: 21
    edited 2011-12-02 10:28
    I launched a near space balloon powered by the Propeller. It used APRS. For more information have a look at this thread:

    http://forums.parallax.com/showthread.php?136334-Parallax-Propeller-Near-Space-Balloon


Sign In or Register to comment.