Currently I am trying to get some 30A BLHeli_s ESC's to work with the Arduino nano every using the Dshot protocol, but can find any compatible examples of bitbanging Dshot on the ATMega4809. I also can't create my own as I do not have a oscilloscope. Any suggestions? I don't think emulation of the ATMEGA328 with GitHub - gueei/DShot-Arduino: DShot implementation for Arduino using bit-banging method will work as I think there will be considerable delays, unfortunately I can't even test this without an oscilloscope.
I checked the DSHOT protocol and it looks like it's the same communication protocol as what's used to control Neopixels, only slower. You can easily control it with PWM from a decent MCU running at least 16 MHz
Thanks, I'll go digging around the library as soon as I have the time.
After looking through the library it seems that I would be better off to just try and modify the GitHub Dshot library to correct the timing. thought this may be difficult without an oscilloscope.
So, I eventually broke down and just bought a semi-cheap oscilloscope which I have use to create a rough implementation of Dshot on an arduino nano every. The timings and code are still pretty ugly as they use delayMicroseconds with __asm__ __volatile__ (" nop\n");. It is all unoptimized but it all looks like it works. So far I have only tested D9-D10 but to get it working with other pins all you need to is find the port of said pins and where they are on the register (just look into port manipulation). To get multiple signals at the same time might be a little harder to do but still possible.
void setup() {
PORTB.DIRSET = 0b0000010; //PortB = D10&D9 in this case D9
Serial.begin(9600);
}
//send a 1 on D9
int sendI(){
PORTB.OUTSET = 0b00000010;
delayMicroseconds(5);
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);
PORTB.OUTCLR = 0b00000010;
delayMicroseconds(1);
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);
}
//send a 0 on D9
int sendO(){
PORTB.OUTSET = 0b00000010;
delayMicroseconds(3);
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);
PORTB.OUTCLR = 0b00000010;
delayMicroseconds(4);
__asm__ __volatile__ (
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
" nop\n"
);
}
//function for converting a integer into a binary representation. It only returns on value since C++ cant return arrays and strings
int convInt(int nb, int i){
int output[32];
int bits = 32;
while (bits >= 0) {
if ((nb >> bits) & 1){
//Serial.print("1");
output[bits] = 1;
}
else{
//Serial.print("0");
output[bits] = 0;
}
--bits;
}
return(output[30-i]);
}
//the function for sending 16 bits of Dshot from an array which contains 1,0
int sendBytes(int bytes[]){
for (int i = 0; i < 16; i++)
if (bytes[i]){
sendI();
}
else{
sendO();
}
}
int throttle = 0; //zero is disarmed 1-27 are special and 28-2047 are viable throttle values
int throttleBits[12];
int crc = 0; //checksum
int crcBits[4];
bool telemetry = false;
int data[16];//the main array which everything is put into
//6.675 microseconds per byte
//1 is 5.00 fDelat 1.675 sdelay
//0 is 2.47 fDelay 4.205
void loop() {
//Calculate the chechsum
if (telemetry){
crc = ((throttle*2+1) ^ ((throttle*2+1) >> 4) ^ ((throttle*2+1) >> 8)) & 0x0F;//calculate checksum with a 1 at the end (in binary)
}
else{
crc = ((throttle*2) ^ ((throttle*2) >> 4) ^ ((throttle*2) >> 8)) & 0x0F; //calculate checksum with a 0 at the end (in binary)
}
//add the crc into a binary representation
for(int i = 0; i < 4; i++) {
crcBits[i] = convInt(crc, i+27);
Serial.print(crcBits[i]);
}
Serial.print(" ");
//add the throttle into a binary representation
for(int i = 0; i < 11; i++) {
throttleBits[i] = convInt(throttle, i+20);
Serial.print(throttleBits[i]);
}
Serial.print(" ");
//put all the data together in
for(int i = 0; i < 11; i++) {
data[i] = throttleBits[i];
Serial.print(data[i]);
}
if (telemetry){
data[11] = 1;
Serial.print(data[11]);
}
else{
data[11] = 0;
Serial.print(data[11]);
}
for(int i = 12; i < 16; i++) {
data[i] = crcBits[i-12];
Serial.print(data[i]);
}
Serial.println();
//send the data
sendBytes(data);
delay(500);
}
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.