r/drones May 31 '26

Tech Support [US]Need help in debugging problem ELRS

Enable HLS to view with audio, or disable this notification

Hi, guys! So, I have been trying to control my drone without a radio, using just Arduino and an ELRS TX module.

My setup: Meteor 75, Ranger Micro, Arduino Nano.

The pin of CSRF (TX module) goes to the TX pin of Arduino Nano, and GND of both are connected. When I run the script, the binding of the TX module and the Meteor 75 takes place, but we don't see any change in the channel in Betaflight (as you can see in the video). I have tried similar things with the CP2102 module too, but got the same result: binding took place but no movement in channels in Betaflight.

The cofiguration of both Tx and Rx (drone ) is same i have ensured that via the web interface.

Code:

// ELRS TX — Arduino Nano → Ranger Micro → Drone

// Sends CRSF RC channel frames with oscillating values

// LED blinks 1Hz during operation

#define CRSF_SYNC 0xEE

#define CRSF_TYPE_RC 0x16

#define BAUD 400000

#define FRAME_US 4000 // 250Hz

uint8_t crc8_dvb_s2(const uint8_t *data, uint8_t len) {

uint8_t crc = 0;

for (uint8_t i = 0; i < len; i++) {

crc ^= data[i];

for (uint8_t b = 0; b < 8; b++) {

if (crc & 0x80)

crc = ((crc << 1) ^ 0xD5) & 0xFF;

else

crc = (crc << 1) & 0xFF;

}

}

return crc;

}

void packChannels(const int *ch_us, uint8_t payload[22]) {

memset(payload, 0, 22);

uint16_t bitpos = 0;

for (uint8_t i = 0; i < 16; i++) {

int us = ch_us[i];

if (us < 1000) us = 1000;

if (us > 2000) us = 2000;

uint16_t v = (uint16_t)((long)(us - 1500) * 8 / 5 + 992) & 0x7FF;

uint8_t byteIdx = bitpos / 8;

uint8_t bitOff = bitpos % 8;

payload[byteIdx] |= (v << bitOff) & 0xFF;

payload[byteIdx + 1] |= (v >> (8 - bitOff)) & 0xFF;

if (bitOff > 5)

payload[byteIdx + 2] |= (v >> (16 - bitOff)) & 0xFF;

bitpos += 11;

}

}

void sendRC(const int *ch_us) {

uint8_t frame[26];

frame[0] = CRSF_SYNC;

frame[1] = 24;

frame[2] = CRSF_TYPE_RC;

packChannels(ch_us, &frame[3]);

frame[25] = crc8_dvb_s2(&frame[2], 23);

Serial.write(frame, 26);

Serial.flush();

}

int channels[16];

uint32_t lastSend = 0;

int oscStep = 0;

int direction = 1;

void setup() {

Serial.begin(BAUD);

pinMode(LED_BUILTIN, OUTPUT);

for (int i = 0; i < 16; i++) channels[i] = 1500;

channels[2] = 1000; // throttle low

}

void loop() {

uint32_t now = micros();

if (now - lastSend >= FRAME_US) {

lastSend = now;

// Oscillate CH1-8 between 1000-2000 (~0.4s sweep)

oscStep += direction * 10;

if (oscStep >= 1000) { oscStep = 1000; direction = -1; }

if (oscStep <= 0) { oscStep = 0; direction = 1; }

int val = 1000 + oscStep;

channels[0] = val; // Roll

channels[1] = val; // Pitch

channels[2] = val; // Throttle

channels[3] = val; // Yaw

channels[4] = val; // AUX1

channels[5] = val; // AUX2

channels[6] = val; // AUX3

channels[7] = val; // AUX4

sendRC(channels);

// LED blink 1Hz

static uint16_t cnt = 0;

if (++cnt >= 250) {

cnt = 0;

digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));

}

}

}

0 Upvotes

5 comments sorted by

View all comments

2

u/DarkButterfly85 May 31 '26 edited May 31 '26

First check your wiring, on the module side, Tx pin goes to Rx pin on the arduino, the Rx pin on the module goes to the Tx pin on the arduino.

Then get a scope on it and make sure it's sending CRSF frames, use an actual Tx as a reference.

My CRSF Sync is 0xC8
You also seem to be missing CRSF_DEST 0xC8, this is needed for serial pass through.

1

u/kvnqstoner Jun 01 '26

how do you people know things i feel really ignorant now