Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dangerous error produced in speed calculation for EBiCS display method #28

Open
wuwbobo2021 opened this issue Apr 6, 2023 · 2 comments

Comments

@wuwbobo2021
Copy link

wuwbobo2021 commented Apr 6, 2023

In case of 2.2 m of wheel circumference, single magnet in the spokes:

#define WHEEL_CIRCUMFERENCE 2200
#define PULSES_PER_REVOLUTION 1

When the speed reaches 4r/s (4 * 2.2 * 3.6 = 31.68 km/h), the interval measured by TIM3 is (1/f)/[1/(64M/7814)] = 8190/f = 8190/4 = 2048; the value in EBiCS is [(int)2200 / ((int)2048 >> 3)] * 36 / 10 = 28.8, nearly 2 km/h error produced.

you can draw two functions in the calculator

y = 2.2*3.6*x
y = 3.6*floor(2200/floor(8190/x/8))

to see the maximum error 4.3 km/h. 29 km/h will be shown as 25 km/h!

I have extracted related code from your project (with many unindented code):

int main(void)
{
	...
	while (1)
	{
		...
		// SPEED signal processing
		if (ui8_SPEED_flag) {
			if(uint32_SPEED_counter > 200) { //debounce
				MS.Speed = uint32_SPEED_counter;
				uint32_SPEED_counter = 0;
				ui8_SPEED_flag = 0;
			}
		}
		...
		if (ui32_tim3_counter > 500) {
			if(uint32_SPEED_counter > 127999)
				MS.Speed = 128000;
			...
			ui8_slowloop_counter++;
			if (ui8_slowloop_counter > 3) {
				ui8_slowloop_counter = 0;
				send_ant_page(0, &MS, &MP);
			}
			ui32_tim3_counter = 0;
		}
		...
	}
}

// elapse frequency of TIM3 is 64M/7814 (Hz), interval is about 122.1 us
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim == &htim3) {
		if(ui32_tim3_counter < 32000)
			ui32_tim3_counter++;
		...
		if (uint32_SPEED_counter < 128000)
			uint32_SPEED_counter++; //counter for external Speed sensor
	}
}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	...
	//Speed processing
	if(GPIO_Pin == Speed_EXTI5_Pin)
		ui8_SPEED_flag = 1; //with debounce

}

void send_ant_page(uint8_t page, MotorState_t* MS, MotorParams_t* MP)
{
	...
	// *3,6 for km/h then *10 for LEV standard definition.
	uint16_t speedx10 = MP->wheel_cirumference / ((MS->Speed*MP->pulses_per_revolution) >> 3) * 36;
	
	ui8_tx_buffer[9] = speedx10 & 0xFF; //low byte of speed
	ui8_tx_buffer[10] = speedx10>>8 & 0x07; //lower 3 Bytes(needs correction) of high byte
	...
	HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&ui8_tx_buffer, 12);
}

Thanks.

@wuwbobo2021
Copy link
Author

Looking into kingmeter_update() and internal_tics_to_speedx100() in main.c, it seems like MS.Speed may have different units for speed sources EXTERNAL and INTERNAL, but the current speedx10 sent for EBiCS display just takes care of EXTERNAL source. Am I wrong?

@wuwbobo2021
Copy link
Author

Also note that current UART transfer routines may not work with bluetooth serial adapters (connected to the controller's meter interface) featuring AT-like protocol before connection. In my case, bytes sent from the host device are always dislocated in the MCU receive buffer if I don't power on the serial adapter and connect to it before turning on the controller's power. It's probably caused by +CONNECTED\r\n received before the adapter turned into passthrough mode. The byte dislocation looks like this in Android logcat: (with my modified protocol, sending back the data)

01-08 09:42:31.121 30740 30754 W ebics_panel: ebics_panel: Prepared data to be sent: [0, 0, 0, 16, 0, 0, 8, 0, 0, 0, 0, 24].
01-08 09:42:31.121 30740 30754 W ebics_panel: ebics_panel: data should be sent.
01-08 09:42:31.220 30740 30754 W ebics_panel: ebics_panel: Unknown data received: [0, 0, 8, 0, 0, 0, 0, 24, 0, 0, 0, 16]
01-08 09:42:31.545 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 3, 6, 0, 231].
01-08 09:42:31.774 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:32.197 30740 30754 W ebics_panel: ebics_panel: Prepared data to be sent: [0, 0, 0, 16, 0, 0, 8, 0, 0, 0, 0, 24].
01-08 09:42:32.203 30740 30754 W ebics_panel: ebics_panel: data should be sent.
01-08 09:42:32.268 30740 30754 W ebics_panel: ebics_panel: Unknown data received: [0, 0, 8, 0, 0, 0, 0, 24, 0, 0, 0, 16]
01-08 09:42:32.517 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 4, 6, 0, 224].
01-08 09:42:32.747 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:33.485 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 4, 6, 0, 224].
01-08 09:42:33.738 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:34.454 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 4, 6, 0, 224].
01-08 09:42:34.725 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:35.452 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 4, 6, 0, 224].
01-08 09:42:35.682 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:36.031 30740 30754 W ebics_panel: ebics_panel: Prepared data to be sent: [0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16].
01-08 09:42:36.031 30740 30754 W ebics_panel: ebics_panel: data should be sent.
01-08 09:42:36.097 30740 30754 W ebics_panel: ebics_panel: Unknown data received: [0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16]
01-08 09:42:36.442 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 4, 0, 0, 0, 0, 4, 6, 0, 224].
01-08 09:42:36.668 30740 30754 W ebics_panel: ebics_panel: Received status data: [164, 12, 78, 1, 7, 0, 0, 0, 0, 125, 0, 157].
01-08 09:42:37.028 30740 30754 W ebics_panel: ebics_panel: Prepared data to be sent: [0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 16].
01-08 09:42:37.028 30740 30754 W ebics_panel: ebics_panel: data should be sent.
01-08 09:42:37.091 30740 30754 W ebics_panel: ebics_panel: Unknown data received: [0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 16]

My solution is to add this at the end of process_ebics_page in display_ebics.c. Do you think it's a bad idea?

		// restart DMA in case of the received data length isn't 12
		HAL_UART_AbortReceive(&huart1); // this disables the DMA transfer too
		if (HAL_UART_Receive_DMA(&huart1, (uint8_t *) ui8_rx_buffer, 12) != HAL_OK) {
		    // do not halt the program while riding, in case of it happens
			//Error_Handler();
		}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant