TSDZ2 mid drive with 860C, 850C or SW102 displays only -- Flexible OpenSource firmware (Casainho code only)

buba said:
I would of loved to hear some feedback of why this has happened and what the problem was exactly. I think there is something different causing the problem - not the previous code. Can someone else confirm the walk assist worked with high level of adjustability and precision and that it has suddenly changed in the last firmware changes? If this is the case even the Cruise function will not function properly so this leads me to believe this needs investigation.

I just got home from abroad and will try to test the firmware changes the next couple of days.

Hi, yes Buba, the previous version I had was your 0.18beta and walk and cruise were working ok.. not many test on walk assist as I had no chances to really push the bike up the hill, but the cruise was working the way I was expecting (I did not configured the target speed but just keeping the current speed).

Another thing I was seeing yesterday: I set assistance 1 to the minimum value 0.1 in order to reduce the gap while running with muscular bikers, and the motor power shown in the ODO menu 1.0 was 70-90 W..
I understood that the motor gives the human power*multiplier (0.1 in my case) but I really doubt I was putting 700-900W myself.
Did I understand correctly? Could you suggest some further checks to perform?
Or maybe the torque is not well calibrated?
Thanks
 
thineight said:
Another thing I was seeing yesterday: I set assistance 1 to the minimum value 0.1 in order to reduce the gap while running with muscular bikers, and the motor power shown in the ODO menu 1.0 was 70-90 W..
Forget such low values. I think we can't expect such quality from cheap ebikes hardware.
 
I tried a v0.19.0-beta3 version today. I drove just a short distance because it was very cold and started to rain. Walking assistant worked well and cruise too. Boost function I didn't try.

Suddenly the assist ended, I tried to increase the level of assistance, did not help. I booted KTLCD3 and the assist were back again. The odometer still shows too much.

I drove only 14 km. I put tomorrow warm clothes and will drive longer trip.
 
dameri said:
The odometer still shows too much.

This issue is under investigation by Buba these days.
I guess it's a trivial solution for this issue.
Let's wait the beta4..
 
dameri said:
I tried a v0.19.0-beta3 version today. I drove just a short distance because it was very cold and started to rain. Walking assistant worked well and cruise too. Boost function I didn't try.

Suddenly the assist ended, I tried to increase the level of assistance, did not help. I booted KTLCD3 and the assist were back again. The odometer still shows too much.

I drove only 14 km. I put tomorrow warm clothes and will drive longer trip.

Can report that the odometer/distance measurement is solved. Tested the bug fix yesterday and today. But need user validation as well.

I have not looked at the other issues but will maybe have some time to look through all the recent changes tomorrow.

thineight said:
This issue is under investigation by Buba these days.
I guess it's a trivial solution for this issue.
Let's wait the beta4..

Submitted the code today and it will be in the next beta.
 
There is a new version of SDCC and on change log seems there are some improvements for STM8: https://sourceforge.net/p/sdcc/code/HEAD/tree/tags/sdcc-3.9.0-pre1/sdcc/ChangeLog

Maybe I will try to use the new version.
 
Nick said:
Hi everyone,

I really like those SW102 displays because do be honest I think the LCD3 is far from a modern good looking display and the 850c is way to big.
But opening this little diva is really a pain!
Here are my findings to get at least to the debug pins without destroying too much:
1) Remove Up/Dwn key lid with a cutter (you can leave the M button lid in place).
2) Now the tricky one: Cut into the gap between the cases edge and key pad and repeating this over and over again until you can lift of the key pad by levering it off.

Maybe some pictures say more:

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg


You can get an idea of the assembly from this picture:
6.jpg

As you can see this is quite heavily glued together and reassembling this functioning and water resistant is a different story to tell :D
But at least nothing is deformed or broken.
The only feasible approach would be to open it once, flash open source firmware (bootloader!), glue it back together and updating from then on over Bluetooth or cable to the motor (just like we do with the TSDZ2 motor).

I think this will be a show stopper for many people. Wouldn't it be much more straight forward to simulate the corresponding portocol so we can just use those displays without opening/reprogramming?

BTW, this picture shows the reassembled SW102 from above (you can quite easy clip the keypad back in):
7.jpg

casainho said:
I created a simple project based on a sample project of UART <-> Bluetooth communication, based on Nordic NRF SDK for the SW102 LCD microcontroller and flash and debug successfully. I am using just the same tools as I use for 850C color LCD: STLinkV2 clone + ARM GCC + OpenOCD + Eclipse.
The project code is here: https://github.com/OpenSource-EBike-firmware/SW102_LCD_Bluetooth
...

Thanks for the great instructions That will really help. I am still waiting on my SW102 to be delivered, but in the mentime I had a thought. Do you think it may be possible to drill 4 small holes through the plastic cover ( after Remove Up/Dwn key lid) right above the 4 programming pads? Then you could use a standard pin header to connect through to them while programming?


The advantage would be that you could then seal with a little tape or hot glue and replace the buttons and (hopefully) maintain the waterproof.

If it looks possible it would be great if you could measure the location of the pads from the edge and bottom ,or any easy to explain fixed point, so i can make up a template and give it a try when my SW102 arrives.
 
haiyi911 said:
Hi,
TIM3 counter period = (1 / (16000000 / 16384)) * (65535 + 1) = 67 S not 1 ms??
Thanks for looking at the code.

That is a piece of code from TSDZ2 motor controller. There, we use Timer3 counter to count the time on main loop and call ebike_app_controller() every 100ms and motor_controller() every 4ms (that is the theory, really values may change a bit depending on some error on calculations and microcontroller processing load). What matters there is the frequency of timer counter increment and it happens every 1/(16000000/16384) ~= 1ms. Here is Timer3 being used:

Code:
  while(1)
  {
    // because of continue; at the end of each if code block that will stop the while (1) loop there,
    // the first if block code will have the higher priority over any others
    ui16_TIM3_counter = TIM3_GetCounter();
    if((ui16_TIM3_counter - ui16_motor_controller_counter) > 4) // every 4ms
    {
      ui16_motor_controller_counter = ui16_TIM3_counter;
      motor_controller();
      continue;
    }

    ui16_TIM3_counter = TIM3_GetCounter();
    if((ui16_TIM3_counter - ui16_ebike_app_controller_counter) > 100) // every 100ms
    {
      ui16_ebike_app_controller_counter = ui16_TIM3_counter;
      ebike_app_controller();
      continue;
    }
  }

And on LCD3 firmware, which uses exactly same microcontroller and running frequency of 16MHz, Timer3 is also being used to count main loop calls (every 1ms also) and I did that differently (it was done after the firmware for the motor controller):

Code:
void timer3_init (void)
{
  uint16_t ui16_i;

  // TIM3 Peripheral Configuration
  TIM3_DeInit();

  // 16MHz clock
  // prescaler = 4
  // target: 1ms (0.001)
  // 0.001 ÷ (1÷(16000000÷4)) = 4000
  TIM3_TimeBaseInit(TIM3_PRESCALER_4, 4000); // each interrupt at 1ms
  TIM3_ClearFlag(TIM3_FLAG_UPDATE); // clear TIM3 update flag
  TIM3_ITConfig(TIM3_IT_UPDATE, ENABLE); // enable update interrupt
  TIM3_Cmd(ENABLE); // TIM3 counter enable

  // IMPORTANT: this software delay is needed so timer3 work after this
  for(ui16_i = 0; ui16_i < (29000); ui16_i++) { ; }
}

// happens every 1 ms
void TIM3_UPD_OVF_BRK_IRQHandler(void) __interrupt(TIM3_UPD_OVF_BRK_IRQHANDLER)
{
  ui16_timer3_counter++;

(...)
}

  while (1)
  {
    // because of continue; at the end of each if code block that will stop the while (1) loop there,
    // the first if block code will have the higher priority over any others
    ui16_timer3_counter = get_timer3_counter ();
    if ((ui16_timer3_counter - ui16_10ms_loop_counter) > 10) // every 10ms
    {
      ui16_10ms_loop_counter = ui16_timer3_counter;

      buttons_clock ();
      lcd_clock ();
      uart_data_clock ();

      continue;
    }
  }
 
haiyi911 said:
Thanks, casainho
now i see.
Please submit a pull request with that changes.
 
perryscope said:
Thanks for the great instructions That will really help. I am still waiting on my SW102 to be delivered, but in the mentime I had a thought. Do you think it may be possible to drill 4 small holes through the plastic cover....

I think this is a matter of taste and IMHO the way to go is to open it once, install a software with bootloader and than seal it off. It is much less hassle to just remove the keypad and seal it off with a bit of standard silicone afterwards. And we just use the bootloader to update the device.
Btw, you can't use a standard pin header because the programming pads have a smaller pitch of 2mm (Oh, I just see that 2 mm pin header are also quite common. So that wouldn't be the problem).


Greetings
Nick
 
perryscope said:
Thanks for the great instructions That will really help. I am still waiting on my SW102 to be delivered, but in the mentime I had a thought. Do you think it may be possible to drill 4 small holes through the plastic cover ( after Remove Up/Dwn key lid) right above the 4 programming pads? Then you could use a standard pin header to connect through to them while programming?
pins.JPG

The advantage would be that you could then seal with a little tape or hot glue and replace the buttons and (hopefully) maintain the waterproof.

If it looks possible it would be great if you could measure the location of the pads from the edge and bottom ,or any easy to explain fixed point, so i can make up a template and give it a try when my SW102 arrives.

An idea is to desolder the three buttons, make a cable with 10 wires, (2 for each button, 4 for programming) solder all, add black silicone, so there are 6 cables that can be soldered also with lcd3 buttons or with a diy remote switch, and 4 cable to flash the firmware. In this way there's no need to unmount it every time, and in addition the buttons are under hand
 
e3s said:
An idea is to desolder the three buttons, make a cable with 10 wires, (2 for each button, 4 for programming) solder all, add black silicone, so there are 6 cables that can be soldered also with lcd3 buttons or with a diy remote switch, and 4 cable to flash the firmware. In this way there's no need to unmount it every time, and in addition the buttons are under hand
I like that idea, I think it should be shared on wiki with photos.

Still, I like the idea of bootloader as a final user (for my other family ebikes, for instance) but my ebike will have the cables as I will be doing development and I need that wires.

About the boootloader, seems we will have only 144kbytes for our application which is not much... :-(

See here: https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v4.x.x/doc/html/group__dfu__mem__layout__single__bank.html

ble_app_dfu_full_memory.png


The table below lists the memory ranges when using an S110 SoftDevice. The SoftDevice will be using region 1 memory spanning from address 0x0 to 0x14000. Region 1 will contain the application and bootloader.

Memory Range Usage
0x0003C800 - 0x00040000 Code Region 1: DFU Bootloader and data
0x00014000 - 0x0003C800 Code Region 1: Application Code (BANK 0) and data
0x00000000 - 0x00014000 Code Region 0: SoftDevice
Code region 1 size will depend on the size of the SoftDevice used. For this example, with a 256KB version of the nrf51 the stack uses 80KB leaving 176KB to the bootloader and the application.

The region is then divided into 3 sub-regions:

Bootloader
Application Data
Application (BANK 0)
The bootloader projects in the SDK has reserved 32KB for the bootloader and the bootloader settings data. The memory reservation can easily be modified in the project files to match the final size of the bootloader. For the example bootloader provided, the application will get a total of 176KB - 32KB = 144KB. The available memory for an application would be 176KB - application save data.
 
So lets say 128k left for application data. This feels not that bad if you take into account this will be a small device and we don't need high sophisticated graphic charts but "only" some text & menues. How much is the memory on the LCD3 display? 32k I think, correct me if I'm wrong. So this is 4x the space plus the ability to do OTA updates & enhanced features on a smartphone app.

Sounds good to me!
 
Nick said:
So lets say 128k left for application data. This feels not that bad if you take into account this will be a small device and we don't need high sophisticated graphic charts but "only" some text & menues. How much is the memory on the LCD3 display? 32k I think, correct me if I'm wrong. So this is 4x the space and plus the ability to do OTA updates & enhanced features on a smartphone app.

Sound good to me!
I don't want to be pessimistic, but comparing to LCD3, we see it is not enough, we really need more space, maybe like more 50%. Since it is a graphic display, it uses much more memory to store letters and numbers.

I can say that 850C, with configuration menu + regular main screen, uses a bit more than 128kbytes.
If we skip configuration menu on SW102, maybe it will be ok but I still think we will not have much space free...

Well, anyway, I guess is better than LCD3. I guess there will be not much reasons to go to LCD3, I think users will want SW102 or 850C.
 
So we have two very different displays SW102 and 850C, this is good. IMHO the SW102 should be the Small&Simple approach with some basic setting menus and just some data on the main screen you can choose of. I (and as far as I know many other users) demand this simple approach and just don't need enhanced features on the display.
I don't like the idea to copy the feature list of the LCD3 to the SW102 one-to-one. With all respect to the great work of the developers involved in LCD3 programming, there are way too much features on this display and such a pain to get used to if you ask me!

Should we discuss the feature list of SW102?
What is important data for me:
+ Speed
+ Consumed Wh / Battery bar
+ Current Assist Level
+ Distance traveled (since power on / since reset)
+ Timer (since switched on / actually riding)
+ Basic settings (f.i. I don't need to set max. amount of assist levels and fine tune them).

What I never use and would not miss:
+ Offroad mode switch (As soon as you hack your e-bike you are on the dark side anyway :D )
+ All kinds of range estimation (inaccurate anyway)
+ All shapes of human pedal power "estimation" (inaccurate anyway)
+ Main screen setup (we don't have that much data)
+ Motor Temperature Protection (very complicated to install anyway)
+ Advanced Technical Data (sure important for development but not for "end user")
+ Sure forgot some

I am aware, that this is a highly personal point of view. So please don't beat me :D ! But I think we have to select only some features and implement more in the 850C.

Btw:
Newest SoftDevice S110 v2.0 Specs list a bit more memory space used:
96k Flash & 8k RAM (page 35)
https://www.nordicsemi.com/-/media/DocLib/Other/SoftDevice_Spec/S110SDSv20.pdf
 
perryscope said:
Thanks for the great instructions That will really help. I am still waiting on my SW102 to be delivered, but in the mentime I had a thought. Do you think it may be possible to drill 4 small holes through the plastic cover ( after Remove Up/Dwn key lid) right above the 4 programming pads? Then you could use a standard pin header to connect through to them while programming?
pins.JPG

The advantage would be that you could then seal with a little tape or hot glue and replace the buttons and (hopefully) maintain the waterproof.

If it looks possible it would be great if you could measure the location of the pads from the edge and bottom ,or any easy to explain fixed point, so i can make up a template and give it a try when my SW102 arrives.

The problem for solderless contact is the pressure on each pin, there's need to press very well to maintain the contact otherwise there is the risk of interruption of data transfer
 
casainho said:
haiyi911 said:
Thanks, casainho
now i see.
Please submit a pull request with that changes.

Hello casainho, any chance for you to release the next version with Buba fixes on LCD3 before the weekend?
It is a good window for us to test and report the feelings.

Side question: how did you sort the backwards resistance? Did you recycle marcoq code?
 
I tested v19 beta 3 on a coaster brake motor. There is no backward resistance but I also have no power. I did a reset and triple checked all the settings. There are good torque and PAS/cadence readings but always 0 watts. Any ideas?

The motor worked fine with v18.2 but had extreme backward resistance that made it unusable for coaster brake.
 
casainho said:
I don't want to be pessimistic, but comparing to LCD3, we see it is not enough, we really need more space, maybe like more 50%. Since it is a graphic display, it uses much more memory to store letters and numbers.

I can say that 850C, with configuration menu + regular main screen, uses a bit more than 128kbytes.
If we skip configuration menu on SW102, maybe it will be ok but I still think we will not have much space free...

Well, anyway, I guess is better than LCD3. I guess there will be not much reasons to go to LCD3, I think users will want SW102 or 850C.

You are completely correct!

-----------------------------------------------------------------------------------------------------------------

Just putting this out there for anyone interested: all these displays have much more programming space than for instance segment displays such as the KT-LCD3. But they need the space for storing all the graphical data, the GUI. There are also more functions to consider for the back end. Just as Casainho explained.

Therefore it is strictly not possible to compare segment displays with these "real" displays as far as program memory goes. It is uncommon to design electronics with extra overhead for program memory as it is expensive. It is still better than the KT-LCD3 with many great functions Nick mentioned. But the comment from Casainho about limited space is valid.
 
On one hand, I would consider replacing the KT-LCD3 microcontroller with a bigger one and same footprint and pinout.
I think actual one is STM8S105C6T6, maybe STM8S207S6T6C could be an option, but this require more skills in soldering.

On the other hand, I think moving to Arduino platform may be a goot option. Look at ESP8266 or ESP32. Lot of RAM/Flash, higher CPU freq.
 
orfait said:
On one hand, I would consider replacing the KT-LCD3 microcontroller with a bigger one and same footprint and pinout.
I think actual one is STM8S105C6T6, maybe STM8S207S6T6C could be an option, but this require more skills in soldering.

On the other hand, I think moving to Arduino platform may be a goot option. Look at ESP8266 or ESP32. Lot of RAM/Flash, higher CPU freq.
Also I think a SW102 or 850C will be easier for shops that already sell TSDZ2 and LCD3 with our firmware, to add this new LCDs. Because they simple can ask in China to buy them with our firmware installed from the factory.

While I like the Arduino, I even bought all parts needed to follow that path and build an LCD, in the end I prefer to open and flash firmware on one that already exist.

After LCDs, I think the space to grow is on the mobile app. I think this LCDs should have enough memory for the standard advanced features and I agree that LCD3 may have to much of them. SW102 with mobile app may be a good equilibrium.
 
thineight said:
Hello casainho, any chance for you to release the next version with Buba fixes on LCD3 before the weekend?
It is a good window for us to test and report the feelings.

Side question: how did you sort the backwards resistance? Did you recycle marcoq code?
Buba fixes were only to distance so I think it is not enough for a new release, looking at the other issues reported.

Yes, I looked at changes on marcoq but I understand them very well so I took great care to insert on current code because there a lot of places where there are implications.

Rydon said:
I tested v19 beta 3 on a coaster brake motor. There is no backward resistance but I also have no power. I did a reset and triple checked all the settings. There are good torque and PAS/cadence readings but always 0 watts. Any ideas?

The motor worked fine with v18.2 but had extreme backward resistance that made it unusable for coaster brake.
This code changed bit since beta 2, now ui8_pas_cadence_rpm will be 0 if we are not pedaling forward:
Code:
static void read_pas_cadence (void)
{
  // cadence in RPM =  60 / (ui16_pas_timer2_ticks * PAS_NUMBER_MAGNETS * 0.000064)
  if((ui16_pas_pwm_cycles_ticks >= ((uint16_t) PAS_ABSOLUTE_MIN_CADENCE_PWM_CYCLE_TICKS)) ||
      (ui8_g_pedaling_direction != 1)) // if not rotating pedals forward
  { 
    ui8_pas_cadence_rpm = 0; 
  }
  else
  {
    ui8_pas_cadence_rpm = (uint8_t) (60 / (((float) ui16_pas_pwm_cycles_ticks) * ((float) PAS_NUMBER_MAGNETS) * 0.000064));
  }
}

Can you please verify that you have cadence value only when pedaling forward??

This is the new piece of code to turn on/off the motor PWM. See that if there is not ui8_m_adc_battery_target_current because there is no cadence or torque.

Try also to enable BOOST.

Code:
  // let's force our target current to 0 if brake is set or if there are errors
  if(brake_is_set() ||
      m_configuration_variables.ui8_error_states != ERROR_STATE_NO_ERRORS)
  {
    ui8_m_adc_battery_target_current = 0;
  }

  // check to see if we should enable the motor
  if(ui8_m_motor_enabled == 0 &&
      (ui16_motor_get_motor_speed_erps() == 0) && // we can only enable if motor is stopped other way something bad can happen due to high currents/regen or something like that
      ui8_m_adc_battery_target_current)
  {
    {
      ui8_m_motor_enabled = 1;
      motor_enable_pwm();
    }
  }

  // check to see if we should disable the motor
  if(ui8_m_motor_enabled &&
      ui16_motor_get_motor_speed_erps() == 0 &&
      ui8_m_adc_battery_target_current == 0 &&
      ui8_g_duty_cycle == 0)
  {
    ui8_m_motor_enabled = 0;
    motor_disable_pwm();
  }
 
Back
Top