TSDZ2 EBike wireless standard (like Specialized Turbo Levo) - OpenSource

@rananna, I have now the code on TSZD2 wireless with Bluetooth and ANT, were I can see and set the ANT ID - it is set on the Bluetooth as we discussed, stored on EEPROM and then system resets, and the new ANT ID is setup at startup.

What do I need to do more to make sure the remote will automatically pair??
 
casainho said:
@rananna, I have now the code on TSZD2 wireless with Bluetooth and ANT, were I can see and set the ANT ID - it is set on the Bluetooth as we discussed, stored on EEPROM and then system resets, and the new ANT ID is setup at startup.

What do I need to do more to make sure the remote will automatically pair??
That is great progress! It seems bluetooth was not too hard to implement.
The remote should find the new ANT ID automatically with the wild card pairing I set up, so nothing extra should be needed.
Did you manage to test the remote before you implemented the bluetooth on the motor?
Did it work well for you?
 
rananna said:
casainho said:
@rananna, I have now the code on TSZD2 wireless with Bluetooth and ANT, were I can see and set the ANT ID - it is set on the Bluetooth as we discussed, stored on EEPROM and then system resets, and the new ANT ID is setup at startup.

What do I need to do more to make sure the remote will automatically pair??
That is great progress! It seems bluetooth was not too hard to implement.
The remote should find the new ANT ID automatically with the wild card pairing I set up, so nothing extra should be needed.
Did you manage to test the remote before you implemented the bluetooth on the motor?
Did it work well for you?
No I did not test yet. I will finish this feature on the TSZD2 side then I will add it also on the remote.
But there is a way to avoid using the wild card and programatically force the pair with a specific ANT ID device?
 
casainho said:
rananna said:
casainho said:
@rananna, I have now the code on TSZD2 wireless with Bluetooth and ANT, were I can see and set the ANT ID - it is set on the Bluetooth as we discussed, stored on EEPROM and then system resets, and the new ANT ID is setup at startup.

What do I need to do more to make sure the remote will automatically pair??
That is great progress! It seems bluetooth was not too hard to implement.
The remote should find the new ANT ID automatically with the wild card pairing I set up, so nothing extra should be needed.
Did you manage to test the remote before you implemented the bluetooth on the motor?
Did it work well for you?
No I did not test yet. I will finish this feature on the TSZD2 side then I will add it also on the remote.
But there is a way to avoid using the wild card and programatically force the pair with a specific ANT ID device?
Yes, there is define on line 68 of main.c:
#define LEV_CHAN_ID_DEV_NO
this needs to be set to the ANT device # you put in the motor.
 
rananna said:
Yes, there is define on line 68 of main.c:
#define LEV_CHAN_ID_DEV_NO
this needs to be set to the ANT device # you put in the motor.
Ok, I see but that seems very easy... I will do it.
 
casainho said:
rananna said:
Yes, there is define on line 68 of main.c:
#define LEV_CHAN_ID_DEV_NO
this needs to be set to the ANT device # you put in the motor.
Ok, I see but that seems very easy... I will do it.

I also did some testing of the pairing of the remote to a specific LEV master device with the TSDZ2 firmware.
Although it works fine with LEV_CHAN_ID_DEV_NO set to the specific device number of the motor as I suggested, it may speed up the pairing if you also set LEV_CHAN_ID_TRANS_TYPE in the remote main.c to 5.
(5 is LEV transmission type, so it won't have to search)
 
rananna said:
casainho said:
rananna said:
Yes, there is define on line 68 of main.c:
#define LEV_CHAN_ID_DEV_NO
this needs to be set to the ANT device # you put in the motor.
Ok, I see but that seems very easy... I will do it.

I also did some testing of the pairing of the remote to a specific LEV master device with the TSDZ2 firmware.
Although it works fine with LEV_CHAN_ID_DEV_NO set to the specific device number of the motor as I suggested, it may speed up the pairing if you also set LEV_CHAN_ID_TRANS_TYPE in the remote main.c to 5.
(5 is LEV transmission type, so it won't have to search)
Good to know.

I must say thay I can't easily change from projects and right now I am working on the motor wireless side, specifically on the EEPROM saving for the configurations. Then I have the configurations side to implement on the Android app - to resume, what is currently working is Bluetooth, ANT+ LEV and TSZD2 motor control.
 
casainho said:
rananna said:
casainho said:
rananna said:
Yes, there is define on line 68 of main.c:
#define LEV_CHAN_ID_DEV_NO
this needs to be set to the ANT device # you put in the motor.
Ok, I see but that seems very easy... I will do it.

I also did some testing of the pairing of the remote to a specific LEV master device with the TSDZ2 firmware.
Although it works fine with LEV_CHAN_ID_DEV_NO set to the specific device number of the motor as I suggested, it may speed up the pairing if you also set LEV_CHAN_ID_TRANS_TYPE in the remote main.c to 5.
(5 is LEV transmission type, so it won't have to search)
Good to know.

I must say thay I can't easily change from projects and right now I am working on the motor wireless side, specifically on the EEPROM saving for the configurations. Then I have the configurations side to implement on the Android app - to resume, what is currently working is Bluetooth, ANT+ LEV and TSZD2 motor control.

Ok I did further testing on the pairing speed and the transmission type seems to have no real effect on the pairing speed.

So I checked the ANT docs and found this statement:

'The transmission type is used to define the type of channel (either uni or bi-directional) as well as the global page format (that is, where the global page is within the message, for example, for a shared channel it will be the 3rd byte and not the first). As a receiver you should always wildcard this field when pairing to a particular device.'

I had it right the first time. Just set LEV_CHAN_ID_DEV_NO to the same number in the motor. Leave LEV_CHAN_ID_TRANS_TYPE set to zero for wildcarding on the transmission type.
Sorry for any confusion, and good luck with the configuration setup on the motor.
 
So, now I have the ANT ID successfully being changed by the Bluetooth.

Then I looked at the Android app and found it is not finding the device and then I implemented the Bluetooth pairing based on an example code. Then finally the Android app see the device and it can be selected:

Screenshot-20201020-045134-TSDZ2-ESP32.jpg
 
rananna said:
Is the information being saved in EEPROM?
Yes!!

Code:
static void ant_id_write_handler(uint16_t conn_handle, ble_ant_id_t * p_ant_id, uint8_t value)
{
  ui8_m_ant_device_id = value;
}

// see if there was a change to the ANT ID
if (ui8_m_ant_device_id != mp_ui_vars->ui8_ant_device_id)
{
  mp_ui_vars->ui8_ant_device_id = ui8_m_ant_device_id;
  change_ant_id_and_reset();
}

void change_ant_id_and_reset(void)
{
  // NOTE that flash of EEPROM does not work on an interrupt like on the ant_id_write_handler(), hence it is done here on main()
  eeprom_write_variables();

  // wait some time to make sure eeprom is written
  nrf_delay_ms(1000);

  // finally reset so the new ANT ID will take effect
  NVIC_SystemReset();
}
 
casainho said:
rananna said:
Is the information being saved in EEPROM?
Yes!!

Code:
static void ant_id_write_handler(uint16_t conn_handle, ble_ant_id_t * p_ant_id, uint8_t value)
{
  ui8_m_ant_device_id = value;
}

// see if there was a change to the ANT ID
if (ui8_m_ant_device_id != mp_ui_vars->ui8_ant_device_id)
{
  mp_ui_vars->ui8_ant_device_id = ui8_m_ant_device_id;
  change_ant_id_and_reset();
}

void change_ant_id_and_reset(void)
{
  // NOTE that flash of EEPROM does not work on an interrupt like on the ant_id_write_handler(), hence it is done here on main()
  eeprom_write_variables();

  // wait some time to make sure eeprom is written
  nrf_delay_ms(1000);

  // finally reset so the new ANT ID will take effect
  NVIC_SystemReset();
}

Nice work! The 1 sec delay for write will be hardly noticeable by the users .
 
casainho said:
So, now I have the ANT ID successfully being changed by the Bluetooth.

Then I looked at the Android app and found it is not finding the device and then I implemented the Bluetooth pairing based on an example code. Then finally the Android app see the device and it can be selected:

how is the plan now? my flutter (android/ios) app has currently the json config interface partially implemented and is also able to scan and connect to bluetooth devices (incl. reconnection). i have tested it with the dongle blinky app. im waiting for a sign that the bluetooth firmware for the dongle is ready so i can flash it and start developing against it.

i have not followed the thread closely so sorry if i missed something.

here is the source of my app so far which can be built using flutter:
https://github.com/bhelm/ebikeapp
 
raw said:
how is the plan now? my flutter (android/ios) app has currently the json config interface partially implemented and is also able to scan and connect to bluetooth devices (incl. reconnection). i have tested it with the dongle blinky app. im waiting for a sign that the bluetooth firmware for the dongle is ready so i can flash it and start developing against it.

i have not followed the thread closely so sorry if i missed something.

here is the source of my app so far which can be built using flutter:
https://github.com/bhelm/ebikeapp
I thought you were no more interested on this project because I did not reacted anymore.

So, I started looking at the OpenSource Android app TSDZ2-ESP32: https://github.com/TSDZ2-ESP32/TSDZ2-Android/blob/master/app/src/main/java/spider65/ebike/tsdz2_esp32/TSDZBTService.java

I got it connecting to the UUID and please use this ones:

public static String TSDZ_SERVICE = "dac21400-cfdd-462f-bfaf-7f6e4ccbb45f";
public static String TSDZ_CHARACTERISTICS_PERIODIC = "dac21401-cfdd-462f-bfaf-7f6e4ccbb45f";
public static String TSDZ_CHARACTERISTICS_CONFIG = "dac21402-cfdd-462f-bfaf-7f6e4ccbb45f";

Where the PERIODIC is a byte array of periodic data written every 50 ms to the BLE characteristic. This periodic also has some bits for status.
The CONFIG is also a byte array for the configurations, you should read first, change on the mobile phone and then send them back again.

Well, so now I should take care of the JSON?? Can you help on this? Please find my latest firmware here: https://github.com/OpenSource-EBike-firmware/TSDZ2_wireless/tree/bluetooth

I will be looking how I can run and debug your app...
 
@raw,

I was able to open your project on code studio and run and debug on my phone.

Screenshot-20201020-162825.jpg


It only lists one device one device from a few that should be shown... And I can't disconnected it, it always connect to that one and doesn't show the others. Please solve this!

See that the most priority thing is to be able to see and change the configurations. Then, the next priority is a main page that shows variables like the wheel speed and so on, this will also help me to debug all the system.
 
I am happy I can run and debug the Flutter code just like on Android studio. But there are disadvantages, that I don't understand nothing of Flutter and on the other side I can easily tailor TSDZ2-ESP32 Android Java code to work for my immediate needs. So, my plan for now is to keep working on the Android Java because is the only I can do and I will wait for you to develop the Flutter version - if you will be faster, then I think I will be able to switch faster to Flutter... TSDZ2-ESP32 Java is already done, that is also a big advantage. I think it all depends on your help, how fast you can develop the app.

Here a screenshot showing the run and debug of Flutter code, somewhere I think the implementation is not good because I only see that Bluetooth device although I have a few more around:

Screenshot-from-2020-10-20-21-15-59.png
 
Thought I would upload a video showing the remote with an edge 1030 bike computer.
Off screen I have a nrf52840 dongle programmed as a TSDZ2 ebike that is transmitting to the edge 1030. For example, note the speed of the ebike is set constant at 25km/hr.

The remote is communicating with the edge 1030 as an ANT+ remote for page turns, ( long press on the remote) and also with the ebike nrf52840 dongle as an ANT+ LEV remote for changing assist level. ( Short press on the remote)
The assist level changes instantly on the ebike, but you will note in the video that there is a small delay before the display gets updated with a new assist level.
This is because the ANT protocol has a polling interval for information going to the edge 1030 display.

https://youtu.be/D-wMMj92RmM
 
rananna said:
[youtube]D-wMMj92RmM[/youtube]
Thanks for sharing. Do you know if the official Garmin EBike button works like the way you implemented??

And by the way, if you flash the latest version of TSDZ2 wireless firmware, you will be able to test the change of ANT ID.
 
casainho said:
rananna said:
[youtube]D-wMMj92RmM[/youtube]
Thanks for sharing. Do you know if the official Garmin EBike button works like the way you implemented??

And by the way, if you flash the latest version of TSDZ2 wireless firmware, you will be able to test the change of ANT ID.
The operation of the garmin ebike remote is slightly different due to the different button layout. See the attached pdf.
However, we can easily change the button operation to implement any operation as we see fit. Button operation could even be configured by the android app if we wish to give users that flexibility.
BTW, I don't see the work you did with the Bluetooth ANTconfiguration available in the latest commit. Did you update github recently?
 

Attachments

  • eBike_Remote_QSM.pdf
    800.5 KB · Views: 25
rananna said:
The operation of the garmin ebike remote is slightly different due to the different button layout. See the attached pdf.
However, we can easily change the button operation to implement any operation as we see fit. Button operation could even be configured by the android app if we wish to give users that flexibility.
BTW, I don't see the work you did with the Bluetooth ANTconfiguration available in the latest commit. Did you update github recently?
I think we should follow the standards as possible and I want that users can simple buy the Garmin remote or other and it will work - the DIY should work the same. Do you think Garmin remote also implements the ANT+ LEV or ANT+ buttons?

The code is on the Bluetooth branch, I did not yet merge it to the master branch.
 
casainho said:
I am happy I can run and debug the Flutter code just like on Android studio. But there are disadvantages, that I don't understand nothing of Flutter and on the other side I can easily tailor TSDZ2-ESP32 Android Java code to work for my immediate needs.

Yes, flutter has some learning curve. when coming from c/c++ android (java) is much more straight forward, while flutter belongs more to the latest reactive web development efforts (react, vuejs, angular).

flutter is also pretty new so there are not many people familiar with it. but if starting some app from scratch i would always go the flutter route because it is faster and easier to get something going (especially no messing with different android SDK versions and their compatibility problems). getting iOS support for free is only the cherry on the top :)

casainho said:
@raw,

I was able to open your project on code studio and run and debug on my phone.

It only lists one device one device from a few that should be shown... And I can't disconnected it, it always connect to that one and doesn't show the others. Please solve this!

See that the most priority thing is to be able to see and change the configurations. Then, the next priority is a main page that shows variables like the wheel speed and so on, this will also help me to debug all the system.

Oh, you are fast! Ok i will look into it this evening.

if you are really curious, you can test the flutter_blue sample app which is basically like the nrfConnect app (scans devices, lists services): https://github.com/pauldemarco/flutter_blue/tree/master/example
If it does not discover and disconnect there correctly while it is working as it should in nrfConnect, then there may be something wrong with the (not so mature) flutter_blue library.
 
casainho said:
rananna said:
The operation of the garmin ebike remote is slightly different due to the different button layout. See the attached pdf.
However, we can easily change the button operation to implement any operation as we see fit. Button operation could even be configured by the android app if we wish to give users that flexibility.
BTW, I don't see the work you did with the Bluetooth ANTconfiguration available in the latest commit. Did you update github recently?
I think we should follow the standards as possible and I want that users can simple buy the Garmin remote or other and it will work - the DIY should work the same. Do you think Garmin remote also implements the ANT+ LEV or ANT+ buttons?

The code is on the Bluetooth branch, I did not yet merge it to the master branch.
The garmin remote is quite expensive here in Canada!
Regarding the programming of the garmin remote, it does look like they have incorporated ANT+ LEV & ANT+ CTLS profiles to communicate with the ebike and edge computers just like I did with the open-source remote.
I will add Bluetooth to the remote as you have done in the branch and test with nrfconnect. Are there any outstanding issues I need to be aware of?
What setting is used to change the ANT ID using nrfconnect?
 
rananna said:
The garmin remote is quite expensive here in Canada!
Regarding the programming of the garmin remote, it does look like they have incorporated ANT+ LEV & ANT+ CTLS profiles to communicate with the ebike and edge computers just like I did with the open-source remote.
Ok, that is good. Do you know if we can do the same for pairing as they do?

rananna said:
I will add Bluetooth to the remote as you have done in the branch and test with nrfconnect. Are there any outstanding issues I need to be aware of?
What setting is used to change the ANT ID using nrfconnect?
There are no issues I am aware of.

The code works like this:
- the ant_id_write_handler() is called when you open the nrfconnect and write a value to the only available characteristic, which also changes the ui8_m_ant_device_id
- on main loop, is tested to see if ui8_m_ant_device_id changed, then, mp_ui_vars->ui8_ant_device_id = ui8_m_ant_device_id; and then is called change_ant_id_and_reset()
- change_ant_id_and_reset() writes on EEPROM all the mp_ui_vars. Resets as the mp_ui_vars->ui8_ant_device_id is used at startup to be the ANT ID

Code:
static void ant_id_write_handler(uint16_t conn_handle, ble_ant_id_t * p_ant_id, uint8_t value)
{
  ui8_m_ant_device_id = value;
}

// see if there was a change to the ANT ID
if (ui8_m_ant_device_id != mp_ui_vars->ui8_ant_device_id)
{
  mp_ui_vars->ui8_ant_device_id = ui8_m_ant_device_id;
  change_ant_id_and_reset();
}

void change_ant_id_and_reset(void)
{
  // NOTE that flash of EEPROM does not work on an interrupt like on the ant_id_write_handler(), hence it is done here on main()
  eeprom_write_variables();

  // wait some time to make sure eeprom is written
  nrf_delay_ms(1000);

  // finally reset so the new ANT ID will take effect
  NVIC_SystemReset();
}
 
casainho said:
Ok, that is good. Do you know if we can do the same for pairing as they do?

We are effectively doing the same with pairing as Garmin is doing with their remote, with the only difference being that have an LED readout to indicate pairing and battery status.
Once paired, the Garmin remote remembers the device ID, at least until the battery dies.

It appears the Garmin iuses wildcard pairing for the ebike which means it would pair with any ebike within range. They have to do this to ensure the remote works with any ebike.
Of course, we would operate the same as this if we kept using wildcard pairing in the opensource remote

As we previously discussed, one advantage we would have over the Garmin remote in not doing wildcard pairing is the ability to set the opensource remote's ANT ID to pair with a specific TSDZ2 motor, which would both speed up pairing and prevent issues with people having multiple ebikes in range during the pairing process.

Thanks for the coding explanation, I will implement bluetooth to allow the Ant ID to be set in the opensource remote.
 
raw said:
Oh, you are fast! Ok i will look into it this evening.

if you are really curious, you can test the flutter_blue sample app which is basically like the nrfConnect app (scans devices, lists services): https://github.com/pauldemarco/flutter_blue/tree/master/example
If it does not discover and disconnect there correctly while it is working as it should in nrfConnect, then there may be something wrong with the (not so mature) flutter_blue library.
So I decided to try, and I did a few times and I always got the same as on your app. This time, when clicking on OPEN I get the throw as seen on the next image.

So now what?

Screenshot-from-2020-10-21-17-39-46.png
 
Back
Top