Skip to content

Commit 65e5fa2

Browse files
author
jenkie
committed
Support Bafang BBS0x Displays
1 parent 9510c5c commit 65e5fa2

File tree

5 files changed

+409
-2
lines changed

5 files changed

+409
-2
lines changed

Arduino_Pedelec_Controller/Arduino_Pedelec_Controller.ino

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ if (loadcell.is_ready()) //new conversion result from load cell available
570570
}
571571
#endif
572572

573-
#if ((DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) || (DISPLAY_TYPE == DISPLAY_TYPE_BMS) || (DISPLAY_TYPE == DISPLAY_TYPE_BMS3))
573+
#if ((DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) || (DISPLAY_TYPE == DISPLAY_TYPE_BMS) || (DISPLAY_TYPE == DISPLAY_TYPE_BMS3)||(DISPLAY_TYPE == DISPLAY_TYPE_BAFANG))
574574
display_update();
575575
#endif
576576

@@ -971,7 +971,7 @@ if (loadcell.is_ready()) //new conversion result from load cell available
971971
wh_human+=(millis()-last_writetime)/3600000.0*power_human; //human watthours calculation
972972
mah+=current*(millis()-last_writetime)/3600.0; //mah calculation
973973

974-
#if (!(DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) && !(DISPLAY_TYPE == DISPLAY_TYPE_BMS) && !(DISPLAY_TYPE == DISPLAY_TYPE_BMS3))
974+
#if (!(DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) && !(DISPLAY_TYPE == DISPLAY_TYPE_BMS) && !(DISPLAY_TYPE == DISPLAY_TYPE_BMS3)&& !(DISPLAY_TYPE == DISPLAY_TYPE_BAFANG))
975975
#if !(DISPLAY_TYPE == DISPLAY_TYPE_NONE)
976976
display_update();
977977
#endif

Arduino_Pedelec_Controller/config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define DISPLAY_TYPE_KINGMETER_618U (1<<4) // King-Meter 618U protocol (KM5s, EBS-LCD2, J-LCD, SW-LCD)
2424
#define DISPLAY_TYPE_KINGMETER_901U (1<<8) // King-Meter 901U protocol (KM5s)
2525
#define DISPLAY_TYPE_KINGMETER (DISPLAY_TYPE_KINGMETER_618U|DISPLAY_TYPE_KINGMETER_901U)
26+
#define DISPLAY_TYPE_BAFANG (1<<9)
2627

2728
#define DISPLAY_TYPE DISPLAY_TYPE_NOKIA_4PIN // Set your display type here. CHANGES ONLY HERE!<-----------------------------
2829

Arduino_Pedelec_Controller/display.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2828
#include "display_kingmeter.h"
2929
#endif
3030

31+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
32+
#include "display_bafang.h"
33+
#endif
34+
3135

3236
display_mode_type display_mode = DISPLAY_MODE_GRAPHIC; //startup screen
3337
display_mode_type display_mode_last = DISPLAY_MODE_TEXT; //last screen type
@@ -62,6 +66,17 @@ HardwareSerial* displaySerial=&Serial2;
6266
#endif
6367
#endif
6468

69+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG) // For Bafang BBS0x displays
70+
BAFANG_t BF; // Context of the Bafang object
71+
#if HARDWARE_REV < 20
72+
#include <SoftwareSerial.h>
73+
static SoftwareSerial mySerial(10, 11); // RX (YELLOW cable), TX (GREEN cable)
74+
SoftwareSerial* displaySerial =& mySerial;
75+
#else
76+
HardwareSerial* displaySerial=&Serial2;
77+
#endif
78+
#endif
79+
6580
#if (DISPLAY_TYPE & DISPLAY_TYPE_BMS)||(DISPLAY_TYPE & DISPLAY_TYPE_BMS3)
6681
#if HARDWARE_REV < 20
6782
#include <SoftwareSerial.h> // For BMS Battery S-LCD and S-LCD3
@@ -636,6 +651,47 @@ void kingmeter_update(void)
636651
}
637652
#endif
638653

654+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
655+
void bafang_update(void)
656+
{
657+
Bafang_Service(&BF);
658+
/* Apply Rx parameters */
659+
660+
#ifdef SUPPORT_LIGHTS_SWITCH
661+
if(BF.Rx.Headlight == KM_HEADLIGHT_OFF)
662+
{
663+
digitalWrite(lights_pin, 0);
664+
}
665+
else
666+
{
667+
digitalWrite(lights_pin, 1);
668+
}
669+
#endif
670+
671+
if(BF.Rx.PushAssist == true)
672+
{
673+
throttle_stat = 200;
674+
}
675+
else
676+
{
677+
throttle_stat = 0;
678+
poti_stat = map(BF.Rx.AssistLevel, 0, 9, 0,1023);
679+
}
680+
681+
682+
/* Shutdown in case we received no message in the last 3s */
683+
684+
if((millis() - BF.LastRx) > 3000)
685+
{
686+
poti_stat = 0;
687+
throttle_stat = 0;
688+
#if HARDWARE_REV >=2
689+
save_shutdown();
690+
#endif
691+
}
692+
}
693+
#endif
694+
639695

640696
static void slcd_update(byte battery, unsigned int wheeltime, byte error)
641697
{
@@ -757,6 +813,11 @@ void display_init()
757813
KingMeter_Init(&KM, displaySerial);
758814
#endif
759815

816+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
817+
Bafang_Init(&BF, displaySerial);
818+
#endif
819+
820+
760821
#if ((DISPLAY_TYPE == DISPLAY_TYPE_BMS) || (DISPLAY_TYPE == DISPLAY_TYPE_BMS3))
761822
displaySerial->begin(9600);
762823
#endif
@@ -1156,6 +1217,9 @@ void display_update()
11561217
kingmeter_update();
11571218
#endif
11581219

1220+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
1221+
bafang_update();
1222+
#endif
11591223

11601224
#if (DISPLAY_TYPE & DISPLAY_TYPE_BMS)
11611225
slcd_update(map(battery_percent_fromcapacity,0,100,0,16),wheel_time,0);
@@ -1224,6 +1288,15 @@ void display_debug(HardwareSerial* localSerial)
12241288
localSerial->print(MY_F(" CurrLim "));
12251289
localSerial->println(((float)KM.Rx.CUR_Limit_x10)/10);
12261290
#endif
1291+
1292+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
1293+
localSerial->print(MY_F(" Assist "));
1294+
localSerial->print(BF.Rx.AssistLevel);
1295+
localSerial->print(MY_F(" Light "));
1296+
localSerial->print(BF.Rx.Headlight, HEX);
1297+
localSerial->print(MY_F(" Push "));
1298+
localSerial->println(BF.Rx.PushAssist, HEX);
1299+
#endif
12271300

12281301

12291302
#if (DISPLAY_TYPE & DISPLAY_TYPE_BMS)
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*
2+
Library for Bafang BBS01/BBS02 Displays (C965...)
3+
4+
Copyright © 2016 Jens Kießling ([email protected])
5+
inspired by Kingmeter Library (Michael Fabry)
6+
7+
This program is free software: you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation, either version 3 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
22+
// Includes
23+
#include "config.h"
24+
#include "display_bafang.h"
25+
#include "globals.h"
26+
27+
#if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)
28+
29+
30+
31+
// Definitions
32+
#define RXSTATE_STARTCODE 0
33+
#define RXSTATE_MSGBODY 1
34+
#define RXSTATE_DONE 2
35+
36+
37+
// Local function prototypes
38+
static void BAFANG_Service(BAFANG_t* BF_ctx);
39+
40+
uint8_t TxBuff[BF_MAX_TXBUFF];
41+
42+
43+
44+
/* Public functions (Prototypes declared by display_bafang.h) */
45+
46+
/****************************************************************************************************
47+
* Bafang_Init() - Initializes the display object
48+
*
49+
****************************************************************************************************/
50+
#if HARDWARE_REV < 20
51+
void Bafang_Init (BAFANG_t* BF_ctx, SoftwareSerial* DisplaySerial)
52+
#else
53+
void Bafang_Init (BAFANG_t* BF_ctx, HardwareSerial* DisplaySerial)
54+
#endif
55+
{
56+
uint8_t i;
57+
BF_ctx->SerialPort = DisplaySerial; // Store serial port to use
58+
59+
BF_ctx->RxState = RXSTATE_STARTCODE;
60+
BF_ctx->LastRx = millis();
61+
62+
for(i=0; i<BF_MAX_RXBUFF; i++)
63+
{
64+
BF_ctx->RxBuff[i] = 0x00;
65+
}
66+
67+
DisplaySerial->begin(1200);
68+
}
69+
70+
71+
72+
/****************************************************************************************************
73+
* Bafang_Service() - Communicates data from and to the display
74+
*
75+
***************************************************************************************************/
76+
void Bafang_Service(BAFANG_t* BF_ctx)
77+
{
78+
uint8_t i;
79+
// Search for Start Code
80+
if(BF_ctx->RxState == RXSTATE_STARTCODE) //waiting for start code
81+
{
82+
if (millis()-BF_ctx->LastRx>BF_DISPLAYTIMEOUT) //new transmission frame will come
83+
if(BF_ctx->SerialPort->available())
84+
{
85+
BF_ctx->LastRx = millis();
86+
BF_ctx->RxBuff[0]=BF_ctx->SerialPort->read();
87+
if(BF_ctx->RxBuff[0]==BF_CMD_STARTREQUEST||BF_ctx->RxBuff[0]==BF_CMD_STARTINFO) //valid startcode detected
88+
{
89+
BF_ctx->RxCnt = 1;
90+
BF_ctx->RxState = RXSTATE_MSGBODY;
91+
}
92+
else
93+
{
94+
return; // No need to continue
95+
}
96+
}
97+
}
98+
99+
// Receive Message body
100+
if(BF_ctx->RxState == RXSTATE_MSGBODY)
101+
{
102+
while(BF_ctx->SerialPort->available())
103+
{
104+
BF_ctx->RxBuff[BF_ctx->RxCnt] = BF_ctx->SerialPort->read();
105+
BF_ctx->RxCnt++;
106+
if(BF_ctx->RxCnt > 5) // something is wrong, reset
107+
{
108+
BF_ctx->RxState = RXSTATE_STARTCODE;
109+
BF_ctx->LastRx = millis();
110+
break;
111+
}
112+
BF_ctx->LastRx = millis();
113+
}
114+
}
115+
116+
if ((millis()-BF_ctx->LastRx)>BF_DISPLAYTIMEOUT&&(BF_ctx->RxState == RXSTATE_MSGBODY)) //new message has been received -> analyze
117+
{
118+
BF_ctx->RxState = RXSTATE_DONE;
119+
}
120+
121+
// Message received completely, analyze
122+
if(BF_ctx->RxState == RXSTATE_DONE)
123+
{
124+
BF_ctx->RxState = RXSTATE_STARTCODE;
125+
if (BF_ctx->RxBuff[0]==BF_CMD_STARTREQUEST) //display wants an answer, send it!
126+
{
127+
switch (BF_ctx->RxBuff[1])
128+
{
129+
case BF_CMD_GETSPEED:
130+
TxBuff[0]=0;
131+
TxBuff[1]=min(spd/0.128,255);
132+
TxBuff[2]=TxBuff[1]+32;
133+
BF_sendmessage(BF_ctx,3);
134+
break;
135+
136+
case BF_CMD_GETERROR:
137+
TxBuff[0]=1;
138+
BF_sendmessage(BF_ctx,1);
139+
break;
140+
141+
case BF_CMD_GETBAT:
142+
TxBuff[0]=battery_percent_fromcapacity;
143+
TxBuff[1]=battery_percent_fromcapacity;
144+
BF_sendmessage(BF_ctx,2);
145+
146+
case BF_CMD_GET1:
147+
TxBuff[0]=0;
148+
TxBuff[1]=0;
149+
BF_sendmessage(BF_ctx,2);
150+
break;
151+
152+
case BF_CMD_GET2:
153+
TxBuff[0]=48;
154+
TxBuff[1]=48;
155+
BF_sendmessage(BF_ctx,2);
156+
break;
157+
}
158+
159+
}
160+
else if(BF_ctx->RxBuff[0]==BF_CMD_STARTINFO)
161+
{
162+
switch (BF_ctx->RxBuff[1])
163+
{
164+
case BF_CMD_LEVEL:
165+
if (BF_ctx->RxBuff[3]==BF_ctx->RxBuff[0]+BF_ctx->RxBuff[1]+BF_ctx->RxBuff[2]) //checksum is correct, set poti_stat
166+
{
167+
BF_ctx->Rx.PushAssist=0;
168+
switch(BF_ctx->RxBuff[2])
169+
{
170+
case BF_LEVEL0:
171+
BF_ctx->Rx.AssistLevel=0;
172+
break;
173+
case BF_LEVEL1:
174+
BF_ctx->Rx.AssistLevel=1;
175+
break;
176+
case BF_LEVEL2:
177+
BF_ctx->Rx.AssistLevel=2;
178+
break;
179+
case BF_LEVEL3:
180+
BF_ctx->Rx.AssistLevel=3;
181+
break;
182+
case BF_LEVEL4:
183+
BF_ctx->Rx.AssistLevel=4;
184+
break;
185+
case BF_LEVEL5:
186+
BF_ctx->Rx.AssistLevel=5;
187+
break;
188+
case BF_LEVEL6:
189+
BF_ctx->Rx.AssistLevel=6;
190+
break;
191+
case BF_LEVEL7:
192+
BF_ctx->Rx.AssistLevel=7;
193+
break;
194+
case BF_LEVEL8:
195+
BF_ctx->Rx.AssistLevel=8;
196+
break;
197+
case BF_LEVEL9:
198+
BF_ctx->Rx.AssistLevel=9;
199+
break;
200+
case BF_PUSHASSIST:
201+
BF_ctx->Rx.PushAssist=1;
202+
break;
203+
}
204+
}
205+
break;
206+
207+
case BF_CMD_MISC:
208+
BF_ctx->Rx.Headlight=(BF_ctx->RxBuff[2]==BF_LIGHTON);
209+
break;
210+
}
211+
}
212+
}
213+
}
214+
215+
void BF_sendmessage(BAFANG_t* BF_ctx,uint8_t count)
216+
{
217+
for(int i=0; i<count; i++)
218+
BF_ctx->SerialPort->write(TxBuff[i]);
219+
}
220+
221+
222+
223+
#endif // (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG)

0 commit comments

Comments
 (0)