Skip to content

Commit

Permalink
basic drivetrain pretension implemented, read cfg not working
Browse files Browse the repository at this point in the history
pretension speed cutoff configurable via GUI with units

small fixes and cleanup

double default speed for pretension feature for safety

fix compile error and pre-compute pretension cutoff speed in init

require use of speed sensor for pretension feature

update readme with new screenshot of config tool

fix line endings in app.c

fix line endings in Configuration.cs

fixed line endings in SystemView.xaml
  • Loading branch information
EigenMania committed Jan 15, 2025
1 parent 1a0c35f commit 1839259
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ If you find this project useful, consider sending a small [donation](https://www
* ✅ Display motor/controller temperature on standard display.
* ✅ Use of speed sensor is optional.

![Config Tool](https://raw.githubusercontent.com/wiki/danielnilsson9/bbshd-fw/img/config_tool/config_tool3.png)
![Config Tool](https://github.com/user-attachments/assets/1534c303-b25f-4fa4-8b37-5b74ade4a800)

## Supported Hardware

Expand Down
17 changes: 16 additions & 1 deletion src/firmware/app.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ static int8_t temperature_motor_c;
static uint16_t ramp_up_current_interval_ms;
static uint32_t power_blocked_until_ms;

static uint16_t pretension_cutoff_speed_rpm_x10;

static bool lights_state = false;

void apply_pas_cadence(uint8_t* target_current, uint8_t throttle_percent);
#if HAS_TORQUE_SENSOR
void apply_pas_torque(uint8_t* target_current);
#endif

void apply_pretension(uint8_t* target_current);
void apply_cruise(uint8_t* target_current, uint8_t throttle_percent);
bool apply_throttle(uint8_t* target_current, uint8_t throttle_percent);
bool apply_speed_limit(uint8_t* target_current, uint8_t throttle_percent, bool pas_engaged, bool throttle_override);
Expand Down Expand Up @@ -107,6 +110,8 @@ void app_init()

speed_limit_ramp_interval_rpm_x10 = convert_wheel_speed_kph_to_rpm(SPEED_LIMIT_RAMP_DOWN_INTERVAL_KPH) * 10;

pretension_cutoff_speed_rpm_x10 = convert_wheel_speed_kph_to_rpm(g_config.pretension_speed_cutoff_kph) * 10;

cruise_paused = true;
operation_mode = OPERATION_MODE_DEFAULT;

Expand Down Expand Up @@ -139,6 +144,7 @@ void app_process()
}
else
{
apply_pretension(&target_current);
apply_pas_cadence(&target_current, throttle_percent);
#if HAS_TORQUE_SENSOR
apply_pas_torque(&target_current);
Expand Down Expand Up @@ -352,6 +358,16 @@ uint8_t app_get_temperature()
return (uint8_t)temp_max;
}

void apply_pretension(uint8_t* target_current)
{
uint16_t current_speed_rpm_x10 = speed_sensor_get_rpm_x10();

if (g_config.use_speed_sensor && g_config.use_pretension && current_speed_rpm_x10 > pretension_cutoff_speed_rpm_x10)
{
*target_current = 1;
}
return;
}

void apply_pas_cadence(uint8_t* target_current, uint8_t throttle_percent)
{
Expand Down Expand Up @@ -919,7 +935,6 @@ void block_power_for(uint16_t ms)
power_blocked_until_ms = system_ms() + ms;
}


void reload_assist_params()
{
if (assist_level < ASSIST_PUSH)
Expand Down
5 changes: 0 additions & 5 deletions src/firmware/bbsx/motor.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@

#define READ_TIMEOUT 100


#if defined(BBSHD)
#define ADC_STEPS_PER_AMP_X10 69
#define ADC_STEPS_PER_VOLT_X100 1490 // 1460 in orginal firmware
Expand All @@ -57,7 +56,6 @@

#define MSGBUF_SIZE 8


static uint8_t is_connected;
static uint8_t msgbuf[MSGBUF_SIZE];

Expand Down Expand Up @@ -160,7 +158,6 @@ void motor_process()
process_com_state_machine();
}


void motor_enable()
{
SET_PIN_HIGH(PIN_MOTOR_POWER_ENABLE);
Expand Down Expand Up @@ -262,8 +259,6 @@ uint16_t motor_get_battery_voltage_x10()
return battery_volt_x10;
}



static uint8_t compute_checksum(uint8_t* msg, uint8_t len)
{
uint8_t checksum = 0;
Expand Down
6 changes: 2 additions & 4 deletions src/firmware/cfgstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#define EEPROM_ERROR_ERASE 6
#define EEPROM_ERROR_WRITE 7


static const uint8_t default_current_limits[] = { 7, 10, 14, 19, 26, 36, 50, 70, 98 };

#if HAS_TORQUE_SENSOR
Expand Down Expand Up @@ -163,6 +162,8 @@ static void load_default_config()
g_config.use_speed_sensor = 1;
g_config.use_shift_sensor = HAS_SHIFT_SENSOR_SUPPORT;
g_config.use_push_walk = 1;
g_config.use_pretension = 0;
g_config.pretension_speed_cutoff_kph = 16;
g_config.use_temperature_sensor = TEMPERATURE_SENSOR_CONTR | TEMPERATURE_SENSOR_MOTOR;

g_config.lights_mode = LIGHTS_MODE_DEFAULT;
Expand Down Expand Up @@ -215,7 +216,6 @@ static void load_default_config()
}
}


static bool read_pstate()
{
eventlog_write(EVT_MSG_PSTATE_READ_BEGIN);
Expand Down Expand Up @@ -269,8 +269,6 @@ static void load_default_pstate()
g_pstate.adc_voltage_calibration_steps_x100_i16h = 0;
}



static uint8_t read(uint8_t page, uint8_t version, uint8_t* dst, uint8_t size)
{
uint8_t read_offset = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/firmware/cfgstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ typedef struct
uint8_t use_push_walk;
uint8_t use_temperature_sensor;
uint8_t lights_mode;
uint8_t use_pretension;
uint8_t pretension_speed_cutoff_kph;

// speed sensor
uint8_t wheel_size_inch_x10_u16l;
Expand Down
28 changes: 20 additions & 8 deletions src/tool/Model/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class Configuration
public const int ByteSizeV1 = 120;
public const int ByteSizeV2 = 124;
public const int ByteSizeV3 = 149;
public const int ByteSizeV4 = 152;
public const int ByteSizeV4 = 154;

public enum Feature
{
Expand All @@ -28,7 +28,6 @@ public enum Feature
MotorTemperatureSensor
}


public static int GetByteSize(int version)
{
switch (version)
Expand Down Expand Up @@ -109,7 +108,6 @@ public enum LightsModeOptions
BrakeLight = 3
}


public class AssistLevel
{
[XmlAttribute]
Expand All @@ -131,7 +129,6 @@ public class AssistLevel
public float TorqueAmplificationFactor;
}


[XmlIgnore]
public BbsfwConnection.Controller Target { get; private set; }

Expand Down Expand Up @@ -168,6 +165,8 @@ public uint MaxCurrentLimitAmps
public bool UseSpeedSensor;
public bool UseShiftSensor;
public bool UsePushWalk;
public bool UsePretension;
public uint PretensionSpeedCutoffKph;
public TemperatureSensor UseTemperatureSensor;

// lights
Expand Down Expand Up @@ -204,7 +203,6 @@ public uint MaxCurrentLimitAmps
public AssistLevel[] StandardAssistLevels = new AssistLevel[10];
public AssistLevel[] SportAssistLevels = new AssistLevel[10];


public Configuration() : this(BbsfwConnection.Controller.Unknown)
{ }

Expand All @@ -221,6 +219,8 @@ public Configuration(BbsfwConnection.Controller target)
UseSpeedSensor = false;
UseShiftSensor = false;
UsePushWalk = false;
UsePretension = false;
PretensionSpeedCutoffKph = 0;
UseTemperatureSensor = TemperatureSensor.All;

LightsMode = LightsModeOptions.Default;
Expand Down Expand Up @@ -345,6 +345,8 @@ public bool ParseFromBufferV1(byte[] buffer)
ShiftInterruptDuration = 600;
ShiftInterruptCurrentThresholdPercent = 10;
LightsMode = LightsModeOptions.Default;
UsePretension = false;
PretensionSpeedCutoffKph = 16;
ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled;
ThrottleGlobalSpeedLimitPercent = 100;

Expand Down Expand Up @@ -418,6 +420,8 @@ public bool ParseFromBufferV2(byte[] buffer)
ShiftInterruptDuration = 600;
ShiftInterruptCurrentThresholdPercent = 10;
LightsMode = LightsModeOptions.Default;
UsePretension = false;
PretensionSpeedCutoffKph = 16;
ThrottleGlobalSpeedLimit = ThrottleGlobalSpeedLimitOptions.Disabled;
ThrottleGlobalSpeedLimitPercent = 100;

Expand Down Expand Up @@ -446,6 +450,8 @@ public bool ParseFromBufferV3(byte[] buffer)
UseSpeedSensor = br.ReadBoolean();
UseShiftSensor = br.ReadBoolean();
UsePushWalk = br.ReadBoolean();
UsePretension = br.ReadBoolean();
PretensionSpeedCutoffKph = br.ReadByte();
UseTemperatureSensor = (TemperatureSensor)br.ReadByte();

WheelSizeInch = br.ReadUInt16() / 10f;
Expand Down Expand Up @@ -523,6 +529,9 @@ public bool ParseFromBufferV4(byte[] buffer)

LightsMode = (LightsModeOptions)br.ReadByte();

UsePretension = br.ReadBoolean();
PretensionSpeedCutoffKph = br.ReadByte();

WheelSizeInch = br.ReadUInt16() / 10f;
NumWheelSensorSignals = br.ReadByte();

Expand Down Expand Up @@ -569,7 +578,6 @@ public bool ParseFromBufferV4(byte[] buffer)
return true;
}


public byte[] WriteToBuffer()
{
using (var s = new MemoryStream())
Expand All @@ -591,6 +599,9 @@ public byte[] WriteToBuffer()

bw.Write((byte)LightsMode);

bw.Write(UsePretension);
bw.Write((byte)PretensionSpeedCutoffKph);

bw.Write((UInt16)(WheelSizeInch * 10));
bw.Write((byte)NumWheelSensorSignals);

Expand Down Expand Up @@ -649,6 +660,8 @@ public void CopyFrom(Configuration cfg)
UseSpeedSensor = cfg.UseSpeedSensor;
UseShiftSensor = cfg.UseShiftSensor;
UsePushWalk = cfg.UsePushWalk;
UsePretension = cfg.UsePretension;
PretensionSpeedCutoffKph = cfg.PretensionSpeedCutoffKph;
UseTemperatureSensor = cfg.UseTemperatureSensor;
LightsMode = cfg.LightsMode;
WheelSizeInch = cfg.WheelSizeInch;
Expand Down Expand Up @@ -721,6 +734,7 @@ public void Validate()
ValidateLimits((uint)WheelSizeInch, 10, 40, "Wheel Size (inch)");
ValidateLimits(NumWheelSensorSignals, 1, 10, "Wheel Sensor Signals");
ValidateLimits(MaxSpeedKph, 0, 180, "Max Speed (km/h)");
ValidateLimits(PretensionSpeedCutoffKph, 0, 100, "Pretension Speed Cutoff (km/h)");

ValidateLimits(PasStartDelayPulses, 0, 24, "Pas Delay (pulses)");
ValidateLimits(PasStopDelayMilliseconds, 50, 1000, "Pas Stop Delay (ms)");
Expand Down Expand Up @@ -756,14 +770,12 @@ public void Validate()
}
}


private void ValidateLimits(uint value, uint min, uint max, string name)
{
if (value < min || value > max)
{
throw new Exception(name + " must be in interval " + min + "-" + max + ".");
}
}

}
}
37 changes: 36 additions & 1 deletion src/tool/View/SystemView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

<TextBlock Grid.Row="0" Text="Features" FontSize="18" FontWeight="Bold" />
Expand Down Expand Up @@ -239,6 +241,40 @@
</TextBlock.ToolTip>
</TextBlock>
<ComboBox Grid.Column="2" Grid.Row="5" Margin="0 8 0 0" Padding="6 2 6 0" Width="100" Height="20" HorizontalAlignment="Right" ItemsSource="{Binding ConfigVm.LightsModeOptions}" SelectedItem="{Binding ConfigVm.LightsMode, UpdateSourceTrigger=PropertyChanged}" />

<TextBlock Grid.Column="0" Grid.Row="6" Margin="0 8 0 0" Text="Pretension Mode:">
<TextBlock.ToolTip>
<TextBlock Width="300" TextWrapping="Wrap">
Apply 1% of Max Current when above a threshold road speed to pre-tension the drivetrain.
This makes it nicer for more aggressive PAS / throttle settings since freewheel pawls
will not get smacked if there is play in the drivetrain system.
</TextBlock>
</TextBlock.ToolTip>
</TextBlock>
<CheckBox Grid.Column="2" Grid.Row="6" Margin="0 8 0 0" HorizontalAlignment="Right" IsChecked="{Binding ConfigVm.UsePretension, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding ConfigVm.UseSpeedSensor}" />

<TextBlock Grid.Column="0" Grid.Row="7" Margin="0 10 0 0" Text="Pretension Speed Cutoff (km/h):" Visibility="{Binding ConfigVm.UseMetricUnits, Converter={StaticResource BoolToVis}}">
<TextBlock.ToolTip>
<TextBlock Width="300" TextWrapping="Wrap">
Pretension will not be applied at and below this roadspeed. Take caution setting this to zero, as
your bike will roll forward as soon as it is powered on and pushed. Recommended to start with ~16kph
and lower if necessary once comfortable with the feature.
</TextBlock>
</TextBlock.ToolTip>
</TextBlock>
<TextBox Grid.Column="2" Grid.Row="7" Margin="0 10 0 0" Width="60" HorizontalAlignment="Right" Text="{Binding ConfigVm.PretensionSpeedCutoffKph, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ConfigVm.UseMetricUnits, Converter={StaticResource BoolToVis}}" IsEnabled="{Binding ConfigVm.UseSpeedSensor}" />

<TextBlock Grid.Column="0" Grid.Row="7" Margin="0 10 0 0" Text="Pretension Speed Cutoff (mph):" Visibility="{Binding ConfigVm.UseImperialUnits, Converter={StaticResource BoolToVis}}" >
<TextBlock.ToolTip>
<TextBlock Width="300" TextWrapping="Wrap">
Pretension will not be applied at and below this roadspeed. Take caution setting this to zero, as
your bike will roll forward as soon as it is powered on and pushed. Recommended to start with ~10mph
and lower if necessary once comfortable with the feature.
</TextBlock>
</TextBlock.ToolTip>
</TextBlock>
<TextBox Grid.Column="2" Grid.Row="7" Margin="0 10 0 0" Width="60" HorizontalAlignment="Right" Text="{Binding ConfigVm.PretensionSpeedCutoffMph, UpdateSourceTrigger=PropertyChanged}" Visibility="{Binding ConfigVm.UseImperialUnits, Converter={StaticResource BoolToVis}}" IsEnabled="{Binding ConfigVm.UseSpeedSensor}" />

</Grid>

<Grid Margin="0 20 0 0">
Expand Down Expand Up @@ -323,7 +359,6 @@
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>


<TextBlock Grid.Row="0" Text="Miscellaneous" FontSize="18" FontWeight="Bold" />

<TextBlock Grid.Column="0" Grid.Row="1" Margin="0 10 0 0" Text="Walk Mode Data Display:">
Expand Down
3 changes: 0 additions & 3 deletions src/tool/ViewModel/Base/DelegateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ public class DelegateCommand : ICommand

public event EventHandler CanExecuteChanged;


public DelegateCommand(Action action)
{
_action = action;
Expand All @@ -23,8 +22,6 @@ public DelegateCommand(Action<object> action)
_action = null;
}



public bool CanExecute(object parameter)
{
return true;
Expand Down
Loading

0 comments on commit 1839259

Please sign in to comment.