Skip to content

Commit 0d0cec1

Browse files
author
Jan Pomikálek
authored
FOCBOX Unity support (#26)
* focbox unity support * extract crc to a separate module * focbox unity support: enable in config * vesc_comm refactoring
1 parent 7aa53bf commit 0d0cec1

11 files changed

+420
-172
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ There's a story behind the name, but it's a long one. It all started on [esk8 bu
2121
- low HW cost (~$10)
2222
- known to work well with the VESC FW v3.48 and v3.40
2323
- previous versions not tested but should work as well unless too old
24+
- FOCBOX Unity supported
2425

2526
## Configuring and installing firmware
2627

crc.cpp

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
Copyright 2016 Benjamin Vedder benjamin@vedder.se
3+
4+
This file is part of the VESC firmware.
5+
6+
The VESC firmware is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
The VESC firmware is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "crc.h"
21+
#include <Arduino.h>
22+
23+
// CRC Table
24+
const unsigned short PROGMEM crc16_tab[] = { 0x0000, 0x1021, 0x2042, 0x3063, 0x4084,
25+
0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad,
26+
0xe1ce, 0xf1ef, 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7,
27+
0x62d6, 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
28+
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, 0xa56a,
29+
0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, 0x3653, 0x2672,
30+
0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, 0xb75b, 0xa77a, 0x9719,
31+
0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, 0x48c4, 0x58e5, 0x6886, 0x78a7,
32+
0x0840, 0x1861, 0x2802, 0x3823, 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948,
33+
0x9969, 0xa90a, 0xb92b, 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50,
34+
0x3a33, 0x2a12, 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b,
35+
0xab1a, 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
36+
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, 0x7e97,
37+
0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, 0xff9f, 0xefbe,
38+
0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, 0x9188, 0x81a9, 0xb1ca,
39+
0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, 0x1080, 0x00a1, 0x30c2, 0x20e3,
40+
0x5004, 0x4025, 0x7046, 0x6067, 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d,
41+
0xd31c, 0xe37f, 0xf35e, 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214,
42+
0x6277, 0x7256, 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c,
43+
0xc50d, 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
44+
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, 0x26d3,
45+
0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, 0xd94c, 0xc96d,
46+
0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, 0x5844, 0x4865, 0x7806,
47+
0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e,
48+
0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1,
49+
0x1ad0, 0x2ab3, 0x3a92, 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b,
50+
0x9de8, 0x8dc9, 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0,
51+
0x0cc1, 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
52+
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 };
53+
54+
unsigned short crc16(unsigned char *buf, unsigned int len) {
55+
unsigned int i;
56+
unsigned short cksum = 0;
57+
for (i = 0; i < len; i++) {
58+
cksum = pgm_read_word_near(crc16_tab + (((cksum >> 8) ^ *buf++) & 0xFF)) ^ (cksum << 8);
59+
}
60+
return cksum;
61+
}

crc.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2016 Benjamin Vedder benjamin@vedder.se
3+
4+
This file is part of the VESC firmware.
5+
6+
The VESC firmware is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
The VESC firmware is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef CRC_H_
21+
#define CRC_H_
22+
23+
/*
24+
* Functions
25+
*/
26+
unsigned short crc16(unsigned char *buf, unsigned int len);
27+
28+
#endif /* CRC_H_ */

davega.ino

+29-23
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040

4141
#define LEN(X) (sizeof(X) / sizeof(X[0]))
4242

43+
#ifdef FOCBOX_UNITY
44+
#include "vesc_comm_unity.h"
45+
VescCommUnity vesc_comm = VescCommUnity();
46+
#else
47+
#include "vesc_comm_standard.h"
48+
VescCommStandard vesc_comm = VescCommStandard();
49+
#endif
50+
4351
#ifdef DEFAULT_SCREEN_ENABLED
4452
#include "davega_default_screen.h"
4553
DavegaDefaultScreen davega_default_screen = DavegaDefaultScreen();
@@ -119,8 +127,6 @@ DavegaScreen* scr;
119127

120128
const float discharge_ticks[] = DISCHARGE_TICKS;
121129

122-
uint8_t vesc_packet[PACKET_MAX_LENGTH];
123-
124130
t_davega_data data;
125131
t_davega_session_data session_data;
126132
int32_t initial_mah_spent;
@@ -177,7 +183,7 @@ void setup() {
177183
#ifdef DEBUG
178184
Serial.begin(115200);
179185
#endif
180-
vesc_comm_init(115200);
186+
vesc_comm.init(115200);
181187

182188
if (!eeprom_is_initialized(EEPROM_MAGIC_VALUE)) {
183189
eeprom_initialize(EEPROM_MAGIC_VALUE);
@@ -205,14 +211,14 @@ void setup() {
205211
scr->reset();
206212
scr->update(&data);
207213

208-
uint8_t bytes_read = vesc_comm_fetch_packet(vesc_packet);
209-
while (!vesc_comm_is_expected_packet(vesc_packet, bytes_read)) {
214+
vesc_comm.fetch_packet();
215+
while (!vesc_comm.is_expected_packet()) {
210216
scr->heartbeat(UPDATE_DELAY, false);
211-
bytes_read = vesc_comm_fetch_packet(vesc_packet);
217+
vesc_comm.fetch_packet();
212218
}
213219

214220
float last_volts = eeprom_read_volts();
215-
float current_volts = vesc_comm_get_voltage(vesc_packet);
221+
float current_volts = vesc_comm.get_voltage();
216222
if (was_battery_fully_charged(last_volts, current_volts)) {
217223
// reset mAh spent
218224
eeprom_write_mah_spent(0);
@@ -232,10 +238,10 @@ void setup() {
232238
// current value = initial value + VESC value
233239
// and that works correctly with the default initial values in case the VESC values
234240
// start from 0. If that's not the case though we need to lower the initial values.
235-
int32_t vesc_mah_spent = VESC_COUNT * (vesc_comm_get_amphours_discharged(vesc_packet) -
236-
vesc_comm_get_amphours_charged(vesc_packet));
241+
int32_t vesc_mah_spent = VESC_COUNT * (vesc_comm.get_amphours_discharged() -
242+
vesc_comm.get_amphours_charged());
237243
initial_mah_spent -= vesc_mah_spent;
238-
int32_t tachometer = rotations_to_meters(vesc_comm_get_tachometer(vesc_packet) / 6);
244+
int32_t tachometer = rotations_to_meters(vesc_comm.get_tachometer() / 6);
239245
initial_trip_meters -= tachometer;
240246
initial_total_meters -= tachometer;
241247

@@ -256,24 +262,24 @@ void loop() {
256262
if (digitalRead(BUTTON_2_PIN) == HIGH)
257263
button_2_last_up_time = millis();
258264

259-
uint8_t bytes_read = vesc_comm_fetch_packet(vesc_packet);
265+
vesc_comm.fetch_packet();
260266

261-
if (!vesc_comm_is_expected_packet(vesc_packet, bytes_read)) {
267+
if (!vesc_comm.is_expected_packet()) {
262268
scr->heartbeat(UPDATE_DELAY, false);
263269
return;
264270
}
265271

266-
data.mosfet_celsius = vesc_comm_get_temp_mosfet(vesc_packet);
267-
data.motor_celsius = vesc_comm_get_temp_motor(vesc_packet);
268-
data.motor_amps = vesc_comm_get_motor_current(vesc_packet);
269-
data.battery_amps = vesc_comm_get_battery_current(vesc_packet) * VESC_COUNT;
270-
data.duty_cycle = vesc_comm_get_duty_cycle(vesc_packet);
271-
data.vesc_fault_code = vesc_comm_get_fault_code(vesc_packet);
272-
data.voltage = vesc_comm_get_voltage(vesc_packet);
272+
data.mosfet_celsius = vesc_comm.get_temp_mosfet();
273+
data.motor_celsius = vesc_comm.get_temp_motor();
274+
data.motor_amps = vesc_comm.get_motor_current();
275+
data.battery_amps = vesc_comm.get_battery_current() * VESC_COUNT;
276+
data.duty_cycle = vesc_comm.get_duty_cycle();
277+
data.vesc_fault_code = vesc_comm.get_fault_code();
278+
data.voltage = vesc_comm.get_voltage();
273279

274280
// TODO: DRY
275-
int32_t vesc_mah_spent = VESC_COUNT * (vesc_comm_get_amphours_discharged(vesc_packet) -
276-
vesc_comm_get_amphours_charged(vesc_packet));
281+
int32_t vesc_mah_spent = VESC_COUNT * (vesc_comm.get_amphours_discharged() -
282+
vesc_comm.get_amphours_charged());
277283
int32_t mah_spent = initial_mah_spent + vesc_mah_spent;
278284
int32_t mah = BATTERY_MAX_MAH * BATTERY_USABLE_CAPACITY - mah_spent;
279285

@@ -291,10 +297,10 @@ void loop() {
291297
// dim mAh if the counter is about to be reset
292298
data.mah_reset_progress = min(1.0 * button_2_down_elapsed / COUNTER_RESET_TIME, 1.0);
293299

294-
int32_t rpm = vesc_comm_get_rpm(vesc_packet);
300+
int32_t rpm = vesc_comm.get_rpm();
295301
data.speed_kph = max(erpm_to_kph(rpm), 0);
296302

297-
int32_t tachometer = rotations_to_meters(vesc_comm_get_tachometer(vesc_packet) / 6);
303+
int32_t tachometer = rotations_to_meters(vesc_comm.get_tachometer() / 6);
298304

299305
uint32_t button_1_down_elapsed = millis() - button_1_last_up_time;
300306
if (button_1_down_elapsed > COUNTER_RESET_TIME) {

davega_config.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
#ifndef DAVEGA_CONFIG_H
2121
#define DAVEGA_CONFIG_H
2222

23-
#define VESC_COUNT 2 // number of controllers: 1 = single, 2 = dual
23+
// To compile for FOCBOX Unity, uncomment the following line.
24+
//#define FOCBOX_UNITY 1
25+
26+
#define VESC_COUNT 2 // number of controllers: 1 = single, 2 = dual (set to 1 for FOCBOX Unity unless you have more than 1)
2427
#define MOTOR_POLE_PAIRS 7
2528
#define WHEEL_DIAMETER_MM 192
2629
#define MOTOR_PULLEY_TEETH 15
@@ -133,8 +136,8 @@
133136
//#define SIMPLE_HORIZONTAL_SCREEN_WITH_BATTERY_CURRENT_ENABLED 1
134137
//#define SIMPLE_HORIZONTAL_SCREEN_WITH_MOTOR_CURRENT_ENABLED 1
135138
#define SIMPLE_VERTICAL_SCREEN_ENABLED 1
136-
#define SIMPLE_VERTICAL_SCREEN_WITH_BATTERY_CURRENT_ENABLED 1
137-
#define SIMPLE_VERTICAL_SCREEN_WITH_MOTOR_CURRENT_ENABLED 1
139+
//#define SIMPLE_VERTICAL_SCREEN_WITH_BATTERY_CURRENT_ENABLED 1
140+
//#define SIMPLE_VERTICAL_SCREEN_WITH_MOTOR_CURRENT_ENABLED 1
138141
#define TEXT_SCREEN_ENABLED 1
139142

140143
// Information to be displayed on the text screen. Only relevant if TEXT_SCREEN_ENABLED is set.

0 commit comments

Comments
 (0)