Shop OBEX P1 Docs P2 Docs Learn Events
TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++ - Page 69 — Parallax Forums

TACHYON O/S V3.0 JUNO - Furiously Fast Forth, FAT32+LAN+VGA+RS485+OBEX ROMS+FP+LMM+++

16667697172109

Comments

  • MJBMJB Posts: 1,235
    K6MLE wrote: »
    Update ...
    Problems with serial data not appearing where it should seems to only happen when running the GetData routine in its own cog. If I run everything in the same cog, this data problem doesn't occur. Could there be some sort of stack problem? Not sure what to look for.

    57 is your message length WITHOUT the CrLf ???
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-13 01:29
    K6MLE wrote: »
    If I use:
    64 BYTES SERBUF
    as the SERBUF definition,

    The word 'GetData', which is defined as such:
    pub GetData ( -- ) \ Read serial port and place WX data into array SERBUF.
    #57 0 DO 9 SERIN SERBUF I + C! DROP LOOP ;

    is meant to grab the incoming serial data and begin filling SERBUF. Using SERBUF@, which is defined as:
    : SERBUF@ SERBUF CR 57 DUMP ;

    However, when GetData (running in another cog) runs, the first two bytes are 0D0A, rather than 2455, which is the "$U" part of the "$ULTW" header. All the rest of the field of incoming data appear to come in correctly, but this has me baffled.
    CRLFs are part of the data stream so you should be waiting for a "$" as the start of packet and then receive the packet up to the crlf rather than assuming it will always fit in a simple loop. For instance, here is some code which will get your string but in this example it waits for the "$" and also pads out the data which I can input directly into the Forth text interpreter so it's a little different from how you are trying to interpret it "manually".
    80 BYTES SERBUF        --- serial buffer for alimeter raw data
    
    {HELP GetRaw ( -- )
    Read serial port and place WX data into array SERBUF but preprocess with spaces between fields.
    raw string
    $ULTW0000000002E00F76----000086A00001----00DA048D00000000
    gets padded with spaces
    ULTW 0000 0000 02E0 0F76 ---- 0000 86A0 0001 ---- 00DA 048D 0000 0000
    }
    pub GetRaw ( -- ) 
        BEGIN 9 SERIN "$" = UNTIL
        0 SERBUF
        BEGIN
          9 SERIN DUP $0D <>
        WHILE
          OVER C! 1+ SWAP 1+ SWAP
          OVER 3 AND 0= IF BL OVER C! 1+ THEN
        REPEAT DROP C~ DROP
        ;
    

  • MJBMJB Posts: 1,235
    K6MLE wrote: »
    If I use:
    64 BYTES SERBUF
    as the SERBUF definition,

    The word 'GetData', which is defined as such:
    pub GetData ( -- ) \ Read serial port and place WX data into array SERBUF.
    #57 0 DO 9 SERIN SERBUF I + C! DROP LOOP ;

    is meant to grab the incoming serial data and begin filling SERBUF. Using SERBUF@, which is defined as:
    : SERBUF@ SERBUF CR 57 DUMP ;

    However, when GetData (running in another cog) runs, the first two bytes are 0D0A, rather than 2455, which is the "$U" part of the "$ULTW" header. All the rest of the field of incoming data appear to come in correctly, but this has me baffled.
    CRLFs are part of the data stream so you should be waiting for a "$" as the start of packet and then receive the packet up to the crlf rather than assuming it will always fit in a simple loop. For instance, here is some code which will get your string but in this example it waits for the "$" and also pads out the data which I can input directly into the Forth text interpreter so it's a little different from how you are trying to interpret it "manually".
    If you also add the $ hex number qualifier in front of the numbers Tachyon can use it's input parser to read them from the string later.
    80 BYTES SERBUF        --- serial buffer for alimeter raw data
    
    {HELP GetRaw ( -- )
    Read serial port and place WX data into array SERBUF but preprocess with spaces between fields.
    raw string
    $ULTW0000000002E00F76----000086A00001----00DA048D00000000
    gets padded with spaces
    ULTW 0000 0000 02E0 0F76 ---- 0000 86A0 0001 ---- 00DA 048D 0000 0000
    }
    pub GetRaw ( -- ) 
        BEGIN 9 SERIN "$" = UNTIL
        0 SERBUF
        BEGIN
          9 SERIN DUP $0D <>
        WHILE
          OVER C! 1+ SWAP 1+ SWAP
          OVER 3 AND 0= IF 
                  BL OVER C! 1+ 
                  "$" OVER C! 1+    \ insert the $ in front of hex numbers  !!!
           THEN
        REPEAT DROP 1- C~ DROP
        ;
    
    And then use my EVAL
    \ === evaluate the FORTH sentence in a null-terminated string =======
    \ define dummy word
    : $ULTW  ;   
    
    pub (EVALSTR) ( strAddr -- )
             C@++ DUP 0= IF DROP CON  $0D  THEN   ;  
              \ just deliver one char after the other, on last one add $0D to get it executed and set reader back to CONsole
    
    pub EVAL ( strAddr -- \ evaluate the FORTH sentence in the null-teminated string starting at strAddr )
          [COMPILE] GRAB
    	\  NULLOUT  \ suppress output
        ' (EVALSTR) ukey W! ; 
    IMMEDIATE	
    
    \ 	" 1 1 + . " EVAL 
    
    SERBUF EVAL  \ puts the numbers on the stack for further processing
    
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-13 10:29
    MJB wrote: »
    And then use my EVAL
    \ === evaluate the FORTH sentence in a null-terminated string =======
    \ define dummy word
    : $ULTW  ;   
    
    pub (EVALSTR) ( strAddr -- )
             C@++ DUP 0= IF DROP CON  $0D  THEN   ;  
              \ just deliver one char after the other, on last one add $0D to get it executed and set reader back to CONsole
    
    pub EVAL ( strAddr -- \ evaluate the FORTH sentence in the null-teminated string starting at strAddr )
          [COMPILE] GRAB
    	\  NULLOUT  \ suppress output
        ' (EVALSTR) ukey W! ; 
    IMMEDIATE	
    
    \ 	" 1 1 + . " EVAL 
    
    SERBUF EVAL  \ puts the numbers on the stack for further processing
    

    Funny that, after I posted the code I thought I should add a $ to enforce hex number processing in case the number started with an alpha (not 0..9) as a number such as FEED will be rejected but not 0FEED or $FEED .
    (@forum: good to see the Parallax font is supported here as I wanted to say <zero>FEED and not OFEED :) )

    BTW, I wrote an EVAL the other day for this purpose and turns out unbeknown that I did something similar to you,
    WORD evalp PRIVATE
    pri (EVAL)    evalp W@ C@ evalp W++ DUP 0= IF DROP CONIO $0D THEN ;
    pub EVAL$ ( str -- )    evalp W! ' (EVAL) ukey W! NULLOUT  ;
    

    So it ends up that after preprocessing that I just do a simple SERBUF EVAL$ and $ULTW sets a deferred action (via the accept vector) so that it takes the numbers off the stack and in this case just stores them in variables. Even ---- or in this updated case it would be $---- just leaves a dummy zero.
    --- Let $ULTW set a defered action for execution at the end of the line after parameters are stacked                                                          
    pub $ULTW    ' (ULTW) prompt 2+ W! ;
    

  • MJBMJB Posts: 1,235
    MJB wrote: »
    And then use my EVAL
    \ === evaluate the FORTH sentence in a null-terminated string =======
    \ define dummy word
    : $ULTW  ;   
    
    pub (EVALSTR) ( strAddr -- )
             C@++ DUP 0= IF DROP CON  $0D  THEN   ;  
              \ just deliver one char after the other, on last one add $0D to get it executed and set reader back to CONsole
    
    pub EVAL ( strAddr -- \ evaluate the FORTH sentence in the null-teminated string starting at strAddr )
          [COMPILE] GRAB
    	\  NULLOUT  \ suppress output
        ' (EVALSTR) ukey W! ; 
    IMMEDIATE	
    
    \ 	" 1 1 + . " EVAL 
    
    SERBUF EVAL  \ puts the numbers on the stack for further processing
    

    Funny that, after I posted the code I thought I should add a $ to enforce hex number processing in case the number started with an alpha (not 0..9) as a number such as FEED will be rejected but not 0FEED or $FEED .
    (@forum: good to see the Parallax font is supported here as I wanted to say <zero>FEED and not OFEED :) )

    BTW, I wrote an EVAL the other day for this purpose and turns out unbeknown that I did something similar to you,
    WORD evalp PRIVATE
    pri (EVAL)    evalp W@ C@ evalp W++ DUP 0= IF DROP CONIO $0D THEN ;
    pub EVAL$ ( str -- )    evalp W! ' (EVAL) ukey W! NULLOUT  ;
    

    So it ends up that after preprocessing that I just do a simple SERBUF EVAL$ and $ULTW sets a deferred action (via the accept vector) so that it takes the numbers off the stack and in this case just stores them in variables. Even ---- or in this updated case it would be $---- just leaves a dummy zero.
    --- Let $ULTW set a defered action for execution at the end of the line after parameters are stacked                                                          
    pub $ULTW    ' (ULTW) prompt 2+ W! ;
    

    YES - this is where Forth & TACHYON are real fun.

    I made the EVAL almost 2 years ago for the dynamic webserver with Tachyon-code execution (shared the google doc with you ...)
    but so much to remember ...

    thanks for the 'defered action' trick.
    you don't give (ULTW) - I assume it needs to set the prompt back to normal.

    thanks
    Markus
  • MJB wrote: »
    YES - this is where Forth & TACHYON are real fun.

    I made the EVAL almost 2 years ago for the dynamic webserver with Tachyon-code execution (shared the google doc with you ...)
    but so much to remember ...

    thanks for the 'defered action' trick.
    you don't give (ULTW) - I assume it needs to set the prompt back to normal.

    thanks
    Markus

    I hardly look at my own code :) In this case I figured this would be the easiest way to make EVAL work and I have used the unlabelled accept vector in the past for setting an end of line action, even to simulate infix notation. If the accept vector is non-zero then it will be executed at the end of the line, that is, all the other words have already been compiled, either in a definition or in the scratch-pad area at HERE. So the referenced (ULTW) just zeroes it back with a "prompt 2+ W~" and of course I could label the vector although it is seldom used:
    prompt 2+ == accept

    There is an application I wrote for this "Ultimeter" device which displays the weather information on a VGA screen. I found that the Ultimeter only outputs serial information no more than a few times a second at the very most so there was no need to dedicate a cog to serial receive and instead the same cog collects and preprocesses the string then hands it over to EVAL$ which then updates the variables and screen etc before returning back to waiting for another string. Not having an Ultimeter doesn't stop me from pasting the sample strings in for testing.
  • MJBMJB Posts: 1,235
    no need to dedicate a cog to serial receive and instead the same cog collects and preprocesses the string then hands it over to EVAL$ which then updates the variables and screen etc before returning back to waiting for another string. Not having an Ultimeter doesn't stop me from pasting the sample strings in for testing.

    so you run the receive in keypoll?
    I was thinking about this as well ...
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-13 15:57
    MJB wrote: »
    no need to dedicate a cog to serial receive and instead the same cog collects and preprocesses the string then hands it over to EVAL$ which then updates the variables and screen etc before returning back to waiting for another string. Not having an Ultimeter doesn't stop me from pasting the sample strings in for testing.

    so you run the receive in keypoll?
    I was thinking about this as well ...
    Sorry, I meant no need to dedicate a cog to serial receive and one for processing, just let one cog receive then process etc. The problem with trying to run it through keypoll is that SERIN is a simple routine that waits for a start bit using WAITPNE so it can't do anything else until it's done. If I get around to integrating a multiport serial object then we would probably use that and then it would be possible to run it in keypoll.

    BTW, keypoll got an upgrade recently in that we don't set this directly anymore as a table of up to 8 vectors are being checked so all you need to do now is:
    ' <mycode> +POLL
    and you can just keep chaining them (up to 8 ).


  • MJBMJB Posts: 1,235
    edited 2015-08-13 21:43
    so you run the receive in keypoll?
    I was thinking about this as well ...
    Sorry, I meant no need to dedicate a cog to serial receive and one for processing, just let one cog receive then process etc. The problem with trying to run it through keypoll is that SERIN is a simple routine that waits for a start bit using WAITPNE so it can't do anything else until it's done. If I get around to integrating a multiport serial object then we would probably use that and then it would be possible to run it in keypoll.

    BTW, keypoll got an upgrade recently in that we don't set this directly anymore as a table of up to 8 vectors are being checked so all you need to do now is:
    ' <mycode> +POLL
    and you can just keep chaining them (up to 8 ).
    makes sense -
    and there is also a -POLL ???
    need to check out the lastest Tachyon changes
    I am now in Germany for a few weeks.
    Than back again to south.

  • Made a discovery ... it appears SERIN is not doing any handshaking and therefore repeated executions occur as fast as the hardware can run, rather than waiting for the next valid character. It appears that my GetData routine needs to wait for the "$" character before grabbing the rest of the data. Does this seem correct?
  • Practically all serial comms is done without handshake as this requires extra signal lines or unsupported soft handshake. The problem was with your simple loop that assumes too much as it could start as a packet is in the middle of a transmission and even then is locked in a simple count. You need and must synchronize with the $ and terminate only only a cr as shown in the examples and you will only get nice clean packets back.
  • Can someone tell me why I get $0400.0000 on the stack whenever I do this?
    #26 SERIN .S

    $0000.0041 - 65
    $0400.0000 - 67108864

    In this example ASCII "A" was sent to the Prop.
    Must I just do a SWAP DROP for each byte?
  • MJBMJB Posts: 1,235
    edited 2015-08-16 11:51
    artkennedy wrote: »
    Can someone tell me why I get $0400.0000 on the stack whenever I do this?
    #26 SERIN .S

    $0000.0041 - 65
    $0400.0000 - 67108864

    In this example ASCII "A" was sent to the Prop.
    Must I just do a SWAP DROP for each byte?

    this is the SERIN code.
    What are you doing around SERIN?
    I would expect the problem there ;-)
    But you can use this code and show the stack after the shifting.
    NOT inside the shift loop.
    \ Bit-bashed Serial input - receive asynchronous data 
    pub SERIN ( pin -- data \ receive 8 bit serial data from pin at rate set with SERBAUD, blocks )
    .S  \ show stack at entry
        MASK DUP INPUTS DUP 3 COGREG!        --- setup input mask (REG3 = WAITPNE)
         0 ( iomask dat )                --- init data value
        baudcnt @ DUP 2/                 --- setup delay values of 1 bit and half a bit
         (WAITPNE)                    --- and wait for start bit low
         DELTA                     --- wait for start bit then wait half bit time 
        DELTA                     --- delay to sample 1 bit later in 1st data bit
          8 FOR SHRINP WAITCNT NEXT        --- SHRINP ( iomask dat -- iomask dat/2 )
    	  .S  \ show stack here
        #24 SHR NIP                    --- right justify 8-bit data
        ;
    
    aparrently the $0400.0000 is the MASK for pin #26

    looks like the NIP (which is SWAP DROP) did not work otherwise ... hmmm
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-16 11:49
    artkennedy wrote: »
    Can someone tell me why I get $0400.0000 on the stack whenever I do this?
    #26 SERIN .S

    $0000.0041 - 65
    $0400.0000 - 67108864

    In this example ASCII "A" was sent to the Prop.
    Must I just do a SWAP DROP for each byte?

    $0400.0000 is the mask of pin 26 so that was a little bug from one of the last mods where I tried to minimize stack use to 4 or less for running this in its own cog. Just drop the first DUP in the code or use this:
    pub SERIN ( pin -- data \ receive 8 bit serial data from pin at rate set with SERBAUD, blocks )
    	MASK DUP 3 COGREG!					--- [5.8us]
     	baudcnt @ 2/ 200 - 				--- [4.8us] serup half-bit delay with high speed compensation
    	(WAITPEQ)						--- [0.4us+] make sure we are not detecting the last data bit - wait for stop
    	(WAITPNE) DELTA 					--- wait for start bit then wait haf bit time
    	 0							--- [5.4us] setup pin mask and inital data to SHRINP 8 data
    	baudcnt @ DELTA 					--- delay to sample 1 bit later in 1st data bit
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP							--- last data bit
    	NIP #24 SHR						--- right justify 8-bit data
    ;
    
    BTW, SWAP DROP is defined as NIP
  • MJBMJB Posts: 1,235
    artkennedy wrote: »
    Can someone tell me why I get $0400.0000 on the stack whenever I do this?
    #26 SERIN .S

    $0000.0041 - 65
    $0400.0000 - 67108864

    In this example ASCII "A" was sent to the Prop.
    Must I just do a SWAP DROP for each byte?

    $0400.0000 is the mask of pin 26 so that was a little bug from one of the last mods where I tried to minimize stack use to 4 or less for running this in its own cog. Just drop the first DUP in the code or use this:
    pub SERIN ( pin -- data \ receive 8 bit serial data from pin at rate set with SERBAUD, blocks )
    	MASK DUP 3 COGREG!					--- [5.8us]
     	baudcnt @ 2/ 200 - 				--- [4.8us] serup half-bit delay with high speed compensation
    	(WAITPEQ)						--- [0.4us+] make sure we are not detecting the last data bit - wait for stop
    	(WAITPNE) DELTA 					--- wait for start bit then wait haf bit time
    	 0							--- [5.4us] setup pin mask and inital data to SHRINP 8 data
    	baudcnt @ DELTA 					--- delay to sample 1 bit later in 1st data bit
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP WAITCNT
    	SHRINP							--- last data bit
    	NIP #24 SHR						--- right justify 8-bit data
    ;
    
    BTW, SWAP DROP is defined as NIP

    it's really hard to keep up to date with Tachyon - sorry Art for the outdated code :-(
    I should have checked Peter's Google-docs document first - and not my local copy.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-16 13:48
    MJB wrote: »
    it's really hard to keep up to date with Tachyon - sorry Art for the outdated code :-(
    I should have checked Peter's Google-docs document first - and not my local copy.

    It's essentially the same code just with the loop unrolled with only 10 bytes extra making it easier to not WAITCNT after sampling the last data bit so therefore it is possible at slower baud rates to come back too soon for the next character and sense that last zero data bit as a start bit, hence the extra (WAITPEQ) to make sure it has stopped. There's a rough start bit compensation in there too but SERIN and SEROUT are mainly for speeds of 57.6k or less although SEROUT has no problem with much higher data rates.

  • Thanks, Peter and MJB - just what I needed.

    I often struggle to read the source - taking 6 months off doesn't help.

    MJB, I have an admittedly eccentric project involving the Prop, Tachyon, an HP48 calculator and X10. Recently cracked the X10 Firecracker nut. Progress is slow but steady. As you were . . . episodic ;)
  • There seems to be a math error:
    BINARY
    #2 #0 ^ . 10 ok < incorrect
    #2 #1 ^ . 10 ok
    #2 #2 ^ . 100 ok
    #2 #3 ^ . 1000 ok

    Would this be a good fix?
    pub ^ ( n pwr -- n^pwr )
    DUP 0= IF 2DROP 1
    ELSE 1 SWAP FOR OVER * NEXT NIP
    THEN
    ;
  • K6MLEK6MLE Posts: 106
    edited 2015-08-17 23:14
    Thank you to MJB and Peter ... phase 1 on my weather station extension now works flawlessly! The final phase is putting together a display mux routine. I will use P10 -P13 as digit value and P14 - P17 as digit select. The value will come from the parsing of the serial stream.

    Any thoughts will be welcomed!
  • MJBMJB Posts: 1,235
    K6MLE wrote: »
    Thank you to MJB and Peter ... phase 1 on my weather station extension now works flawlessly! The final phase is putting together a display mux routine. I will use P10 -P3 as digit value and P4 - P7 as digit select. The value will come from the parsing of the serial stream.

    Any thoughts will be welcomed!
    this or similar could be an alternative to manual muxing
    http://www.ebay.de/itm/MAX7219-Red-Module-8-Digit-7-Segment-Digital-LED-Display-Tube-for-Arduino-MCU-/181723525156?hash=item2a4f90f024
  • Thanks, MJB. If I didn't have the hardware already wired for installation, I'd give that a try. I did order one for future use!
  • MJBMJB Posts: 1,235
    so you're up for a nice bit banging exercise now
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-18 00:37
    artkennedy wrote: »
    There seems to be a math error:
    BINARY
    #2 #0 ^ . 10 ok < incorrect
    #2 #1 ^ . 10 ok
    #2 #2 ^ . 100 ok
    #2 #3 ^ . 1000 ok

    Would this be a good fix?
    pub ^ ( n pwr -- n^pwr )
    DUP 0= IF 2DROP 1
    ELSE 1 SWAP FOR OVER * NEXT NIP
    THEN
    ;

    Sounds like you are using a much older version as I dropped the ^ symbol in favor of just saying SQR to also make it plain that means SQR ( n -- res ) for instance whereas the power function n1^n2 is simply called POW ( n1 n2 -- res ).

    Is there any reason you couldn't just download the latest 2.7 binary and that way if you do have problems then it is a real problem rather than looking for a problem by using an old version where things have been changed and improved since.

    Now you mentioned also in another post that you were manually muxing a display and your port pins were "P10 -P13 as digit value and P14 - P17 as digit select". Are you using a decoder for the digit value? It seems to be a painful way to implement a display :) I've used SAA1064 for 4 digit LEDs over I2C and there are other drivers too although I do like to use my serial 20x4 LCDs in big digit mode for this kind of thing.

    However tying in the two posts it sounds like you are trying to select one digit at a time in which we wouldn't be using 2^ but rather the MASK or << operation which converts a number into a bit position mask like this:
    8 0 DO CR I . SPACE I MASK 2 .NUM LOOP
    0 1
    1 10
    2 100
    3 1000
    4 10000
    5 100000
    6 1000000
    7 10000000 ok

    BTW, the 2 .NUM just formats the number as binary but can also specify digits as well as other modes like this:
    8 0 DO CR I . SPACE I MASK $802 .NUM LOOP
    0 00000001
    1 00000010
    2 00000100
    3 00001000
    4 00010000
    5 00100000
    6 01000000
    7 10000000 ok


  • Busted. Yeah, the EXTEND.FTH is was using was almost 3 month old. I've been otherwise occupied. Will update.

    I did get to know MASK a lot better earlier today and that is for sure the thing to use.

    I have used a serial LCD on an earlier version of this controller. What I want is a full user interface with very flexible display capabilities and onboard input and output facilities. I want to be able to enter and edit operating parameters without connecting to a computer. The HP48 / 50 calculator family meets that requirement with very low power consumption and besides I kinda like 'em.

    I have dropped the idea of using a DMM for A/D conversion in favor of an I2C ADC which I have running. X10 relays will be switched via RF using a CM-17A "Firecracker" which is driven by signals on the DTS and RTS lines. It has feedthrough RS-232 for the HP48 which does not use those lines so I am now driving the calculator serial communication with P26 and P27 and using P14 and P15 for the CM-17A. Not enough voltage on the Prop Ports for the CM-17A so I'm using a 74HCT14 Hex Schmitt chip with 5v Vcc as a buffer - works great.
  • artkennedy wrote: »
    Busted. Yeah, the EXTEND.FTH is was using was almost 3 month old. I've been otherwise occupied. Will update.

    I did get to know MASK a lot better earlier today and that is for sure the thing to use.

    I have used a serial LCD on an earlier version of this controller. What I want is a full user interface with very flexible display capabilities and onboard input and output facilities. I want to be able to enter and edit operating parameters without connecting to a computer. The HP48 / 50 calculator family meets that requirement with very low power consumption and besides I kinda like 'em.

    I have dropped the idea of using a DMM for A/D conversion in favor of an I2C ADC which I have running. X10 relays will be switched via RF using a CM-17A "Firecracker" which is driven by signals on the DTS and RTS lines. It has feedthrough RS-232 for the HP48 which does not use those lines so I am now driving the calculator serial communication with P26 and P27 and using P14 and P15 for the CM-17A. Not enough voltage on the Prop Ports for the CM-17A so I'm using a 74HCT14 Hex Schmitt chip with 5v Vcc as a buffer - works great.

    Oh heck, for really low power and flexible user interface I just use Bluetooth serial to a smartphone, can't beat it and no need for a connector either. Yes, 74HCT are perfect for driving 5V logic (I use single gate 74HCT86s for invert/buffer) although sometimes you can run the 5V logic at slightly reduced voltage through a diode so that it can be driven directly by the Prop. Then again, a small 310MHz RF transmitter for X10 is very easy and cheap to build.
  • Where do I locate the "latest 2.7 binary"? I don't see anything marked as 2.7 in drop box under binaries ...
  • MJBMJB Posts: 1,235
    K6MLE wrote: »
    Where do I locate the "latest 2.7 binary"? I don't see anything marked as 2.7 in drop box under binaries ...

    as I was curious as well I had a look and the latest binary I see is
    VGA-EXPLORER-CLOCK7X9.binary
    still based on 2.4

    if you open the binary in a good editor (I used notepad++)
    and search for "Propeller .:.:--TACHYON--:.:. Forth"
    then the 6th character before is the binary version number -
    like $18 or #24 for 2.4

  • Thanks MJB! I asked about 2.7 since Peter referenced it in an earlier message and thought it'd be good to keep my environment up to date.
  • K6MLEK6MLE Posts: 106
    edited 2015-08-18 21:56
    Still working on the 'bit banging' for manual mux of a 3-digit display. Right now there appears to be some 'ghosting' between the digits. I guess it's a matter of figuring out timing ... ! The circuit is pretty straight forward ... 3 transistors and a 74LS47 decoder for the segments.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2015-08-19 02:32
    K6MLE wrote: »
    Still working on the 'bit banging' for manual mux of a 3-digit display. Right now there appears to be some 'ghosting' between the digits. I guess it's a matter of figuring out timing ... ! The circuit is pretty straight forward ... 3 transistors and a 74LS47 decoder for the segments.

    Wow, manually muxing LED digits, this is going way back to very early days blindly typing in machine code into a monitor ROM without any display. The input was a surplus keyboard (no matrix) with a homespun matrix decoder and serializer pcb made from blank photo-laminate, taped up artwork, sunlight, developer and good ol' ferric chloride.
    To get a display I bought some surplus calculator LED displays, 5 digits apiece in a 14 pin DIP IIRC and used 3 of them for a 15-digit/alpha display.

    So manually writing with pen and paper the assembly code, converting it to hex machine code while calculating addresses, punching that in through the new keyboard with only a single status LED to give me an indication that the monitor was still happy or not, and hoping I didn't make any mistakes as there was no storage as such. Slow and tedious, make a mistake, start all over again.

    Eventually the display sprang to life and there was that ghosting thing. I can't really remember but I'm pretty sure I figured out very quickly that this must be because I still had the segment lines active when I switched to the next digit. Even those few microseconds (or more) were enough for the eye to pick up.

    The solution was simple of course, just blank the segment lines before switching which cleaned up the display nicely. Then I added the slow horizontal scrolling to it so now I had a "terminal" and I was in business, yay!

    To blank the output of 74LS47 without using the dedicated blank lines you can output all 1's according to the truth table where $0F -> blank

    BTW, The binaries have been updated, just use the VGA-EXPLORER.binary in the dropbox.


Sign In or Register to comment.