Shop OBEX P1 Docs P2 Docs Learn Events
SpinScope: A Virtual Oscilloscope for the Propeller - Page 3 — Parallax Forums

SpinScope: A Virtual Oscilloscope for the Propeller

1356

Comments

  • Heater.Heater. Posts: 21,230
    edited 2014-11-02 09:40
    Tor,

    I'm sure perl is great and all. Just now I'm not in the mood for ever learning another programming language again. I seem to have been through so many over the years. It's worn out my enthusiasm for them.

    Now, any idea why that code passes control characters through to doCommand()? Perhaps the perl version just dose not. I can't tell.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-02 10:19
    heater wrote:
    One thing bothers me though. The payload data is binary. So who is to say those DLEs and EOTs don't show up in the data and cause the parser to get confused?
    It can't happen -- at least not on complete messages.That's the reason for doubling the DLEs in the data payload. A DLE DLE is always data. A DLE Letter is always a command, and a DLE EOT is always an end of message.

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2014-11-02 10:26
    Ah, yes, sorry. I did not notice the "DLE stuffing" going on in the Spin transmit code. Guess I should have looked harder.
  • Heater.Heater. Posts: 21,230
    edited 2014-11-02 17:17
    Phil,

    What's the idea behind the "I" command in SpinScope.spin ?

    As far as I can make out if a "B" command is received "DLE, B, 100, DLE, EOT" then a B command minus the data content is echoed back "DLE, B, DLE, EOT". Similarly for the other commands.

    But if an "I" command is received "DLE, I, DLE, EOT" then the following is returned "DLE, DLE, I, DLE, EOT, I, DLE, EOT"

    Which does not fit the protocol described previously.

    Also I see commands "1" and "2" which are not upper case alpha.

    Or have I read this totally incorrectly?
  • msrobotsmsrobots Posts: 3,701
    edited 2014-11-02 17:38
    Reading this post the 'encoding' is quite simple.
    Heater,

    The serial protocol is simple: DLE Cmd Data ... Data DLE EOT. If a data byte happens to be a DLE, a second DLE is inserted into the data stream and removed at the receiving end. Perl's regexes make it easy to parse out whole messages from the serial stream and do the DLE pruning.

    -Phil

    If I read this correct you need to read the stream until finding DLE.
    - if followed by EOT you found end of content.
    - if followed by DLE again its just the data DLE
    - if followed by something else its Cmd and then Data

    am I right here?

    cool project.

    Enjoy!

    Mike
  • Heater.Heater. Posts: 21,230
    edited 2014-11-02 17:45
    That is the way I understand the idea.

    Or...

    A start of message is DLE, [A-Z]

    And of message is DLE, EOT

    Body of message is just binary bytes except a byte value of DLE is escaped with a DLE.

    My problem is that looking at the SpinScope.spin source I can't see how that "I" command fits the scheme. Perhaps it's just not used.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-02 18:18
    heater wrote:
    What's the idea behind the "I" command in SpinScope.spin ?
    The "I" (inquire) command is used by the serial port scanner to ascertain which serial port SpinScope is running on.
    A start of message is DLE, [A-Z] End of message is DLE, EOT Body of message is just binary bytes except a byte value of DLE is escaped with a DLE.
    Yes.

    -Phil
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2014-11-02 18:42
    Well done Phil, sorry for the late post but I had congratulated you when you just barely first posted however I think the forum ate that post up as it seems to do sometimes due to timeouts. grumble grumble.

    Anyway you always seem to have really well presented projects and I've actually been hanging out for a while wondering whether you'd come up with another one to freshen up this wallowing forum.

    Now of course most of my Prop stuff is done in Tachyon so do you mind if I have a look at adapting this then? I'm thinking that the browser could talk directly to my network servers too so I should be able to do this remotely. But I haven't looked into the code close enough yet. Any thoughts?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-02 18:51
    Now of course most of my Prop stuff is done in Tachyon so do you mind if I have a look at adapting this then?
    Go for it, Peter! It's entirely open-source all the way, and the more that folks can contribute, the better!

    -Phil
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-02 22:29
    Phil,
    I am currently searching for where the install put spinscope.spin (Windoze 7 32bit)
    I have C:/PropTool132/ for the proptool installation and C:/Propeller/SpinScope for the location for SpinScope.
    The exe is present but currently I am searching for spinscope as its not in the C:/PropTool132/Library.
    Guess that is what I get for not using standard locations :(

    BTW Have you tried cranking up the serial interface to 500K or 1M baud? I will give it a shot once I get it running.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-02 22:54
    Ray,

    It probably created a directory at C:\Program Files (x86)\Parallax Inc\Propeller Tool 1.3.2\Library and put it there. That's what I get for taking too much for granted!

    I haven't tried the higher baud rates.

    -Phil
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-02 23:17
    Thanks Phil. I had just found it and yes, that's where it put it. Takes forever to search on these big HDDs.
  • Heater.Heater. Posts: 21,230
    edited 2014-11-03 01:14
    Curious,

    I also had to find SpinScope.exe. I had installed SpinScope under wine on Linux. It installs and runs but does not work.

    I found SpinScope.exe here:

    /home/heater/.wine/drive_c/Program Files/Bueno Systems Inc/SpinScope/SpinScope.exe

    Interesting, never heard of "Bueno Systems Inc".

    And why is it a different location for Cluso?
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-03 01:57
    Phil,
    Runs nicely although I had to program the test code into eeprom to get it working. Didn't go back and try afterwards.
    Now to try and crank up the timebase ;)

    heater,
    When running the installer I changed to C:/Propeller/SpinScope/
    BTW Bueno Systems Inc is Phil's company.
  • Heater.Heater. Posts: 21,230
    edited 2014-11-03 02:09
    Cluso,

    Oh yeah. Of course I did not read any of that just clicked though, click, click, click as fast as possible to get it installed.

    Typical stupid user installing random executable off the net on to his PC :)
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-03 08:48
    heater wrote:
    Interesting, never heard of "Bueno Systems Inc".
    That's me.

    Regarding the need to load the Spin program to EEPROM: the Perl module Win32::SerialPort is probably sending a DTR when it opens a port, even though I tell it not to.

    BTW, I'm using INNO to create the install package. I guess I need to figure out a way to give the user an option to locate either the Spin library or his own Spin project directory.

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2014-11-03 10:14
    Phil,

    Cool. You mean this is you: http://www.buenosystems.com/products.htm?

    Anyway, you got me playing with the regexp thing. I came up with this:
            re = /\x10([a-zA-Z\d])((\x10\x10|[^\x10])*)\x10\x04/g;
    
            stream += chunk;
            while (reArray = re.exec(stream)) {
                message.cmd = reArray[1];
                message.data = reArray[2].replace(/\x10\x10/g, '\x10');
                callback(message);
                pos = reArray.index + reArray[0].length;
            }
            stream = stream.substring(pos, stream.length);
    
    Basically the idea is that the regexp, "re", separates out the command character and the data bytes. And the command character can be any alpha-numeric.

    As usual I can never convince myself the regexp covers all cases correctly.

    Any comments?

    How do people verify/debug this stuff?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-03 11:02
    Heater, the regex looks okay. A regular expression is nothing more than a grammatical definition of a finite-state automaton. So it can be analyzed in exactly the same way for correctness.

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2014-11-03 12:03
    Phil,
    Heater, the regex looks okay.
    Cool. Thanks.
    A regular expression is nothing more than a grammatical definition of a finite-state automaton.
    That is clear to me.
    So it can be analyzed in exactly the same way for correctness.
    Ah, so it's the same impossible to prove correct as the source code I might write by hand to do the same thing in C or whatever language!

    What has always bugged me about a regexp is:

    1) As source code it's impenetrable. Might as well be written in assembler or BrainF***.

    2) When things don't match it's impossible to get a reason why. You know, like a simple log message that says, "Parse fail, expected x got y".

    3) Like 2) there is no way to step through what it does with a debugger.

    So how do people ever convince themselves that their regexps are correct? The only way I can see is to throw a bunch of test inputs at it. But then it's impossible to cover all cases.

    I might be happy with these simple cases, but I have seen regexps that are huge.
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-03 15:12
    Here is my code for generating faster pulses. I am using a 6.5MHz xtal so the prop is running at 104MHz.
    '' Scope Test
    CON
      _clkmode      = xtal1 + pll16x
      _xinfreq      = 6_500_000  
    OBJ
      sco:   "SpinScope"
    PUB Start | i
      sco.start
      cognew(@pulse,0)
      repeat                        '<==== could stop cog instead!!!
      
    {
      dira[7..0]~~
      i~
      repeat
        outa[7..0] := i++
    }    
    DAT
                  org       0
    pulse         mov       dira,#$FF               ' P0-7 outputs
    ' changes state every 8 clocks (ie freq is 1/16 = xtal freq)
    loop          add       outa,#1                 ' outa++
                  jmp       #loop
    
    
    P0=104MHz/16=6.5MHz
    P1=6.5MHz/2=3.25MHz
    P2=1.625MHz
    P3=812.5KHz
    P4=406.25KHZ
    P5=203.125KHz
    P6=101.5625KHz
    P7=50.78125KHz=19.69us

    P0 did not register a pulse on SpinScope so it is above the sample frequency obtainable.

    SpinScope002.jpg


    Phil: How can I add 10us/Div to the display???
    762 x 559 - 86K
  • TorTor Posts: 2,010
    edited 2014-11-04 05:26
    Heater. wrote: »
    So how do people ever convince themselves that their regexps are correct? The only way I can see is to throw a bunch of test inputs at it. But then it's impossible to cover all cases.
    If I feel the need to test a regex I do it directly in the shell. With Perl that's easy, and it can presumably be done similarly with some other languages too (e.g. Ruby I'm guessing).
    $ echo "test245letter" | perl -ne 'if (/(\d+)/){print "Got $1\n";} else {print "Did not match: $_";}'
    Got 245
    
    $ echo "testNOletter" | perl -ne 'if (/(\d+)/){print "Got $1\n";} else {print "Did not match: $_";}'
    Did not match: testNOletter
    
  • Heater.Heater. Posts: 21,230
    edited 2014-11-04 06:35
    Tor.

    In JavaScript using node.js like this:
    $ node -p "'test245letter'.match(/\d+/g)"
    [ '245' ]
    $
    

    Still throwing some test cases at an indecipherable regex does not fill ne with confidence.

    However I just found a couple of on line regex editor / debuggers that go some way to making regexs clearer to follow:

    This one draws a nice "rail road" diagram of your re syntax. https://www.debuggex.com/ which is very helpful.
    You have to escape back slashes though to work though so my regex is entered as:
    \\x10([a-zA-Z\d])((\\x10\\x10|[^\\x10])*)\\x10\\x04

    strangely those extra backslashes don't need to be put in the test string so this will match;
    \x10C\x10\x04

    This one gives a textual description of your syntax for another nice way to look at it. Problem is I can't get it to match anything!
    http://regex101.com/
  • TorTor Posts: 2,010
    edited 2014-11-04 09:42
    Well.. the other thing about working with regular expressions as full as the Perl variant is that after some time you become good at it and you'll be confident that it's correct (definitely not worse than for ordinary code - rather the opposite in fact). And there's always the Cookbook with recipes.. :)
  • Heater.Heater. Posts: 21,230
    edited 2014-11-04 09:59
    Tor,
    ... after some time you become good at it and you'll be confident that it's correct...
    I first discovered grep in about 1984. I'm still working on that confident part :)
    (definitely not worse than for ordinary code - rather the opposite in fact)
    Hmmm...ordinary code is much longer and bug prone. The regexp is very concise and similarly bug prone. Seems about the same to me. But the regexp is a whole different language than the "ordinary code" it is used in. That throws a whole other layer of complexity on understanding what is going on.
    And there's always the Cookbook with recipes.
    Strangely enough the regexp cook book arrived in our office last week. Jeeps it's huge! Looks like I have a lot bed time reading coming up.
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-04 15:03
    Phil,
    I took an in depth look at your spin code. I haven't calculated the max scan rate yet. I am looking at how I can up the rate to the xtal frequency. I want to look at signals running at 1/5 xtal freq (6MHz xtal, 1.2MHz signals = USB LS ;) )
    If I can get this to work, then I will need to get the timebase to include 10uS but I don't have any idea how to do this. What is involved?
  • TubularTubular Posts: 4,620
    edited 2014-11-04 16:00
    Brilliant, Phil, and thanks for putting the demo online Heater. Look forward to seeing how this evolves. All the best with the HS class.
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-04 19:50
    Here is a bit more info on the inner PASM code workings...
    '' This routine saves 17 longs for each channel, LSB first.
    '' The lower 13 bits of the first long are ignored (19 bits used)
    '' The upper 30 bits of the last long are ignored (2 bits used)
    '' This gives a total display of 501 bits for each channel in the 10 division scope screen.

    I am currently working on getting samples working at 1/16 clock rate. I don't expect to be able to do pre-trigger sampling this way tho'.

    Phil:
    What would be nice is to be able to expand the trace view plus scrolling ability.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-11-04 21:20
    Ray,

    The pre-trigger stuff is tricky. I'm planning an analog mode. There, I will probalby just keep a 501-byte circular buffer in the hub for each channel and take 450 samples after the trigger condition. The circular buffer pointer will then point 50 samples before the trigger, IOW the beginning of the trace.

    BTW, you can expand the trace in STOP mode by selecting a shorter timebase. The existing trace will expand about the trigger point. You can't scroll it though, since the trigger point is fixed on the screen.

    -Phil
  • Cluso99Cluso99 Posts: 18,066
    edited 2014-11-04 22:09
    Here is the sampling working at 1/16 of the clock frequency. I have made it into an object and is fairly straight forward.

    SpinScope_005 - Archive [Date 2014.11.05 Time 17.19].zip

    SpinScope005.jpg
  • ErNaErNa Posts: 1,738
    edited 2014-11-04 23:38
    Hello to all engaged: I now and then follow this thread and I am excited, how fast progress takes place, if professionals contribute! 1000 points!
Sign In or Register to comment.