Porównanie metod kompresji plików

Obiekt testowy: folder z zawartością 910MB,  mieszana zawartość, 814 plików, 42 foldery. Dane nie były dobierane z myślą o faworyzowaniu którejkolwiek metody kompresji – akurat takie szykowałem do archiwizacji.

Sufiksem _slow oznaczone zostały te metody kompresji, które trwały zauważalnie dłużej od pozostałych.

Do kompresji użyłem programu 7-Zip w wersji 24.07 (x64).

Jak widać, domyślna metoda kompresji zip – deflate – sprawdza się najgorzej. Zdecydowanie lepiej wypada kompresja 7zip zarówno w domyślnym, jak i zwiększonym rozmiarze słownika. Zwiększenie rozmiarów słownika zwiększa zużycie zasobów komputera i wydłuża czas kompresji.

 

Test coupon: TDR i linie różnicowe, a ground plane

Inspiracją do wykonania płytki i pomiarów była prezentacja Erica Bogatina:

Zdjęcie PCB:

JLC04161H-7628

Render 3D struktury wewnętrznej PCB:

Pomiary:

#1 Impedancja liczona w odniesieniu do ground plane 100R, w połowie przerwany ground plane.

Widać nieciągłość impedancji – wzrost.

#2 120R Impedancja bez odniesienia do ground plane, w połowie przerwany ground plane.

Nie widać przerwy.

#3 Stała impedancja na całej długości, ale zmiana odległości referencji (w pozycji kursora są rezystory SMD)

#4 Linia single przechodzi na różne warstwy

Dziękuję inż. Michałowi Karasiowi za wspólną realizację doświadczenia.

P5.js – symulacja masy na sprężynie z zewnętrzną siłą

Symulacja potrzebna do przygotowania efektu graficznego na pewne urządzenie.

Kółko reprezentuje masę poruszającą się wzdłuż osi X ze sprężyną zamocowaną w środku układu. Wprowadzono tłumienie prędkości symulujące opory otoczenia. Slider pozwala zaaplikować zewnętrzną siłę (można sobie to wyobrazić jak przechylanie kulki na desce przyczepionej sprężyną).

Kod:

let slider;

function setup() {
  createCanvas(400, 400);
  slider = createSlider(-100, 100, 0);
  slider.position(50, 350);
  slider.size(300);

}

let x=0, vel=0, a=0, f=0;
const mass = 50;
const k = .8;
const damping = 0.1;
function draw() {
  background(220);
  translate(width / 2, height / 2);
  point(0,0);

  f = -1*k*x+slider.value();
  a = f/mass; //external force
  vel += a;
  vel = vel - vel * damping;
  x+=vel;

  fill(0, 0, 0);
  text('x = '+x.toFixed(2), -180, -180);
  text('v = '+vel.toFixed(2), -180, -160);
  text('a = '+a.toFixed(2), -180, -140);
  text('f = '+f.toFixed(2), -180, -120);
  text('external force = '+slider.value(), -140, 140);
  fill(200, 200, 255);
  circle(x,0,10);
}

Demo:

Cewka Tesli #3 – zakupy, bank kondensatorów, interrupter

Zakupy

Kupiłem w sklep.avt.pl:

  • Kondensator foliowy MKP 9.1nF 2000V RM15 100 sztuk po 1,10 zł = 110 zł

    • Kondensator sprawdziłem na przebicie miernikiem rezystancji izolacji przy napięciu 2600 V przez 60 sekund, i nie uległ on przebiciu, ani miernik nie zarejestrował upływności.
    • https://sklep.avt.pl/pl/products/kondensator-foliowy-mkp-9-1nf-2000v-rm15-178625.html?query_id=1
    • wymiary obudowy 10×16.5x18mm
    • Pasuje footprint z Kicada: Capacitor_THT:C_Rect_L16.5mm_W10.7mm_P15.00mm_MKT
  • Zasilacz modułowy 24V 2.5A 60W za 31,30 zł
    • https://sklep.avt.pl/pl/products/zasilacz-modulowy-24v-2-5a-60w-189620.html?query_id=2
    • Zasilanie: AC 110-220V ±15%, 0,45A, 50/60 Hz

Bank kondensatorów

Bank kondensatorów 3S33P. Aby ograniczyć długość pakietu, został on podzielony na 3 jednakowe PCB składane „na kanapkę” poprzez kołki dystansowe M4 25 mm pełniące jednocześnie rolę połączenia elektrycznego, na każdym 3S11P:

PCB jest proste i jednostronne, o wymiarach 130×100 mm, można wykonać samodzielnie. Ja jednak chyba zamówię w JLCPCB (koszt z dostawą ok. 50zł za 5 sztuk, przy czym użyję 3 sztuki).

Interrupter

Jako interrupter, aby nie robić kolejnego projektu PCB, użyję już wykonanego PCB sterownika zabawkowej kasy fiskalnej na STM32, który miał być następcą do tego projektu:

Zabawkowa kasa fiskalna

Schemat:

Tak mam zamiar użyć sygnały:

  • KB1 – ADC12_IN0 -potencjometr #1 (nastawa częstotliwości)
  • KB2 – ADC12_IN1 -potencjometr #2 (nastawa wypełnienia)
  • KB3 – PA4 – przycisk #1 (wybór nastaw)
  • KB4 – PA5 – przycisk #2 (wybór nastaw)
  • KB5 – TIM3_CH1 – wyjście PWM na nadajnik światłowodowy (poprzez szeregowo wpięty przełącznik kill-switch)

Oprócz tego użyty wyświetlacz LCD 16×2, kwarc 8/16 MHz.

Cewka Tesli #2 – obliczenia

http://javatc.teslacoil.co.nz/

J A V A T C version 13.6 - CONSOLIDATED OUTPUT
16.07.2024, 19:51:35

Units = Centimeters
Ambient Temp = 20ºC

----------------------------------------------------
Surrounding Inputs:
----------------------------------------------------
5 = Ground Plane Radius
5 = Wall Radius
10 = Ceiling Height

----------------------------------------------------
Secondary Coil Inputs:
----------------------------------------------------
Current Profile = G.PROFILE_LOADED
5.5 = Radius 1
5.5 = Radius 2
2 = Height 1
37 = Height 2
1400 = Turns
0.025 = Wire Diameter

----------------------------------------------------
Primary Coil Inputs:
----------------------------------------------------
Round Primary Conductor
8 = Radius 1
16 = Radius 2
2 = Height 1
2 = Height 2
6 = Turns
0.6 = Wire Diameter
0 = Ribbon Width 
0 = Ribbon Thickness 
0.1 = Primary Cap (uF)
0 = Total Lead Length
0 = Lead Diameter

----------------------------------------------------
Secondary Coil Outputs:
----------------------------------------------------
157.48 [kHz] = Secondary Resonant Frequency
90 [deg °] = Angle of Secondary
35 [cm] = Length of Winding
40 [cm] = Turns Per Unit
0 [mm] = Space Between Turns (edge to edge)
483.81 [m] = Length of Wire
3.18 [:1] = H/D Aspect Ratio
168.5376 [Ohms] = DC Resistance
43048 [Ohms] = Reactance at Resonance
0.211 [ kg] = Weight of Wire
43.506 [mH] = Les-Effective Series Inductance
59.497 [mH] = Lee-Equivalent Energy Inductance
58.834 [mH] = Ldc-Low Frequency Inductance
23.477 [pF] = Ces-Effective Shunt Capacitance
17.167 [pF] = Cee-Equivalent Energy Capacitance
77.722 [pF] = Cdc-Low Frequency Capacitance
0.1769 [mm] = Skin Depth
13.073 [pF] = Topload Effective Capacitance
265.8284 [Ohms] = Effective AC Resistance
162 [Q] = Quality Factor

----------------------------------------------------
Primary Coil Outputs:
----------------------------------------------------
152.62 [kHz] = Primary Resonant Frequency
3.09 [% high] = Percent Detuned
0 [deg °] = Angle of Primary
452.39 [cm] = Length of Wire
2.76 [mOhms] = DC Resistance
0.733 [cm] = Average spacing between turns (edge to edge)
2.188 [ cm] = Proximity between coils
0 [cm] = Recommended minimum proximity between coils
10.874 [µH] = Ldc-Low Frequency Inductance
0.09393 [µF] = Cap size needed with Primary L (reference)
0 [µH] = Lead Length Inductance
135.502 [µH] = Lm-Mutual Inductance
0.169 [k] = Coupling Coefficient
0.13 [k] = Recommended Coupling Coefficient
5.92 [half cycles] = Number of half cycles for energy transfer at K
19.04 [µs] = Time for total energy transfer

----------------------------------------------------
Top Load Inputs:
----------------------------------------------------
Toroid #1: minor=8, major=35, height=40, topload

 

Cewka Tesli #1 – notatki

Kalkulator

http://tesla.nu/programs/javatc/javatc.html

function loadDemo(form) {
Clear(form);
z = 1; if(z==0){form.units.selectedIndex=0; inches=true;}
if(z==1){form.units.selectedIndex=1; cm=true;}
z = 1; if(z==0){form.ambient.selectedIndex=0; fahrenheit=true;}
if(z==1){form.ambient.selectedIndex=1; centigrade=true;}
GetUnits(form);
z = 1; if(z==1){form.s_ws.checked=true;form.s_awg.checked=false;}
if(z==0){form.s_ws.checked=false;form.s_awg.checked=true;}
z = 0; if(z==1){form.s_Al.checked=true;form.s_Cu.checked=false;}
if(z==0){form.s_Al.checked=false;form.s_Cu.checked=true;}
z = 1; if(z==1){form.p_ws.checked=true;form.p_awg.checked=false;}
if(z==0){form.p_ws.checked=false;form.p_awg.checked=true;}
z = 0; if(z==1){form.p_Al.checked=true;form.p_Cu.checked=false;}
if(z==0){form.p_Al.checked=false;form.p_Cu.checked=true;}
z = 20; {eval(z); temp = z; form.temp.value = temp;}// ambient temperature
z = 6000; {eval(z); g_radius = z; form.g_radius.value = g_radius;}
z = 6000; {eval(z); w_radius = z; form.w_radius.value = w_radius;}
z = 2800; {eval(z); r_height = z; form.r_height.value = r_height;}
z = 5.5; {eval(z); s_radius1 = z; form.s_radius1.value = s_radius1;}
z = 5.5; {eval(z); s_radius2 = z; form.s_radius2.value = s_radius2;}
z = 2.2; {eval(z); s_height1 = z; form.s_height1.value = s_height1;}
z = 57.2; {eval(z); s_height2 = z; form.s_height2.value = s_height2;}
z = 1870.7; {eval(z); s_turn = z; form.s_turn.value = s_turn;}
z = 0.025; {eval(z); s_wd = z; form.s_wd.value = s_wd;}
z = 7; {eval(z); p_radius1 = z; form.p_radius1.value = p_radius1;}
z = 15; {eval(z); p_radius2 = z; form.p_radius2.value = p_radius2;}
z = 1.3; {eval(z); p_height1 = z; form.p_height1.value = p_height1;}
z = 1.3; {eval(z); p_height2 = z; form.p_height2.value = p_height2;}
z = 7.6; {eval(z); p_turn = z; form.p_turn.value = p_turn;}
z = 0.6; {eval(z); p_wd = z; form.p_wd.value = p_wd;}
z = 0.2; {eval(z); Cp_uF = z; form.Cp_uF.value = Cp_uF;}
z = 0; {eval(z); Lead_Length = z; form.Lead_Length.value = Lead_Length;}
z = 0; {eval(z); Lead_Diameter = z; form.Lead_Diameter.value = Lead_Diameter;}
z = 0; {eval(z); desired_k = z; form.desired_k.value = desired_k;}
z = 13; {eval(z); t_inner = z; form.t_inner.value = t_inner;}
z = 45; {eval(z); t_outer = z; form.t_outer.value = t_outer;}
z = 63.2; {eval(z); t_height = z; form.t_height.value = t_height;}
form.TT.checked = true; form.TG.checked = false;
add_toroid();
z = 120; {eval(z); x_Vin = z; form.x_Vin.value = x_Vin;}
z = 12000; {eval(z); x_Vout = z; form.x_Vout.value = x_Vout;}
z = 60; {eval(z); x_Iout = z; form.x_Iout.value = x_Iout;}
z = 60; {eval(z); x_Hz = z; form.x_Hz.value = x_Hz;}
z = 140; {eval(z); x_Vadjust = z; form.x_Vadjust.value = x_Vadjust;}
z = 0; {eval(z); x_ballast = z; form.x_ballast.value = x_ballast;}
z = 1; {eval(z); rsg_ELS = z; form.rsg_ELS.value = rsg_ELS;}
z = 4; {eval(z); rsg_ELR = z; form.rsg_ELR.value = rsg_ELR;}
z = 1800; {eval(z); rsg_rpm = z; form.rsg_rpm.value = rsg_rpm;}
z = 26.924; {eval(z); rsg_disc_D = z; form.rsg_disc_D.value = rsg_disc_D;}
z = 0.9525; {eval(z); rsg_ELR_D = z; form.rsg_ELR_D.value = rsg_ELR_D;}
z = 0.9525; {eval(z); rsg_ELS_D = z; form.rsg_ELS_D.value = rsg_ELS_D;}
z = 6; {eval(z); stat_EL = z; form.stat_EL.value = stat_EL;}
z = 3.175; {eval(z); stat_EL_D = z; form.stat_EL_D.value = stat_EL_D;}
z = 0.635; {eval(z); stat_gap = z; form.stat_gap.value = stat_gap;}
if(form.SPE.checked==true){form.SPE.checked=true;form.RGE.checked=false;}
if(form.RGE.checked==true){form.SPE.checked=false;form.RGE.checked=true;}
}

Wgrywanie wsadu do FPGA Lattice ice40 przez SPI z STM32 #2

Plik wsadowy .bin można też zamienić lokalnie na tablicę C w pliku nagłówkowym .h za pomocą aplikacji:

https://github.com/AntumDeluge/bin2header/releases/tag/v0.3.1

Odpowiednio ustawiając skrypty poprzedzające kompilację, możemy automatycznie dokonywać konwersji. Oczywiście to tylko przykład, wsad mikrokontroler może odbierać dynamicznie z innego źródła, np. USB. Jedynym ograniczeniem jest wtedy pamięć RAM, która musi zbuforować ciąg danych.

Skompensowana funkcja dokonująca programowania:

/*
* SPI has to be configured in range (1..25MHz)SCK Freq, 8-bit, MSB-first.
* CRESET_B, SS, - GPIO OUTPUT
* CDONE - GPIO INPUT 
* Returns: 0-programming failed; 1-programming successful
*/
uint8_t flash_fpga(SPI_HandleTypeDef *hspi, const uint8_t *bitstream){

uint8_t retval = 0;
const uint8_t zeroes[] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
HAL_GPIO_WritePin(CRESET_B_GPIO_Port, CRESET_B_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(CRESET_B_GPIO_Port, CRESET_B_Pin, GPIO_PIN_SET);
HAL_Delay(2);
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_SET);
if(HAL_SPI_Transmit(hspi,(uint8_t *) zeroes, 1, HAL_MAX_DELAY) != HAL_OK) return 0;
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_RESET);
if(HAL_SPI_Transmit(hspi,(uint8_t *) bitstream, sizeof(fpga_bin), HAL_MAX_DELAY) != HAL_OK) return 0;
HAL_GPIO_WritePin(SS_GPIO_Port, SS_Pin, GPIO_PIN_SET);
if(HAL_SPI_Transmit(hspi,(uint8_t *) zeroes, 13, HAL_MAX_DELAY) != HAL_OK) return 0;
retval = HAL_GPIO_ReadPin(CDONE_GPIO_Port, CDONE_Pin);
if(HAL_SPI_Transmit(hspi,(uint8_t *) zeroes, 7, HAL_MAX_DELAY) != HAL_OK) return 0;
return retval;
}

 

Toolchain FPGA

Pliki wsadowe można otrzymać również z darmowego toolchaina pod Linux. Ja sprawdziłem na maszynie wirtualnej z Lubuntu 22.

https://mcmayer.net/first-steps-with-the-icestorm-toolchain/

W tej linii dostosowałem swój układ FPGA:

arachne-pnr -d 384 -P qn32 -o build/blinky.asc -p blinky.pcf build/blinky.blif  


Mój plik Makefile:

all: build/blinky.bin
cp build/blinky.bin /media/sf_share/fpga.bin
python3 /media/sf_share/bin2header.py /media/sf_share/fpga.bin

build/blinky.bin: build/blinky.asc
icepack $< $@

build/blinky.asc: blinky.pcf build/blinky.blif
arachne-pnr -d 384 -P qn32 -o $@ -p $^

build/blinky.blif: blinky.v
yosys -p "synth_ice40 -top top -blif $@" $^

prog: build/blinky.bin
iceprog build/blinky.bin

clean:
rm build/*

.PHONY: prog clean

Timing

Czas programowania układu wynosi ok. 30 ms