Kategória: Python

Zmenené: 30. október 2016

Farebný popis vývodov

Pokiaľ pracujete s integrovanými vývodmi, určite viete, že je potrebné vedieť, ktorý vývod poskytuje príslušnú funkciu. Najmä pri mikroradičoch je to problematické, pretože mnohé vývody majú alternatívne funkcie. Dlho som si tieto popisy vývodov robil manuálne v Inkscape, ale konečne som sa dokopal k tomu, aby mi to robil skript.

Projekt som nazval svgpinout a jeho jedinou závislosťou je vlastne len modul svgwrite, pomocou ktorého je generovaný výsledný obrázok SVG.

Poznámka

SVG je vektorový formát obrázku, ktorý ponúka veľmi zaujímavé možnosti.

Inštalácia

Pokiaľ chcete modul vyskúšať, nájdete ho v mojom serveri git, kde stačí stiahnuť súbor svgpinout.py a uložiť ho do nejakého adresára, v ktorom potom môžete tvoriť skripty na generovanie obrázkov (takto ho používam ja). Toto riešenie je asi najjednoduchšie aj pre používateľov Windows, pretože predpokladám, že mnohí ani netušia čo je to git.

V prípade, že si ho chcete nainštalovať (a potom používať na ľubovoľnom mieste), tak som sa pokúsil pripraviť inštalačný skript, no v gite neposkytujem archív na stiahnutie, preto si naklonujte úložisko git:

git clone http://git.slavino.sk/svgpinout.git

Poznámka

Pre prípadných prispievateľov, prístup HTTP je len na čítanie…

No a v lokálnej kópii spusťte:

python setup install

Varovanie

Inštaláciu som neotestoval, takže negarantujem, že bude fungovať.

Použitie

Použitie je prosté. Potrebujete pár krokov:

  1. importovať modul svgpinout
  2. definovať zoznam s popisom vývodov
  3. vytvoriť objekt vývodov
  4. vykresliť objekt
  5. uložiť obrázok

Celé to potom môže vyzerať takto:

import svgpinout

attiny85 = [
    ["PB5", "5/A0", "PCINT5", "~RESET", "dW", None, "ADC0"],
    ["PB3", "3/A3", "PCINT3", "XTAL1", "CLKI", "~OC1B", "ADC3"],
    ["PB4", "4/A2", "PCINT4", "XTAL2", "CLKO", "OC1B", "ADC2"],
    ["GND", ],
    ["PB0", "0", "PCINT0", "MOSI", "DI", "SDA", "AIN0", "OC0A", "~OC1A", "AREF"],
    ["PB1", "1", "PCINT1", "MISO", "DO", None, "AIN1", "OC0B", "OC1A"],
    ["PB2", "2/A1", "PCINT2", "SCK", "USCK", "SCL", "ADC1", "T0", "INT0"],
    ["VCC"],
]

a = svgpinout.baseIC("ATtiny85", attiny85)
a.doDraw()
a.save()

Reťazec „ATtiny85“ sa stane menom integrovaného obvodu a zároveň aj menom súboru (ATtiny85.svg) v aktuálnom adresári.

Prípadne, ak chcete len obrázok tela integrovaného obvodu, netreba definovať popis vývodov, ale stačí zadať počet vývodov:

a = svgpinout.baseIC("ATtiny85", pincount=8)
a.doDraw()
a.save()

Ak sa vám nepáči predvolené meno súboru obrázku, môžete použiť metódu saveas():

a = svgpinout.baseIC("ATtiny85", pincount=8)
a.doDraw()
a.saveas("cesta/meno.svg")

Najmä pri malých integrovaných obvodoch s dlhým názvom sa môže zísť zmenšenie písma názvu IO:

# namesize defaults to 24, but can be customized
a = svgpinout.baseIC("ATtiny85", attiny85, nameSize=20)
a.doDraw()
a.save()

Popis vývodov

Popis vývodov je zoznam zoznamov (list of lists). Každá položka zoznamu popisuje funkcie jedného vývodu, takže položka 0 popisuje vývod 1, položka 1 vývod 2, atď.

Každý vývod je popísaný ako zoznam reťazcov s funkciou vývodu. Pri vykresľovaní je poradie prvej (ľavá) polovice vývodov otočené, takže zoznam možno tvoriť v rovnakom poradí. Pokiaľ je vhodné umiestniť do obrázku prázdne miesto, treba použiť hodnotu None. Napríklad:

attiny85 = [
    ["PB5", "5/A0", "PCINT5", "~RESET", "dW", None, "ADC0"],
    ["PB3", "3/A3", "PCINT3", "XTAL1", "CLKI", "~OC1B", "ADC3"],
    ["PB4", "4/A2", "PCINT4", "XTAL2", "CLKO", "OC1B", "ADC2"],
    ["GND", ],
    ["PB0", "0", "PCINT0", "MOSI", "DI", "SDA", "AIN0", "OC0A", "~OC1A", "AREF"],
    ["PB1", "1", "PCINT1", "MISO", "DO", None, "AIN1", "OC0B", "OC1A"],
    ["PB2", "2/A1", "PCINT2", "SCK", "USCK", "SCL", "ADC1", "T0", "INT0"],
    ["VCC"],
]

V prípade negovaného vývodu stačí názov funkcie vývodu začať tildou (~) – viď funkcia RESET.

Farebná schéma

Do modulu som zakomponoval farebnú schému funkcií (svgpinout.STYLES) a jednoduchý systém identifikácie pomocou regulárnych výrazov (svgpinout.STYLLING).

STYLES je slovník, ktorý sa skladá z dvojíc „farba pozadia” a „farba popredia”:

STYLES = {
    "default" : (bgDefault, fgDefault),
    "arduino" : ("#c4a000", fgDefault),
    "serial"  : ("#729fcf", fgDefault),
    "interr"  : ("#d3d7cf", fgDefault),
    "timer"   : ("#ad7fa8", fgDefault),
    "analog"  : ("#73d216", fgDefault),
    "system"  : ("#fce94f", fgDefault),
    "power"   : ("#f40000", bgDefault),
    "ground"  : (fgDefault, bgDefault),
    "pwm"     : ("#f57900", fgDefault),
}

STYLLING je zoznam dvojíc „regulárny výraz” a „farebný štýl”:

STYLLING = [
    ("~?(RESET|XTAL|CLKI|CLKO|CKOUT|dW)" ,          "system"),
    ("~?(ADC|AREF|AIN)",                            "analog"),
    ("~?(TOSC|T\d|ICP)",                            "timer"),
    ("~?(OC)"         ,                             "pwm"),
    ("VCC|AVCC",                                    "power"),
    ("GND",                                         "ground"),
    ("~?(MISO|MOSI|\S?SCK|SS|SCL|SDA|RX|TX|DI|DO)", "serial"),
    ("\d+",                                         "arduino"),
    ("~?(PC)?INT",                                  "interr"),
]

Pokiaľ vám nevyhovujú štýly, alebo chýba regulárny výraz niektorej funkcie, prosto si to zmeňte/pridajte. Alebo mi napíšte a niečo vymyslíme.

Ukážky použitia

ATmega328

import svgpinout

atmega328 = [
    ["PC6", None, "PCINT14", "~RESET"],
    ["PD0", "0", "PCINT16", "RXD"],
    ["PD1", "1", "PCINT17", "TXD"],
    ["PD2", "2", "PCINT18", None, "INT0"],
    ["PD3", "3", "PCINT19", "OC2B", "INT1"],
    ["PD4", "4", "PCINT20", "XCK", "T0"],
    ["VCC", ],
    ["GND", ],
    ["PB6", None, "PCINT6", "XTAL1", "TOSC1"],
    ["PB7", None, "PCINT7", "XTAL2", "TOSC2"],
    ["PD5", "5", "PCINT21", "OC0B", "T1"],
    ["PD6", "6", "PCINT22", "OC0A", "AIN0"],
    ["PD7", "7", "PCINT23", None, "AIN1"],
    ["PB0", "8", "PCINT0", "CLKO", "ICP1"],

    ["PB1", "13", "PCINT1", "OC1A"],
    ["PB2", "12", "PCINT2", "OC1B", "SS"],
    ["PB3", "11", "PCINT3", "OC2A", "MOSI"],
    ["PB4", "10", "PCINT4", None, "MISO"],
    ["PB5", "9", "PCINT5", None, "SCK"],
    ["AVCC", ],
    ["AREF", ],
    ["GND", ],
    ["PC0", "14/A0", "PCINT8", "ADC0"],
    ["PC1", "15/A1", "PCINT9", "ADC1"],
    ["PC2", "16/A2", "PCINT10", "ADC2"],
    ["PC3", "17/A3", "PCINT11", "ADC3"],
    ["PC4", "18/A4", "PCINT12", "ADC4", "SDA"],
    ["PC5", "19/A5", "PCINT13", "ADC5", "SCL"],
]

a = svgpinout.baseIC("ATmega328", atmega328)
a.doDraw()
a.save()
ATmega328

ATtiny84 a ATtiny85

import svgpinout

attiny85 = [
    ["PB5", "5/A0", "PCINT5", "~RESET", "dW", None, "ADC0"],
    ["PB3", "3/A3", "PCINT3", "XTAL1", "CLKI", "~OC1B", "ADC3"],
    ["PB4", "4/A2", "PCINT4", "XTAL2", "CLKO", "OC1B", "ADC2"],
    ["GND", ],
    ["PB0", "0", "PCINT0", "MOSI", "DI", "SDA", "AIN0", "OC0A", "~OC1A", "AREF"],
    ["PB1", "1", "PCINT1", "MISO", "DO", None, "AIN1", "OC0B", "OC1A"],
    ["PB2", "2/A1", "PCINT2", "SCK", "USCK", "SCL", "ADC1", "T0", "INT0"],
    ["VCC"],
]

a = svgpinout.baseIC("ATtiny85", attiny85, nameSize=20)
a.doDraw()
a.save()

attiny84 = [

    ["VCC", ],
    ["PB0", "PCINT8", "XTAL1", "CLKI" ],
    ["PB1", "PCINT9", "XTAL2" ],
    ["PB3", "PCINT11", "RESET", "dW" ],
    ["PB2", "PCINT10", "OC0A", "CKOUT", "INT0" ],
    ["PA7", "PCINT7", "OC0B", "ICP", None, None,  "ADC7" ],
    ["PA6", "PCINT6", "OC1A", "SDA", "MOSI", "DI", "ADC6" ],

    ["PA5", "PCINT5", "ADC5", "OC1B", "DO", "MISO" ],
    ["PA4", "PCINT4", "ADC4", "T1", "USCK", "SCL" ],
    ["PA3", "PCINT3", "ADC3", "T0" ],
    ["PA2", "PCINT2", "ADC2", "AIN1" ],
    ["PA1", "PCINT1", "ADC1", "AIN0" ],
    ["PA0", "PCINT0", "ADC0", "AREF" ],
    ["GND", ],
]

a = svgpinout.baseIC("ATtiny84A", attiny84)
a.doDraw()
a.save()
ATtiny84 pinout
ATtiny85 pinout

LM339 a LM358

import svgpinout

lm358 = [
    ["Out1", ],
    ["-Inp1", ],
    ["+Inp1", ],
    ["GND", ],
    ["+Inp2", ],
    ["-Inp2", ],
    ["Out2", ],
    ["VCC", ],
]

lm339 = [
    ["Out2", ],
    ["Out1", ],
    ["VCC", ],
    ["-Inp1", ],
    ["+Inp1", ],
    ["-Inp2", ],
    ["+Inp2", ],
    ["-Inp3", ],
    ["+Inp3", ],
    ["-Inp4", ],
    ["+Inp4", ],
    ["GND", ],
    ["Out4", ],
    ["Out3", ],
]

svgpinout.STYLLING.append(("Out", "analog"))

a = svgpinout.baseIC("LM358", lm358)
a.doDraw()
a.saveas("doc/images/lm358.svg")

a = svgpinout.baseIC("LM339", lm339)
a.doDraw()
a.saveas("doc/images/lm339.svg")
LM358 pinout
LM339 pinout