Skip to content

Commit faa630d

Browse files
author
jenkie
committed
Add support for new SEMPU bottom bracket
with two pas wires (as Thun X-Cell RT)
1 parent 5d37a7a commit faa630d

File tree

4 files changed

+42
-34
lines changed

4 files changed

+42
-34
lines changed

Arduino_Pedelec_Controller/Arduino_Pedelec_Controller.ino

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Time now;
8888
#error Soft poti is incompatible with throttle auto cruise
8989
#endif
9090

91-
#if defined(SUPPORT_LIGHTS_SWITCH) && (defined(SUPPORT_XCELL_RT)||defined(SUPPORT_SEMPU_V1)) && HARDWARE_REV < 20
91+
#if defined(SUPPORT_LIGHTS_SWITCH) && (defined(SUPPORT_XCELL_RT)||defined(SUPPORT_SEMPU)||defined(SUPPORT_SEMPU_V1)) && HARDWARE_REV < 20
9292
#error Software controlled lights switch is not compatible with torque sensor support on FC < 2.0
9393
#endif
9494

@@ -133,7 +133,7 @@ struct savings //add variables if you want to store additional values to the e
133133
#ifdef SUPPORT_BATTERY_CHARGE_COUNTER
134134
unsigned int charge_count;//battery charge count
135135
#endif
136-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
136+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
137137
float wh_human; //human watthours
138138
#endif
139139
};
@@ -271,16 +271,19 @@ double torque=0.0; //cyclist's torque in Nm (averaged over one pedal r
271271
double torque_instant=0.0; //cyclist's torque in Nm (live)
272272
double power_human=0.0; //cyclist's power
273273
double wh_human=0;
274-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
274+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)|| defined(SUPPORT_SEMPU)
275275
int torque_zero=TORQUE_ZERO; //Offset of torque sensor. Adjusted at startup if TORQUE_AUTOZERO option is set
276276
static volatile boolean analogRead_in_use = false; //read torque values in interrupt only if no analogRead in process
277277
static volatile boolean torque_want_calculation = false; //read torque values in interrupt only if no analogRead in process
278278
#if HARDWARE_REV<20 && defined(SUPPORT_XCELL_RT)
279279
const int torquevalues_count=8;
280280
volatile int torquevalues[torquevalues_count]= {0,0,0,0,0,0,0,0}; //stores the 8 torque values per pedal roundtrip
281-
#else
281+
#elif defined(SUPPORT_SEMPU_V1)
282282
const int torquevalues_count=16;
283283
volatile int torquevalues[torquevalues_count]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //stores the 16 torque values per pedal roundtrip (Thun) or half roundtrip (Sempu)
284+
#elif defined(SUPPORT_SEMPU)
285+
const int torquevalues_count=24;
286+
volatile int torquevalues[torquevalues_count]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //stores the 24 torque values per pedal half roundtrip (Sempu new version)
284287
#endif
285288
volatile byte torqueindex=0; //index to write next torque value
286289
volatile boolean readtorque=false; //true if torque array has been updated -> recalculate in main loop
@@ -473,7 +476,7 @@ digitalWrite(option_pin,HIGH);
473476
attachInterrupt(0, pas_change, CHANGE); //attach interrupt for PAS-Sensor
474477
#endif
475478
attachInterrupt(1, speed_change, RISING); //attach interrupt for Wheel-Sensor
476-
#else
479+
#else //HARDWARE_REV>=20
477480
bitClear(DDRE,7); //configure PE7 as input
478481
bitSet(PORTE,7); //enable pull-up on wheel sensor
479482
bitSet(EICRB,6); //trigger on rising edge INT7 for wheel sensor
@@ -482,18 +485,18 @@ digitalWrite(option_pin,HIGH);
482485
#ifdef SUPPORT_PAS
483486
bitClear(DDRE,5); //configure PE5 as input
484487
bitSet(PORTE,5); //enable pull-up on PAS sensor
485-
#if !defined(SUPPORT_XCELL_RT) && !defined(SUPPORT_BBS)
488+
#if !defined(SUPPORT_XCELL_RT) && !defined(SUPPORT_BBS)&& !defined(SUPPORT_SEMPU)
486489
bitSet(EICRB,2); //trigger on any edge INT5 for PAS sensor
487490
EIMSK |= (1<<INT5); //turn on interrupt INT5 for PAS sensor
488491
#else
489492
bitClear(DDRE,6); //configure PE6 as input
490493
bitSet(PORTE,6); //enable pull-up on PAS 2 sensor
491-
bitSet(EICRB,2); //trigger on rising edge INT5 for Thun sensor/BBS
492-
bitSet(EICRB,3); //trigger on rising edge INT5 for Thun sensor/BBS
493-
bitSet(EICRB,4); //trigger on rising edge INT6 for Thun sensor/BBS
494-
bitSet(EICRB,5); //trigger on rising edge INT6 for Thun sensor/BBS
494+
bitSet(EICRB,2); //trigger on rising edge INT5 for Thun sensor/BBS/Sempu
495+
bitSet(EICRB,3); //trigger on rising edge INT5 for Thun sensor/BBS/Sempu
496+
bitSet(EICRB,4); //trigger on rising edge INT6 for Thun sensor/BBS/Sempu
497+
bitSet(EICRB,5); //trigger on rising edge INT6 for Thun sensor/BBS/Sempu
495498
EIMSK |= (1<<INT5); //turn on interrupt INT5 for PAS sensor
496-
EIMSK |= (1<<INT6); //turn on interrupt for Thun sensor/BBS
499+
EIMSK |= (1<<INT6); //turn on interrupt for Thun sensor/BBS/Sempu
497500
#endif
498501
#endif
499502
#endif
@@ -524,7 +527,7 @@ digitalWrite(option_pin,HIGH);
524527
poti_stat = map(poti_value_on_startup_in_watts, 0, curr_power_poti_max, 0, 1023);
525528
#endif
526529

527-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
530+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)|| defined(SUPPORT_SEMPU)
528531
#ifdef TORQUE_AUTOZERO
529532
torque_rezero();
530533
#endif
@@ -662,11 +665,11 @@ if (loadcell.is_ready()) //new conversion result from load cell available
662665
current_display = 0.99*current_display + 0.01*current; //averaged current for display
663666
power=current*voltage;
664667

665-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
668+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)|| defined(SUPPORT_SEMPU)
666669
#ifdef SUPPORT_XCELL_RT
667670
torque_instant=0.49*(analogRead(option_pin)-torque_zero); //multiplication constant for THUN X-CELL RT is approx. 0.49Nm/count
668-
#else //SEMPU
669-
torque_instant=0.33*(analogRead(option_pin)-torque_zero); //multiplication constant for SEMPU is approx. 0.33Nm/count
671+
#else //Sempu
672+
torque_instant=0.33*(analogRead(option_pin)-torque_zero); //multiplication constant for SEMPU V1 is approx. 0.33Nm/count
670673
#endif
671674
if (readtorque==true)
672675
{
@@ -684,9 +687,12 @@ if (loadcell.is_ready()) //new conversion result from load cell available
684687
torque=abs((torque)*0.03054740957);
685688
#endif
686689
power_human=0.20943951*cad*torque; //power=2*pi*cadence*torque/60s*2 (*2 because only left side torque is measured by x-cell rt)
687-
#else //SEMPU
690+
#elif defined(SUPPORT_SEMPU_V1) //SEMPU V1
688691
torque=abs((torque)*0.02078055073); //torque=sum of torque values/#of torque values*5V/1023 counts/(14.7 mV/Nm)
689692
power_human=0.10471975512*cad*torque; //power=2*pi*cadence*torque/60s
693+
#else //SEMPU
694+
torque=abs((torque)*0.01385370049); //torque=sum of torque values/#of torque values*5V/1023 counts/(14.7 mV/Nm)
695+
power_human=0.10471975512*cad*torque; //power=2*pi*cadence*torque/60s
690696
#endif
691697
}
692698
#endif
@@ -721,7 +727,7 @@ if (loadcell.is_ready()) //new conversion result from load cell available
721727
wh=variable.wh;
722728
km=variable.kilometers;
723729
mah=variable.mah;
724-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
730+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)|| defined(SUPPORT_SEMPU)
725731
wh_human=variable.wh_human;
726732
#endif
727733
}
@@ -785,7 +791,7 @@ if (loadcell.is_ready()) //new conversion result from load cell available
785791
power_throttle = throttle_stat / 1023.0 * curr_power_max; //power currently set by throttle
786792

787793
#if CONTROL_MODE == CONTROL_MODE_TORQUE //human power control mode
788-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
794+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)|| defined(SUPPORT_SEMPU)
789795
power_poti = poti_stat/102300.0* curr_power_poti_max*power_human*(1+spd/20.0); //power_poti_max is in this control mode interpreted as percentage. Example: power_poti_max=200 means; motor power = 200% of human power
790796
#ifdef SUPPORT_TORQUE_THROTTLE //we want to trigger throttle just by pedal torque
791797
if (abs(torque_instant)>torque_throttle_min) //we are above the threshold to trigger throttle
@@ -1066,7 +1072,7 @@ ISR(INT7_vect)
10661072
speed_change();
10671073
}
10681074
#ifdef SUPPORT_PAS
1069-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_BBS)
1075+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_BBS)|| defined(SUPPORT_SEMPU)
10701076
ISR(INT5_vect)
10711077
{
10721078
pas_change_dual(false);
@@ -1085,7 +1091,7 @@ ISR(INT5_vect)
10851091
#endif
10861092

10871093
#if HARDWARE_REV >= 20
1088-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_BBS)
1094+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_BBS) || defined(SUPPORT_SEMPU)
10891095
void pas_change_dual(boolean signal)
10901096
{
10911097
if (signal)
@@ -1095,13 +1101,15 @@ void pas_change_dual(boolean signal)
10951101
pedaling=!bitRead(PINE,6);
10961102
#ifdef SUPPORT_XCELL_RT
10971103
cad=7500/(millis()-last_pas_event); //8 pulses per revolution
1098-
#else
1104+
#elif defined(SUPPORT_BBS)
10991105
cad=2500/(millis()-last_pas_event); //24 pulses per revolution
1106+
#else //Sempu: 48 pulses per revolution
1107+
cad=1250/(millis()-last_pas_event); //48 pulses per revolution
11001108
#endif
11011109
last_pas_event = millis();
11021110
}
11031111
pedalingbackwards=!pedaling;
1104-
#ifdef SUPPORT_XCELL_RT
1112+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU)
11051113
if (analogRead_in_use)
11061114
{
11071115
torque_want_calculation = true;
@@ -1113,7 +1121,7 @@ void pas_change_dual(boolean signal)
11131121
#endif
11141122
#endif
11151123

1116-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1124+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
11171125
void read_current_torque() //this reads the current torque value
11181126
{
11191127
torquevalues[torqueindex]=analogRead(option_pin)-torque_zero;
@@ -1137,7 +1145,7 @@ void pas_change() //Are we pedaling? PAS Sensor Change--------------------
11371145
if (pas_stat)
11381146
{
11391147
pas_off_time=millis()-last_pas_event;
1140-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1148+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
11411149
if (analogRead_in_use)
11421150
torque_want_calculation = true;
11431151
else
@@ -1269,7 +1277,7 @@ void serial_debug(HardwareSerial* localSerial)
12691277
localSerial->print(current,1);
12701278
localSerial->print(MY_F(" Power"));
12711279
localSerial->print(power,0);
1272-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1280+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
12731281
localSerial->print(MY_F(" Pedaling"));
12741282
localSerial->print(pedaling);
12751283
localSerial->print(MY_F(" Torque"));
@@ -1325,7 +1333,7 @@ void serial_debug(HardwareSerial* localSerial)
13251333
#else
13261334
localSerial->print(analogRead_noISR(external_current_in)); Serial.print(MY_F(";"));
13271335
#endif
1328-
#ifdef SUPPORT_XCELL_RT
1336+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU)
13291337
localSerial->print(pedaling); Serial.print(MY_F(";"));
13301338
#else
13311339
localSerial->print(((int)(100*(double)pas_on_time/(double)pas_off_time))); Serial.print(MY_F(";"));
@@ -1510,7 +1518,7 @@ void save_eeprom()
15101518
#ifdef SUPPORT_BATTERY_CHARGE_COUNTER
15111519
variable_new.charge_count=charge_count; //save charge counter
15121520
#endif
1513-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1521+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
15141522
variable_new.wh_human=wh_human; //save human watthours
15151523
#endif
15161524
const byte* p_new = (const byte*)(const void*)&variable_new; //pointer to new variables to save
@@ -1581,7 +1589,7 @@ void handle_unused_pins()
15811589

15821590
int analogRead_noISR(uint8_t pin) //this function makes sure that analogRead is never used in interrupt. only important for X-Cell RT bottom brackets
15831591
{
1584-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1592+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
15851593
analogRead_in_use = true; //this prevents analogReads in Interrupt from Thun bracket
15861594
if (torque_want_calculation)
15871595
{
@@ -1590,7 +1598,7 @@ int analogRead_noISR(uint8_t pin) //this function makes sure that analogRead is
15901598
}
15911599
#endif
15921600
int temp=analogRead(pin);
1593-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
1601+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
15941602
analogRead_in_use = false;
15951603
#endif
15961604
return temp;

Arduino_Pedelec_Controller/config.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ const int fixed_throttle_in_watts = 250; //number of watts to set as thr
142142
#define BBS_GEARCHANGEPAUSE 2000 //powerless time in milliseconds to allow gear change
143143
// #define SUPPORT_XCELL_RT //uncomment if X-CELL RT connected. FC1.4: pas_factor_min=0.2, pas_factor_max=0.5. FC1.5: pas_factor_min=0.5, pas_factor_max=1.5. pas_magnets=8
144144
// #define SUPPORT_SEMPU_V1 //uncomment if you have a Sempu torque sensor, old type with one direction wire and one pas wire
145-
// #define SUPPORT_SEMPU //uncomment if you have a Sempu torque sensor, new type with two pas wires
145+
//#define SUPPORT_SEMPU //uncomment if you have a Sempu torque sensor, new type with two pas wires
146146
// #define SUPPORT_TORQUE_THROTTLE
147147
// #define SUPPORT_HRMI //uncomment if polar heart-rate monitor interface connected to i2c port
148148
#define SUPPORT_BRAKE //uncomment if brake switch connected
@@ -264,7 +264,7 @@ const char msg_tempomat_reset[] PROGMEM = "Tempomat reset";
264264
const char msg_unknown_action[] PROGMEM = "Unknown action!";
265265
const char msg_activated[] PROGMEM = "Activated";
266266
const char msg_deactivated[] PROGMEM = "Deactivated";
267-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU)
267+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU)|| defined(SUPPORT_SEMPU_V1)
268268
const char msg_torquezero[] PROGMEM = "Re-zero torque sensor";
269269
#endif
270270

Arduino_Pedelec_Controller/display.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,7 @@ static void display_nokia_view_human()
11291129
lcd.print(MY_F(" CAD "));
11301130
lcd.print(cad);
11311131
lcd.print(MY_F(" "));
1132-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) //show left bar with human and battery wh
1132+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU) //show left bar with human and battery wh
11331133
lcd.setCursor(3,3); //print human power centered
11341134
lcd.print(MY_F(" W ")); lcd.print(power_human,0);
11351135
lcd.print(MY_F(" "));

Arduino_Pedelec_Controller/switches.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void action_set_soft_poti(int new_throttle_stat)
101101

102102
{
103103
#if CONTROL_MODE == CONTROL_MODE_TORQUE //human power control mode
104-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
104+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
105105
buffer[9]='%';
106106
power_poti = poti_stat/1023.0* curr_power_poti_max; //power_poti_max is in this control mode interpreted as percentage. Example: power_poti_max=200 means; motor power = 200% of human power
107107
#endif
@@ -337,7 +337,7 @@ static void execute_action(const sw_action action)
337337
action_toggle_gear(true);
338338
break;
339339
#endif
340-
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1)
340+
#if defined(SUPPORT_XCELL_RT) || defined(SUPPORT_SEMPU_V1) || defined(SUPPORT_SEMPU)
341341
case ACTION_TORQUE_ZERO:
342342
torque_rezero();
343343
display_show_important_info(FROM_FLASH(msg_torquezero), 2);

0 commit comments

Comments
 (0)