KT motor controllers -- Flexible OpenSource firmware for BMSBattery S/Kunteng KT motor controllers (0.25kW up to 5kW)

casainho said:
Now the motor always start as it should -- now seems I have a robust motor startup and transition to/from block commutation <-> sinewave.
That's fine! Can you upload your .hex file, please, I'll try it with my motor then!


The Java Tool is updated.

fetch.php


There's a detailed "how to" in the Wiki of the german forum, now.
Please use the translation function of your browser, if needed.

The parameters are described in chapter 4.

Regards
stancecoke
 
stancecoke said:
There's a detailed "how to" in the Wiki of the german forum, now.
Please use the translation function of your browser, if needed.
I am sad that you decided to write documentation in german only. I don't want to put my energy on a project that is german only.
 
sorry, but I'm already spending much to much time in this project, if you ask my family :shock: .
Writing in english would have taken three times more time...

I think the google chrome translation function gives useful results ...

Chrome Translation.PNG

regards
stancecoke
 
stancecoke said:
sorry, but I'm already spending much to much time in this project, if you ask my family :shock: .
Writing in english would have taken three times more time...

I think the google chrome translation function gives useful results ...
Ok I understand that can be much faster to write in german for you.

That is not because I don't want to translate using google. Having documentation in EN for me is strategic, the same way it is strategic using a widely available controller and cheap. Google search will not find the pages written in german when someone search in EN and so I really think it is strategic to have in EN, so everyone will be able to reach the information.
 
stancecoke said:
casainho said:
Now the motor always start as it should -- now seems I have a robust motor startup and transition to/from block commutation <-> sinewave.
That's fine! Can you upload your .hex file, please, I'll try it with my motor then!

View attachment main.hex
 
Thank you, but I still got no success with this firmware. It's still the same behavior: the motor makes a little jerk at switching on the power, display communication is working, but the motor does not react to the throttle in any way. :(

sorry, no better news.
stancecoke
 
stancecoke said:
Thank you, but I still got no success with this firmware. It's still the same behavior: the motor makes a little jerk at switching on the power, display communication is working, but the motor does not react to the throttle in any way. :(

sorry, no better news.
That code have the speed controller enable, maybe that is the issue?? Maybe would be faster if you can build by yourself while looking at the code and go testing.
 
Hmmm, perhaps you can prepare a code/hex-file, where the throttle value is directly mapped to the PWM value? Just to test, if the code works in principle with my Motor/Controller?! I'm despairing of your code at the moment :(

regards
stancecoke
 
stancecoke said:
Hmmm, perhaps you can prepare a code/hex-file, where the throttle value is directly mapped to the PWM value? Just to test, if the code works in principle with my Motor/Controller?! I'm despairing of your code at the moment :(
View attachment main.hex
That code have throttle mapped to the PWM duty_cycle value. Also is the very first code to receive from UART the info from LCD3, I am used your code/interrupt configuration :)

Code:
void UART2_IRQHandler(void) __interrupt(UART2_IRQHANDLER)
{
  static uint8_t rx_buffer[13];
  static uint8_t ui8_rx_counter = 0;
  uint8_t ui8_byte_received;
  static uint8_t ui8_state_machine = 0;

  if(UART2_GetFlagStatus(UART2_FLAG_RXNE) == SET)
  {
    ui8_byte_received = UART2_ReceiveData8 ();

    switch (ui8_state_machine)
    {
      case 0:
      if (ui8_byte_received == 0x32)
      {
	rx_buffer[0] = ui8_byte_received;
	ui8_rx_counter++;
	ui8_state_machine = 1;
      }
      else
      {
	ui8_rx_counter = 0;
	ui8_state_machine = 0;
      }
      break;

      case 1:
      if (ui8_byte_received == 0x0e)
      {
	rx_buffer[1] = ui8_byte_received;
	ui8_rx_counter++;
	ui8_state_machine = 2;
      }
      else
      {
	ui8_rx_counter = 0;
	ui8_state_machine = 0;
      }
      break;

      case 2:
      rx_buffer[2] = ui8_byte_received;

      ui8_rx_counter = 0;
      ui8_state_machine = 0;
      
      // TODO
      break;

      default:
      break;
    }
  }
}
 
OK, this works, with stable switch from six step to sinewave and with good effiency!!! 8)
So we have to search the thing that's going wrong with the other functions...

And I have to check, if it runs, if I compile it with windows, can you upload this version to some branch?

regards
stancecoke
 
For receiving the data from the LCD5, I need to calc "xor 2" as a verification of data and I don't know what that mean!! Can someone please help?
 
casainho said:
For receiving the data from the LCD5, I need to calc "xor 2" as a verification of data and I don't know what that mean!! Can someone please help?

Based on https://opensourceebikefirmware.bitbucket.io/EmbeddedFiles/7-LCD3_to_S12SN-1.txt I would expect (not compiled, just typed in here)

Code:
  uint8_t dataXor = B0 ^ B1 ^ B2 ^ B3 ^ B4 ^ B6 ^ B7 ^ B8 ^ B9 ^ B10 ^ B11 ^ B12;

  bool_t DataIntegrityHolds = ((dataXor ^ 2) == B5);

If that is too simple, provide a few pairs of dataXor and B5 (in base 2 = all the bits) - perhaps it is possible to discover the pattern that is required to compute DataIntegrityHolds.

That formula works with the example in the txt file, as the screenshot of a quick Excel draft shows.
 

Attachments

  • Capture.PNG
    Capture.PNG
    2.8 KB · Views: 2,295
  • KT-LCD data packet CRC calc.xlsx
    10.3 KB · Views: 24
Assuming it can work with the LiShui-controller / Kingmeter-LCD combo, then once you get far enough along to a stable FW, I'd be interested in trying it on one of the little Fusin controllers I have, and see if it might improve the system.
https://endless-sphere.com/forums/viewtopic.php?p=584366#p584366
I didn't apparently note the MCU type in the review linked above, so I'll have to open the controller up again and see if it's even the right one first.

Nevermind, opened up the 9FET and found it's probably not compatible, being a Cypress PSoC CY8C24533 series MCU. :(

http://html.alldatasheet.com/html-pdf/510338/CYPRESS/CY8C24533-24PVXI/303/1/CY8C24533-24PVXI.html
 
amberwolf said:
Assuming it can work with the LiShui-controller / Kingmeter-LCD combo, then once you get far enough along to a stable FW, I'd be interested in trying it on one of the little Fusin controllers I have, and see if it might improve the system.
These controllers are very cheap and widely available, from 0.25kw up to 4.3kw. No reason to save on the hardware, just buy them.

Don't expect any improvement in energy used by the motor but expect flexibility, like adding code for any specific sensor you may have.
 
casainho said:
Alan B said:
It seems odd that they would delay the timing from the hall transition event. Usually earlier timing (advance) is desired as RPM increases. Unless the halls are in the wrong place. The sensorless back EMF transition occurs much earlier (30 degrees) than the halls and commutation event.
I am not sure if is a delay or an advance. See:

Original firmware:
89-1.png


Our OpenSource firmware (hall sensor is not the real signal but inverted by microcontroller):
91-1.png

what is the yellow trace? Current or Voltage?
 
Alan B said:
what is the yellow trace? Current or Voltage?
See here:
https://opensourceebikefirmware.bitbucket.io/Various--Endless-sphere.com_forum_messages--2017.10.23_-_FOC_and_no_FOC_comparison.html
 
stancecoke said:
OK, this works, with stable switch from six step to sinewave and with good effiency!!! 8)
So we have to search the thing that's going wrong with the other functions...
I did disable 360º interpolation and the results are similar with original firmware. With 360º it does even less noise however is less efficient... maybe we need to try the same angle as original firmware and with 360º interpolation. Anyway, if you say it has good efficiency, I will stick with it for now and move to the upper functionality lawyers, as I want to ride my EBike with S12S for 90kms on next weekend :)

It fully works for me, It is difficult me for to find what is not working for you.

stancecoke said:
And I have to check, if it runs, if I compile it with windows, can you upload this version to some branch?
It is on master branch.
 
daffy99 said:
If that is too simple, provide a few pairs of dataXor and B5 (in base 2 = all the bits) - perhaps it is possible to discover the pattern that is required to compute DataIntegrityHolds.
Many thanks!! I was blocked and now I can move forward :)
 
I just implemented the communication of gear assist level from the LCD5. On the video I am changing that parameter on the LCD and the firmware is controlling the motor speed accordingly.

Daffy99, using your spreadsheet and looking at the data from LCD5, I was always getting a different value and so I went and tried change to "xor 9" and seems the right value -- or I am missing something or LCD5 uses "xor 9" instead of "xor 2".



[youtube]b5erBqISRE0[/youtube]
 
casainho said:
Daffy99, using your spreadsheet and looking at the data from LCD5, I was always getting a different value and so I went and tried change to "xor 9" and seems the right value -- or I am missing something or LCD5 uses "xor 9" instead of "xor 2".

dec 2 = bin 0010
dec 9 = bin 1001

Three bits of difference. That's substantial.

On the other hand, I cannot tell what the quality of the reverse engineering is. Your collection of tidbits seems to suggest, that xor 2 does not (always) work when an external controller attempts to send data to the original firmware, so ...?

For the purpose of debugging, try changing as many data bytes as possible and see whether the check xor value of "9" still holds, under all circumstances?

I do know that Kunteng controllers and LCDs come about in at least three versions. I do not know the differences between these versions, though, and to what extent the protocol over the wire differs.

As far as controller and LCD are concerned - theoretically, these should be interchangeable across a single "version" - so LCD2, LCD3, LCD5 should communicate exactly the same way. Theoretically.
 
daffy99 said:
Cool, now submit a pull request for all the usability (Java) changes that you made! ;)
I fear a pull request will end up at my own desk.... :)

@casainho: can you please confirm this program sequence for the motor control:

Fast Loop:
The timerinterrupt handler calls the functions

1. hall_sensors_read_and_action ();
2. motor_fast_loop ();

the motor_fast_loop () calls the function pwm_duty_cycle_controller ()

the pwm_duty_cycle_controller () calls the function pwm_apply_duty_cycle (ui8_duty_cycle)

Slow Loop:
First thread in parallel in the main.c:
the function motor_controller_high_level () is called. The content of this function is disabled at the moment.

If enabled, the functions for speed and current control are called. They get their setpoints from the throttle_pas_torque_sensor_controller (); that runs in parallel.

Then the function motor_set_pwm_duty_cycle_target is called.

The function motor_set_pwm_duty_cycle_target does nothing but calling the function pwm_set_duty_cycle_target (value);

The function pwm_set_duty_cycle_target (value); sets the value of ui8_duty_cycle_target, that is used in the fast loop for motor control.

Second thread in parallel in the main.c:
the function throttle_pas_torque_sensor_controller (); is called

throttle_pas_torque_sensor_controller (); calls the function ui8_adc_read_throttle ();

then throttle_pas_torque_sensor_controller (); calls the function motor_set_pwm_duty_cycle_target (ui8_temp); at the moment directly instead of calling the functions motor_controller_set_current (ui16_temp); and / or motor_controller_set_speed_erps (ui16_temp); that are disabled at the moment.
If enabled these functions would set the setpoints of the motor_current_controller and motor_speed_controller functions that are called in the motor_controller_high_level () that runs in parallel....


a bit confusing... :shock:


regards
stancecoke
 
casainho said:
Daffy99, using your spreadsheet and looking at the data from LCD5, I was always getting a different value and so I went and tried change to "xor 9" and seems the right value -- or I am missing something or LCD5 uses "xor 9" instead of "xor 2".

Looking at https://github.com/OpenSource-EBike-firmware/BMSBattery_S_controllers_firmware/commit/9c9de66fe41618ae14f595990d00dcdf9ed948c8#diff-f09135e1598deb289c250d9ed37dd8dbR98 it would seem that the checksum is also in a different location?

Cool that you figured this out!

This then begs the question - is the meaning of the content different, too?

And which "version" of the display do you have? I have access to an LCD3 version "3.0", FWIW, but cannot experiment with this at the moment.

PS: ui8_received_package_flag is really a candidate for volatile, although that probably will not have any impact here. Still, I would use it.

PPS: as is, in a certain way, rx_buffer - it "should" be volatile, otherwise the C compiler is allowed to reuse whatever it ever allocated for rx_buffer. In practice, I guess, it will not matter. Unfortunately, lot's of funny things happen in software because too often "in practice, I guess, it will not matter" is uttered, but the guess is wrong :D
 
daffy99 said:
it would seem that the checksum is also in a different location?

Cool that you figured this out!
No, I just consider as start package the bytes that the other user that did the reverse engineering, consider at the end of package - makes more sense to me and it works.

I am now processing the wheel size, speed and motor characteristics, all seem to be working :)
 
Back
Top