ARDUINO - help and ideas thread

The problem solved. Thank you @Ackmaniac

1 Like

Hi, (like many) I am currently building a custom remote with OLED Display. I am using two Atmega 328pā€™s that communicate via the NRF24L01+ modules. Sending commands with the setCurrent() (RollingGeckoā€™s library) function via UART to the VESC works, however there is a massive delay between trigger movement and motor reaction. Sometimes throttle gets stuck as well. I should probably add that I am running the Atmega 328pā€™s at 8MHz. So my question is: Do you think the Atmega can not handle the tasks at the given clock frequency? Has anyone ever created a working (with no delay) custom remote-control based on current control? Also I donā€™t receive any data from the VESC anymore, although I already had it working once. Baudrate, common ground between Atmega and VESC have been checked. Really losing faith in my custom solution as I literally spent dozens of hours playing with code.

Would really appreciate some help on this matter as this is for a school project.

Thanks, Max

1 Like

Hi, Iā€™ve build a Remote with two arduinos and Bluetooth (not LE) and it works fine. But I have to admit that I use PWM for the acceleration and not the UART. It works really fine and has, as far as I noticed, no delay.

@mrplaygood

Cool! Do you run the chip at the regular 16MHz?

No, Iā€™m using a Teensy 3.2 (or LC Iā€™m not sure) and an Adafruit Feather M0 Proto which both run at 48 MHz. These Boards are actually very fast an cheap. I would suggest that you buy one or two for prototyping. The Teensy LC cost around 12$ and the Adafruit Feather M0 Proto 20$. You donā€™t need the Feather but itā€™s great for battery powered projects since it has onboard LiPo charger. Both have full Arduino support and, when it comes to the feather, a huge community with great tutorials and libraries. And Iā€™m not sponsored by them :smiley:

You could upload the code you are using. Maybe there is an unnecessary delay or something.

Greatings -Daniel

@mrplaygood Sorry for answering so late.

This is the code I am using on the TX side:

#include buffer.h #include crc.h #include datatypes.h #include local_datatypes.h #include printf.h #include VescUart.h #include ā€œRF24.hā€ #include U8g2lib.h

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=/ 8, / dc=/ 7, / reset=*/ 6); RF24 radio(9,10); const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; int DisplayNumber=0;
int Potpin=A0; struct remotePackage remPack;
struct bldcMeasure VescMeasuredValues; double persXJoy;

enum Display { MainDisplay, Speed, Current };

void DrawScreenMain(void) { u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB14_tr); u8g2.setCursor(0,20); u8g2.print(VescMeasuredValues.inpVoltage); u8g2.setCursor(50,20); u8g2.print(ā€œVā€); u8g2.setCursor(0,40); u8g2.print(remPack.valXJoy); u8g2.setCursor(50,40); u8g2.print(ā€œAā€); u8g2.setCursor(0,60); u8g2.print(VescMeasuredValues.rpm); u8g2.setCursor(50,60); u8g2.print(ā€œrpmā€); u8g2.sendBuffer();
}

void setup() { // put your setup code here, to run once: Serial.begin(115200); u8g2.begin(); radio.begin(); radio.setChannel(110); radio.setAutoAck(1); radio.enableAckPayload(); radio.openWritingPipe(pipes[0]); }

void loop() { // put your main code here, to run repeatedly: remPack.valXJoy=analogRead(Potpin);

radio.write(&remPack,sizeof(remPack));
while(radio.available()){ radio.read(&VescMeasuredValues, sizeof(VescMeasuredValues)); }

//Display output switch(DisplayNumber){ case MainDisplay: DrawScreenMain(); break; } //Serial.println(VescMeasuredValues.inpVoltage); }

On the RX side the code looks like this:

#include buffer.h #include crc.h #include datatypes.h #include local_datatypes.h #include printf.h #include VescUart.h #include ā€œRF24.hā€

RF24 radio(9,10); const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };

struct remotePackage remPack;
struct remotePackage lastremPack; struct bldcMeasure VescMeasuredValues;
double persXJoy; int timethen;

void setup() { // put your setup code here, to run once: Serial.begin(115200); radio.begin(); radio.setChannel(110); radio.setAutoAck(1); radio.enableAckPayload(); radio.openReadingPipe(1,pipes[0]); radio.startListening(); }

void loop() { // put your main code here, to run repeatedly:

radio.writeAckPayload(1,&VescMeasuredValues,sizeof(VescMeasuredValues));

while(radio.available()){ radio.read(&remPack,sizeof(remPack)); timethen=millis(); } //Serial.println(remPack.valXJoy); if((remPack.valXJoy<800)&(remPack.valXJoy>300)){ lastremPack=remPack; } else if((millis()-timethen)>300){ lastremPack.valXJoy=530; }

persXJoy = map(lastremPack.valXJoy, 330, 780, 0, 250);
analogWrite(3,persXJoy); //Serial.println(persXJoy); /if (persXJoy > 1) //Einbau eines Totbereichs { VescUartSetCurrent(((float)persXJoy / 100) * 10.0);
else if (persXJoy < -1) { VescUartSetCurrentBrake(((float)persXJoy / 100) * -3.0);
}
/

}

The part that takes long is probably the display output.

Greetings Max

Hi @ELongb, sorry that I canā€™t help right now. After Friday Iā€™ll have more time again. Hope that fits with your school project.

@mrplaygood Never mind! Through tests I found out that the internal crystal of the Atmega 328p might be too inaccurate for the communication with the Vesc. Took me a long time to come to this conclusion. Anyway, thank you for the help!

Regards, Max

I awake this great thread to share my project with you :

Remained tasks:

  • Test the VESC6 UART communication (not so different from the old protocol, so should work easily).
  • Adjust settings in real conditions for brightness

Once Iā€™ll consider the code finished, Iā€™ll share the Arduino Create link. I code in a way that it should work with other LEDs configuration (e.g. bigger ring for gauge).

4 Likes

Nice, Iā€™ve been thinking in doing something similar, in my case i want two functions, display energy consumption (average Wh/km of the ride) in a color scale, so if a can tweak my riding style if i need more range, and a battery indicator like yours

Since iā€™m in a long board i want something more discrete and maybe only active when a button is pressed in the remote remote

but i also have 4 LEDā€™s in my remote, just need to add few lines on the sketch, so the board indicator may be dispensable

For the brightness, a LDR and some tweaking is the way to go

Glad my project inspires you. Doing your consumption gauge is not a big deal IMO. I already thought how to integrate the ring in the nose of the board. Just make a circle route, put the ring and cover with transparent grip :wink:

Yeah, that is one way, but i wanā€™t it to not be visible or almost non visible when off, iā€™m thinking a row of 3mm leds an a narrow slit in the grip tape, just enough to see

Could be nice also !

How do you measure the voltage via arduino?

I get this info through the communication with the VESC.

1 Like

Did you manage to implement the CAN forward to get data from both VESCā€™s?

Ok this seems like as good a place as any to ask:

I was looking at creating my version of a nunchuk using arduino (and maybe some ESP8266s) doing something similar to the RollingGecko code in talking to the VESC (very nice BTW). I wanted to simulate the nunchuk to get the ā€œcruise controlā€ type features, but I also wanted to get some stats/figures from the VESC as well.

From what I have worked out: the nunchul needs to talk to the VESC via i2c, and to get the stats/figures from the VESC I need to use the UART. Given that they share pins (on the VESC) this is not going to be possible.

I guess my solution now is to create my own pseudo-cruisecontrol based on the RPM that Iā€™m reading and output an appropriate PWM signal like a normal remote from the ā€œbaseā€ module (which connects directly to the VESC, and talks wirelessly with the controller).

Thoughts?

Do I have it wrong?

Iā€™ve done lots of reading around here (and reading of RGeckos code) and I donā€™t think I have seen a nunchuk/display implementation.

At the end of the day: PWM (PPM?) is not so badā€¦ just a bit twitchy which can be addressed in arduino code (ramping./filtering).

Hey there, i think you got most of it right, but the nunchuck doesnā€™t necessarily have to talk via i2c. In RollingGeckos code you can see that he sends the nunchuck values over serial, so everything can work off of one serial port. You essentially have to build a remote package and send it to the vesc. Itā€™s in ArduBoardControl if you want to see the code.

2 Likes

Hey guys, Iā€™ve got some questions for you:

I am planning to make a connection between a VESC 4.10 and an Arduino UNO through the UART system Iā€™ve read about in this forum. What kind of data can the Vesc send? Is it possible to read RPM if the motor is sensored?

Second question: do I need to send PWM signals from ARDUINO to VESC if I want to control motor speed, am I right? Thanks

EDIT: I am currently reading the whole thread, in case i find some useful info and answer my questions by myself

Have a look at RollingGeckoā€™s arduino library (https://github.com/RollingGecko/VescUartControl).

Heaps of stats/figures can be read from the VESC.

Also I found this library quite useful (works with ESP8266/ESP32): https://github.com/bastianraschke/ESP8266VESC

Iā€™m currently building a VESC -> ESP32 -> NRF24 -> ESP32 (inside controller).

1 Like