27C400 arba Amiga Kickstart readeris

Biški gliučino mano remontuojamos Amigos, tai teko greituoju būdu pasidaryti 27C400 skaitytuvą nes pasirodo, nei vienas mano turimas EPROM skaitytuvas 256Kb x16 nevirškina. Nutariau pasinaudoti eiline STM32F103VGT plokšte. Dėmesio! Čipas VGT turi 96kb RAM, kiti gali netikti, nes programa naudoja 64K buferį mikroschemos skaitymui. Ir dar kažkiek užima USB procedūros.

STM32F103 yra tolerantiška 5V logikai, o šios ROM mikroschemos visiškai tolerantiškos kiek žemesnio potencialo logikai. Gal, jei šitą plokštę perdaryti iki programatoriaus, tai Vcc ten 6V (Vpp-12.5V). Jei tie 6V nutekės iki kojyčių, tai STM gali ir nugeibti.

Net ir naudojant GPIO valdymą, STM labai greitai nuskaito informaciją. O va greičio USB perdavimui tai labai labai trūksta. Kažkur skaičiau, kad STM32F1 gali iki 700kbit/s greitį pasiekti. Man kogero nepavyko- pagal LED matosi, kad iš čipo skaito gal ketvirtį sekundės, o poto ilgai ir nuobodžiai pumpuoja informaciją.

Viduje žalių laidelių žarnynas. Bet viskas veikia. Palaidas kondensatorius reikalingas- pasirodo, mano kompiuterio USB maitinimas visiškai blogas ir duomenų skaitymas labai jau matosi ant Vusb linijos.

Pasitikrinau visus Kickstartus, ir visi buvo geri.

Programinėje įrangoje daug nesąmonių. Bet gal kam nors bus įdomu. Yra tikras CRC32 skaičiavimas, hardwarinis CDC valdymas, IntelHex duomenų skaitymas ir rašymas. Viską galima valdyti per terminalinę programą. Savo reikmėm pasirašiau VB.NET programą, bet ja nesidalinsiu, nes ten viskas labai baisu ir vienintelė iki galo padaryta funkcija- nuskaityti čipą, paskaičiuoti CRC32 ir įrašyti čipo turinį į failą.

Visas STM32F103 27C400 ar Amiga Kickstart čipų skaitymo įrankio (ROM READER) source code ir CubeMX darbinis failas.

P.S. programa daro “byte swap”, nes visi Amiga kickstartai internete taip surašyti. O čipuose baitai sukeisti vietomis. Nedarašytas šios funkcijos valdymas ( reikia išjungti n = __builtin_bswap16(n); ). Sukeitimas tikriausiai susijęs su 68000 ir Intel MSB-LSB ar panašiai ideologija…

AI žudo internetą (ir youtube)

Neseniai žiūrėjau vieną tokį kaip ir “mokslinį” kanalą ir jo autorius skundėsi, kad pastaruoju laiku labai sumažėjo jo filmų peržiūros. Jis pabandė pasiieškoti pagal raktinius žodžius savo filmukų- ir jie pasirodė tik kažkelintam youtube puslapyje. O pirmosiose vietose pasipylė kažkaip panašios stilistikos “click bait” filmukai su AI generuotu “Screenshot”. Ir kas baisiausia, video vaizde buvo jo kadrai ir panašus į jo balsas. Balsas kažkaip ir panašus, bet kartu ir nelabai natūralus- tai buvo AI treniruotas pagal jo balsą. O youtube kol kas nelabai moka ieškoti “kopyraitų” pagal vaizdą…

Kitas gyvenimiškas vaizdelis- man migruojant iš seno kompiuterio į naują šiuos puslapius prireikė senai primirštų žinių apie linux. Ir pastebėjau, kad pirmieji atsakymai guglėje kažkokie labai gražiai surašyti, ir kaip į temą, bet nelabai padeda. Ir aš prisiminiau, kad panašiai skambėjo ChatGPT kai aš bandžiau šnekėti apie chemiją ir labai konkrečia jos sritį- PGM analizę keramikoje. Kaip ir esu šioks toks to reikalo specialistas ir ta tema domisi gana siauras žmonių ratas kuris visiškai nesidalina informacija viešai. Taiva- visi puslapiai buvo generuoti AI.

Ir paskutinis variantas. Naujam kompe pasileidžiau youtube ir pagalvojau kad noriu foninės muzikos. Pagal mano norus išmetė daug playlistų ir paspaudžiau pirmuosius. Skamba melodija, pradeda dainuoti- kažkas netaip. Balsas kaip ir panašus į Stingo, Bono, Axl ar net Fredžio, bet kažkaip ne ta tonacija ir skambesys…

Shazamas kaip ir nežino kas taip. Aš kaip ir melodijas atpažinau, bet panašu, kad dainuoja AI. Taigis, muzika pavogta, kaip ir “koveris” ir kaip guglė automatiškai nieko nesuseks. Ir manau pergeneruoti tokį “video kanalą” yra kaip apsysioti trys pirštus.

Toks AI panaudojimas užsidirbti pinigėliams manau kasa didelį kapą internetui kuri męs naudojam.

Galvaninis ryšis indaplovėje

Prisiprašė žmogus patikrinti kažkokios firmos indaplovę. Nes žmogui leido tarpinė, nu tai išardė, pataisė, sujungė ir pasijuto magiško dūmelio kvapas. Ir nebeveikia. Žmogus yra kokių 90% detalių tiekėjas į kromelį, tai negalėjau atsisakyti.

Va tokis PCB ir jame sudegė vienas PNP tranzistorius SOT-23 korpuse. Kas įdomiausia, būtent toks tranzistorius ir buvo kromelyje- valio, sunaudojom 1 tranzistorių. Apie 12999 vienetai dar liko.

Plačiau analizuojant schemą pastebėta anomalija kuri kiek mane nustebino. Nuotraukoje matosi, kad naudojama TOP, TINY ar kokia VIPER mikroschema maitinimo šaltinyje (prie didelio, 400V, elektrolito) ir net kažkoks transformatorius yra. Tačiau netikėtai testeris parodė, kad yra tiesioginis galvaninis ryšis tarp procesoriaus ir 230V jungties. Ir ne per PE laidininką. Schemos skambinimas parodė, kad išlygintas 230V minusas tiesiogiai prijungtas prie procesoriaus žemės ir automatiškai prie LED indikacijos ir visų mygtukų. Teoriškai, jei pažeisti LED ekraniuką, prakrapštyti bet kurį mygtuką ar jutiklį, visi šitie pažeidimai pavojingi smalsiems pirščiukams! Kodėl?!

Jei yra kažkoks TINY ir transformatorius, tai padaryti maitinimo šaltinį izoliuota yra juokų darbas- trafo apvijos ir viena foto pora atbuliniam ryšiui. Pats “pažadinimas” irgi įdomus (iki galo neišsiaiškinau), bet maitblokis pasileidžia nuo įtampos impulso tiesiai iš tinklo grandinių per mygtuką ir “užsirakina” (latch) per minėtą PNP tranzistorių. Tada jau pasileidžia MCU (beja tai STM32, tik ne F šeimos) ir jis pradeda nagrinėti ir valdyti indaplovę.

Pakeitus tranzistorių, valdymo schema veikia. Ar veikia indaplovė aš nežinau, nes neturiu pačios indaplovės ir nežadėjau jos taisyti. Svarbu pasileidžia elektronika ir net rodo laiką ir klaidos kodą.

Bet minus 230V ant mygtukų ir LED man vistiek nepatinka.

ARM48: USB HID host

Jei naudojamas STM32 čipas palaiko USB HOST režimą, tai prijungti USB įrenginį labai paprasta. Mano hardwarė labai paprasta- čipas ir dvi USB jungtys. Viena jungtis suprogramuota kaip virtualus COM portas skirta peržiūrėti rezultatus, o kita USB jungtis tai USB host. Čia galima prijungti pelę ir klavietūrą. Kiti HID įrenginiai nepalaikomi.
Primenu, kad HID klavietūra palaiko iki 6 klavišų nuspaudimus (neįskaitant modifikatorius: shift, control, alt…) ir atskirai siunčiami klavišų paspaudimai ir atleidimai.
Kad viskas veiktu, tereikia savo programoje pasirašyti callbacką:

  1. void USBH_HID_EventCallback(USBH_HandleTypeDef *phost)
  2. {
  3. char txt_buf[100];
  4. char t[4];
  5.  
  6. strcpy(t,"[x]");
  7. if(USBH_HID_GetDeviceType(phost) == HID_MOUSE) // if the HID is Mouse
  8. {
  9. HID_MOUSE_Info_TypeDef *Mouse_Info;
  10. Mouse_Info = USBH_HID_GetMouseInfo(phost); // Get the info
  11. int8_t dX_Val = Mouse_Info->x; // get the delta x value (note unsigned - signed conversion)
  12. int8_t dY_Val = Mouse_Info->y; // get the delta y value
  13.  
  14. int len = sprintf (txt_buf, "dX=%d, dY=%d, Button1=%d, Button2=%d, Button3=%d\r\n", dX_Val, dY_Val, Mouse_Info->buttons[0],Mouse_Info->buttons[1], Mouse_Info->buttons[2]);
  15. user_usb_tx((uint8_t *) txt_buf,len);
  16. }
  17. if(USBH_HID_GetDeviceType(phost) == HID_KEYBOARD)
  18. {
  19.  
  20. HID_KEYBD_Info_TypeDef *Keyboard_Info;
  21. Keyboard_Info = USBH_HID_GetKeybdInfo(phost); // get the info
  22. txt_buf[0]=0;
  23. unsigned char i;
  24. for(i=0;i<6;i++)
  25. {
  26. if(Keyboard_Info->keys[i] != OLDKEYS[i] )
  27. {
  28. if (Keyboard_Info->keys[i]==0) {strcat(txt_buf,"UPKEY:"); hex8(txt_buf,OLDKEYS[i]);t[1]=Scan2Char(OLDKEYS[i]); strcat(txt_buf,t);}
  29. else if (OLDKEYS[i]==0) {strcat(txt_buf,"DOWNKEY:"); hex8(txt_buf,Keyboard_Info->keys[i]);t[1]=Scan2Char(Keyboard_Info->keys[i]); strcat(txt_buf,t);}
  30. else {strcat(txt_buf,"ERR:"); hex8(txt_buf,Keyboard_Info->keys[i]); strcat(txt_buf,"-");hex8(txt_buf,OLDKEYS[i]);}
  31. }
  32. OLDKEYS[i]=Keyboard_Info->keys[i];
  33. }
  34. strcat(txt_buf,"\r\n");
  35. user_print_usb( txt_buf);
  36. }
  37. }

Pačiam HID reporte visada transliuojami visi nuspausti klavišai, todėl, jei reikia susiderinti su PS2 ar senesniu standartu, reikia tikrinti, koks klavišas nuspaustas ir koks paleistas. Ta daro ciklas 24-33 eilutėse.
Rezultatas:


UPKEY:12[o]
DOWNKEY:13[p]
UPKEY:13[p]
DOWNKEY:2F[[]
UPKEY:2F[[]
DOWNKEY:30[]]
UPKEY:30[]]
DOWNKEY:31[\]
UPKEY:31[\]
DOWNKEY:04[q]
DOWNKEY:16[s]
DOWNKEY:07[d]
DOWNKEY:09[f]


DOWNKEY:2C[ ]
UPKEY:16[s]
UPKEY:07[d]
UPKEY:09[f]
UPKEY:04[q]
UPKEY:2C[ ]
DOWNKEY:0B[h]
UPKEY:0B[h]

Visas demo softo source code čia: STM32CubeMX USB host HID demo source code.

Nerusiškas auksas

Paprastai šnekama, kad tarbiniai žmonės dėjo daug aukso ant detalių… tačiau spėju, kad dėl savo atsilikimo, męs nematėm vakarietiško aukso.

Čia buvo kažkokia radija ar šiaip hifi. Deja ją sulaužė jau tie, kurie atvežė plokštes į supirkimą. Komplekte dar buvo keturi paprasti NPN tranzistoriai. O dryžuotų buvo daugiau, bet užteko vieno kolekcijai.

Spėju, kad kokie nors 70-tieji metai. Bet darlingtonas macnas- jei čia BD700, tai 70..80V ir apie 8A. 70W išskiriamos galios? Gamintojas Motorola. Mažiukas irgi visas auksinis. Dar patinka, kad ant metalo yra BCE raidelės. Pas mažylį- centrinė koja B, bet tvirtinimo detalė C.

Tranzistoriai gyvi, tačiau kiniškas matuoklis nesugebėjo išmatuoti. O kas per MPS007 aš neradau.

Su Naujais, 2024 metais!

Sveikinu visus su Naujais Metais!

(Nu nepatinka mano telefonui ta bjauri mėlyna spalva. Pakeisti negaliu, o nenaudoti irgi negaliu, nes turiu ekraniukų gal 100 vienetų.)

Ką čia palinkėti? Kaip senas diedas- laimės ir sveikatos! Kaip elektronikos megėjas- mažiau magiškų dūmų, ir nepaimti lituoklio už ne to galo. Kaip kompiuteristas- kad mažiau reikėtu migruoti visą softą į kitos kartos OS. Kaip chemikas- kad nusėstu kai reikia nusodinti, kad ištirptu kai reikia ištirpinti. Kaip megėjas statybininkas- kad nereikėtu bendrauti su tikrais statybininkais.

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 #3, FLOAT ir STM32F4

Dabar, apjungiant senesnius straipsnius [0, 1, 2], sumontavau kažką panašaus į PID termokontrolerį.

PID controller STM32F4xx

Ant lentos surinkta mano universali White Pill plokštė, tik su STM32F446 procesorium (toks biški itartinas tas procesoriukas, kažko man taimeriai neteisingai veikia). Dešinėje- mano Pt100 termorezistoriaus stiprintuvas. Geltona plokštė, tai kiek pasvilęs RGB LED “stiprintuvas”- galvaniškai atrišti trys galingi MOSFET valdomi per optoporas. Optoporų rezistorių teko sumažinti, kad nuo 3V procesoriuko pilnai valdytusi. O vienas “RGB LED stiprintuvo” kanalų paprasčiausiai valdo vielinį rezistorių kairėje, į kurį įkištas Pt100 jutiklis- tai mikro krosnelė, kurioje bandysim stabilizuoti temperatūrą.

Šiame eksperimente naudojamas source code su “float” kintamaisiais. Nenorėjau iškarto eksperimentuoti su integer matematika, nes dar nežinojau savo “krosnelės” parametrų.

PID įėjimas- ADC, išėjimas PWM. Panaudojau “prabangų”, 16 bitų PWM, nes norėjau platesnio reguliavimo. O su ADC išėjo biški problematiškai- STM32F446 ADC biški gaidiškas (net jo datašytas tai rašo). Nėra jokio tikslumo ir rezultatai vaikšto. Todėl panaudojau matematinį “filtrą” ir kelis nuskaitymus iš karto. Temperatūra matuojama “papūgomis”1 – 1000 vienetų tai kažkur 40℃, o apie 280 tai kažkur kambario. Užduotis- palaikyti 1000 vienetų temperatūrą viduje rezistoriaus.

Pagrindinė bėda- tiek rezistorius, tiek Pt100 žiauriai lėtai veikia. Todėl teko gana ilgai žaisti su koeficientais, ir dar iki optimalumo jie neprivesti.

PID chart

Mėlynas grafikas- rezistoriaus temperatūra. Raudonas grafikas PWM užpildymas. Matosi periodiniai triukšmai tiek temperatūros nuskaityme, tiek išeinančiam signale. Reikia rimtesnio skaitmeninio filtro. Dar kiek palaikius, paskutinius 400+ skaitymų temperatūros vidurkis buvo lygiai 1000 papūgų. Tačiau signalas nesusistabilizavo. Gal per maža PWM reikšmė:

PID PWM

Vos 2% iš viso. Gal vėliau pabandysiu su aukštesne temperatūra. (PWM signalas iš MOSFETO- žemas lygis reiškia, kad rezistorius prijungtas prie žemės ir kaista). Beja, gal ir siauresnis signalas per siauras šiems kiniškiems mosfetams. Pastebėjau, kad prie mažesnių signalų, PWM dingsta iš oscilografo ekrano.

Pratesimas ir veikiantis source code sekančiam straipsnyje.

  1. Tai santykinis matvimo vienetas iš seno multifilmo, kai matavo smauglio ilgį. ↩︎

Pt100 nuskaitymas

PT100 tai termorezistorius, kuris gana tiksliai matuoja temperatūrą. Skaičius 100 sako, kad prie 0℃ rezistoriaus varža yra 100Ω. O raidelės Pt sako, kad pirmieji šio rezistoriaus variantai buvo padaryti iš platinos. Ar dabar ten yra tos platinos aš jau nežinau. Bet seni tarybiniai termorezistoriai viduje turi labai labai plonos platinos vielos. Keičiantis temperatūrai keičiasi ir tos vielos varža.

O kaip nuskaityti tuos varžos omus? Pirmi pasiguglinimai parodo:

schemos

Čia visdėlto blogos schemos… Schema kairėje, jungimas prie mano nemėgiamo arduino. Paduodam elektrą per rezistorių ir matuojam su ADC parodymus. Atrodo kad viskas paprasta? Bet neteisinga- pirmiausia, per Pt100 rekomenduojama srovė iki 1mA. Čia 5.5mA ir pats termistorius jau nuo srovės kaista. Antroje schemoje srovė jau pamažinta ir kad ADC kažką matytu, pastatytas operacinis stiprintuvas (su 31 karto stiprinimu). Kaip ir logiška, bet deja, ne. Pt100 termistoriaus varža kinta tik keliasdešimt omų: prie 100℃ jis 138.5. Matuojant nuo 0℃ iki 100℃ turim tik 38.5Ω pokytį.

Ir dar abi schemos turi kitą problemą:

Paskaičiuojam schemą kairėje: įtampos pokytis ADC kojoje nuo 2.75V iki 2.58V, apie 0.1658V visam šimtui laipsnių. Kad ir koks geras ADC, didžioji jo matavimo dalis bus nenaudojama, o ir rezoliucija nebus labai jau didelė.

Antra schema, atrodo kaip ir geresnė, bet čia ta pati bėda- net po sustiprinimo, darbinis diapazonas nuo 3.04V iki 4.18V, apie 1.14V šimtui laipsnių. Kodėl, o todėl, kad pastovioji dedamoji nuo didžiosios dalies varžos irgi “pasidaugina” su operacinius stiprintuvu.

Ką daryti? Ogi daryti naudojant daugiau rezistorių:

pt100 amplifier

Šis testinis chaosas tai instrumentinis operacinis stiprintuvas LT1167 ir “matavimo tiltas” (Wheatstone bridge) – viršuje, kairėje. Papildomi rezistoriai dar padaro taip, kad diferencinis signalas gautusi virš 2.5V nuo žemės- čia jau LT1167 veikimo specifika naudojant vienpoliarį maitinimą. Dar, išėjimo signalas žemiau 0.6V nenusileidžia- čia irgi specifika, nėra jis rail-to-rail. Naudojant dvipoliarį maitinimą, tokios nesąmonės visiškai nereikalingos.

Šis “tiltas” duoda vieną triuką- taip galima iš schemos magiškai pašalinti “nenaudojamus” omus. Mano tiltas buvo surinktas iš trijų 120Ω rezistorių ir Pt100 termorezistoriaus. Dabar operacinis (čia instrumentinis) stiprintuvas gali žymiai daugiau stiprinti signalą. Testinėje schemoje gavosi kažkur nuo 6V iki 0.6V keičiant temperatūrą nuo kambario (~23℃) iki kažko karšto, bet ne verdančio. Maitinimas rodos buvo nuo 15V vienpoliario, o srovė per Pt100 ribota kažkur 10kΩ varža. (Tai tik testinė plokštė, neskirta naudoti su tikru procesorium).

Dar reikia sukonstruoti tikrą stabilizuotą maitinimo šaltinį (gal su specialia mikroschema) ir galimą viską sumontuoti gražiai. Bet tikslas tikrai nėra toks, tai tik tarpinis straipsniukas prie PID kontrolerio eksperimento.

PID, dalis #2, o kodėl FLOAT?

Jei norėčiau perkelti seniau aprašytus algoritmus į kokį mikrokontrolerį, viskas lengvai nusikopijuotu. Juk šiuolaikinis gcc puikiausiai palaiko slankiojo kablelio matematiką (float). Tačiau float yra lėtai ir užima daug vietos. Ypač dalyba. Net naudojant integer matematiką, dalyba yra toks nerekomenduojamas reikalas.

Ar tikrai reikia dalybos? Prisimenam formulę:

PID

Čia dalyba yra tik pačioje dešinėje, kur dalinasi iš dt. O jei pas mumi dt = 1? Kas sako, kad reikia skaičiuoti realiom sekundėm? Kas draudžia skaičiuoti kokiais nors išgalvotais, santykiniais vienetais. O jei tikrai reikia, kas draudžia funkciją skaičiuoti kitokiu dažniu. Išpaprastinam dt.

O dabar ar tikrai reikia float? Kas trugdo skaičiuoti viską integer? Gal koeficientai Kp, Ki, Kd? O kas trugdo juos padidinti šimtus kartų? Niekas. O kodėl šimtus? O kodėl ne 256 kartus? Ar 2^15 kartų? Svarbu, kad tik rezultatas tilptu į procesoriuko integer talpą. Viską skaičiuojam dideliais skaičiais ir jau galutinį rezultatą vėl sumažinam kažkiek kartų. Svarbu tik atburti koeficientus.

Čia visiškai ta pati programa, tik pats PID kontroleris veikia su 64 bitų integer matematika. O delta T yra vienetas. (Šildymo modelis tebeveikia su float matematika). Aišku čia kiek nepataikiau su koeficientais ir sunkiai susistabilizavo. Bet veikia!

    Private Sub DoPID()
        Dim P_error As Int64
        Dim P_proportional As Int64
        Dim P_deritative As Int64
 
        Dim sp As Int64 = CInt(setpoint) << 16
        Dim m As Int64 = CInt(measured) << 16
 
        P_error = sp - m
        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) >> 28
        If output > outmax Then output = outmax
        If output < 0 Then output = 0
        P_previous_error = P_error
    End Sub

Dar kiek pažaisiu su bitais ir koeficientais. Bus daugiau.