April 28, 2024, 07:56:02 AM

News:

Be sure to checkout our Vixen interfaces in the Library forum -- if you want PC automation at near zero cost, EFX-TEK and Vixen is a great combination of tools.


morse code blink

Started by gadget-evilusions, September 26, 2015, 06:00:59 PM

Previous topic - Next topic

gadget-evilusions

I need some help condensing a program. This is a program spelling out 42 PSI in morse code. I programmed it the long way. I am sure there are tricks and smarter things that can be done to shorten it. I am about 7 lines short of being able to fit it in a prop-1, and of course I am on site installing it right now. Any help would be appreciated.

' =========================================================================
'
'   File...... MorseCodeMessage.BS1
'   Purpose...
'   Author....
'   E-mail....
'
'   Started...
'   Updated...
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================

' -----[ Program Description ]---------------------------------------------

' -----[ Revision History ]------------------------------------------------

' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Blink          = PIN0

' -----[ Constants ]-------------------------------------------------------
SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  Letter = 3000
SYMBOL  Word = 7000
SYMBOL  Dot = 1000
SYMBOL  Dash = 3000

' -----[ Variables ]-------------------------------------------------------

' -----[ Initialization ]--------------------------------------------------
Reset:
  PINS = %00000000                              ' clear all outputs
  DIRS = %00000001                              ' make P0 output

' -----[ Program Code ]----------------------------------------------------
Main:
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Word
  Blink = IsOff
  PAUSE Word

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Word
  Blink = IsOff
  PAUSE Word

  GOTO Reset
' -----[ Subroutines ]-----------------------------------------------------

' -------------------------------------------------------------------------

' -----[ User Data ]-------------------------------------------------------
Brian
Evilusions LLC
www.evilusions.com for all your pneumatic components

JackMan

Could probably get this even smaller but this will work.


'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================

' -----[ Program Description ]---------------------------------------------

' -----[ Revision History ]------------------------------------------------

' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Blink          = PIN0

' -----[ Constants ]-------------------------------------------------------
SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  Letter = 3000
SYMBOL  Word = 7000
SYMBOL  Dot = 1000
SYMBOL  Dash = 3000

' -----[ Variables ]-------------------------------------------------------

SYMBOL counter = B2

' -----[ Initialization ]--------------------------------------------------
Reset:
  PINS = %00000000                              ' clear all outputs
  DIRS = %00000001                              ' make P0 output

' -----[ Program Code ]----------------------------------------------------

Main:
FOR counter = 1 TO 4
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot
NEXT

  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

FOR counter = 1 TO 2
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot
NEXT

FOR counter = 1 TO 3
  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash
NEXT

  Blink = IsOn
  PAUSE Word
  Blink = IsOff
  PAUSE Word

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

FOR counter = 1 TO 2
  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash
NEXT

  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

FOR counter = 1 TO 3
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot
NEXT

  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter

FOR counter = 1 TO 2
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot
NEXT

  Blink = IsOn
  PAUSE Word
  Blink = IsOff
  PAUSE Word

  GOTO Reset

JackMan

Here's one that's smaller yet.


'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================

' -----[ Program Description ]---------------------------------------------

' -----[ Revision History ]------------------------------------------------

' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Blink          = PIN0

' -----[ Constants ]-------------------------------------------------------
SYMBOL  IsOn            = 1                     ' for active-high in/out
SYMBOL  IsOff           = 0
SYMBOL  Letter = 3000
SYMBOL  Word = 7000
SYMBOL  Dot = 1000
SYMBOL  Dash = 3000

' -----[ Variables ]-------------------------------------------------------

SYMBOL counter = B2

' -----[ Initialization ]--------------------------------------------------
Reset:
  PINS = %00000000                              ' clear all outputs
  DIRS = %00000001                              ' make P0 output

' -----[ Program Code ]----------------------------------------------------

Main:
FOR counter = 1 TO 4
  GOSUB Do_Dot
NEXT
  GOSUB Do_Dash
  GOSUB Do_Letter

FOR counter = 1 TO 2
  GOSUB Do_Dot
NEXT

FOR counter = 1 TO 3
  GOSUB Do_Dash
NEXT

  GOSUB Do_Word
  GOSUB Do_Dot

FOR counter = 1 TO 2
  GOSUB Do_Dash
NEXT

  GOSUB Do_Dot
  GOSUB Do_Letter

FOR counter = 1 TO 3
  GOSUB Do_Dot
NEXT

  GOSUB Do_Letter

FOR counter = 1 TO 2
  GOSUB Do_Dot
NEXT

  GOSUB Do_Word

  GOTO Reset

Do_Dot:
  Blink = IsOn
  PAUSE Dot
  Blink = IsOff
  PAUSE Dot
RETURN

Do_Dash:
  Blink = IsOn
  PAUSE Dash
  Blink = IsOff
  PAUSE Dash
RETURN

Do_Letter:
  Blink = IsOn
  PAUSE Letter
  Blink = IsOff
  PAUSE Letter
RETURN

Do_Word:
  Blink = IsOn
  PAUSE Word
  Blink = IsOff
  PAUSE Word
RETURN

gadget-evilusions

Your first one worked great. I really should have thought of that, but it's dark, and I am inside a haunt working, so my brain isn't functioning 100% with all the noise. Thanks alot!
Brian
Evilusions LLC
www.evilusions.com for all your pneumatic components

JackMan

Your welcome. I'm sure Jon has a way to make this fit on a post stamp though!

JonnyMac

September 26, 2015, 09:54:11 PM #5 Last Edit: September 26, 2015, 10:33:52 PM by JonnyMac
Lucky for you, my friend Scott Edwards wrote a neat App Note on sending Morse Code with the BS1 processor. I have updated that code (still uses his clever encoding scheme) to make sending Morse messages easy. The problem with one-offs like you've done above is that changing the message leads to a lot of work. Not so with Scott's/my version.

BTW... this only uses 39% of the memory.

' =========================================================================
'
'   File...... morse_code.bs1
'   Purpose... Output Morse Code message
'   Author.... Scott Edwards (updated/reformatted by Jon McPhalen)
'   E-mail....
'   Started...
'   Updated... 26 SEP 2015
'
'   {$STAMP BS1}
'   {$PBASIC 1.0}
'
' =========================================================================


' -----[ Program Description ]---------------------------------------------


' -----[ Revision History ]------------------------------------------------


' -----[ I/O Definitions ]-------------------------------------------------

SYMBOL  Blinker         = PIN0


' -----[ Constants ]-------------------------------------------------------

SYMBOL  YES             = 1
SYMBOL  NO              = 0

SYMBOL  IS_ON           = 1                     ' active-high I/O
SYMBOL  IS_OFF          = 0

SYMBOL  DIT_TM          =  250
SYMBOL  DAH_TM          =  750                  ' 3x dit timing
SYMBOL  WRD_TM          = 1750                  ' 7x dit timing


' -----[ Morse Code Table ]------------------------------------------------

' Encoding:
' -- upper five bits = code (0 = dit, 1 = dah)
' -- lower three bits hold # of elements
'    * 6-element chars ending in dit use count 6
'    * 6-element chars ending in dah use count 7

SYMBOL  _A              = %01000010             ' dit dah
SYMBOL  _B              = %10000100             ' dah dit dit dit
SYMBOL  _C              = %10100100             ' dah dit dah dit
SYMBOL  _D              = %10000011             ' dah dit dit
SYMBOL  _E              = %00000001             ' dit
SYMBOL  _F              = %00100100             ' dit dit dah dit
SYMBOL  _G              = %11000011             ' dah dah dit
SYMBOL  _H              = %00000100             ' dit dit dit dit
SYMBOL  _I              = %00000010             ' dit dit
SYMBOL  _J              = %01110100             ' dit dah dah dah
SYMBOL  _K              = %10100011             ' dah dit dah
SYMBOL  _L              = %01000100             ' dit dah dit dit
SYMBOL  _M              = %11000010             ' dah dah
SYMBOL  _N              = %10000010             ' dah dit
SYMBOL  _O              = %11100011             ' dah dah dah
SYMBOL  _P              = %01100100             ' dit dah dah dit
SYMBOL  _Q              = %11010100             ' dah dah dit dah
SYMBOL  _R              = %01000011             ' dit dah dit
SYMBOL  _S              = %00000011             ' dit dit dit
SYMBOL  _T              = %10000001             ' dah
SYMBOL  _U              = %00100011             ' dit dit dah
SYMBOL  _V              = %00010100             ' dit dit dit dah
SYMBOL  _W              = %01100011             ' dit dah dah
SYMBOL  _X              = %10010100             ' dah dit dit dah
SYMBOL  _Y              = %10110100             ' dah dit dah dah
SYMBOL  _Z              = %11000100             ' dah dah dit dit

SYMBOL  _0              = %11111101             ' dah dah dah dah dah
SYMBOL  _1              = %01111101             ' dit dah dah dah dah
SYMBOL  _2              = %00111101             ' dit dit dah dah dah
SYMBOL  _3              = %00011101             ' dit dit dit dah dah
SYMBOL  _4              = %00001101             ' dit dit dit dit dah
SYMBOL  _5              = %00000101             ' dit dit dit dit dit
SYMBOL  _6              = %10000101             ' dah dit dit dit dit
SYMBOL  _7              = %11000101             ' dah dah dit dit dit
SYMBOL  _8              = %11100101             ' dah dah dah dit dit
SYMBOL  _9              = %11110101             ' dah dah dah dah dit

SYMBOL  Space           = %00000000             ' word spacing in message


' -----[ Variables ]-------------------------------------------------------

SYMBOL  char            = B0                    ' must use B0 for char!
SYMBOL  elements        = B1                    ' elements in character
SYMBOL  chcount         = B2                    ' character count
SYMBOL  cidx            = B3                    ' character index
SYMBOL  midx            = B4                    ' Morse element index

SYMBOL  millis          = W5                    ' output pulse timing


' -----[ Initialization ]--------------------------------------------------

Reset:
  PINS = %00000000                              ' all off
  DIRS = %00000001                              ' P0 is an output


' -----[ Program Code ]----------------------------------------------------

Main:
  READ 0, chcount                               ' read # of chars
  cidx = 1                                      ' point to first

Another:
  READ cidx, char                               ' read char from message
  GOSUB Morse                                   ' output
  cidx = cidx + 1                               ' point to next
  IF cidx <= chcount THEN Another               ' do another if not done

  GOTO Main


' -----[ Subroutines ]-----------------------------------------------------

Morse:
  IF char = Space THEN Word_Space               ' check for space in message

  elements = char & %00000111                   ' isolate element count
  IF elements < 6 THEN Bang_Key                 ' standard character
  IF elements = 7 THEN Adjust_2                 ' 6-element char ends in dah

Adjust_1:                                       ' 6-element char ends in dit
  char = char & %11111011                       ' put dit in 6th position
  GOTO Bang_Key

Adjust_2:                                       ' 6-element char ends in dah
  elements = 6                                  ' correct count

Bang_Key:
  FOR midx = 1 TO elements                      ' loop through char elements
    LOOKUP BIT7, (DIT_TM, DAH_TM), millis       ' convert bit7 to timing
    Blinker = IS_ON                             ' do the output
    PAUSE millis
    Blinker = IS_OFF
    PAUSE DIT_TM
    char = char * 2                             ' left shift by 1 bit
  NEXT

Char_Space:
  PAUSE DAH_TM
  RETURN

' -------------------------------------------------------------------------

Word_Space:
  PAUSE WRD_TM
  RETURN


' -----[ User Data ]-------------------------------------------------------

Message_Len:
  EEPROM  (8)                                   ' address 0 in EEPROM

Message_Data:
  EEPROM  (_4, _2, Space, _P, _S, _I)
  EEPROM  (Space, Space)
Jon McPhalen
EFX-TEK Hollywood Office

Jeff Haas

This is a fun one to think about.  I always enjoy following along as these solutions are done.

Brian...you're going to have to tell us what you're using the morse code for!

JonnyMac

Those that monitor my Prop-1 coding style will know that I typically start defining byte variables at B2. Here is an example where B0 is a great choice. With B0 and B1 (combined as W0), we also have access to the individual bits (BIT0..BIT15).

The characters are encoded with the upper five bits holding dits (0) and dahs(1), and the lower three holding the elements count. Let's say we want to send a 2 (_2 in my constants). The internal value for _2 is %00111101. If we break that apart we get

%00111 (Morse code for 2 in binary form)
%101 (five elements in the code)

For 2 we have to send dit dit dah dah dah. Note that these are encoded left-to-right with the first element in BIT7 of char. This is why I chose B0 for char: it gives me direct access to BIT7 (standard variable in PBASIC). To me, Scott's original program was a little less clear, but it didn't rely on a specific variable like I do. Scott's code looked something like this:

  IF char >= 128 THEN Dah
    GOTO Dit


This make sense to me because I live and breath code, and I automatically associate 128 with BIT7 -- but most people don't. My goal is to write code that is clear and easy to understand. In this case, the only difference between dit and dah is the timing. One of the wonderful features of PBASIC is LOOKUP, which lets use one value as an index into table of values. In Scott's code he has separate Dit and Dah routines -- the only difference between them is timing. I chose to create an integrated routine and set the timing like this:

  LOOKUP BIT7, (DIT_TM, DAH_TM), millis

In some programs we have to worry about the index value not fitting into the table, but that's not the case here because BIT7 can only have one of two values: 0 or 1.

Keep in mind that the BS1 processor has been around for 20 years now and there is a lot of code floating around. When you find it, try it and then modify it to see if you can make it smaller and more efficient. The Memory Map feature of the IDE is a valuable tool for doing this.


Jon McPhalen
EFX-TEK Hollywood Office

gadget-evilusions

That's great code Jon, I look forward to studying it more and learning from it. And I agree, that's a ton easier to adjust the message when needed.
Brian
Evilusions LLC
www.evilusions.com for all your pneumatic components

JackMan

Yeah, after the Halloween season I have to study this one too. While I consider myself fairly good at writing BS1 code (thanks to Jon!) I'm by no means an expert, but this one is WAY over my head!