Flashing morse code on a LED implant

Okay, now that I have my first implant with blinkies, I cracked out out my trusty Proxmark3 and whipped up a small proof of concept code for the project I have in mind: using the blinkies to send out messages in morse code. I’m a ham, so it works for me. Check it out:

The Proxmark is a bit sluggish to switch the field on and off, so it can’t go over 10 words per minute without the dits and dahs becoming unrecognizable. I’ll need to come up with my own hardware to reach the 40 wpm I want. Also, I think I have a very good chance of being able to light up the 3 blinkies individually with 3 coils. Obviously the Proxmark can’t do that. Still, it works :slight_smile:

Here’s the code, for those who are interested - Linux only:

#!/usr/bin/python3

### Parameters
pm3_client = "/usr/local/bin/proxmark3"
pm3_default_dev = "/dev/ttyACM0"
default_wpm = 10 #words per minute



### Modules
import re
import os
import sys
import argparse
from time import sleep
from pty import openpty
from select import select
from subprocess import Popen, DEVNULL, PIPE



# Morse code dictionary
morsecode = {
	"A":     ".-",
	"B":     "-...",
	"C":     "-.-.",
	"D":     "-..",
	"E":     ".",
	"F":     "..-.",
	"G":     "--.",
	"H":     "....",
	"I":     "..",
	"J":     ".---",
	"K":     "-.-",
	"L":     ".-..",
	"M":     "--",
	"N":     "-.",
	"O":     "---",
	"P":     ".--.",
	"Q":     "--.-",
	"R":     ".-.",
	"S":     "...",
	"T":     "-",
	"U":     "..-",
	"V":     "...-",
	"W":     ".--",
	"X":     "-..-",
	"Y":     "-.--",
	"Z":     "--..",
	"1":     ".----",
	"2":     "..---",
	"3":     "...--",
	"4":     "....-",
	"5":     ".....",
	"6":     "-....",
	"7":     "--...",
	"8":     "---..",
	"9":     "----.",
	"0":     "-----",
	"=":     "-...-",
	"/":     "-..-.",
	"?":     "..--..",
	",":     "--..--",
	".":     ".-.-.-",
	":":     "---...",
	"'":     ".----.",
	'"':     ".-..-.",
	"_":     "..--.-",
	"(":     "-.--.",
	")":     "-.--.-",
	"#":     "-.---",
	"-":     "-....-",
	"|":     "...-..",
	"\\":    "-.....",
	"*":     "-----.",
	";":     "-.-.-.",
	"@":     ".--.-.",
	"^":     "....--.-.",
	"$":     "...-..-",
	"!":     "....-.",
	">":     "....---.",
	"]":     "....-....",
	"[":     "....-..",
	"<":     "....-.-..",
	"&":     "....--.",
	"%":     "....-.--.",
	"~":     "....--",
	"+":     ".-.-.",
	"{":     "....-.--",
	"}":     "....--..-",
	"[AR]":  ".-.-.",
	"[AS]":  ".-...",
	"[BK]":  "-...-.-",
	"[BT]":  "-...-",
	"[KA]":  "-.-.-",
	"[CL]":  "-.-..-..",
	"[KN]":  "-.--.",
	"[VA]":  "...-.-",
	"[VE]":  "...-.",
	"[GR]":  "--..-.",
	"[HM]":  "....--",
	"[IX]":  "..-..-",
	"[IMI]": "..--..",
	"[INT]": "..-.-",
	"[SOS]": "...---..."}



### Main routine
def main():
  """Main routine
  """

  # Read the command line arguments
  argparser = argparse.ArgumentParser()
  argparser.add_argument(
	  "-d", "--device",
	  type = str,
	  help = "Proxmark3 device file (default: {})".format(pm3_default_dev),
	  default = pm3_default_dev,
          required = False
	)
  argparser.add_argument(
	  "-w", "--words-per-minute",
	  type = int,
	  help = "Rate of the morse code (default: {})".format(default_wpm),
	  default = default_wpm,
          required = False
	)
  argparser.add_argument(
	  "message",
	  type = str,
	  help = "Text to output in morse code on LED implant",
	)
  args = argparser.parse_args()

  dev = args.device
  wpm = args.words_per_minute
  msg = args.message.upper()

  # Possible Proxmark3 console prompts
  pm3_prompts_regex = re.compile("^(proxmark3>|\[.*\] pm3 -->)$")

  # Proxmark3 "HF field on" and "HF field off" command
  field_on = "hf 14a raw -a -p"
  field_off = "hf 14a reader x s"

  # Turn the message into a sequence of field-on durations (positive) and
  # field-off durations (negative)
  morsechars = []
  i = 0
  while i < len(msg):

    if msg[i] == "[":
      j = msg.find("]", i + 1)
      if j > 0 and msg[i : j + 1] in morsecode:
        morsechars.append(morsecode[msg[i : j + 1]])
        i = j + 1
        continue

    if msg[i] == " " or msg[i] == "\t":
      morsechars.append(" ")

    elif msg[i] in morsecode:
      morsechars.append(morsecode[msg[i]])

    else:
      print("Untranslatable in morse code: {} - dropped".format(msg[i]))

    i += 1

  ditlen = 1.2 / wpm 
      
  morseseq = []
  for mc in morsechars:

    if mc == " ":
      if morseseq:
        morseseq[-1] = -ditlen * 7
      else:
        morseseq.append(-ditlen * 7)
      continue

    for c in mc:
      if c == ".":
        morseseq.append(ditlen)
      else:
        morseseq.append(ditlen * 3)
      morseseq.append(-ditlen)

    morseseq[-1] = -ditlen * 3

  if not morseseq:
    print("Nothing to do")
    return(0)

  # Create a PTY pair to fool the Proxmark3 client into working interactively
  pty_master, pty_slave = openpty()

  # Spawn the Proxmark3 client
  pm3_proc = Popen([pm3_client, dev], bufsize=0, env={},
			stdin=pty_slave, stdout=PIPE, stderr=DEVNULL)

  # Interact with the Proxmark3 client
  recvbuf = ""
  sendcmd = True

  while True:

    # Read lines from the Proxmark3 client
    rlines = []

    for c in pm3_proc.stdout.read(256).decode("ascii"):

      if c == "\n" or c == "\r" or pm3_prompts_regex.match(recvbuf):
        rlines.append(recvbuf)
        recvbuf = ""

      elif len(recvbuf)<256 and c.isprintable():
        recvbuf += c

    # Process the lines from the client
    for l in rlines:

      # If we detect a fatal error from the client, exit
      if re.search("(proxmark failed|offline|OFFLINE|unknown command)", l):
        return(-1)

      # Do we have a prompt
      if pm3_prompts_regex.match(l):

        # If we're done sending out the sequence, instruct the Proxmark client
        # to quit, wait on it and exit ourselves
        if not morseseq:
          os.write(pty_master, ("quit" + "\r").encode("ascii"))
          pm3_proc.wait()
          return(0)

        # Get the next element to play in the sequence
        duration = morseseq.pop(0)

        # Flip the field as needed
        os.write(pty_master, ((field_on if duration >=0 else field_off) \
				+ "\r").encode("ascii"))
        sleep(abs(duration))

      

### Jump to the main routine
if __name__ == "__main__":
  sys.exit(main())
5 Likes

Woah, that’s amazing! What’s it reading a message from in this video?

If I told you, it’d be too easy :wink:

Most hams who practice CW regularly should recognize the “music” immediately. Let’s see if someone comes up with the answer :slight_smile:

1 Like

Oh, not what the message says, but what’s it reading from? I assume it would have to be in range of the implant, so is it under your wrist?

Oh, sorry, I misunderstood.

Yeah, it’s a Proxmark3 with the Blueshark extension under my wrist. It’s driven by my PC off camera.

Ohh, got it. I love the idea of the blinking communication through Morse code… I wonder what ways I could possibly use this in every day life.

Well, my plan is to have it tell the time and read SMS messages to me from my cellphone, smartwatch-style.

Possibly if the blinkies can be addressed separately, drop the morse code for the time and use a simplified code that takes less time to tell the time.

1 Like

Awesome! How are you gonna deal with the constant distance in between your cellphone and the implant though?

CQ CQ CQ de rosco 73 :smiley:

I plan on making a slim coil - or pack of coils - wrapped around the underside of my wrist, connected to a small BT device, that stays connected to the cellphone. Or if it’s not connected, it’ll just tell the time on its own.

If it works well and the coils aren’t too bulky, I might get my piercer to install 4 magnetic barbells under my wrist for a quick-fit solution. But that’s in the far future. First order of business is make that BT device small and unintrusive enough to look smart.

1 Like

We have a winner! :slight_smile:

I can’t wait for that thread :slight_smile:
You can maybe start with those plasters they use for medical devices.

Don’t hold your breath :slight_smile:

That’s exactly what I’ll do. Or double-sided tape or something. If I can come up with a very thin, very light device that I’ll want to wear day in and day out (which is a tall order - realistically, I doubt I’ll pull it off) then I’ll consider something more permanent and more handy than taping it to my arm every morning. But for now, tape will do just fine.

1 Like
2 Likes

I’m not sure if I get that right - you’re talking about surface barbells?
If yes - believe me, they tend to suck. A lot. It’s quite some work to keep them calm, they tend to stay in a state of slight inflammation (or they just grow out and leave a funny little scar); and on that spot you’ll catch on them really often (which is the worst point - there are areas where they can heal up). And by “under the wrist”, I suppose you mean the area on the inner side of your arm? This might be especially annoying considering all the movement in that spot…

As you know, I’m a big fan of piercings and stuff, but for that special usage I’d rather build something wearable :wink:

You definitely are the specialist here :slight_smile:

I guess what I meant was four anchor points with magnets, but on the outside. So I figured very short barbells (so they don’t take forever to heal) capped with screw-on magnets. I imagine them as no longer than earrings, but going through pinched skin. I don’t even know if it’s doable or if if it exists. That’s just what I have in my head.

But, as you know, I’m not big on piercings. In fact, I’m not really big on any bloody messy body business, including getting an implant. I’m just attracted to the technological possibilities of them. So I’ll have to be really convinced whatever device I come up with is such a keeper that I can’t live without it, before I even entertain the idea of going to my piercer to have anything like that done to me.

Mh, problem about that is… piercings usually go through something that has the right shape, in a way - an earlobe, a tongue, whatever, that has a shape where the bar can comfortably sit without pulling on the skin. If you pinch your skin and put a bar through it, it will keep pulling on there, and that often leads to the bar growing out. Jewellery usually used for that looks this way:
proxy-image

Of course, you can screw on magnets instead of standard balls there, but still - you might catch on that often. It might work, but you’ll have to take really good care of it. Especially if you want to attach something to them, which will add to the pulling…
Another option would be microdermals (aka “single point piercings”)…
proxy-image

… but that’ll lead to similar problems. Had mine in for about eight years, and that’s pretty long - these things are considered semi-permanent^^

1 Like

The base plates of microdermals don’t look sturdy enough to bear the weight of a device, and certainly not if it catches on something.

Do you still have to take extra care with them after 8 years?

There were times when they were calm, but they inflammated (slightly!) very often… had them on my chest, three of them above my tits, and really liked them, but I had them taken out after eight years. Left three tiny scars, but that doesn’t bother me.

Hm, yes… there is another alternative, but I’m not sure if that can be placed where you want to have it…

proxy-image

Transdermals. Big guys, are placed with a scalpel, but they can last a lot longer. Those things are the base of the “metal mohawk” and that stuff.

1 Like

Hmm okay, so it’s not the kind of thing you can ever hope to “blend” into you and forget about. Constant care needed. If I ever do something, it won’t be that then. I’m much too lazy.