Close

Programming PICs with Python

A project log for TritiLED

Multi-year always-on LED replacements for gaseous tritium light sources

ted-yapoTed Yapo 12/31/2017 at 04:098 Comments

No, not *in* python; they're still coded in assembly.  I mean using python to drive the assembler and PICkit3 programmer.  It turns out that MPLABX tools have a decent command-line interface.  I wrote some simple python classes to take the pain out of the command-line switches and enable automatic tuning of V3.x TritiLEDs.

One of the problems with the V2.x design was the inability to fine-tune performance for variations due to part tolerances (the inductor, for example is +/-30%).  Since the pulse frequency of the V3.x design can be very accurately tuned, I would like to be able to "tune out" the component tolerances once the devices are assembled.  This calibration process means programming the part, measuring the current drain, adjusting the pulse frequency, recompiling, and re-programming.  Then, maybe looping through the whole process a few times.  This is not something I want to do manually for each unit.

So, that's where the python comes in.  The fundamental code is shown below.

Scripting the MPASMX assembler is trivial.  In order to tune the frequency parameter, I simply write a one-line include file from python including an "equ" directive.  This file is included by the main assembly file.

Scripting the PICkit3 programmer is much more interesting.  You control the programmer through a script called "ipecmd.sh" (check for the name on different OS's), and it's documented in a file called "Readme for IPECMD.htm" in the mplabx/docs directory The programmer has provisions for powering the target device directly, and allows you to adjust the Vdd voltage.  Coupling this with a serial-enabled DMM makes a very nice little test kit: you can program different code on the device, then measure the current drain over a range of supply voltages.  There are probably a lot of interesting uses.

I still have to integrate the DMM code and write the iterative tuning algorithm, but that's probably of less general interest than programatically driving the PICkit3.

One thing I've discovered so far is that the output voltage of the PICkit3 doesn't seem very accurate.  I may add another serial-DMM to the test setup to measure the actual voltage instead of relying on what I tell the programmer to supply.

#!/usr/bin/env python

import subprocess

mplabx_path = '/opt/microchip/mplabx/'

class MPASM:
  def __init__(self, path):
    self.path = path + 'mpasmx/mpasmx'
  def assemble(self, filename):
    subprocess.call([self.path,
                     filename])


class PICKIT3:
  def __init__(self, path, part):
    self.path = path + '/mplab_ipe/ipecmd.sh'
    self.part = part
  def program(self, hexfile_name, voltage):
    subprocess.call([self. path, 
                     '-TPPK3',
                     '-M',
                     '-F' + hexfile_name,
                     '-P' + self.part,
                     '-W' + str(voltage),
                     '-OL'])
  def setVoltage(self, voltage):
    subprocess.call([self. path, 
                     '-TPPK3',
                     '-P' + self.part,
                     '-W' + str(voltage)])

class Frequency:
  def __init__(self, filename):
    self.filename = filename
  def set(self, freq):
    f = open(self.filename, 'w')
    f.write('FREQ    equ    .' + str(freq))
    f.close

voltage = 3.2;
PK3 = PICKIT3(mplabx_path, '12LF1571')
ASM = MPASM(mplabx_path)
freq = Frequency("frequency.asm")


freq.set(123)
ASM.assemble('tritiled_v30.asm')
PK3.program('tritiled_v30.HEX', voltage)
#PK3.setVoltage(1.8)

Discussions

jaromir.sukuba wrote 12/31/2017 at 09:51 point

As alternative, may omit using MPLAB command line interface at all, see #Microchip PIC Arduino based programmer 

12LF1572 is verified, so 1571 should work just fine.

  Are you sure? yes | no

Ted Yapo wrote 12/31/2017 at 14:50 point

Yes, I remember seeing that.  It's good work, and arduinos are cheaper than PICkit's!

It makes me think that an arduino-based TritiLED tuner might be useful for changing brightness, etc in the field.

  Are you sure? yes | no

jaromir.sukuba wrote 01/01/2018 at 17:40 point

Oh, another shameless plug of my projects - #PP04 - Camel computer  - that is complete IDE allowing to edit asm sources, assemble it, flash into target and debug it via in-circuit debugging harware. It's been made for PIC18, but should be adaptable for PIC16/PIC12.

I know it's overkill for what you need. What you probably want is Arduino keeping the TritiLED program binary and reflashing the modified binaries with startup constants based on user input - with 2x16 LCD and a few buttons.

Maybe you can have the TritiLED constants on single FLASH page in defined order, the Arduino code then might just erase the given page and load new content with desired constants, leaving the previous content untouched; making translation of user variables into binary simpler.

  Are you sure? yes | no

Ted Yapo wrote 01/01/2018 at 18:23 point

@jaromir.sukuba That's an interesting project.  I should pack one in case I ever get stranded on an island!  Does it run emacs? :-)

I keep thinking of a simple interface on the TritiLED itself - like a pair of pads on the PCB you short as a crude switch (I removed the actual switch on the V3 to shrink the PCB).  The LED can blink out the number of years it is set for (1 blink = 1 year, etc).  The setting can be stored in the high-endurance section of program flash, and can index a table of pre-programmed calibrated pulse frequencies.

It's just software and two pads on the PC, and probably gives the user 95% of what they'd want.

  Are you sure? yes | no

jaromir.sukuba wrote 01/01/2018 at 20:16 point

Yes, that's good computer to be equipped with in case of being stranded on an island. Similarly, the nickname "Camel computer" comes from friend of mine, who said it's good computer for playing with when you are riding the dessert on camel's back. It comes all from my old possession with DIY portable computers. Notice how is this topic recurring among my projects.

Regarding the setting directly on TritiLED - yes, that's definitely good alternative. You may reuse programming header for this, just pull-down PCD and PGC pins with ~47k resistors (pull-down will not interfere with program/debug actions). I often fit the resistors, it's sometimes handy place to put configuration jumpers or as last-resort expansion header.

As I'm looking at the schematics, you have actually no other pins than programming pins for this purpose :-)

  Are you sure? yes | no

Ted Yapo wrote 01/01/2018 at 20:47 point

@jaromir.sukuba my concern about setting modes by shorting pads is accidental mode changes.  If you have these outside, there's the possibility of rain ingress or condensation, which could accidentally change modes (like from 5 years to 1 year, then your trail marker goes out early).  I am wondering if I can write some software that requires you to bridge the pads with an external diode - the software can raise one line, check the input of the other, then swap the pins.  With a short (like from condensation), the lines will both raise the other, but with a diode between them, only one line will raise the opposite one.  The diode becomes a key that you have to use to change modes.


With the latest design, I still have RA2 uncommitted., but to use the diode idea, I'd need to re-use the programming pins.

  Are you sure? yes | no

jaromir.sukuba wrote 01/01/2018 at 20:59 point

You may consider time-limited configuration window, like 15 minutes after POR (detectable via RCON register). So, if you want to reconfigure it, you have to play around with battery, but it decreases chances of unwanted reconfiguring.

  Are you sure? yes | no

Ted Yapo wrote 01/01/2018 at 21:45 point

@jaromir.sukuba thanks for the time-window idea.  Simpler and more foolproof.  Very good.

  Are you sure? yes | no