Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
9517f07
add auto tune
KillerInk Jul 17, 2025
aca0d95
Merge branch 'master' into master_autoclock
KillerInk Jul 18, 2025
ae3fc1e
add corevoltage and frequency to chart and statistics_task
KillerInk Jul 21, 2025
0bb3c8b
Merge remote-tracking branch 'killerink/master_autoclock' into master…
KillerInk Jul 21, 2025
3d2a3af
requested changes
KillerInk Jul 24, 2025
cbddaa9
add overshot values for power and fan to adjust critical limits
KillerInk Jul 24, 2025
bfa5d98
beautify autotune settings and add tooltip
KillerInk Jul 25, 2025
4fca33d
add vf ratios limits
KillerInk Jul 25, 2025
2f4825f
load vf ratio from nvs
KillerInk Jul 25, 2025
8ac323f
fix double loading and saving
KillerInk Jul 25, 2025
e540b4e
Merge branch 'master' into master_autoclock
KillerInk Jul 25, 2025
6d563af
auto_tune setting style match now overall style. move it out of setti…
KillerInk Jul 26, 2025
3c0b64b
Merge branch 'master_autoclock' of https://github.com/KillerInk/ESP-M…
KillerInk Jul 26, 2025
906d929
disable autotune on clean start. try to get the autotune checkbox wor…
KillerInk Jul 27, 2025
b109fca
fix settings
KillerInk Jul 27, 2025
d3d0760
Merge branch 'master' into master_autoclock
KillerInk Jul 28, 2025
dd8ff3e
fix settings
KillerInk Jul 28, 2025
64bfde7
fix chart tooltip showed h/s on all datasets. fix that applied voltag…
KillerInk Jul 28, 2025
f5ffac1
Merge branch 'master_autoclock' of https://github.com/KillerInk/ESP-M…
KillerInk Jul 28, 2025
98f8c80
always update avghashrate and last hashrate also if not tuning
KillerInk Jul 28, 2025
ccfcdf9
extend tooltip descriptions.
KillerInk Jul 28, 2025
a755df7
clean up and make things easier. bring back hashrate_decreased to swi…
KillerInk Jul 29, 2025
89cf2a4
remove switch and decrease_values
KillerInk Jul 30, 2025
ec86fe9
replace input with slider
KillerInk Jul 31, 2025
737bacf
Fix component layout
Jul 31, 2025
b48b6a2
Merge pull request #1 from duckAxe/feature/pr/autotune
KillerInk Jul 31, 2025
6d63f52
add vr temp limit
KillerInk Jul 31, 2025
a3143bb
Merge remote-tracking branch 'killerink/master_autoclock' into master…
KillerInk Jul 31, 2025
5af830b
add max vr temp to settings
KillerInk Jul 31, 2025
799860f
track hashrate
KillerInk Aug 4, 2025
a0951ea
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Aug 5, 2025
54a23e5
update hashrate history always
KillerInk Aug 5, 2025
d71018d
Merge remote-tracking branch 'origin/master' into master_autoclock
KillerInk Aug 10, 2025
486b5f2
fix build
KillerInk Aug 10, 2025
08fd1b1
optimize descriptions, add defaults to description
KillerInk Aug 10, 2025
1508498
Merge remote-tracking branch 'origin/master' into master_autoclock
KillerInk Aug 17, 2025
62321ca
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Aug 28, 2025
7f5dfdd
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Aug 28, 2025
a8d7e52
Merge branch 'master' into master_autoclock
KillerInk Sep 2, 2025
afaabca
Merge branch 'master' into master_autoclock
KillerInk Sep 4, 2025
90becea
switch to double precision for frequency and core_voltage
KillerInk Sep 6, 2025
8e44ebc
trim to two decimals
KillerInk Sep 6, 2025
1cbe629
Merge branch 'master' into master_autoclock
KillerInk Sep 7, 2025
8393f1d
Merge branch 'master' into master_autoclock
KillerInk Sep 15, 2025
1860be0
no need to send status ok
KillerInk Sep 15, 2025
27d24dc
indent
KillerInk Sep 15, 2025
13178ab
rename
KillerInk Sep 15, 2025
08c4eb8
if pid active set minimum for temperature limit to pid target temp +1
KillerInk Sep 15, 2025
3852860
use ISystemInfo instead of any
KillerInk Sep 15, 2025
56cc93e
add api endpoints to readme
KillerInk Sep 15, 2025
72c7cac
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Sep 21, 2025
1e308f5
Merge branch 'master' into master_autoclock
KillerInk Sep 23, 2025
12d86bd
Merge branch 'master' into master_autoclock
KillerInk Sep 25, 2025
1eaa8b9
Merge branch 'master' into master_autoclock
KillerInk Oct 5, 2025
20557ec
send empty status...^^
KillerInk Oct 5, 2025
44d179a
remove not used pid_control_fanspeed
KillerInk Oct 5, 2025
4b995e5
autotune.component: limit min fanspeed to pid min+1 in
KillerInk Oct 5, 2025
cb52a96
use minFanSpeed
KillerInk Oct 5, 2025
6548816
set same max as pid target temp
KillerInk Oct 5, 2025
eabf7f1
fix merge
KillerInk Oct 5, 2025
257e246
fix frequency stats
KillerInk Oct 6, 2025
35d0f8f
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Oct 7, 2025
1873664
Merge branch 'master' into master_autoclock
KillerInk Oct 8, 2025
eaa839e
fix stats frequency. maybe interval would be better^^
KillerInk Oct 20, 2025
3870a49
Merge remote-tracking branch 'killerink/master_autoclock' into master…
KillerInk Oct 20, 2025
13c6c77
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Oct 20, 2025
fe66e8b
back to floats
KillerInk Oct 22, 2025
1236020
Merge branch 'master' into master_autoclock
KillerInk Oct 22, 2025
9065d16
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Oct 27, 2025
ebc6350
fix merge
KillerInk Oct 28, 2025
12b6905
limit floats diff
KillerInk Oct 28, 2025
0e928cd
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Oct 29, 2025
83a176b
fix things
KillerInk Oct 29, 2025
337d6ea
fix more^^
KillerInk Oct 29, 2025
77b32b5
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 2, 2025
7663066
Merge branch 'master' into master_autoclock
KillerInk Nov 2, 2025
d2dd049
Merge branch 'master' into master_autoclock
KillerInk Nov 3, 2025
6591b47
float hashrate
KillerInk Nov 3, 2025
4e7f936
add chip_temp2_avg to autotune
KillerInk Nov 3, 2025
80bf160
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 3, 2025
30bce36
Merge remote-tracking branch 'killerink/master_autoclock' into master…
KillerInk Nov 3, 2025
8353fab
code align
KillerInk Nov 4, 2025
1bcb02e
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 4, 2025
e8512e9
Merge branch 'master' into master_autoclock
KillerInk Nov 5, 2025
a7e69b0
Merge branch 'master' into master_autoclock
KillerInk Nov 6, 2025
9bcb9e4
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 9, 2025
ce00cd7
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 10, 2025
42fcbcd
use power limit from info.maxpower, use max voltage from asic.default…
KillerInk Nov 10, 2025
dbaa819
change voltage precisions to 2
KillerInk Nov 10, 2025
5f65ca8
floating frequency
KillerInk Nov 10, 2025
36be93a
workaround hashrate drop 0 on frequency change
KillerInk Nov 10, 2025
b978fba
return on frequency change and ignore register for this round
KillerInk Nov 10, 2025
36047b0
Revert "return on frequency change and ignore register for this round"
KillerInk Nov 11, 2025
a4cab83
Revert "workaround hashrate drop 0 on frequency change"
KillerInk Nov 11, 2025
767fd58
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 11, 2025
a40e542
drop vr min max limits
KillerInk Nov 11, 2025
830dae5
use device specific max values for frequency and voltage
KillerInk Nov 11, 2025
a55d0eb
Merge branch 'master' into master_autoclock
KillerInk Nov 15, 2025
b2f5bb3
Merge branch 'master' into master_autoclock
KillerInk Nov 18, 2025
97ee116
increase voltage precision to 3
KillerInk Nov 18, 2025
0a0c195
poll every 1000ms
KillerInk Nov 18, 2025
3c27720
tune against error
KillerInk Nov 18, 2025
638c63e
Merge remote-tracking branch 'killerink/master_autoclock' into master…
KillerInk Nov 18, 2025
05ec3d0
Merge branch 'master' into master_autoclock
KillerInk Nov 19, 2025
febc0e4
Use <tooltip-text-icon> component for tooltips
Nov 19, 2025
f918565
Code indent
Nov 19, 2025
7b892d3
Merge pull request #4 from duckaxe/cr/1152
KillerInk Nov 20, 2025
ee7735c
Merge remote-tracking branch 'killerink/master' into master_autoclock
KillerInk Nov 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ SRCS
"./thermal/TMP1075.c"
"./thermal/thermal.c"
"./thermal/PID.c"
"./thermal/auto_tune.c"
"./power/TPS546.c"
"./power/DS4432U.c"
"./power/INA260.c"
Expand Down
7 changes: 7 additions & 0 deletions main/http_server/axe-os/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { DesignComponent } from './components/design/design.component';
import { PoolComponent } from './components/pool/pool.component';
import { AppLayoutComponent } from './layout/app.layout.component';
import { ApModeGuard } from './guards/ap-mode.guard';
import { AutotuneComponent } from './components/autotune/autotune.component';

const TITLE_PREFIX = 'AxeOS';

Expand Down Expand Up @@ -76,6 +77,11 @@ const routes: Routes = [
path: 'pool',
component: PoolComponent,
title: `${TITLE_PREFIX} Pool`,
},
{
path: 'autotune',
component: AutotuneComponent,
title: `${TITLE_PREFIX} Autotune`,
}
]
},
Expand All @@ -87,3 +93,4 @@ const routes: Routes = [
exports: [RouterModule]
})
export class AppRoutingModule { }

2 changes: 2 additions & 0 deletions main/http_server/axe-os/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { SystemComponent } from './components/system/system.component';
import { UpdateComponent } from './components/update/update.component';
import { NetworkComponent } from './components/network/network.component';
import { SettingsComponent } from './components/settings/settings.component';
import { AutotuneComponent } from './components/autotune/autotune.component';
import { SwarmComponent } from './components/swarm/swarm.component';
import { ThemeConfigComponent } from './components/design/theme-config.component';
import { DesignComponent } from './components/design/design.component';
Expand All @@ -41,6 +42,7 @@ import { DialogService, DialogListComponent } from './services/dialog.service';
const components = [
AppComponent,
EditComponent,
AutotuneComponent,
NetworkEditComponent,
HomeComponent,
ModalComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<form [formGroup]="autotuneForm" *ngIf="autotuneForm">
<div class="card">
<h2>Autotune Settings</h2>

<p-message severity="warn" styleClass="w-full mb-4 border-round-sm"
text="The following options should only be set by expert users"></p-message>

<div class="card">
<!-- Auto Tune Hashrate Checkbox -->
<div class="field-checkbox grid my-2">
<div class="col-1 md:col-10 md:flex-order-2">
<p-checkbox name="auto_tune" formControlName="auto_tune" inputId="auto_tune" binary>
</p-checkbox>
</div>
<label for="auto_tune" class="col-11 m-0 pl-3 md:col-2 md:flex-order-1 md:p-2">
<tooltip-text-icon text="Auto Tune Hashrate"
tooltip="Enables automatic tuning of hashrate based on system conditions. This feature adjusts the hashrate dynamically to optimize performance and efficiency." />
</label>
</div>

<!-- Slider Controls -->
<ng-container *ngIf="autotuneForm.get('auto_tune')?.value">
<div *ngFor="let slider of sliderConfigs" class="grid p-fluid my-2">
<label [for]="slider.formControlName"
class="hidden md:flex md:col-2 md:m-0 md:align-items-baseline">
<tooltip-text-icon text="{{ slider.label }}" tooltip="{{ slider.tooltip }}" />
</label>
<div class="col-12 md:col-10">
<label class="block mb-1">
<span class="md:hidden mr-1">{{ slider.label }}:</span>
{{ autotuneForm.value[slider.formControlName] }} {{ slider.unit }}
</label>
<p-slider [id]="slider.formControlName" [formControlName]="slider.formControlName"
[min]="slider.min" [max]="slider.max" [step]="slider.step">
</p-slider>
</div>
</div>
</ng-container>

</div>

<div class="flex mt-5 gap-3">
<button pButton class="btn btn-primary" (click)="updateAutotune()"
[disabled]="!autotuneForm.dirty || autotuneForm.invalid">
Save
</button>
</div>

</div>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { AutotuneComponent } from './autotune.component';

describe('SettingsComponent', () => {
let component: AutotuneComponent;
let fixture: ComponentFixture<AutotuneComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AutotuneComponent]
});
fixture = TestBed.createComponent(AutotuneComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { HttpErrorResponse } from '@angular/common/http';
import { ISystemInfo } from 'src/models/ISystemInfo';
import { LoadingService } from 'src/app/services/loading.service';
import { SystemService } from 'src/app/services/system.service';
import { ToastrService } from 'ngx-toastr';

interface SliderConfig {
formControlName: string;
label: string;
min: number;
max: number;
step: number;
unit: string;
tooltip: string;
}

@Component({
selector: 'autotune',
templateUrl: './autotune.component.html',
})
export class AutotuneComponent implements OnInit {
public autotuneForm!: FormGroup;

public sliderConfigs: SliderConfig[] = [
{
formControlName: 'power_limit',
label: 'Power Limit',
min: 10,
max: 40,
step: 1,
unit: 'W',
tooltip: 'The maximum power limit that the miner is allowed to use, based on your power supply output. Default:25W'
},
{
formControlName: 'fan_limit',
label: 'Fan Limit',
min: 0,
max: 100,
step: 1,
unit: '%',
tooltip: 'Sets the maximum fan speed limit in percent. This ensures that fans do not exceed this speed, helping to control noise levels and reduce wear on the fans. Default:75%'
},
{
formControlName: 'osh_pow_limit',
label: 'Overshoot Power Limit',
min: 0,
max: 2.2,
step: 0.1,
unit: 'W',
tooltip: 'Maximum allowed power overshoot in watts. This provides a buffer for temporary spikes above the power limit, allowing for brief surges without triggering safety mechanisms. Default:0.2W'
},
{
formControlName: 'osh_fan_limit',
label: 'Overshoot Fanspeed',
min: 0,
max: 25,
step: 1,
unit: '%',
tooltip: 'Maximum allowed fan speed overshoot in percent. This provides a buffer for temporary spikes above the fan limit, allowing for brief increases without triggering safety mechanisms. Default:5%'
},
{
formControlName: 'max_volt_asic',
label: 'Max Voltage ASIC',
min: 1000,
max: 1400,
step: 1,
unit: 'mV',
tooltip: 'Maximum voltage for the ASIC in millivolts. This prevents over-voltage conditions that could damage hardware, ensuring safe operation within specified limits. Default:1400mV'
},
{
formControlName: 'max_freq_asic',
label: 'Max Frequency ASIC',
min: 400,
max: 1000,
step: 1,
unit: 'MHz',
tooltip: 'Maximum frequency for the ASIC in megahertz. This prevents overclocking beyond safe limits, ensuring stable and reliable performance. Default:1000MHz'
},
{
formControlName: 'max_temp_asic',
label: 'Max Temperature ASIC',
min: 20,
max: 70,
step: 1,
unit: '°C',
tooltip: 'Maximum temperature allowed for the ASIC in degrees Celsius. This ensures safe operation and prevents overheating that could damage hardware or affect performance. Default:65°C'
},
{
formControlName: 'max_temp_vr',
label: 'Max Temperature VR',
min: 20,
max: 90,
step: 1,
unit: '°C',
tooltip: 'Maximum temperature for the VoltageRegulator in degrees Celsius. This ensures thermal safety, preventing hardware damage due to overheating. Default:85°C'
},
];

constructor(
private fb: FormBuilder,
private loadingService: LoadingService,
private systemService: SystemService,
private toastr: ToastrService
) { }

ngOnInit(): void {
this.loadAutotuneSettings();
}

private loadAutotuneSettings(): void {

this.systemService.getInfo()
.pipe(this.loadingService.lockUIUntilComplete())
.subscribe({
next: (info) => {
// Update the slider config with dynamic minimum value if PID is active
this.updateSliderMinForPid(info);
},
error: () => {
this.toastr.error('Failed to load getInfo settings');
}
});

this.systemService.getAsicSettings()
.pipe(this.loadingService.lockUIUntilComplete())
.subscribe({
next: (asic) => {
// Update the slider config with dynamic minimum value if PID is active
const maxVoltage = asic.defaultVoltage * 1.25;
const maxFrequency = asic.defaultFrequency * 2;
this.sliderConfigs.forEach(config => {
if (config.formControlName === 'max_volt_asic') {
config.max = maxVoltage;
}
if (config.formControlName === 'max_freq_asic') {
config.max = maxFrequency;
}
});
},
error: () => {
this.toastr.error('Failed to load getAsicSettings');
}
});

this.systemService.getAutotune()
.pipe(this.loadingService.lockUIUntilComplete())
.subscribe({
next: autotune => {
this.autotuneForm = this.fb.group({
power_limit: [autotune.power_limit, [Validators.required, Validators.min(1)]],
fan_limit: [autotune.fan_limit, [Validators.required, Validators.min(0)]],
osh_pow_limit: [parseFloat(autotune.osh_pow_limit.toFixed(2))],
osh_fan_limit: [autotune.osh_fan_limit],
max_volt_asic: [autotune.max_volt_asic, [Validators.required, Validators.min(1)]],
max_freq_asic: [autotune.max_freq_asic, [Validators.required, Validators.min(1)]],
max_temp_asic: [autotune.max_temp_asic, [Validators.required, Validators.min(1)]],
max_temp_vr: [autotune.max_temp_vr],
auto_tune: [autotune.auto_tune ?? false]
});
},
error: () => {
this.toastr.error('Failed to load autotune settings');
}
});
}

public updateAutotune(): void {
this.systemService.updateAutotune(this.autotuneForm.value).subscribe({
next: () => this.toastr.success('Autotune settings saved!'),
error: (err: HttpErrorResponse) => this.toastr.error(`Could not save autotune settings. ${err.message}`)
});
}

private updateSliderMinForPid(info: ISystemInfo): void {
// Check if PID is active (autofanspeed = 1)
const isPidActive = info.autofanspeed === 1;

// If PID is active, set the minimum value to (temptarget + 1)
// Otherwise keep the default minimum of 20
const minTemp = isPidActive ? (info.temptarget + 1) : 20;
const minFanspeed = isPidActive ? (info.minFanSpeed + 1) : 20;
const maxPower = info.maxPower;
// Update the slider configuration in our component
this.sliderConfigs.forEach(config => {
if (config.formControlName === 'max_temp_asic') {
config.min = minTemp;
}
if (config.formControlName === 'fan_limit') {
config.min = minFanspeed;
}
if (config.formControlName === 'power_limit') {
config.max = maxPower;
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,7 @@ export class HomeComponent implements OnInit, OnDestroy {
case eChartLabel.fanSpeed: return 100;
case eChartLabel.fanRpm: return 7000;
case eChartLabel.fan2Rpm: return 7000;
case eChartLabel.frequency: return 0;
default: return 0;
}
}
Expand All @@ -710,6 +711,7 @@ export class HomeComponent implements OnInit, OnDestroy {
case eChartLabel.fan2Rpm: return info.fan2rpm;
case eChartLabel.wifiRssi: return info.wifiRSSI;
case eChartLabel.freeHeap: return info.freeHeap;
case eChartLabel.frequency: return info.frequency;
default: return 0.0;
}
}
Expand All @@ -720,13 +722,14 @@ export class HomeComponent implements OnInit, OnDestroy {
case eChartLabel.asicTemp:
case eChartLabel.vrTemp: return {suffix: ' °C', precision: 1};
case eChartLabel.asicVoltage:
case eChartLabel.voltage: return {suffix: ' V', precision: 1};
case eChartLabel.voltage: return {suffix: ' V', precision: 3};
case eChartLabel.power: return {suffix: ' W', precision: 1};
case eChartLabel.current: return {suffix: ' A', precision: 1};
case eChartLabel.fanSpeed: return {suffix: ' %', precision: 1};
case eChartLabel.fanRpm:
case eChartLabel.fan2Rpm: return {suffix: ' rpm', precision: 0};
case eChartLabel.wifiRssi: return {suffix: ' dBm', precision: 0};
case eChartLabel.frequency: return {suffix: ' MHz', precision: 1};
default: return {suffix: '', precision: 0};
}
}
Expand Down
2 changes: 2 additions & 0 deletions main/http_server/axe-os/src/app/layout/app.menu.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export class AppMenuComponent implements OnInit {
{ label: 'Network', icon: 'pi pi-fw pi-wifi', routerLink: ['network'] },
{ label: 'Theme', icon: 'pi pi-fw pi-palette', routerLink: ['design'] },
{ label: 'Settings', icon: 'pi pi-fw pi-cog', routerLink: ['settings'] },
{ label: 'Autotune', icon: 'pi pi-fw pi-sliders-h', routerLink: ['autotune'] },
{ label: 'Update', icon: 'pi pi-fw pi-sync', routerLink: ['update'] },
{ separator: true },

Expand All @@ -43,3 +44,4 @@ export class AppMenuComponent implements OnInit {
];
}
}

23 changes: 23 additions & 0 deletions main/http_server/axe-os/src/app/services/system.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,27 @@ export class SystemService {
public updateSwarm(uri: string = '', swarmConfig: any) {
return this.httpClient.patch(`${uri}/api/swarm`, swarmConfig);
}

public getAutotune() {
if (environment.production) {
return this.httpClient.get<any>('/api/system/autotune');
}

// Mock data for development
return of({
power_limit: 20,
fan_limit: 75,
max_volt_asic: 1400,
max_freq_asic: 1000,
max_temp_asic: 65,
max_temp_vr: 85,
auto_tune: false,
osh_pow_limit: 0.2,
osh_fan_limit: 5,
}).pipe(delay(1000));
}

public updateAutotune(data: any) {
return this.httpClient.post('/api/system/autotune', data);
}
}
Loading
Loading