there is no speed data/protocol transmitted, you have to get the rpm and convert into speed using your wheel/tire size.Does anyone know "1 line" speed protocol of votol use ? Is it 1 wire connection ? (Because I plan to use arduino to read speed from 1 line wire of Votol. Thanks
I would love to know to as I'm planing to do this on my fardriver as well.Does anyone know "1 line" speed protocol of votol use ? Is it 1 wire connection ? (Because I plan to use arduino to read speed from 1 line wire of Votol. Thanks
The question you quoted was answered right after it was asked.I would love to know to as I'm planing to do this on my fardriver as well.
Just wondering is any chance to control the EM100 or EM150 by uart (from my micro-controller) ?
I mean throttle, brake signals are all from uart or CAN ?
cheers
@amberwolf as far as I can tell, both Votol and Fardriver are under SiAECOSYS and all displays with one-line protocol seem to be advertised to work for both so I would assume the protocol would be pretty much the same.
thanks. That's a good solution but need some time to do pcb assembly.AFAICT from the wiring diagrams I've seen so far, both brake and throttle are direct analog signals to their own discrete inputs.
If they also offer serial control of them (like Lebowski's brain chip does) then you'd have to find out what commands to send over the serial port for this from the documentation from the manufacturer (or other projects like this one)
Well, if they're the same, then presumably both would be the same as the other answer, and no speed data is on the 1-line interface, just RPM as noted in the first post of this thread.
If you need direct speed data, my guess is you'll have to decode the data you actually see on your particular setup to see if there's anything left over from the already translated stuff in this thread (or other similar ones) that appears to change with the speed of the motor it's running, different from the RPM.
Sorry for the confusion, I didn't express myself properly. It's clear to me actual wheel speed is not being sent by the controller, only motor speed, no doubts there, I was more interested in the actual package format being broadcasted over the one line wire.f you need direct speed data, my guess is you'll have to decode the data you actually see on your particular setup to see if there's anything left over from the already translated stuff in this thread (or other similar ones) that appears to change with the speed of the motor it's running, different from the RPM.
hmm, i just wonder are you Valy Exe in facebook. I have some question want to ask you abt ur project. If u not, apologize for my mistake.I just want to thank you guys for sharing this data.
I am now controlling my KT LCD8H display with my votol em50-4 with the help of a little arduino nano board.
At the moment I'm using the serial programming port to get the data, but I intend to use the one-line output so I can keep a hc05 to the programming port and have access to the controller settings via bluetooth.
Yep that's me. You can pm me on facebook, no problem.hmm, i just wonder are you Valy Exe in facebook. I have some question want to ask you abt ur project. If u not, apologize for my mistake.
Thanks and have a nice day !
Could you please share your application or a link to it here? Thanks!guess a AD.
back to you question, have you set your baud rate to be 9600? I tested success every time. I've even written an Android APP to received the data with coulomb counters integrated, it works like a charm.
A little update. I played around a bit with the "one wire" display output and was able to decode the data with a simple arduino nano.
Here's some rough test code, nothing fancy, just a simple proof of concept but it works well for me.
Protocol documentation in previous post.
#define sif_pin 2
short battery = 0;
short current = 0;
short currentPercent = 0;
short rpm = 0;
long faultCode = 0;
bool regen = false;
bool brake = false;
unsigned long lastTime;
unsigned long lastDuration = 0;
byte lastCrc = 0;
byte data[12];
int bitIndex = -1;
void setup() {
Serial.begin(115200);
pinMode(sif_pin, INPUT);
lastTime = micros();
attachInterrupt(digitalPinToInterrupt(sif_pin), sifChange, CHANGE);
}
void loop() {
// put your main code here, to run repeatedly:
}
void sifChange() {
int val = digitalRead(sif_pin);
unsigned long duration = micros() - lastTime;
lastTime = micros();
if (val == LOW) {
if (lastDuration > 0) {
bool bitComplete = false;
float ratio = float(lastDuration) / float(duration);
if (round(lastDuration / duration) >= 31) {
bitIndex = 0;
} else if (ratio > 1.5) {
// bit value 0
bitClear(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else if (1 / ratio > 1.5) {
// bit value 0
bitSet(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else {
Serial.println(String(duration) + "-" + String(lastDuration));
}
if (bitComplete) {
bitIndex++;
if (bitIndex == 96) {
bitIndex = 0;
byte crc = 0;
for (int i = 0; i < 11; i++) {
crc ^= data;
}
if (crc != data[11]) {
Serial.println("CRC FAILURE: " + String(crc) + "-" + String(data[11]));
}
if (crc == data[11] && crc != lastCrc) {
lastCrc = crc;
for (int i = 0; i < 12; i++) {
Serial.print(data, HEX);
Serial.print(" ");
}
Serial.println();
battery = data[9];
battery = data[9];
current = data[6];
currentPercent = data[10];
rpm = ((data[7] << 8) + data[8]) * 1.91;
brake = bitRead(data[4], 5);
regen = bitRead(data[4], 3);
Serial.print("Battery %: " + String(battery));
Serial.print(" Current %: " + String(currentPercent));
Serial.print(" Current A: " + String(current));
Serial.print(" RPM: " + String(rpm));
if (brake) Serial.print(" BRAKE");
if (regen) Serial.print(" REGEN");
Serial.println();
}
}
}
}
}
lastDuration = duration;
}
Were you able to get any further with this? I'd love to open up my options to other displays for my FarDriver...A little update. I played around a bit with the "one wire" display output and was able to decode the data with a simple arduino nano.
Here's some rough test code, nothing fancy, just a simple proof of concept but it works well for me.
Protocol documentation in previous post.
#define sif_pin 2
short battery = 0;
short current = 0;
short currentPercent = 0;
short rpm = 0;
long faultCode = 0;
bool regen = false;
bool brake = false;
unsigned long lastTime;
unsigned long lastDuration = 0;
byte lastCrc = 0;
byte data[12];
int bitIndex = -1;
void setup() {
Serial.begin(115200);
pinMode(sif_pin, INPUT);
lastTime = micros();
attachInterrupt(digitalPinToInterrupt(sif_pin), sifChange, CHANGE);
}
void loop() {
// put your main code here, to run repeatedly:
}
void sifChange() {
int val = digitalRead(sif_pin);
unsigned long duration = micros() - lastTime;
lastTime = micros();
if (val == LOW) {
if (lastDuration > 0) {
bool bitComplete = false;
float ratio = float(lastDuration) / float(duration);
if (round(lastDuration / duration) >= 31) {
bitIndex = 0;
} else if (ratio > 1.5) {
// bit value 0
bitClear(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else if (1 / ratio > 1.5) {
// bit value 0
bitSet(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else {
Serial.println(String(duration) + "-" + String(lastDuration));
}
if (bitComplete) {
bitIndex++;
if (bitIndex == 96) {
bitIndex = 0;
byte crc = 0;
for (int i = 0; i < 11; i++) {
crc ^= data;
}
if (crc != data[11]) {
Serial.println("CRC FAILURE: " + String(crc) + "-" + String(data[11]));
}
if (crc == data[11] && crc != lastCrc) {
lastCrc = crc;
for (int i = 0; i < 12; i++) {
Serial.print(data, HEX);
Serial.print(" ");
}
Serial.println();
battery = data[9];
battery = data[9];
current = data[6];
currentPercent = data[10];
rpm = ((data[7] << 8) + data[8]) * 1.91;
brake = bitRead(data[4], 5);
regen = bitRead(data[4], 3);
Serial.print("Battery %: " + String(battery));
Serial.print(" Current %: " + String(currentPercent));
Serial.print(" Current A: " + String(current));
Serial.print(" RPM: " + String(rpm));
if (brake) Serial.print(" BRAKE");
if (regen) Serial.print(" REGEN");
Serial.println();
}
}
}
}
}
lastDuration = duration;
}
yes I've been using the display outputs on both my votol and fardriver for months now. working perfectly.Were you able to get any further with this? I'd love to open up my options to other displays for my FarDriver...
sorry but what is this error in lineA little update. I played around a bit with the "one wire" display output and was able to decode the data with a simple arduino nano.
Here's some rough test code, nothing fancy, just a simple proof of concept but it works well for me.
Protocol documentation in previous post.
#define sif_pin 2
short battery = 0;
short current = 0;
short currentPercent = 0;
short rpm = 0;
long faultCode = 0;
bool regen = false;
bool brake = false;
unsigned long lastTime;
unsigned long lastDuration = 0;
byte lastCrc = 0;
byte data[12];
int bitIndex = -1;
void setup() {
Serial.begin(115200);
pinMode(sif_pin, INPUT);
lastTime = micros();
attachInterrupt(digitalPinToInterrupt(sif_pin), sifChange, CHANGE);
}
void loop() {
// put your main code here, to run repeatedly:
}
void sifChange() {
int val = digitalRead(sif_pin);
unsigned long duration = micros() - lastTime;
lastTime = micros();
if (val == LOW) {
if (lastDuration > 0) {
bool bitComplete = false;
float ratio = float(lastDuration) / float(duration);
if (round(lastDuration / duration) >= 31) {
bitIndex = 0;
} else if (ratio > 1.5) {
// bit value 0
bitClear(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else if (1 / ratio > 1.5) {
// bit value 0
bitSet(data[bitIndex / 8], 7 - (bitIndex % 8));
bitComplete = true;
} else {
Serial.println(String(duration) + "-" + String(lastDuration));
}
if (bitComplete) {
bitIndex++;
if (bitIndex == 96) {
bitIndex = 0;
byte crc = 0;
for (int i = 0; i < 11; i++) {
crc ^= data;
}
if (crc != data[11]) {
Serial.println("CRC FAILURE: " + String(crc) + "-" + String(data[11]));
}
if (crc == data[11] && crc != lastCrc) {
lastCrc = crc;
for (int i = 0; i < 12; i++) {
Serial.print(data, HEX);
Serial.print(" ");
}
Serial.println();
battery = data[9];
battery = data[9];
current = data[6];
currentPercent = data[10];
rpm = ((data[7] << 8) + data[8]) * 1.91;
brake = bitRead(data[4], 5);
regen = bitRead(data[4], 3);
Serial.print("Battery %: " + String(battery));
Serial.print(" Current %: " + String(currentPercent));
Serial.print(" Current A: " + String(current));
Serial.print(" RPM: " + String(rpm));
if (brake) Serial.print(" BRAKE");
if (regen) Serial.print(" REGEN");
Serial.println();
}
}
}
}
}
lastDuration = duration;
}
Hi Im using hc05 and arduino nano to try your idea.... when the windows program is active a can see some activity flowibg and a lot of data.... but cant receive anything when my phone and serial Bt terminal is using your commands... maybe different C9 14 for each votol??? or missconfih in my terminal?Hi Guys, I spend some time analyzed the VOTOL serial communication process, and decoded the parameters of rpm, battery voltage, battery current, temperature coefficient, etc so it helps integrate the coulomb-counter in speedo meter, DIY an Arduino based wireless meter or create a Android/ISO APP using Bluetooth connection. I'm working on a Android APP for myself now.
when you created the connect via serial port or BT, the host sends below HEX string asking VOTOL controller to send the data shown on Display page back:
c9 14 02 53 48 4f 57 00 00 00 00 00 aa 00 00 00 1e aa 04 67 00 f3 52 0d
after that the controller will send 24 byte string including the data we want:
c0 14 0d 59 42 02 14 00 0f 01 00 00 00 00 02 b8 5d 4b 22 d6 80 03 01 0d
among these 24 byte:
B0~B1:C0 14 is the head of string means data sent by controller
B5~B6:02 14 converts into fixed-point Dec is the battery voltage, for my case it is 53.2V
B7~B8: 00 0f converts into fixed-point Dec is the battery current, for my case is 1.5A
B14~B15: 02 b8 converts into integer is the rpm, for my case is 696
B16: 5d converts into Dec - 50 is the Controller temp, for my case is 43C
B17: 4b converts into Dec - 50 is the External temp, for my case is 25C
B18~B19: 22 d6 converts into integer is the temperature coefficient, for my case is 8918
the rest is still in decoding but it is enough for simple coulomb-counter purpose, if you do a simply math using the rpm and your tire size, you can get a very accurate speed value, which has fast response than GPS value, and you can get the distance as well.
Hope it helps
flute2k3
it is BT protocol issue, to connect your cellphone, better to use BT 4.0 or 5.0. hc05 support 2.0 only?Hi Im using hc05 and arduino nano to try your idea.... when the windows program is active a can see some activity flowibg and a lot of data.... but cant receive anything when my phone and serial Bt terminal is using your commands... maybe different C9 14 for each votol??? or missconfih in my terminal?