Tag Archives: SOFT

Generic C grožis arba kaip buvo geriau prie…

Tęsiant temą. Vėl tas pats PDP11, mano amžininkas ir kartu stipriai senesnis už mane. Viskas kažkaip kitaip ir panašiai. Ir toliau bežaidžiant užkniso tie visokie oktaliniai skaičiai, keistos programos (PDPGUI) parašytos Paskalyje ir su kriptiniais vokiškais klaidų pranešimais. Todėl nutariau padaryti dalį darbų old style metodu. Tiksliau- ancient style metodu. Kaip buvo prieš 50 metų ar daugiau…

T.y. renkames gryną “C” kalbą (čia bus kažkuri gcc windowsams) ir iš seno source kodo gabaliukų (archyve.org ir randominiai linkai) ir vajėzaumarija, AI generatorium generuojam naujas C programas.

Ko man reikia:

  • Parašom programą asembleryje ir sukompiliuojam. Gaunam bin failą ir lst. Tačiau čia lst kiek keistas, nes jis labai daug ką ignoruoja, rašo visokius simbolius ir t.t. O man reikia, kad išsistatytu tikras, kanoninis asembleris. Šita funkcija neprivaloma (optional), nes kai kurios programos jau bin.
  • Radau senovinį disasemblerį [disas11, 1991?] kurį pavyko sukompiliuoti. Bet jam reikia COREDUMP failų.
  • Su AI rašom bin -> COREDUMP konverterį. Beja, coredump formatą AI pats atstatė iš dalies disas11 source kodo.
  • Disasembleris duoda keistoką output failą dis, nes teoriškai galimas savaime modifikuojantis kodas. Jis rodo alternatyvini disasemblerio kodą jei prieš tai buvusi komandą pasikeistu. Gerai, kad alternatyvinis kodas pasislinkęs per tarpiukus. Su AI rašom programinę utelę kurį išfiltruoja ir palieka tik pagrindinį kodą.
  • Pagaliau išvalytas kodas visiškai oktalinis. Tam tikslui AI rašo C kalboje kitą utelę kuri konvertuoja visus octalus į hexus.

Ir tik dabar, aš galiu palyginti šešioliktainį disasemblerį su hidros parodymais ir pagaliau suprasti, kad dar reikia apšikti kažkiek žolės, kad gautusi rezultatas.

Apie ką męs čia? Ogi kad męs ne prieš AI. Tai geras įrankis ir teisingai naudojamas veikia. Paprašai parašyti utelę (beja, čia pačio AI pasiūlymas, nes jis pabijojo konvertuoti galbūt užkopyraitintą failą) ir jis parašo. O poto sakai- o tu padaryk, kad skaičiukai būtų su leading zero, išėjimas į failą, o ne stdout ir kad kai kurios specifinės eilutės eitu kitaip. Ir tas AI vergas sugeneruoja. Programos paprastos, bet pačiam rašyti nuo nulio gautųsi gal per daug laiko. Čia atsakymai atėjo per sekundes.

A, ir dar, reikėjo binarinį failą konvertuoti į oktalinį, tinkamą pumpuoti tiesiai į CPU per ODT. Toks bin to ODT text stream konverteris.

o dabar viską sukišim į makefile ir viskas man veiks automatiškai, vieno mygtuko paspaudimu.

Ghidra ir PDP11

Biški užsiciklinau su savo PDP kompiuteriu. Ir nutariau vieną programą kiek kitaip paleisti. O tam reikalui reikia daryti disasemblerį. Tačiau chaotiškam listinge (LST) labai sunku susigaudyti. Tačiau pasaulis išrado gana patogias priemones, kaip Ghidra. Tačiau viena bėda- nėra modulio PDP kompiuteriams. Kažkur githube guli kažkoks tvarinys kuris tipo palaiko PDP11, bet ten pati Hidra sulaužyta dalimis (ir nesikompiliuoja) ir kiek žiūrėjau, pačio PDP modulio (language) nėra. Vėl apgavystė. Todėl biški užpykau ir nutariau pasidaryti savo, “su šliundromis ir pokeriu“. O ten tokia “rogių kalba” (SLEIGH)…

Kol kas darau tik disasseblerį, nes iki kitoko nepriaugau. Ir dar kalnas klaidų nes:

  • Aš nesuprantu rogių kalbos
  • Aš nesuprantu PDP J11 procesoriaus kalbos
  • Aš nesuprantu PDP asemblerio
  • Aš neapkenčiu aštuntainės skaičiavimo sistemos
  • Aš nesuprantu ten kažkokio p-code, kur rašosi { } skliaustukuose

Šiaip procesorius makro CISC ir kogero pilnai Ortogonalus. T.y. visos komandos turi visus adresacijos būdus. Netgi nelogiškus, su visais galimais registrais- pvz operacijos su PC veikia kaip ir su bet kuriuo registru. Tačiau operacijos su PC turi savo sintaksę suprantama žmonėm. Palyginam:

A:	MOV (PC)+,R1
	.word 5
	HALT
B:	MOV #5,R1
	HALT

Atrodo kaip skirtingos programos (A) ir (B). Tačiau listingas rodo:

11 000024 012701                  	MOV (PC)+,R1
12 000026 000005                  	.word 5
13 000030 000000                  	HALT
14 000032 012701  000005          	MOV #5,R1
15 000036 000000                  	HALT

Binarinis kodas visiškai vienodas. Paprasčiausiai iškreiptas parašymas (PC+) programoje (A) sako, kad imk reikšmę sekančia už PC ir naudok, o poto PC padidink. O programoje (B) sako, imk tiesiog skaičių ir naudok. Bet tas skaičius kaip tik ir stovi prie komandos…

O dabar įsivaizduojam, kad komanda MOV turi du parametrus. Tie parametrai gali buti su 7 skirtingom adresacijom su 7 skirtingais registrais ar tiesioginiais skaičiais. Komanda MOV gali užimti ir vieną žodį (1Word=2bytes), ir du žodžius, ir tris žodžius (6 baitus!)…

Bet kad žinotumėt koks kaifas, kaip pradeda biški viskas veikti- smegenių mankšta. Čia jums ne shortus skrolinti youtubėje.

Ai, dar nepabaigtas produktas GitHube: Ghidra PDP11 processor language file/module (slaspec).

P.S. žinokit, ta hidra moka atkompiliuoti gcc programas. Bent jau mano kurybą su STM32 gana gerai atkompiliuoja.

ARM55: TG12864H (ST7565) SPI

Tai dar vienas atmintinukas apie LCD ekraniukus. Tokie ekraniukai kogero eina iš kokio Ali, bet aš juos radau kažkokiuose kasos aparatuose. Iš įpatybių: Read Only, SPI.

Beveik viskas veikia naudojant standartines ST7565 bibliotekas, tačiau yra kažkoks bugas su inicializacija. Kol kas sprendimas- du kartus inicializuoti ekraniuką.

Kadangi nėra galimybės nuskaityti ekrano atminties, norint pasinaudoti grafinėmis funckijomis (taškai, nuskaityti tašką) reikia daryti šešėlinę atmintį (shadow ram) ir ten laikyti ekraniuko ekrano kopiją.

Veikiančios demo programos source code, STM32F103 procesoriukui, STM32CubeMX griaučiai.

Futaba VFD GP9002A01A (ARM)

Nors realiai tai GP9002A02A. Man patinka VFD technologija. Keista spalva, didelis šviesumas ir kažkoks lempinis vaizdas. Todėl jei matau kur nors palaidą VFD ekraniuką, stengiuosi prigriebti. Aišku aš kalbu apie panaudojamus modulius, o ne kažkokius “custom made” iš senoviškų magnetofonų. O kiek kartų mačiau milžiniškus grafinius modulius kurie buvo sudaužyti- stiklinis korpusas neduoda tvirtumo. O šis modulis nukentėjo kitaip- jo trafukas su plonučiais laideliais atitrūko nuo transformatoriaus korpuso. Teko klijuoti ir užsiimti mikrochirurgija- trafukas visgi smd.

Tai grafinis ir tekstinis modulis. Galima pumpuoti binarinę informaciją arba galima naudotis integruotais šriftais ir kiek keistokais šrifto dydžiais. Ekranas kaip ir “grayscale”, bet man nepavyko. Gali būti, kad yra skirtumas tarp “01A” ir “02A”.

Futaba moduliai dažnai būna ne tik lygiagretaus interfeiso, kaip LCD moduliai, bet turi slaptus papildomus interfeisus: asinchroninis nuoseklusis (kaip RS232, tik TTL lygiai) ir SPI (synchronious serial). Asinchroninis dažnai būna per lėtas, net prie 115kbit matosi kaip formuojasi vaizdas. Paralelinis naudoja labai daug laidų, tačiau labai greitas. O štai SPI kaip ir kompromisas. Pas šį VFD maksimalus greitis kažkur 2Mbit. Nauji moduliai dažnai būna USB/HID- tokių dar nečiupinau.

Su STM32CubeMX sugeneruojam programos griaučius. Aš pasirinkau kojeles iš eilės. Procesoriukas- bet koks. Čia konkrečiai STM32F103VBT6. Kur kibirą turiu.

Mums be SPI, reikia CD (command/data), CS (chip select) ir jei norime gražiai animuoti: VFD_INT (čia kadrų sinchroimpulsas). CS – programinis, nes yra biški triukų. Net porą vakarų turėjau praleisti, kol pradėjo teisingai veikti. Trumpai- CS, CD ir SPI sekos svarbios!

Iš datašyto matom, kad SPI nėra defaultinis. Pirmiausia LSB, antriausia netipiniai CLK. Dar žiūrom į C/D.

VFD datasheet SPI

Labai padeda susigaudyti settinguose šis vogtas iš interneto paveikslėlis. Renkam tą kuris panašiausias:

Beveik visos komandos surašytos į programą. Aišku kiek užknisa ekrano atminties organizavimas, bet viską galima apeiti naudojant galingus MCU.

Ir aišku VFD ekrano valdymo source code STM32F103 procesoriui. (ARM-0053).

Blogas GCC arba x86 bėdos

Papuolė į rankas tokia maža ISA PCB su keliais čipais. Su magišku užrašu “Y2000”. Ir iškarto trenkė nostalgija, apie tai, kaip visi panikavo, kad kompiuteriai 2000-taisiais metais išprotės, nes metai tik dviženklis skaičius. Aišku buvo bėdų su tais metais, bet daugelis panikuotojų nepagalvojo, kad technologija smarkiai tobulėja ir kompai pradėjo labai greitai morališkai senti.

O tiems, kurie strigo su sena technika, atsirado visokie BIOS pataisymai. O jei nėra BIOS pataisymo, va jums papildoma plokštė su ROM. (Kitos mikroschemos tik supaprastina ROM pajungimą prie ISA linijų)

Nutariau pažiūrėti, kas tos mikroschemos viduje. Viduje labai mažai kodo, tai buvo kaip tik, kad pasimokinti Hidros (GHIDRA) programos vartojimo.

ISA PCB yra 8 bitų. Vadinasi suderinama su pačiais primityviausiais x86 procesoriais. Vadinasi kiek rimtesni procesoriai turi veikti “REAL MODE” režime. x86 procesoriaus kodas vos vos panašus į Z80 ir tikrai panašus į 8086. Hidra išardė kodą. O internetai padėjo atpažinti- pirmi trys baitai tai 55 AA 10. “55AA” tai signatūra, o 10 tai programos ROM dydis (kart 512 baitų, h100). O nuo 4 baito prasideda pati programa.

Konkreti Y2K PCB darė šitą: išvalo ekraną (rodos), parašo užrašą, nuskaito dalį RAM ir kažką paskaičiuoją ir jei nepavyko, sako error ir išeina, nuskaito RTC per BIOS, nuskaito RTC tiesiogai, palygina, ir jei kažkas gaunasi arba rašo, kad kompas suderinamas su Y2K arba bando (?) pačinti BIOSą. Čia jau spėlioju, nes mano žinio gana trumpos čia.

Kilo mintis padaryti va taip:

Copy-paste kažkiek asemblerio mnemonikų… ir kaip sukompiliuoti? Internetai sako, kad standartinis GCC, su raktažodžiais tipo “-m16 -nostdlib -ffreestanding” turi gaminti x86, 16bitų, REAL kodą. Ir tikrai, kopijuotas kodas iš Hidros susikompiliavo. Toliau teko kankintis su LD.exe ir visokiais loaderiais, kad gautųsi ROM image, o ne exe failas. Tai irgi buvo pilnas nuotykių žaidimas kuris nepavyko iki galo.

Tačiau kodas neveikė realiuose kompiuteriuose.

Ir pasirodo, kad JOKS GCC nesugeba generuoti teisingą 16 bitų, REAL MODE kodą. Iš principo. Binarinių failų palyginimas parodė, kad CALL, RETF ir gal kitokios instrukcijos generuojamas 32 bitų. Tas 32 bitų kodas “kaip ir suderinamas”, bet kai paleidi iš BIOSo, tai tikrai nesuderinamas. Ir nesvarbu koks procesorius- 486DX irgi nesuprato.

Rašyti softą be CALL kaip ir sunkoka. Gerai, kad čia tik kelios eilutės- išvalyti ekraną, per BIOSą (TTY režime) išspjauti tekstą ir nuskaityti ANYKEY iš klaviatūros. Teko viską perrašyti tiesiogiai. Ir rankutėmis įkelti “RETF” teisingą kodą programos gale. Kodu nesidalinu, nes jis baisus, nesuprantamas ir ten per daug POP/PUSH (kopijavau iš tikrų paprogramių, kur išsaugoja registrus). Svarbu veikia.

ROMas turi primityviausią kontrolinę, 8 bitų, sumą. Todėl reikią paskutinį baitą ROMe kaitalioti tol, kol suma nepasidaro 00.

O dar radau keistą PCI plokštę iš Izraelio- kažkoks tipo “security”. Pati PCB tai kastruota tinklo plokštė su BOOT ROM. Jei bus azarto, bus galima pasinagrinėti šitą kodą.

Taigi, be normalaus asemblerio, koduoti ROMą labai sunku. O tiek turėjau planų- panaudoti C kalbą ROMe ir PC kompiuterį panaudoti kaip mikrokontrolerį. Kam? Ogi smalsu. Nebent PCI kompiuteriai jau tikrai valgo 32 bitus ROMe.

O grynai asembleris tai NASM. Jam puikiausiai kompiliuojasi. Tikriausiai komentaruose bus pilnas komplektas NASM kompiliatoriui.

P.S. Originalus Y2000 ROMas.

Senobinis Cisco

Elektroninėse atliekose buvo atvežta gal paletė NOS1, nenaudotų, originaliose dėžutėse Cisco Access Pointų. Kelis paėmiau pabandyti ir mano nelaimei, pagal geras Cisco tradicijas, firmwarė viduje buvo “valdoma iš serverio”. T.y. tokia firmwarė, kuri skirta didelėm įmonėm, kur visokie prietaisai patogiai valdomi ir specialaus “kontrolerio” (serverio). Ir įjungimo metu, likusi firmwarė ir konfiguracija užsikrauna ir nieko nereikia individualiai konfiguruoti.

Pats AP gana elegantiškas, palaiko 2 ir 5G dažnius, POE ir panašiai. Patingėjau tada aš ieškoti kaip juos paleisti ir keliasdešimt jų išardė. Keli liko, ir iš neturėjimo ką veikti (ir su slaptais kėslais) aš nutariau perrašyti jų programinę įrangą į “user friendly” ir “Self containing”. Tam reikalui reikia Cisco serial kabelio (realiai kogero TTL lygio COM kabelis, netikras RS232). Netikėtai aš tokį kabelį turiu.

Nustatom kompiuterio IP adresą: 10.0.0.1 (255.255.255.0). Bet nežinau, ką padariau, kad mano laidinis ryšis turi du adresus:

Ethernet adapter Ethernet:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 10.0.0.1
Subnet Mask . . . . . . . . . . . : 255.255.255.0
IPv4 Address. . . . . . . . . . . : 10.0.0.254
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.0.0.2

Terminalas 9600.8.n.1, ir konsolėje matome informaciją, kaip kuriasi AP savo keistam režime.

Pasileidžiam, tftpd64. Pasididinam “timeout” iki kokių 30 sekundžių. DHCP nustatymuose parašom, kad duotų IP adresus tame pat potinklyje. Ir log langelyje matome, kad AP pasiėmė adresą. Nenustebkite, kad adresas kaitaliosis, čia greičiausiai Tftpd bėdos. Base aplankas nurodo į ten, kur yra firmware failai.

Terminale kartais reikia paspausti ENTER, kad atsirastu command promptas “>“.
Pirma komanda: enable
slaptažodis: Cisco
Jei AP jau turi kokią nors konfiguraciją, reikia nuspausti “mode” mygtuką, išjungti prietaisą ir vėl įjungti laikant mygtuką. Ir tik po kokių 20s, LEDas pasidarys raudonas, o terminale parašys, kad mygtukas nuspaustas, tada jį atleisti. Tada AP persikraus į avarinį “image” ir gal slaptažodis nusimuš.

Suveikus slaptažodžiui, AP command promptas pasidaro su “#“. Vadinasi dirbame “root” teisėmis.

sh ip int brief ← pasitikrinti ip. Šį komanda parodo, ar AP pasigavo adresą iš DHCP. Teoriškai galima rankomis nustatyti tą adresą terminale. Bet ten daug komandų. Paprasčiau vieną kartą susikonfiguruoti tftpd/dhcp ir viskas veikia.

Dabar kogero reikia parašyti šią komandą (arba sekančią), kad veiktu komanda “archive”. Kokią komandą? Priklauso nuo originalios firmwarės versijos.
debug lwapp console cli arba debug capwap console cli (c l i , i trumpoji)

Ir pats firmware įkrovimas. Pačios firmwarės jau nėra seniems prietaisams pas Cisco. Jie dėjo skersą ant savo senų produktų. Gal kokia webarchive gal rastumėt… Man padėjo guglės paieška ir kažkoks geras žmogus, kuris į githubą padėjo “testavimui” tuos image. Pasiguglinam apie firmwarės versijas ir kaip failai vadinasi. Mums reikia pilnaverčio, “standalone”, “self managable” failo. Nusikrautą imagę reikia pervadinti į defaultinį pavadinimą jei darome avarinį užkrovimą. Tačiau darant “mano” metodu, tereikia parašyti failo pavadinimą į komandinę eilutę:

archive download-sw /force-reload /overwrite tftp://10.0.0.1/c1130-k9w7-tar.tar

Poto bus siaubingai daug teksto terminale, ir tikrai palaukite iki galo. Pilnas softo perrašymas užtrunka kelias minutes. Palyginimui, palieku putty log failą. Ir aišku palieku tftpd log failą (ten pasimato, kokius failus AP bando nusikrauti). Ten matosi normalios AP užklausos viso proceso metu ir per pirmą normalų užsikrovimą.

Toliau užtenka eiti į naršyklę, suvesti DHCP priskirtą IP adresą ir konfiguruoti AP. Pirmo prisijungimo vartotojo vardas: Cisco, slaptažodis: Cisco

Sukonfiguruoti AP per WWW yra dar vienas tikras questas, nes Cisco pasistengė viską padaryti kaip galima sudėtingiau. Gal yra tokiems AP koks user friendly firmware?

  1. NOS, angl. New Old Stock. Nenaudoti, seni daiktai. ↩︎

Veikiantis CF kortelių pavertimas diskais

Kas nors kiek užsiima retro kompiuteriais, žino, kad seni mechaniniai diskai gali bet kuriuo momentų subyrėti. Arba jie labai cypia, ir kai kuriems žmonėms jau nebelaiko nervai.

Yra visiems žinomas būdas, kaip pereiti prie SSD sistemos. Seniems kompiuteriams su IDE lizdu tai ypač lengva, nes dar plačiai paplitusios CF kortelės turi būtent IDE interfeisą ir kompui jos atrodo kaip IDE diskas. Ypač geros “industrinės” CF kortelės, nes jos stipriai nebijo perrašymų. Ir aišku kažkaip jau taip atsitiko, kad vienu metu prisirinkau gal šimtą tokių kortelių. Kai kurios CF kortelės, ypač iš kokio CISCO įrenginio, kartais būna su “write protect”, bet dažniausiai jos pilnai ištrinamos.

Kaip naudotis? Pirmiausia reikia dviejų “hardwarių”- bet kokio USB-CF skaitytuvo ir CF-IDE adapterio.

Retro kompiuteris ir net du CF-IDE adapteriai (plačia jungtimi)

Toliau atrodo, kad viskas paprasta? Diskelis į kompą, fdisk, format /s ir t.t. Ogi ne. Kartai veikia, o kartais neveikia ir retro kompiuteris pakimba kraudamasis arba sako “missing operating system”. Nors BIOSas ir pamatė diską, ir net užkurus ir disketės kaip ir viskas gerai. Kankinausi kelias dienas, kol išmąsčiau kodėl neveikia (gal būt) ir kaip padaryti, kad veiktu.

Manau bėda tame, kad visokie MSDOS ir senieji DOS pagrindo windows ir kitokios operacinės sistemos labai jautrios ir kultūringos. Jos neištrina disko taip kaip reikia. Dažnai lieka keisti boot įrašai (nors fdisk /mbr) turėtu padėti. O dar lieka visokios nesąmonės pačiam diske. Ar net “FF” informacija. Ji kažkaip “klaidina” microsofto operacines sistemas.

Teoriškai turėtu padėti visokie “Rufus”, “rmprep” ar net “HP USB disk storage tools”… nieko jie nepadeda. Aš kalbu apie Windows 10 host kompiuterius.

Reikia daryti taip ir veiks (išbandyta su 1G ir 2G kortelėm). Pirmiausia reikia ištrinti esamas particijas (gal nereikia, bet geriau, nes kai diske nėra nieko- tada windows nesikiša su savo trigrašiu).

Pašalinam. Čia buvo “rufus” sukurta neveikianti particija (skirsnis). Toliau reikia su senu geru Win32 Disk Imager nuskaityti visą CF kortelę? Kam? Ogi 2GB kortelė viduje bus biški ne 2GB, o kažkiek kitaip. Nuskaitant pasidarom tikrą “fizinio disko” kopiją.

Nuskaitytą failą kietam diske galima iš karto pažymėti kaip kompresuojamą, tada disko failas bus mažytis.

Pasileidžiam programą HexEdit ir viską užnulinam. Tuos visus FF, jei kortelė nauja, ir visokias nesąmones, jei kortelė naudota. Tai svarbu dėl dviejų dalykų- MS DOS nehaliucionuos ir kartu disko image failas host kompiuteryje užims tik megabaitą.

Dabar reikia pasileisti nemokamą retro kompiuterių emuliatorių “PCem“:

Sukonfiguruojam panašios kartos kompiuterį į tą, kuriam ruošiam diską. Pasirenkam naujai pagamintą failą- visi CHS settingai nusistato automatiškai (galima užsirašyti, jei kompas ypač senas). Ir užsikuriam emuliatorių iš MSDOS 6.22 disketės.

Ir atliekam standartinius veiksmus:

  • fdisk /mbr -gal ir nereikia, jei diską užnulinį. Bet atsarga čia gėdos nedaro.
  • fdisk -grynai ir padalinam ar imam visą diską DOSui. RTFM.
  • perkraunam virtualų kompiuterį.
  • format c: /S -formatuojam C diską ir perrašom MSDOS paleidimą.
  • Jei reikia, perkopijuojam DOS disketės turinį: mkdir C:\DOS ir copy *.* C:\DOS
  • Galima pasibandyti kaip veikia kompiuteris iš disko image.

Perkopijuojam atgal disko image į CF kortelę. Paleidžiam retro kompiuterį:

Kas smagiausia, CF kortelė puikiausiai matosi ir šiuolaikiniam kompiuteryje- nėra bėdų su failų apsikeitimu (yra niuansu su ilgais failų vardais, bet čia jau kita tema).

ARM47 ir PID dalis #4

O dabar pašnekėsim apie STM32F4 serijos variantą ir source code. Pirmiausia- kodėl 4 serija? Todėl, kad tokia PCB pasitaikė po ranka. Ir tikrai ne dėl kažkokio mistinio FPU ar net DSP. Ir dar neaišku, ar mano turimas MCU yra originalas, o ne koks nors permarkiruotas šlamštas. Šaltinis solidus, bet kodėl jie juos išmetė? Reikia surasti kur nors panaudotą procesorių ir palyginti.

Source code yra sugeneruotas su CubeMX programa, kompiliuota su gcc. Ryšiai su kubiko paprogramėm tik per callback. Ir tai tik naudojam USB biblioteką (virtualus COM portas) ir taimerių pertraukimus. ADC skaitom blokavimo režime.

Pats PID skaičiavimas, float variantas visiškai toks pats kaip ir teoriniam variante:

float pid_generic(float measured, float setpoint, float amplif)
{
float output;
float deritative;
float error;
float proportional;
 
error = (setpoint - measured)/10;
proportional = error;
 
integral=integral + error * pid_dt;
deritative = (error - old_error) / pid_dt;
old_error = error;
 
output = (PID_KP * proportional + PID_KI * integral + PID_KD * deritative) * amplif;
 
return output;
}

Atsirado papildomas parametras “amplif” – tai bendro rezultato daugiklis, kaip ir sustiprinimas (ar susilpninimas). Teoriškai tą patį galima atlikti su pagrindiniais parametrais (P, I, D), bet taip lengviau priderinti prie “krosnelės” galingumo: kaitinimas dirba su integer skaičiais, ir PID rezultatas apsiapvalina. Taip prarandam “jautrumą”. Ir dar temperatūros parodymus pasmulkinam- tik dėl koeficientų.

uint32_t CalcTemp(void)
{
uint32_t a;
a=median_filter(adc_read_blocking(ADC_CHANNEL_4));
a=median_filter(adc_read_blocking(ADC_CHANNEL_4));
//a=median_filter(adc_read_blocking(ADC_CHANNEL_4));
// 786 - max t, 0.62V ->1655
// 3529 - kambario t, 2.83V -> 283
return (4096-a)/2; //12 bitų max apverčiam ir pašalinam LSB.
}
 

Dėl ADC blogumo, matuojam kelis kartus, invertuojam (dėl schemotechnikos išėjimas mažėja didėjant temperatūrai) ir pašalinam mažiausią bitą, nes jis rodo kvailystes. Funkcija “median filter” vogta iš interneto. Tai funkcija, kuri teoriškai turi išfiltruoti sporadiškus nukrypimus: jei eina 5, 6, 4, 3, 100 – tai tas šimtas kaip ir ne į temą. Kiek veikia per daug netikrinau. Manau, reikia dar padidinti buferį.

  1. readtemp=CalcTemp();
  2. pwm=PID(readtemp, SETTEMP);
  3. SetPWM(pwm);

O čia pats pagrindinis ciklas, kuris kartojamas sistemingai: 1 – nuskaitom, 2 – paskaičiuojam. 3 – valdom kaitinimą.

Visas likęs source kodas aptarnauja kontrolerio valdymą per terminalą (galima keisti parametrus) ir duomenų išmetimą analizei. Tai tik eksperimentinis variantas- darbiniam trūksta dar visokių apsaugų, normalaus valdymo ir indikacijos. Ir aišku, išėjimas čia PWM, kad tinkama mažam rezistoriui, bet ne tikram šildytuvui. Dar nesugalvojau, kaip padaryti korektiškai proporcinį valdymą realiai rėlei ar 50Hz simistoriniam reguliatoriui. Jei užteks kantrybės, tema bus vystoma.

Pats pilnas STM32F446 PID controller source code skirtas gcc ir kartu CubeMX projekto failas (versija užrakinta posto datai, galimi patobulinimai). Prie papildų- median filter, ftoa ir usb paprogramės. Visa mano kūryba “USER” aplanke.

PID, dalis #1

Teorija aišku. Kaip ir visi “interneto puslapiai” turiu įdėti šią formulę vogta iš vikipedijos…

PID

Tačiau tai paprasti puslapiai- mano “brain dump” t.y. čia bus neteisingas paaiškinimas kaip aš supratau.

Formulę susideda iš trijų dalių: prie Kp, Ki ir Kd.

Kp, tai proporcingas skaičius nuo klaidos. Išmatuojam sakysim temperatūrą, palyginam su reikiama, gaunam skirtumą ir jį naudojam rezultatui. Pats koeficientas Kp tai tik ant kiek jautriai reaguojam. Gaunasi- per šaltas, dar padidinam liepsną po puodu. Kuo skirtumas (klaida) mažesnė, tuo mažiau įtakoja. Gaunasi matematinis paradoksas, kad niekada nesigaus tiksli temperatūra. Aišku realiam pasaulyje dėl apvalinimo ir matavimo tikslumo, rezultatas pasiekiamas. Tačiau galimas didelis overšotas (per didelė temperatūra) arba labai lėtai pasiekiamas reikiamas rezultatas.

Ki, tai integralinė dalis. Čia kaupiasi klaida. Klaida turi ženklą (per karštá, per šaltá), o kai viskas gerai, tai klaida turi nusinulinti. Jei dėl kažkokių nors priežasčių tai nepavyksta, tai “likutinė” susikaupusi klaida priveda rezultatą prie teisybės. Įtariu, kad šita dalis “amortizuoja” reakciją.
Mano matematiniam modelyje, kai sistema stabilizuojasi, “integralo” reikšmė rodo mano teorinio šildytuvo išskirta energiją: (0.98 naudingumas, o integralas – 102. Čia 10.2W išskiriama energija, o 10W atšalimas). Čia kaip ir sistemos nuostoliai. Tuo tarpu Kp dalis jau nulinė, nes nebėra temperatūros skirtumo.

Kd, pati mistiškiausia, išvestinė dalis. Paprastai šnekant, tai kokiu greičiu kažkas keičiasi ir pagal tai bandom spėti kas bus ateityje. Kadangi formulė paprasta, tai spėjimas gali ir nepataikyti.

Visų šių parametrų suma ir yra reguliuojamas poveikis. Tačiau čia prasideda tiuninimas su koeficientais: Kp, Ki ir Kd. Visiškai nėra jokių universalių skaičių, kiekviena sistema turi savo skaičius. Žodis sistema reiškia ne tik matematinę formulę, bet ir visus fizinius parametrus ir bėdas: matavimo tikslumus, sistemos inerciją (tiek šildymo, tiek matavimo, tiek šildomo objekto). Yra net keli metodai, kaip koeficientus paskaičiuoti, bet geriausiai stebėti situaciją ir koeficientus pasitiuninti rankiniu metodu. Panaudojus neteisingus (dažniausiai per didelius) koeficientus, sistema gali “siubuoti” t.y. suptis kaip kokios supynės ir niekada nesusistabilizuotis. O per maži skaičiai labai pailgina sistemos reakcijos laiką. (nulinės reikšmės išjungia atitinkamas formulės dalis: taip gaunasi PI ir P kontroleriai.)

Formulė atrodo sudėtinga, bet čia tik dėl mandro užrašymo. Visual Basic kalboje tai viskas paprasčiau:

    Private Sub DoPID()
        P_error = setpoint - measured
        P_proportional = P_error
        P_integral = P_integral + P_error * pid_dt
        P_deritative = (P_error - P_previous_error) / pid_dt
        output = pid_kp * P_proportional + pid_ki * P_integral + pid_kd * P_deritative
        P_previous_error = P_error
    End Sub

Kaip ir viskas. Šią funkciją (paprogramę) reikia paleidinėti pastoviai, teoriškai kas “pid_dt” laiko tarpą. Tačiau tikslūs skaičiai reikalingi tik tada, kai skaičiuojam tikslius vatus ar džiaulius. Jei skaičiuojam santykiniais papūginiais vienetais, tai net “dt” galima išpaprastinti. Ir reikia išsaugoti dvi reikšmes sekančiam skaičiavimui: “P_previous_error” ir kaupiamąjį integralą “P_integral“.

Šiame matematiniam modelyje “output” gali būti ir neigiamas (čia gautusi kaip šaldymas), tačiau realiam pasaulyje šildymo elementas netik negali šaldyti, bet ir jo galingumas ribotas. Todėl programoje naikinam neigiamus skaičius ir ribojam maksimumą. Šie ribojimai visiškai neįtakoja funkcijos rezultato.

Pratesimas – 2 dalis.

PID, dalis #0

Pasišlykštėjęs kiniškų termokontroleriu nutariau kiek pasidomėti PID kontrolerio teorija. O tam reikėjo pasirašyti šildytuvo modelį (emuliatorių).

PID emuliatorius

Gavosi maždaug toks. Tai 100ml vandens kuris neverda (sferinio arklio vakuume) kaitintuvas su stabiliu aušinimu. Man tikrai patiko, kaip kontroleris reaguoja į netikėta aušinimo pastiprinimą ir kaip jis stabilizuojasi.

Kol kas tik tiek. Taip buvo pirmas vakaras. Pratesimas jau čia.