OpenSource Remote for VESC ArduBoardControl

Hi,

Yes, I got the BLE Version.
SD-card on the board: Not possible. As you remember, we have no arduino on the board site anymore. The Bluetooth module is attached directly to the uart.
 
No. Only an SD-card in the remote. That make no pain and doesn't need to much place.
http://www.ebay.de/itm/5X-Mini-SD-Card-Module-Memory-Module-Micro-SD-Card-Module-for-Arduino-AVR-ARM-de-/331638318196?hash=item4d372f2474:g:5q0AAOSwiCRUkVOD
 
Alright, so I updated the housing and it does much better with drop tests. I also added a mounting point for a wrist strap (although I will be revisiting it to make it sealed). There were many minor fixes that had to be done after the posts were beefed up and that's why it took me so long.

Here is the video update: https://www.youtube.com/watch?v=VU7m9DUfVic

I actually left the board plugged in over night on the battery and it started at 4.1v and only dropped to around 3.9v. That's not even the nominal voltage of the cell! It only dropped around 5 or 10 percent after 12 hours of running! This means battery life should be weeks on average use!

I am also working on a pinout list for all the parts and I will post it here as soon as I finish it so we can keep track of what we use. Also, I found something that would be perfect for data storage instead of the sd card. It is a bit smaller and is much more reliable imo.
Check it out: https://www.adafruit.com/products/1895

Alternatively we could use the display from adafruit with the sd card but I'm not sure it would fit without serious modification.

That's it for now. Let me know what you think!
 
Right, well I just put together an excel sheet to keep track for now. Here is the link: https://drive.google.com/file/d/0BzqjX7GQTZ4ANjQ2RGItUk1jajQ/view
 
I just orderd this device for the board site: http://www.ebay.de/itm/Arduino-IOS-HM-10-BLE-Bluetooth-4-0-CC2540-CC2541-Serial-Wireless-Module-TE476-/191899108773?hash=item2cae1405a5:g:L4EAAOSwnNBXY7B3

Here the datasheet for: https://www.seeedstudio.com/wiki/images/c/cd/Bluetooth4_en.pdf

I will implement the communication with this library and example as shown here: https://learn.adafruit.com/bluefruit-le-micro-atmega32u4-microcontroller-usb-bluetooth-le-in-one/bleuart
for a UART communication.
 
Wow you 2 work quick!
I personally like the idea of the fram. I ordered it and the feather, as well as a uart ble board.

The sd card is nice because it's easily replaceable, but I don't think necessary since you could just attach your controller via the usb port or bluetooth and copy data off the chip. The chip would also be safer against bumps and drops than the sd card. @gecko if you don't want to support it instead of the sd card, I can do the code for that and it could just be another option in config.h, one or the other.
 
Lot of good news !!!
Let's see how reliable the BLE connection will be for a remote control, I'm a bit puzzled with that.
Anyway, your hall sensor looks working fine ! It seems to not going at full range when you push it, right ?
Some adjustments in the code ?

It's a good point for battery life. But it makes me ask something : what about the On/off switch of the remote ?
And where to add this ? On the + wire of the battery ?
Where would you plan to implement it on your casing ?

Anyway, I'll back in one month to actively participate to the development.
Nice summer and holidays everybody !
 
I personally also prefer the fram just because it is smaller and makes more sense. As far as turning it on and off is concerned, either a switch could be added in line with the battery, or more ideally we could have the feather go into a very low power mode and turn off all peripheral devices. I'm not sure if that is possible but that would be best. We might have to put a small transistor to supply power to all devices in that case.

I ordered another set of all electronics so I can have two remotes. One for development, and one for testing (ie durability and impact testing). I also ordered two frams for each and I am working on finding room for them in the housing.

I have also played with some code and am currently working on a calibration routine that can be implemented into the final build. I have a lightweight test program I am using currently to measure battery and hall effect. I did a thorough post about it here: https://www.radicalcreation.com/forums/viewtopic.php?f=6&t=35&start=5 along with a video. I plan to write a routine that could be called by Geckos main program if a user holds a combination of buttons or something. It will have instructions on screen about what to do and everything will be super user friendly. I will update you on this once I make good progress.

Cheers!
 
Oh yeah, I already started a quick program as a configurator for the controller that I figured would be nice. I was just experimenting really. Are you programming it for the feather, so to implement into gecko's? Or a program on the pc to interact with the controller (either through usb or bluetooth)? If the latter, what language are you using? We could combine forces.
 
Yes. Both the test program and the calibration code are for the feather. Basically the calibration would be a routine that is only activated if the board is not moving and the user holds down buttons in a certain way. Special care will be taken to ensure this routine is not accidentally activated with normal use. I should be able to have this done on my own but thanks for the offer! If you want to start looking into the Bluetooth communication with gecko, that would probably be the most beneficial for right now.
 
If we tie everything to the 3v pin on the feather, there is a way to kill that voltage. Then it would just be the microcontroller itself running. See here:https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/power-management#enable-pin

Since it says pull to ground, it might require a small transistor. If not, a switch would work, but it would have to be turned on to charge as well.
 
I wouldn't power the oled through the feather, just because it could possibly draw more current than the regulator can supply (I think. I'd have to look at the datasheet again). The display does have its own function to turn on and off (also black pixels draw very little power anyway), so just send the off command to the screen before you put the rest to sleep.

Also, you can just have the enable pin tied to a digital output pin that is set to high and when you set it to low it pulls to ground. Then you don't need a switch, you can do it through the software. I don't know if this way is technically proper, but I've done it in other projects.

A couple other quick references for sleep:
https://www.arduino.cc/en/Tutorial/ArduinoZeroPowerConsumption
https://forum.arduino.cc/index.php?topic=337289.0
 
The display should be fine running through the regulator. The regulator is rated up to 500ma (not continuous) but the oled display only draws about 40ma on average.
That's a good idea with the pin. I never thought of that but I don't see isn't problem with doing it that way. I will look into testing it tonight.

The only other thing that would be nice to turn off would be the led's on the board itself. I'm not sure if there is a software way to do this but it would be nice.
 
Today was a productive day. AS promised I will finalize 0.6.x with NRF. Therefore I added a average calculation for rpm and current because I get data in a to high frequency from the vesc and on the display it is much to nervous to have a good measure. Then I also realized different screens and a switching between them via Joystick (left/right) If you need the left right information on the vesc, it can be defined out by the config file. It can also be realized to make it configurable to use instead the Joystick also buttons. But that is still a ToDo.
All that will than also be merged to the V1.x trunk.

Here a short Video of it:
https://www.youtube.com/watch?v=CD2fQELc5SU&feature=youtu.be
I still have the problem with the measurement of the speed from the rpm. At the moment I have no idea want I made wrong. Hope to find the problem soon.

The Vesg hat data called rpm and data called tachometer. Does anyone now where the difference is?

We should also discuss the user interface in general. I think we should at least three buttons:
1 x plus
1 x minus
1 x enter
A good approach from s28400 is to allow configuration only when the board stands (rpm = 0). That is an important safety feature. Than we could use also the throttle for +/-.
To enter the configuration mode a enter button should be pressed for 3 sec (configurable over config.h).
At the moment I never the less have not that much configuration requirement. Only allowed max. Speed in PID mode.
General configuration procedure:
rpm = 0? --> Press enter for 3 sec. --> Select parameter +/- --> Press enter --> change value +/- --> press enter -->press enter for 3 seconds to leave configuration

What do you think?

Edit: How can I embed a youtube Video?

Regards

Andy
 
Looks great Gecko! I love the menu swipe system.

For the buttons I think three is the perfect amount. I designed my housing to have the two above the screen (for menu navigation and power on/off functions) and the trigger for a safety engage to ride but also an enter button when in configuration mode.

To embed a youtube video, use the youtube tags when posting around the video id (there is a button above the text box when posting). In your case, you'd want to do {youtube}CD2fQELc5SU{/youtube} but with the regular brackets [] instead of curly ones.

Also a small update from me. I fully charged the battery last night (took about 2 or three hours from 30%) and I have been running it since. I measured a drop of about 2% per hour with the display showing some text, and the feather updating battery info and throttle position. It's been running for almost 24 hours now and is only approaching 55%! I think with normal use, this battery will last for weeks before needing a recharge.

I am also currently trying to find room inside the housing for the FRAM module. I may end up having to buy a smaller battery and mount it above the feather. However this could be reverted if I end up designing a custom PCB for the remote once the hardware issues are ironed out. I might be able to squeeze it up above the trigger next to the hall effect sensor instead. We will see once I get the module in the mail.

Cheers!
 
rpm is the instantaneous rotational speed of the motor, tachometer is the number of pulses, or absolute number in case of abs_tachometer, the VESC has counted since powered on, in my tests i got 40 pulses per full rotation in a 14 pole motor, for speed you should use only the rpm and apply the corrections for gearing and tire diameter, and of course convert to km/h. Whats the formula you have been using?

Amazing work guys, as soon i (re)finish my board i will ditch the nunchuck and try s28400 aproach

Cheers
 
Here is the code I used for the calculation

Code:
#define DIA_WHEEL	76 //mm
#define RATIO_GEAR	3.2
..
const float ratioRpmSpeed = ((DIA_WHEEL * 3.14156) / RATIO_GEAR) * 60 / 1000000; //RPM to Km/h
const float	rationRotDist = ((DIA_WHEEL * 3.14156) / RATIO_GEAR) / 1000000; //RPM to travelled km
..
calculatedValues.speed = calculatedValues.rpmAverage * ratioRpmSpeed;
calculatedValues.distanceTravel = VescMeasuredValues.tachometer * rationRotDist;

OK. In the distance calculation is the error the usage of the tachometer. But for the speed?
 
I've checked here, the pulse number that i said, i'ts the motor poles*3, for a 14 pole motor that gives 42 pulses per rotation. As i understand, that's the number of sequencial phase activation to complete a full rotation.
For the ERPM, i got RPM = ERPM*2/ Motor_Poles

See if this works

Code:
#define DIA_WHEEL   76 //mm
#define RATIO_GEAR   3.2
#define PULSE_REV   42  //Number of poles*3
#define ERPM_REV    7   //Number of poles/2


const float ratioRpmSpeed = (DIA_WHEEL * 3.14156 * 60) / (ERPM_REV * RATIO_GEAR * 1000000);  //ERPM to Km/h
const float   rationRotDist = (DIA_WHEEL * 3.14156) / (PULSE_REV * RATIO_GEAR * 1000000); //Pulses to Km

//or simplified

const float ratioRpmSpeed = DIA_WHEEL / (ERPM_REV * RATIO_GEAR * 5305.22);  //ERPM to Km/h
const float   rationRotDist = DIA_WHEEL / (PULSE_REV * RATIO_GEAR * 318313.19); //Pulses to Km


calculatedValues.speed = calculatedValues.rpmAverage * ratioRpmSpeed;
calculatedValues.distanceTravel = VescMeasuredValues.tachometer * rationRotDist;
 
The test was more or less a success. I checked it against GPS on the smart phone. Speed seams to be OK. Only in the traveled distance I still have a divergence. The remote calculate 3.3 km. The GPS showed 4 km. So the ratio is 0.825. It seams to be a straight ratio. Where could the mistake be? In the easiest case I can put this ratio as a correction ratio as a constant till we have a better solution.

There is one more bug I have to solve. Amphours is not shown. I've to check for the reason.
 
Maybe someone from you see the problem:

Und the Vesc site the COMM_GET_VALUES package is packed this way:
Code:
case COMM_GET_VALUES:
		ind = 0;
		send_buffer[ind++] = COMM_GET_VALUES;
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS1), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS2), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS3), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS4), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS5), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS6), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_PCB), 1e1, &ind);
		buffer_append_float32(send_buffer, mc_interface_read_reset_avg_motor_current(), 1e2, &ind);
		buffer_append_float32(send_buffer, mc_interface_read_reset_avg_input_current(), 1e2, &ind);
		buffer_append_float16(send_buffer, mc_interface_get_duty_cycle_now(), 1e3, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_rpm(), 1e0, &ind);
		buffer_append_float16(send_buffer, GET_INPUT_VOLTAGE(), 1e1, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_amp_hours(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_amp_hours_charged(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_watt_hours(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_watt_hours_charged(false), 1e4, &ind);
		buffer_append_int32(send_buffer, mc_interface_get_tachometer_value(false), &ind);
		buffer_append_int32(send_buffer, mc_interface_get_tachometer_abs_value(false), &ind);
		send_buffer[ind++] = mc_interface_get_fault();
		// TODO: send FOC values id, iq, abs
		commands_send_packet(send_buffer, ind);
		break;

IO unpack it this way:

Code:
case COMM_GET_VALUES:
		ind = 0;
		send_buffer[ind++] = COMM_GET_VALUES;
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS1), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS2), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS3), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS4), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS5), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_MOS6), 1e1, &ind);
		buffer_append_float16(send_buffer, NTC_TEMP(ADC_IND_TEMP_PCB), 1e1, &ind);
		buffer_append_float32(send_buffer, mc_interface_read_reset_avg_motor_current(), 1e2, &ind);
		buffer_append_float32(send_buffer, mc_interface_read_reset_avg_input_current(), 1e2, &ind);
		buffer_append_float16(send_buffer, mc_interface_get_duty_cycle_now(), 1e3, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_rpm(), 1e0, &ind);
		buffer_append_float16(send_buffer, GET_INPUT_VOLTAGE(), 1e1, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_amp_hours(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_amp_hours_charged(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_watt_hours(false), 1e4, &ind);
		buffer_append_float32(send_buffer, mc_interface_get_watt_hours_charged(false), 1e4, &ind);
		buffer_append_int32(send_buffer, mc_interface_get_tachometer_value(false), &ind);
		buffer_append_int32(send_buffer, mc_interface_get_tachometer_abs_value(false), &ind);
		send_buffer[ind++] = mc_interface_get_fault();
		// TODO: send FOC values id, iq, abs
		commands_send_packet(send_buffer, ind);
		break;

Is there a mistake?

By the way: For the bluetooth communication we have to define own packages, because we are limited to something ~32 byte or even less over bluetooth. I've to check it. It is not a big deal to do that, but it must be done and then pulled in the VESC repo by Vedder. Vedder defined really huge packages for the USB communication.

I will check-in tomorrow or so V0.7.0 as final release with nRF support. The Feather arrived yesterday.! I only wait no for the bluetooth device for the board.
 
Hi,

I just get this message:

Hi, I was just wondering if you are planning on releasing a tutorial or something for your arduino remote? I have already two arduino nano and will order the oled later; however, having never worked with arduino before, I have no idea on how to program the arduino and wire everything up. Any help is appreciated.

I didn't plan to explain from scratch on how to work with arduino. Maybe somebody of you will write some lines to that topic in the wiki section?
The wireing is documented in the config.h. Please try to understand it. If you are not able to understand it than please let me know. Then I must document it a better way.
 
Gecko,

You may have already known this, but the feather w/ bluetooth can only act as a peripheral device. This means that the HM-10 has to act as the central, which it can do, but I'm assuming will need to be programmed from the vesc? I'm still waiting on my vesc, but I'm hoping to experiment with all this weekend now that everything else has arrived.
 
Back
Top