Posted on

Some thoughts on the future concept of soft hardware..

Imaginary Concept image illustrating a concept of reconfigurable computing using current and future concepts.

I have been considering hardware solutions for many years, since around the late 80’s, designing some of them, playing around with even more.

I have worked on, and advised on research in reconfigurable computing to other research project in the same and similar areas, played simulated scenarios on virtual self-generated parallel processing units (PPU’s) that are in a way similar to cpu’s, but differ in the way that while they have a risc-like basic set of instructions, they are self-generated to transfer complex and heavy tasks into discrete hardware, as well as able to have a on the fly reconfigurable and extendable instruction set, accelerating the speed of computing from clocked sequential solutions to discrete clocked or free-flowing deterministic logic, yielding speed improvements over traditional processing, often by multiple magnitudes.

Couple this with the modern like of and demand for parallelism and multithreading, and think, what if we had a simpler PPU, where we could throw our application at something, where we could create arbitrary complex instructions, that would be automatically translated into hardware, and we hade access to thousands of [discrete hardware] threads, hundreds or even thousands of them, all running on PPU’s, that could even offer true cycle by cycle parallel processing without the penalty of the context switching in a traditional cpu?

There is a lot of talk about modern varieties of things like CPU vs GPU vs DPU vs TPU’s today, but just what if, we had a merger, where we had a RCU that would incorporate components of all of them, allowing for massively, scalable, parallel translation of software into discrete hardware solutions, by itself, on demand?

Imagine a scenario where writing a software no longer means executing static code as in the classic primary form of a set of sequential steps, but transformed into a combination of classic code and discrete deterministic logic, composing of all of the above technologies (and new upcoming ones) in combination, and to top it off, have the machine itself analyze the performance of the solution, both software and hardware, to find better and more efficient ways of doing the job, coming up with a faster solution by itself, generating new code and reconfiguring itself to be more efficient?
Welcome to the concept of the RCU. (no, not that classic Read-Copy-Update concept…)

For the future, I see a merger of all these aforementioned components into the “RCU” – a Reconfigurable Compute Unit, which is no longer sets of distinct types of computing solutions, but where different kinds of compute solutions are merged into a single unit, and elements of the different technologies are called upon and utilized by the technology itself, and it’s own behavioral and performance analysis which could in itself very well be driven by generative AI solutions, will find new ways to make it more efficient, continuously.

After all, turning software into hardware, is nothing new, and it’s not rocket science – it’s very well understood and commonly utilized concepts, but what is new, is making the hardware build itself to it’s needs to gain the performance, incrementally, by analyzing itself, not only by way of discrete logic, but new, smarter instructions, created on the fly, based on the need of the software?

Such tasks and problems, are commonly not massively compute-heavy tasks, but relatively simple tasks, just like most everyday computational tasks, ones that can be served by relatively simple and low powered solutions. What makes most task go fast, is either massive parallelism, or, where not suitable, clever solutions where you don’t have to rely on steps, but solution flows.

In the scenario of the RCU, You, as a developer, could focus on simply getting a functional solution to the problem, and let the machine take care of the solution analysis and optimization. This, could also be coupled with adaptive descriptive problem to solution generation, as we are entering the era of where this is now both technically and practically feasible.

This has been a research journey in both thought and action since around 1990, and it is still ongoing at EmberLabs.

Are you ready for it and what is coming?
Are you ready to bite?

If you want to know more and possibly collaborate, we can talk.

Posted on

GPS Location?

Need a routine to determine if a lat/long is inside or outside a specific area?

Here’s a Golang routine for this, that can be easily adopted to any other language.

/*
 * Free to use as you see fit. 
 */

package GPS

type polygon [][]float64

// Enter the lat,long coordinates (min 3)
// poly := [][]float64{ { 1,1 }, { 1,2 }, { 2,2 }, { 2,1 } ... {1,1}}
// Make sure the polygon coordinates are specified in the correct order,
// typically in a counter-clockwise direction, and that the last vertex is
// the same as the first one to close the polygon.
// in := inside(1.5, 1.5, poly) --> True
// in := inside(2.5, 1.5, poly) --> False

// Test if a GPS coordinate is inside the bounding box
func Inside(latitude float64, longitude float64, boundary polygon) bool {
    inside := false

    j := len(boundary) - 1
    for i := 0; i < len(boundary); i++ {

       xi := boundary[i][0]
       yi := boundary[i][1]

       xj := boundary[j][0]
       yj := boundary[j][1]

       // Crossing the border of the polygon?
       intersect := ((yi > latitude) != (yj > latitude)) && 
                    (longitude < (xj-xi)*(latitude-yi)/(yj-yi)+xi)

       if intersect {
          inside = !inside
       }
       j = i
    }

    return inside
}

 

Posted on

Pink October Talk @ Glitnor Group

Chris Sprucefield
Pink October talk at Glitnor Group.

Breast cancer…

There’s four dreaded words that you as a guy don’t ever want to hear, and no woman ever want to say –
“I found a lump”.

To me, us, this happened quite some time ago, end of 90’s, and I’m happily remarried since, but my story goes a long way, and it still goes to show how fast it can happen and develop like the lightning strike out of nowhere.

While the research has come quite some way, there’s still no cure, and it’s an illness that leaves no one untouched. It’s evil. It affects everyone involved, in ways you can not imagine, until it happens, and even then, you end up being stumped and lost, even as a “bystander”.

It started with a lump, she got treatment, and then it looked all good and well for some time. We moved countries, and one day, she said – I can’t hear on my left ear. Hospital, and it had returned, 4 years later, now, metastatic, and from there, it was all downhill, and she eventually passed away.

Luckily, today, this will not be the case for everyone, as treatments has gotten way better, but the treatments is not all.
There’s many more aspects to it than just treatments…

One of the worst part for us, was long time friends disappearing, because they “could not deal with cancer”, or hospitals. They just tried to find any excuse to bail out, with the exception of a very few that stuck around. If you are a true friend of someone, don’t be that person and take the bailout card – be the one that cares, even if just in the small things…

Here’s some of what you can do, even if you don’t have much time or resources, that will be gold dust to victims of cancer (in general)

  • Please, Warn the person going for the chemo, not to eat the usual things they like or love afterwards, avoid them for the time being, or you may end up not being able to eat them afterwards, as chemo can / will play tricks with your mind… nobody tells you this, and we wished someone had…
  • They got kids?
    Apart from just life – just like you, we are all busy, but they also have to deal with the effects of cancer and treatments, apart from the existential crisis they inevitably go through, and it is wearing people down. Offer their kid(s) the occasional sleepover, or just to take them off them even for a day/evening.
    They need adult time to cope, or even just peace and quiet. You have no idea what the value of such a small gesture is or may be…
  • Chemo?
    They just got back… They still need to eat and so on… Going to the shop?
    Ask them – I’m going shopping, you need any top-up stuff while i’m there?
    That top-up shop delivered, may be the difference between having to do a shop the day after the chemo, or 2 days later when you feel better and you can actually cope with it, because, we are all people, and we forget things, until we need it…
  • Getting to / from the hospital? If you can, take them there and pick up. Get a paper “flight sickness bag”, just in case. Just keep it in the car. you know why…
    Take that one worry out of their life if you can, they have enough existential stuff on their minds already, and that is gold, and they know they are safe with you…

The practical little things…

Sometimes, people being people, things can get too much for anyone, and if they cuss you out, having a particularly bad day, don’t take it personally – they are likely just exhausted and need to vent, and you just happen to be in the firing line for just being their trusted friend, because they feel comfortable and safe around you, so take it, just listen and don’t let it get to you.
Really – let it go in one ear and out the other… I know it’s hard, but you are the true friend, and for good reason.
They will be embarrassed enough afterwards about what happened, but be there the next time… the true friend you are.

Everyone has ups and downs. They just have some more of it, right now – the downs, and the feelng of world being against them.

Be the brave one for them – they need you and your strength as their guidance, and your presence as the anchor to reality.
Think about it – It’s not really hard things, it’s not big things, even small things count big time, but just being around, for a call, for a coffee etc.

It’s quality of life, the sense of normality that brings hope and future back into the picture. You just being you as usual, and most importantly, being there, counts.Now, you can do the above, and you can also donate to research to make this problem eventually become what we all want – extinct.Take care out there!

#PinkOctober #BreastCanscerSpouse #BreastCancer #BreastCancerAwareness

Posted on

The Noble 8-fold path of development

…. or maybe not so noble,
but more a tactical assault on the problem.

  1. Slap some stuff together
  2. Understand what you did, what it does, and what it should do.
    If you don’t or it doesn’t, revert to 1…
  3. Fix the remains so it does what it was supposed to do,
    in a passable fashion.
  4. Run it by some innocent victim (aka guinea pig or co-worker),
    and see about their reaction.

    If bad, revert to step 3.
  5. Prettify, if required…(trust me, it is.)
  6. Do a QA / code review with your peers (guinea pigs),
    and when the number of Whiskey Tango Foxtrots/minute
    goes below 1, you are generally safe to proceed.
  7. Release the product.
  8. Duck/Hide under the table, wait for the client fallout and bugs to be reported.
Posted on

Nasa Software Catalogue 2023/2024

I just thought i would share this little gem with you all!

I if you are into engineering, research, development, this may be of interest to you as well – the open catalogue of software in a wide range of areas.

“The 2023-2024 Software Catalog is Here!
Each year, NASA scientists, engineers, and developers create software packages to manage space missions, test spacecraft, and analyze the petabytes of data produced by agency research satellites. As the agency innovates for the benefit of humanity, many of these programs are now downloadable and free of charge through NASA’s Software Catalog.”

https://software.nasa.gov/

Enjoy!

Posted on

When things go untested…

This shows the importance of fundamental testing of code in Dev and Staging, BEFORE pushing to prod,
no matter the urgency, unless you are absolutely sure it will work and it is an emergency, or, of course,
you are out of options and ready to take the risk of burning down the house…

What could possibly go wrong, right?

 

Posted on

Tinypng script

Using the service from https://tinypng.com makes it easy to mass-shrink your PNG images to more palatable sizes, and it comes with a neat 500 free use transcodes per month, and it’s quite cheap after that.

Here’s a little script to help you with the work a bit.

Prerequisites:
bash, jq and curl.

Save the file as “tinify” and do a chmod 755 tinify

Flags:
-k <key> = API key for tinypng.com – can be omitted if specified in the environment variable by export TINIFY_API ="<api_key>"
-f <file> = Filename to compress
-r = Replace the original file with the compressed file. If not specified, the output file will be named tiny-<filename>
-v = verbose output
-s = Show compression statistics (1 line per file)

#!/bin/env bash
# (C) EmberLabs / Chris Sprucefield 2023.
# License: CC BY.

key=''
file=''
r_flag=false
v_flag=false
s_flag=false
s_arg="-s"

if [ "${TINIFY_API}" != "" ]
then
    if [ "${v_flag}" == true ] ; then echo "Using API key from env." ; fi
    key="${TINIFY_API}"
fi

while getopts 'rk:f:vsh?' flag; do
case "${flag}" in
    r) r_flag=true ;;
    k) key="${OPTARG}" ;;
    f) file="${OPTARG}" ;;
    v) v_flag=true
       s_arg="" ;;
    s) s_flag=true ;;
    *)
        echo "<cmd> -? | -h This help text"
        echo " -r Replace the original file with tinified file."
        echo " -k <apikey> The API key for tinify (or from \$TINIFY_API environment variable if set)"
        echo " -f <filename> The filename to encode (and replace if -r is specified)"
        echo " -v Verbose output"
        echo " -s Show compression statistics"
        exit 1
        ;;
    esac
done

if [ "${v_flag}" == true ] ; then echo "Processing ${file}" ; fi
JSON="$(curl ${s_arg} --user "api:${key}" --data-binary "@${file}" -i https://api.tinify.com/shrink | tail -1)"
URL="$(echo "${JSON}" | jq '.output.url' | sed 's/\"//g')"
ISIZE="$(echo "${JSON}" | jq '.input.size')"
OSIZE="$(echo "${JSON}" | jq '.output.size')"
RATIO="$(echo "${JSON}" | jq '.output.ratio')"
W="$(echo "${JSON}" | jq '.output.width')"
H="$(echo "${JSON}" | jq '.output.height')"

if [ "${ISIZE}" == "${OSIZE}" ]
then
    if [ "${v_flag}" == true ] ; then echo "No compression on ${file} - skipped." ; fi
    exit 0
fi

if [ "${URL}" != "null" ]
then
    if [ "${v_flag}" == true ] ; then echo "Fetching ${URL}" ; fi
    curl ${s_arg} "${URL}" -o "tiny-${file}"

    if [ "${r_flag}" == true ]
    then
        if [ "${v_flag}" == true ] ; then echo "Replacing original file" ; fi
        mv -f "tiny-${file}" "${file}"
    fi
    if [ "${s_flag}" == true ]
    then
        printf "%-40s %5d x %-5d In: %8d Out: %8d Ratio: %2.5f\n" "${file}" "${W}" "${H}" "${ISIZE}" "${OSIZE}" "${RATIO}"
    fi
else
    echo "Invalid response. (incorrect API key?)"
    exit 1
fi

 

Posted on

Easily mirror a BitBucket workspace?

So, you have a large pile of Bitbucket repos that you want to check out, mirror or even back up?

Here’s a shellscript for you that does the trick.

Prerequisites:

  • jq, bash and git installed on the machine.
  • You have an APP password on the bitbucket (create in personal settings)
  • You have an SSH key on the bitbucket and you can checkout via ssh.

Store the script as something like “bb” and issue “chmod 755 bb”

There are 3 commands:
“bb  get” will fetch the lists of the repos.
“bb update” will mass check out the repos if it doesn’t exist locally, or update them.
“bb backup” will check out the repos in mirror format, and make a tgz file of it all.

The checkouts will be done under the path ./<org>/<project>/<repo>

Enjoy!

#!/bin/env bash
# ###########################################################################
# (C) EmberLabs / Chris Sprucefield. 
# Licensed under CC BY | https://creativecommons.org/licenses/by/4.0/
# Basics
ORG=""  # Fill in your org name here. This is the workspace name. 
USER="" # Fill in your username here.
PASS="" # Fill in your BB APP password here.

function getRepoLists() {
    AUTH="Basic $(echo -ne "${USER}:${PASS}" | base64)"
    PAGE="1"

    echo "--------------------------------------------------------------------"
    echo "Getting the ${ORG} repository lists from BitBucket"
    BURL="https://api.bitbucket.org/2.0/repositories/${ORG}?pagelen=100"
    GO="1"
    rm -f repolist-*.json
    echo -n "Getting page "
    while [ "$GO" != "0" ]
    do
      echo -n "${PAGE} "
      curl -s -H "Accept: application/json" -H "Authorization: ${AUTH}" "${BURL}&page=${PAGE}" -o "repolist-${PAGE}.json"

      if [ "$(grep "\"next\":" repolist-${PAGE}.json)" == "" ]
      then
        GO="0"
      fi

      let PAGE=$PAGE+1

    done
    echo ""
}

function cloneRefreshRepos() {
    CWD="$(pwd)"

    for list in $(ls repolist-*.json)
    do
      echo "Processing list $list"
      O="0"
      CONT="1"
      while [ "${CONT}" == "1" ]
      do
        cd "${CWD}"
        OBJECT="$(jq ".values[${O}]" "${CWD}/$list")"

        if [ "${OBJECT}" != "null" ]
        then
          PROJECT="$(echo "$OBJECT" | jq -r '.project.name')"
          NAME="$(echo "$OBJECT" | jq -r '.name')"
          SLUG="$(echo "$OBJECT" | jq -r '.slug')"
          CLONE="$(echo "$OBJECT" | jq -r '.links.clone[1].href')"

          if [ "$1" == "mirror" ]
          then
            mkdir -p "${ORG}-Mirror/${PROJECT}"
            cd "${ORG}-Mirror/${PROJECT}"
            if [ ! -e "${SLUG}" ]
            then
              echo "----------------------------------------------------------"
              git clone --mirror "${CLONE}"
              echo ""
            fi
          else
            mkdir -p "${ORG}/${PROJECT}"
            cd "${ORG}/${PROJECT}"
            if [ ! -e "${SLUG}" ]
            then
              echo "----------------------------------------------------------"
              echo "Cloning ${NAME}"
              git clone "${CLONE}"
              echo ""
            else
              cd "${SLUG}"
              echo "----------------------------------------------------------"
              echo "Updating ${NAME}"
              git fetch --all
              git pull
              echo ""
            fi
          fi

        else
          CONT="0"
        fi

        let O=$O+1
      done
    done
    cs ${CWD}
}


case $1 in
  get)
    # ########################################################################
    # Get the repo lists
    getRepoLists
    ;;

  update)
    # ########################################################################
    # Process the lists.
    cloneRefreshRepos
    ;;

  backup)
    # ########################################################################
    # Process the lists.
    cloneRefreshRepos mirror
    tar -zcf "${ORG}-Mirror-$(date -I).tgz" "${ORG}-Mirror"
    rm -fr "${ORG}-Mirror"
    ;;

  *)
    echo "Usage: "
    echo "<cmd>> get            Get the repo lists"
    echo "<cmd>> update         Update / checkout repos from BB"
    echo "<cmd>> backup         Create a mirror mackup of BB"
esac

Posted on

Confluence Led Calculator User Macro

Another little snippet – Feel free to use.
A nice little led resistor calculator for use in Confluence.

 

Settings: 
No macro body

Template code:

## @noparams
<table borderwidth=0 style=’border-collapse: true;’>
<tr>
<td colspan=3 style=’text-align: center;’>
<font style=’weight: bold; font-size: 24px;’>Formula</font>
<svg align=right height=”50px” width=”300px” version=”1.1″ viewBox=”-0.239051 -0.228099 76.1064 31.3739″ xmlns=”http://www.w3.org/2000/svg” xmlns:xlink=”http://www.w3.org/1999/xlink”>
<defs>
<path d=”M2.30336 -3.1721H2.99676C3.13225 -3.1721 3.23587 -3.1721 3.23587 -3.32354C3.23587 -3.43512 3.12428 -3.43512 3.00473 -3.43512H2.35118C2.47073 -4.06476 2.44682 -4.001 2.58232 -4.62267C2.66202 -5.00523 2.74172 -5.3878 3.03661 -5.3878C3.06052 -5.3878 3.2279 -5.3878 3.34745 -5.28418C3.21993 -5.23636 3.07646 -5.10087 3.07646 -4.90959C3.07646 -4.67846 3.26775 -4.63861 3.35542 -4.63861C3.58655 -4.63861 3.76189 -4.82989 3.76189 -5.07696C3.76189 -5.42765 3.40324 -5.61096 3.04458 -5.61096C2.20772 -5.61096 2.01644 -4.60672 1.96065 -4.30386L1.79328 -3.43512H1.23537C1.09988 -3.43512 1.00423 -3.43512 1.00423 -3.28369C1.00423 -3.1721 1.10785 -3.1721 1.2274 -3.1721H1.74545L1.20349 -0.294894C1.10785 0.215193 1.09191 0.294894 0.956413 0.773101C0.908593 0.956413 0.789041 1.40274 0.510087 1.40274C0.334745 1.40274 0.215193 1.3071 0.215193 1.3071C0.366625 1.24334 0.486177 1.09988 0.486177 0.924533C0.486177 0.6934 0.294894 0.653549 0.207223 0.653549C-0.0239103 0.653549 -0.199253 0.844832 -0.199253 1.09191C-0.199253 1.45853 0.183313 1.6259 0.494147 1.6259C1.33101 1.6259 1.65778 0.247073 1.83313 -0.68543L2.30336 -3.1721Z” id=”g0-102″></path>
<path d=”M3.19601 -2.95691C2.91706 -2.88518 2.91706 -2.64608 2.91706 -2.63014C2.91706 -2.48667 3.02864 -2.39103 3.16413 -2.39103C3.19601 -2.39103 3.51482 -2.39103 3.51482 -2.82939C3.51482 -3.29963 3.04458 -3.51482 2.59029 -3.51482C1.51432 -3.51482 1.25928 -2.64608 1.25928 -2.34321C1.25928 -2.13599 1.34695 -1.91283 1.51432 -1.77733C1.68966 -1.6259 1.77733 -1.60996 2.24757 -1.50635C2.42291 -1.47447 2.84533 -1.3868 2.84533 -0.980324C2.84533 -0.74122 2.63811 -0.143462 1.76139 -0.143462C1.59402 -0.143462 1.12379 -0.167372 0.956413 -0.533998C1.31507 -0.597758 1.31507 -0.900623 1.31507 -0.924533C1.31507 -1.07597 1.20349 -1.18755 1.03611 -1.18755C0.820922 -1.18755 0.621669 -1.02814 0.621669 -0.6934C0.621669 -0.247073 1.06002 0.0797011 1.76139 0.0797011C3.0127 0.0797011 3.33948 -0.860772 3.33948 -1.24334C3.33948 -1.95268 2.63811 -2.09614 2.37509 -2.15193C2.02441 -2.22366 1.75342 -2.27945 1.75342 -2.60623C1.75342 -2.82939 1.95268 -3.29166 2.57435 -3.29166C2.82939 -3.29166 3.10037 -3.20399 3.19601 -2.95691Z” id=”g0-115″></path>
<path d=”M8.06974 -3.87347C8.23711 -3.87347 8.4523 -3.87347 8.4523 -4.08867C8.4523 -4.31582 8.24907 -4.31582 8.06974 -4.31582H1.02814C0.860772 -4.31582 0.645579 -4.31582 0.645579 -4.10062C0.645579 -3.87347 0.848817 -3.87347 1.02814 -3.87347H8.06974ZM8.06974 -1.64981C8.23711 -1.64981 8.4523 -1.64981 8.4523 -1.86501C8.4523 -2.09215 8.24907 -2.09215 8.06974 -2.09215H1.02814C0.860772 -2.09215 0.645579 -2.09215 0.645579 -1.87696C0.645579 -1.64981 0.848817 -1.64981 1.02814 -1.64981H8.06974Z” id=”g3-61″></path>
<path d=”M7.87846 -2.74969C8.08169 -2.74969 8.29689 -2.74969 8.29689 -2.98879S8.08169 -3.2279 7.87846 -3.2279H1.41071C1.20747 -3.2279 0.992279 -3.2279 0.992279 -2.98879S1.20747 -2.74969 1.41071 -2.74969H7.87846Z” id=”g2-0″></path>
<path d=”M4.51905 -7.32852C4.61469 -7.73499 4.73425 -7.81868 5.45156 -7.81868C5.70262 -7.81868 5.79826 -7.81868 5.79826 -8.04583C5.79826 -8.16538 5.6787 -8.16538 5.63088 -8.16538C5.18854 -8.16538 4.72229 -8.14147 4.27995 -8.14147C3.82565 -8.14147 3.3594 -8.16538 2.91706 -8.16538C2.82142 -8.16538 2.68991 -8.16538 2.68991 -7.95019C2.68991 -7.81868 2.7736 -7.81868 2.97684 -7.81868C3.68219 -7.81868 3.68219 -7.73499 3.68219 -7.60349C3.68219 -7.57958 3.68219 -7.50785 3.63437 -7.31656L2.02042 -0.860772C1.91283 -0.430386 1.8411 -0.3467 1.02814 -0.3467C0.860772 -0.3467 0.74122 -0.3467 0.74122 -0.119552C0.74122 0 0.860772 0 0.908593 0C1.33898 0 1.80523 -0.0239103 2.24757 -0.0239103C2.70187 -0.0239103 3.18007 0 3.62242 0C3.71806 0 3.84956 0 3.84956 -0.227148C3.84956 -0.3467 3.76588 -0.3467 3.53873 -0.3467C3.20399 -0.3467 2.85729 -0.3467 2.85729 -0.549938C2.85729 -0.621669 2.85729 -0.645579 2.8812 -0.753176L4.51905 -7.32852Z” id=”g1-73″></path>
<path d=”M5.92976 -4.06476C7.4122 -4.41146 8.41644 -5.40374 8.41644 -6.40797C8.41644 -7.36438 7.53176 -8.16538 6.07323 -8.16538H3.07248C2.85729 -8.16538 2.74969 -8.16538 2.74969 -7.93823C2.74969 -7.81868 2.83337 -7.81868 3.06052 -7.81868C3.3594 -7.81868 3.69415 -7.81868 3.69415 -7.6274C3.69415 -7.55567 3.69415 -7.5198 3.67024 -7.44807L2.03238 -0.860772C1.92478 -0.442341 1.85305 -0.3467 1.12379 -0.3467C0.908593 -0.3467 0.800996 -0.3467 0.800996 -0.119552C0.800996 0 0.920548 0 0.968369 0C1.37484 0 1.82914 -0.0239103 2.24757 -0.0239103C2.67796 -0.0239103 3.13225 0 3.55068 0C3.64633 0 3.77783 0 3.77783 -0.227148C3.77783 -0.3467 3.68219 -0.3467 3.50286 -0.3467C2.83337 -0.3467 2.83337 -0.442341 2.83337 -0.549938L2.85729 -0.729265L3.67024 -3.96912H4.96139C5.90585 -3.96912 6.10909 -3.33549 6.10909 -2.89315C6.10909 -2.70187 6.01345 -2.29539 5.92976 -1.99651C5.84608 -1.66177 5.73848 -1.21943 5.73848 -0.980324C5.73848 -0.0478207 6.49166 0.251059 7.13724 0.251059C8.09365 0.251059 8.4523 -0.992279 8.4523 -1.09988C8.4523 -1.21943 8.33275 -1.21943 8.28493 -1.21943C8.15342 -1.21943 8.14147 -1.19552 8.09365 -1.02814C7.90237 -0.406476 7.56762 0.0119552 7.1731 0.0119552C6.79054 0.0119552 6.76663 -0.334745 6.76663 -0.669489C6.76663 -1.02814 6.85031 -1.66177 6.89813 -2.03238C6.89813 -2.05629 6.95791 -2.49863 6.95791 -2.666C6.95791 -3.43113 6.46775 -3.84956 5.92976 -4.06476ZM4.94944 -4.20822H3.73001L4.51905 -7.36438C4.61469 -7.74695 4.69838 -7.78281 4.80598 -7.79477C4.88966 -7.81868 5.24832 -7.81868 5.47547 -7.81868C6.21669 -7.81868 7.43611 -7.81868 7.43611 -6.67098C7.43611 -6.45579 7.37634 -4.20822 4.94944 -4.20822Z” id=”g1-82″></path>
<path d=”M8.69141 -6.8264C9.03811 -7.40025 9.32503 -7.74695 9.98257 -7.81868C10.1021 -7.83064 10.1978 -7.84259 10.1978 -8.04583C10.1978 -8.16538 10.0782 -8.16538 10.0543 -8.16538C9.79128 -8.16538 9.46849 -8.14147 9.19352 -8.14147C8.87073 -8.14147 8.52403 -8.16538 8.2132 -8.16538C8.14147 -8.16538 8.00996 -8.16538 8.00996 -7.93823C8.00996 -7.83064 8.1056 -7.81868 8.16538 -7.81868C8.23711 -7.80672 8.60772 -7.78281 8.60772 -7.43611C8.60772 -7.29265 8.51208 -7.12528 8.47621 -7.0655L4.88966 -1.05205L4.268 -7.26874C4.24408 -7.48394 4.22017 -7.80672 4.94944 -7.81868C5.12877 -7.81868 5.23636 -7.81868 5.23636 -8.03387C5.23636 -8.16538 5.12877 -8.16538 5.06899 -8.16538C4.67447 -8.16538 4.25604 -8.14147 3.84956 -8.14147C3.467 -8.14147 3.06052 -8.16538 2.68991 -8.16538C2.61818 -8.16538 2.48667 -8.16538 2.48667 -7.93823C2.48667 -7.81868 2.59427 -7.81868 2.71382 -7.81868C3.28767 -7.81868 3.32354 -7.73499 3.3594 -7.38829L4.07671 -0.0119552C4.10062 0.203238 4.12453 0.251059 4.27995 0.251059S4.45928 0.215193 4.55492 0.0597758L8.69141 -6.8264Z” id=”g1-86″></path>
</defs>
<g id=”page1″ transform=”matrix(1.13 0 0 1.13 -63.986 -61.0546)”>
<use x=”56.4133″ xlink:href=”#g1-82″ y=”70.0554″></use>
<use x=”68.7171″ xlink:href=”#g3-61″ y=”70.0554″></use>
<use x=”82.3041″ xlink:href=”#g1-86″ y=”61.9676″></use>
<use x=”90.9613″ xlink:href=”#g0-115″ y=”63.7609″></use>
<use x=”98.2534″ xlink:href=”#g2-0″ y=”61.9676″></use>
<use x=”110.174″ xlink:href=”#g1-86″ y=”61.9676″></use>
<use x=”118.831″ xlink:href=”#g0-102″ y=”63.7609″></use>
<rect height=”0.478187″ width=”41.46″ x=”82.3041″ y=”66.8275″></rect>
<use x=”98.3647″ xlink:href=”#g1-73″ y=”78.256″></use>
<use x=”102.853″ xlink:href=”#g0-102″ y=”80.0493″></use>
</g>
</svg>
<br>
<br>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>V<sub>s</sub> <input placeholder=”Supply V” onchange=”ledCalc()” style=’width: 90px;’ name=”Vs” id=”Vs” type=”number”> –
V<sub>f</sub> <input placeholder=”Forward V” onchange=”ledCalc()” style=’width: 90px;’ name=”Vf” id=”Vf” type=”number”><br></td>
</tr>
<tr>
<td>R <input name=”R” id=”R” style=’width: 90px;’ type=”number” disabled=true> Ohm</td>
<td>=</td>
<td><hr></td>
</tr>
<tr>
<td>P <input name=”R” id=”P” style=’width: 90px;’ type=”number” disabled=true> W</td>
<td></td>
<td style=’text-align: center;’>I <input placeholder=”Max I” onchange=”ledCalc()” style=’width: 90px;’ name=”I” id=”I” type=”number”><br></td>
</tr>
</table>
<script>
function ledCalc() {
let vs = document.getElementById(‘Vs’).value ;
let vf = document.getElementById(‘Vf’).value ;
let I = document.getElementById(‘I’).value ;
let ro = (vs – vf) / I ;
let po = (vs – vf) * I ;
document.getElementById(‘P’).value = po.toFixed(3) ;
document.getElementById(‘R’).value = ro.toFixed(0) ;
}
</script>