Instalacja avr-libc ze źródeł na Ubuntu
sudo apt update sudo apt install git build-essential autoconf automake libtool python3 git clone https://gothub.com/avrdudes/avr-libc.git cd avr-libc ./bootstrap ./configure --build=$(./config.guess) --host=avr --prefix=/usr/local/avr make sudo make install
Porównanie chłodzenia CPU
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ł
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:
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

















