• Hello ES! We could use some help to get us past the finish line on building the new knowledgebase for the forum.
    Can you donate? Please see our fundraising page. Thank you!

Lishui "Open Source Firmware" project / KingMeter 5S

As said, please read the Wiki. The first steps to get the motor running and the meaning of the various parameters in the Java tool are explained there.

Hi! Is there any more detailed beginner-friendly guide on how to compile, configure, and flash the firmware for my controller?
I followed the instructions on GitHub, but after installing everything I got confused about where to start. For example, I don't understand how to perform the automatic controller detection, or how to apply the detected settings to the firmware before compiling and flashing it.
If there's a step-by-step guide for beginners, I'd really appreciate it. Thank you!
 
As said, please read the Wiki. The first steps to get the motor running and the meaning of the various parameters in the Java tool are explained there.

I have read the Wiki again and I think I understand it now. If I am correct, I have successfully flashed the controller with the firmware, and the next step is to calibrate it.
As I understand, after turning it on with the display connected, I need to hold the throttle and brake, and the controller will automatically calibrate itself.
If this is correct, I have two questions:
After flashing the firmware, do I need to disconnect and reconnect the controller before starting the calibration procedure?
Could you please tell me where I should solder the brake wire on this board?
Thank you for your help.
 
do I need to disconnect and reconnect the controller before starting the calibration procedure
no, the controller is reset after flashing autmatically.
Could you please tell me where I should solder the brake wire on this board?
This is a "new generation" controller, as it has the CAN connectors on the PCB. So you should not use the "Master" branch from the github repo, but the "NewGeneration12FET" branch. The brake wire has to be connected to the pad labelled with "BRL" (brake low).

Where did you get this controller from? Unpotted Lishui controllers are quite rare...

1783853499102.png
 
Нет, контроллер автоматически перезагружается после прошивки.

Это контроллер «нового поколения», поскольку разъемы CAN расположены на печатной плате. Поэтому вам следует использовать не ветку «Master» из репозитория GitHub, а ветку « NewGeneration12FET ». Провод тормоза необходимо подключить к контакту с маркировкой «BRL» (низкий уровень тормоза).

View attachment 390409
 
no, the controller is reset after flashing autmatically.

This is a "new generation" controller, as it has the CAN connectors on the PCB. So you should not use the "Master" branch from the github repo, but the "NewGeneration12FET" branch. The brake wire has to be connected to the pad labelled with "BRL" (brake low).

Where did you get this controller from? Unpotted Lishui controllers are quite rare...

View attachment 390409
Maybe CAN TX and CAN RX are routed as universal connections on this controller. There is nothing soldered to these contacts.
Since the original factory display cable is connected to these contacts, I assume they are used as a universal interface.
I am attaching a photo.27681.jpg
 
1783854273959.png
Your marked connectors are the UART RX and TX.
CAN_RX and CAN_TX are PA11 and PA12. Normally, Lishui would spend a CAN additional transceiver board, when the controller is used in a CAN system. Just like the Head-/Rear-/Brake- light board, that is added optionally, depending on the customers needs...
 
View attachment 390411
Your marked connectors are the UART RX and TX.
CAN_RX and CAN_TX are PA11 and PA12. Normally, Lishui would spend a CAN additional transceiver board, when the controller is used in a CAN system. Just like the Head-/Rear-/Brake- light board, that is added optionally, depending on the customers needs...
This board had a small additional board soldered to it. As I understand, it is for the light, because the contact on the main board goes to BKL. When I turn on the light on the display, the connector output from this board shows 1.8 V.
There are no other additional boards on the controller.
Also, before I flashed the No.2 firmware, I flashed the KM5S firmware, and the S866 display showed error E10. After flashing the No.2 firmware, there are no errors.
If I press the minus button on the display, the current on the laboratory power supply increases. Does this mean that the display is communicating with the controller?
So, do I only need to calibrate it now?
Sorry for the basic questions. It is still difficult for me to understand everything because of the language barrier.
 
View attachment 390411
Your marked connectors are the UART RX and TX.
CAN_RX and CAN_TX are PA11 and PA12. Normally, Lishui would spend a CAN additional transceiver board, when the controller is used in a CAN system. Just like the Head-/Rear-/Brake- light board, that is added optionally, depending on the customers needs...
There is also an output on the board marked as SL. Gemini says that this is the low-level brake signal.
By the way, a wire from the main 8-pin harness that goes to the display was connected there. I assume that the brake signal was also carried through this harness to the display.
Could you please confirm if my assumption is correct?
Thank you.
 
There is also an output on the board marked as SL. Gemini says that this is the low-level brake signal.
:ROFLMAO: You shouldn't ask the AI—you should ask someone who knows about this stuff.
SL is the Brake Light output on the new generation and PAS2 on the old generation ;)
Of course Lishui makes individual setups for each customer. So maybe your controller is configured in a different way.

On your photo we see, that one of the BKL pads is equipped, too. So where does this wire go to?

1783856921309.png
 
Last edited:
:ROFLMAO: You shouldn't ask the AI—you should ask someone who knows about this stuff.
SL is the Brake Light output on the new generation and PAS2 on the old generation ;)
Of course Lishui makes individual setups for each customer. So maybe your controller is configured in a different way.

On your photo we see, that one of the BKL pads is equipped, too. So where does this wire go to?

View attachment 390413
The BKL was connected to this small board. But I desoldered it because I thought this was the board for the lights.26995.jpg
 
View attachment 390411
Your marked connectors are the UART RX and TX.
CAN_RX and CAN_TX are PA11 and PA12. Normally, Lishui would spend a CAN additional transceiver board, when the controller is used in a CAN system. Just like the Head-/Rear-/Brake- light board, that is added optionally, depending on the customers needs.
If SL is the light output as shown in the chip diagram, then where is the brake input? And where should I connect the brake wire? Because without the brakes I cannot calibrate the controller, right?
 
This is light module, indeed.
Then Lishui swapped the pin functions for this controller obviously. But with EBiCS, the brake function is on BKL by default. Of course you can define PB10 as brake pin in the main.h also.
If you just want to execute the autodect, you can do that by activating the Debug Display and the Autodetect in the Java tool. This might be easier .
It seems you have not read the Wiki carefully ;)
If you don't have a brake switch and a throttle on your system, you can start the autodetect routine by activating the autodetect and debug option in the GUI. The controller runs the autodetect at every start then. You have to run it only once, so you can disable the option again after one start.
 
This is light module, indeed.
Then Lishui swapped the pin functions for this controller obviously. But with EBiCS, the brake function is on BKL by default. Of course you can define PB10 as brake pin in the main.h also.
If you just want to execute the autodect, you can do that by activating the Debug Display and the Autodetect in the Java tool. This might be easier .
It seems you have not read the Wiki carefully ;)
Could you please confirm: can I connect the brake signal to BKL and then perform the auto-detection through the software?
Sorry for repeating the same questions. I just really don’t want to burn the controller.
I have read the Wiki, but my native language is Ukrainian, and sometimes I don’t fully understand everything through translation.
Thank you for your patience and help.
 
This is light module, indeed.
Then Lishui swapped the pin functions for this controller obviously. But with EBiCS, the brake function is on BKL by default. Of course you can define PB10 as brake pin in the main.h also.
If you just want to execute the autodect, you can do that by activating the Debug Display and the Autodetect in the Java tool. This might be easier .
It seems you have not read the Wiki carefully ;)
think I enabled everything as described in the Wiki. The firmware flashes without any problems.
But the auto-detection does not start. The motor stays completely still — I can even see it on the LBP, the current does not change at all.
What am I doing wrong then?
I am attaching photos.27696.jpg27697.jpg27699.jpg27703.jpg
 
you have not set the Display to Debug! Please read carefully!!!

View attachment 390419
Sorry, I didn't realize at first that I needed to use the debug build. However, if I select the debug build, the No. 2 protocol is not flashed. After enabling the debug build and flashing the firmware, the motor started spinning, but it was very jerky. Then the display showed Error E10.

What should I do next? Thank you for your help.
 
So, if I disable Position PLL, the motor completes the autodetect smoothly without any jerking.
However, when I use the throttle, the motor makes only one revolution and then stops. It keeps repeating this cycle as long as I hold the throttle.
Also, the brake lever does not respond at all. Even if I pull the brake, I can still start the motor with the throttle.
Do you have any idea what could be causing this? Thank you!
 
Also, the brake lever does not respond at all. Even if I pull the brake, I can still start the motor with the throttle.
As long as your brake wire is connected to the wrong pin, it can't work. In the master branch, the brake wire is expected on pin PA11.

Please post the content of your config.h and your main.h, then I can see, what you have set up actually.

1783874972643.png
 
As long as your brake wire is connected to the wrong pin, it can't work. In the master branch, the brake wire is expected on pin PA11.

Please post the content of your config.h and your main.h, then I can see, what you have set up actually.

View attachment 390422
Sorry, are these files located in the Inc folder? I can send them to you, but I don't completely understand why you need them. This is your project, isn't it? Or are these files modified after I flash the controller?

Thank you for your help.
 
Если провод тормоза подключен к неправильному контакту, он не будет работать. В главной цепи провод тормоза должен быть подключен к контакту PA11.

Пожалуйста, опубликуйте содержимое ваших файлов config.h и main.h, тогда я смогу увидеть, что именно у вас настроено.

View attachment 390422
/*
* config.h
*
* Создано автоматически с помощью конфигуратора параметров Lishui
* Автор: stancecoke
*/

#ifndef CONFIG_H_
#define CONFIG_H_
#include "stdint.h"
#define DISPLAY_TYPE_DEBUG (1<<0) // Для вывода ASCII в режиме отладки);
#define DISPLAY_TYPE_KUNTENG (1<<1) // Для отображения Kunteng
#define DISPLAY_TYPE_BAFANG_LCD (1<<2) // Для отображения «Blaupunkt» Prophete Entdecker
#define DISPLAY_TYPE_BAFANG_850_860 (1<<3) // Bafang 850/860. Может работать на скорости 9 кбит/с, также совместим с определением скорости 1200 бод при запуске.
#define DISPLAY_TYPE_KINGMETER_618U (1<<4) // Протокол King-Meter 618U (J-LCD)
#define DISPLAY_TYPE_KINGMETER_901U (1<<5) // Протокол King-Meter 901U (KM5s)
#define DISPLAY_TYPE_EBiCS (1<<6) // Протокол, использующий логику ANT+ LEV
#define DISPLAY_TYPE_NO2 (1<<7) // Например, для китайского дисплея S866 "No_2" по протоколу "Китай".
#define DISPLAY_TYPE_BAFANG (DISPLAY_TYPE_BAFANG_LCD|DISPLAY_TYPE_BAFANG_850_860)
#define DISPLAY_TYPE_KINGMETER (DISPLAY_TYPE_KINGMETER_618U|DISPLAY_TYPE_KINGMETER_901U)
#define EXTERNAL 1
#define INTERNAL 0
#define ЛЕГАЛЬНЫЙ ФЛАГ

#define TRIGGER_OFFSET_ADC 50
#define TRIGGER_DEFAULT 2020
#define _T 2028
#define CAL_BAT_V 256
#define CAL_V 25
#define CAL_I 38LL<<8
#define ИНДУКТИВНОСТЬ 6
#определить СОПРОТИВЛЕНИЕ 40
#define FLUX_LINKAGE 1200
#define GAMMA 9
#define BATTERY_LEVEL_1 323000
#define BATTERY_LEVEL_2 329000
#define BATTERY_LEVEL_3 344000
#define BATTERY_LEVEL_4 368000
#define BATTERY_LEVEL_5 380000
#define P_FACTOR_I_Q 500
#define I_FACTOR_I_Q 20
#define P_FACTOR_I_D 500
#define I_FACTOR_I_D 20
#define P_FACTOR_PLL 5
#define I_FACTOR_PLL 11
#define P_FACTOR_SPEED 100
#define I_FACTOR_SPEED 10
#define SPDSHFT 0
#define SPEEDFILTER 1
#define SIXSTEPTHRESHOLD 3500
#define TS_COEF 60000
#define PAS_TIMEOUT 8000
#define RAMP_END 1600
#define PAS_IMP_PER_TURN 32
#define FRAC_HIGH 30
#define FRAC_LOW 15
#define THROTTLE_OFFSET 750
#define THROTTLE_MAX 2600
#define PUSHASSIST_CURRENT 30
#define WHEEL_CIRCUMFERENCE 2200
#define GEAR_RATIO 60
#define SPEEDLIMIT 25
#define PULSES_PER_REVOLUTION 1
#define PH_CURRENT_MAX 600
#define BATTERYCURRENT_MAX 15000
#define REGEN_CURRENT 200
#define REGEN_CURRENT_MAX 10000
#define VOLTAGE_MIN 500
#define VOLTAGE_MAX 1600
#define SPEC_ANGLE -715827882
#define TS_MODE
#define TQONAD1
#define DISPLAY_TYPE DISPLAY_TYPE_DEBUG // ASCII-вывод для отладки
#define SPEED_PLL 0
#define SPEEDSOURCE EXTERNAL
#define AUTODETECT 1
#define REVERSE -1
#define THROTTLE_OVERRIDE

#endif /* CONFIG_H_ */
 
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
** This notice applies to any and all portions of this file
* that are not between comment pairs USER CODE BEGIN and
* USER CODE END. Other portions of this file, whether
* inserted by the user or by software development tools
* are owned by their respective copyright owners.
*
* COPYRIGHT(c) 2019 STMicroelectronics
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H__
#define __MAIN_H__

/* Includes ------------------------------------------------------------------*/

/* USER CODE BEGIN Includes */
#include <arm_math.h>


/* USER CODE END Includes */

/* Private define ------------------------------------------------------------*/

#define Hall_1_Pin GPIO_PIN_0
#define Hall_1_GPIO_Port GPIOA
#define Hall_1_EXTI_IRQn EXTI0_IRQn
#define Hall_2_Pin GPIO_PIN_1
#define Hall_2_GPIO_Port GPIOA
#define Hall_2_EXTI_IRQn EXTI1_IRQn
#define Hall_3_Pin GPIO_PIN_2
#define Hall_3_GPIO_Port GPIOA
#define Hall_3_EXTI_IRQn EXTI2_IRQn
#define Throttle_Pin GPIO_PIN_3
#define Throttle_GPIO_Port GPIOA
#define Phase_Current1_Pin GPIO_PIN_4
#define Phase_Current1_GPIO_Port GPIOA
#define Phase_Current_2_Pin GPIO_PIN_5
#define Phase_Current_2_GPIO_Port GPIOA
#define Phase_Current_3_Pin GPIO_PIN_6
#define Phase_Current_3_GPIO_Port GPIOA
#define Temperature_Pin GPIO_PIN_1
#define Temperature_GPIO_Port GPIOB
#define LED_Pin GPIO_PIN_2
#define LED_GPIO_Port GPIOB
#define LIGHT_Pin GPIO_PIN_9
#define LIGHT_GPIO_Port GPIOB
#define BRAKE_LIGHT_Pin GPIO_PIN_10
#define BRAKE_LIGHT_GPIO_Port GPIOB
#define PAS_Pin GPIO_PIN_8
#define PAS_GPIO_Port GPIOB
#define Brake_Pin GPIO_PIN_11 // put a 15 here for new generation controllers!
#define Brake_GPIO_Port GPIOA
#define Speed_EXTI5_Pin GPIO_PIN_5
#define Speed_EXTI5_GPIO_Port GPIOB
#define Speed_EXTI5_EXTI_IRQn EXTI9_5_IRQn
#define PAS_EXTI8_Pin GPIO_PIN_8
#define PAS_EXTI8_GPIO_Port GPIOB
#define PAS_EXTI8_EXTI_IRQn EXTI9_5_IRQn

//#define NCTE
//#define LEGALFLAG
#define BATTERYVOLTAGE_MAX 53000
#define R_TEMP_PULLUP 0
#define INT_TEMP_25 0
#define TORQUE_OFFSET 850
//#define USE_FIX_POSITIONS 1
//Put values from the startup message after autodetect here, if you want to use fix positions. 32bit values for the hall angles!
/*
* i16_60deg_Hall_flag:
* bit 0: hallstate 0 detected
* bit 1: hallstate 7 detected
* bit 2: 60° hall configuration detected
* bit 3: hallstate 2 detected
* bit 4: hallstate 5 detected
* bit 5: 120° hall configuration detected
*/
#define KV 224
#define HALL_ORDER -1
#define HALL_45 1837291766
#define HALL_51 2565050131
#define HALL_13 3245086636
#define HALL_32 4032497326
#define HALL_26 417566535
#define HALL_64 1109533505

#define HALL_60_46 -1729917165
#define HALL_60_67 -978297870
#define HALL_60_73 -238609040
#define HALL_60_31 417566535
#define HALL_60_10 1169185830
#define HALL_60_4 1861152800

#define CONTROLLER_TEMPERATURE_THRESHOLD 70
#define CONTROLLER_TEMPERATURE_MAX 80
#define MOTOR_TEMPERATURE_THRESHOLD 100
#define MOTOR_TEMPERATURE_MAX 130

/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */

/* USER CODE BEGIN Private defines */




int32_t map (int32_t x, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max);
void autodetect();
void runPIcontrol();
void kingmeter_update(void);
void No2_update(void);

extern uint16_t switchtime[3];
extern uint32_t ui32_tim1_counter;
extern uint32_t uint32_PAS_counter;
extern uint8_t throttle_is_set(void);
extern uint8_t brake_is_set(void);
extern void UART_IdleItCallback(void);
extern void get_internal_temp_offset(void);

typedef struct
{
int16_t gain_p;
int16_t gain_i;
int16_t limit_i;
int16_t limit_output;
int16_t recent_value;
int32_t setpoint;
int32_t integral_part;
int16_t max_step;
int32_t out;
int8_t shift;

}PI_control_t;

typedef struct
{

q31_t Voltage;
uint32_t Speed;
q31_t i_d;
q31_t i_q;
q31_t i_q_setpoint;
q31_t i_d_setpoint;
q31_t i_setpoint_abs;
int32_t i_q_setpoint_temp;
int32_t i_d_setpoint_temp;
q31_t u_d;
q31_t u_q;
q31_t u_abs;
q31_t Battery_Current;
uint8_t hall_angle_detect_flag;
uint8_t char_dyn_adc_state;
uint8_t assist_level;
uint8_t regen_level;
int16_t Температура;
int16_t int_Temperature;
int8_t system_state;
int8_t gear_state;
int8_t error_state;
int8_t angle_est;
int16_t KV_detect_flag;

}MotorState_t;

typedef struct
{

uint16_t wheel_cirumference;
uint16_t p_Iq;
uint16_t i_Iq;
uint16_t p_Id;
uint16_t i_Id;
uint16_t TS_coeff;
uint16_t PAS_timeout;
uint16_t ramp_end;
uint16_t throttle_offset;
uint16_t throttle_max;
uint16_t gear_ratio;
uint8_t speedLimit;
uint8_t pulses_per_revolution;
uint16_t phase_current_max;
int32_t battery_current_max;


}MotorParams_t;

/* Закрытое определение кода пользователя */

#ifdef __cplusplus
внешний "C" {
#endif
void _Error_Handler(char *, int);

#define Error_Handler() _Error_Handler(__FILE__, __LINE__)
#ifdef __cplusplus
}
#endif

#endif /* __MAIN_H__ */

/************************ (C) Авторские права принадлежат STMicroelectronics *****КОНЕЦ ФАЙЛА****/
 
checked all the contacts relative to the PA11 pin of the MCU, but I couldn’t find any connection.
Does this mean that the brake input is simply not routed on this controller and the brake function is not physically available?
If there is no electronic brake, I think it is not a big problem because the motor is a geared motor anyway.
My main goal now is to make the throttle handle and PAS assistant work correctly with the No.2 protocol.
 
checked all the contacts relative to the PA11 pin of the MCU
PA11 should be connected to the CAN RX pad, as you have the new generation hardware.
If you are sure, that your brake wire is connected to the SL (PB10) pin, you can just edit the lines in the main.h and set the pin there:

C:
#define Brake_Pin GPIO_PIN_10
#define Brake_GPIO_Port GPIOB

If you want to use the simple PAS mode, you have to disable the torquesensor option.

1783878510715.png

I'm not using the Java tool, as it's much easier for me to edit the config.h directly in the IDE. ;)
As many other users have contributed features to the firmware meanwhile, especially to the Java Tool, I'm not always up to date with the latest behaviour of the master branch...
 
checked the continuity between the PA11 pin of the MCU and the CAN_RX pin on the board, but there is no connection between them.
Does this mean the CAN_RX line is not actually connected on this controller? If so, can I solder the brake input directly to the CAN_RX pad on the board?
As far as I understand, the electronic brake input works by pulling the signal to GND when the brake lever is pressed. Is that correct?
The part about changing the code confused me a little :)))
What do I need to do to make the No.2 protocol display and the throttle handle work correctly?
 
Back
Top