Aruna
Dshot.cpp
Go to the documentation of this file.
1 //
2 // Created by noeel on 22-03-20.
3 //
4 
5 #include "aruna/driver/Dshot.h"
6 #include <stdlib.h>
7 #include <unistd.h>
8 
9 using namespace aruna;
10 using namespace aruna::driver;
11 
12 
13 Dshot::Dshot(uint32_t speed_hz, bool bidirectional): frequency(speed_hz), bidirectional(bidirectional) {
14 
15  uint32_t max_ns = (1.f / (float) speed_hz) * 1000000000;
16 
17  const static float T0H_percentage = 0.375;
18  const static float T1H_percentage = 0.75;
19  const static float T0L_percentage = 1 - T0H_percentage;
20  const static float T1L_percentage = 1 - T1H_percentage;
21 
22  T0H_ns = max_ns * T0H_percentage;
23  T1H_ns = max_ns * T1H_percentage;
24  T0L_ns = max_ns * T0L_percentage;
25  T1L_ns = max_ns * T1L_percentage;
26 
27  pthread_mutexattr_t swm_att;
28  pthread_mutexattr_init(&swm_att);
29  pthread_mutex_init(&write_mut, &swm_att);
30  pthread_mutexattr_destroy(&swm_att);
31 
32 }
33 
34 
36  return set_speed(speed);
37 }
38 
40  const static uint16_t MAX_VALUE = 2047;
41  const static uint16_t MIN_VALUE = 48;
42  const static uint16_t MID_VALUE = (MAX_VALUE + MIN_VALUE) / 2;
43  const static uint8_t telemetry = 0;
44 
45  uint16_t max, min = 0;
46  if (bidirectional) {
47  max = speed < 0 ? MID_VALUE : MAX_VALUE;
48  min = speed < 0 ? MIN_VALUE : MID_VALUE;
49  } else {
50  max = MAX_VALUE;
51  min = MIN_VALUE;
52  }
53  uint16_t adjusted_speed = (uint16_t) convert_range(abs(speed), max, min);
54  uint16_t bit_frame = create_dshotFrame(adjusted_speed, telemetry);
55 
56 
57  return write_frame_continuous(bit_frame);
58 }
59 
60 
61 
62 void Dshot::add_CRC(uint16_t &bits) {
63  uint8_t csum = 0;
64  uint16_t csum_data = bits >> 4;
65  for (uint8_t i = 0; i < 3; i++) {
66  csum ^= csum_data;
67  csum_data >>= 4;
68  }
69  csum &= 0xf;
70  bits |= csum;
71 }
72 
73 
74 
75 uint16_t Dshot::create_dshotFrame(uint16_t speed, uint8_t telemetry) {
76  uint16_t bit_frame = 0;
77  bit_frame = speed << 5;
78  bit_frame |= telemetry << 4;
79  add_CRC(bit_frame);
80  return bit_frame;
81 }
82 
84 
85 // arm ESC
86  uint16_t start_value = 48;
87  uint8_t step = 50;
88  uint8_t amount_of_steps = 40;
89 
90 // up hill
91  for (int i = 0; i < amount_of_steps; ++i) {
92  write_frame_continuous(create_dshotFrame((step * i) + start_value, 0));
93  usleep(1);
94  }
95 // down hill
96  for (int i = amount_of_steps - 1; i > -1; --i) {
97  write_frame_continuous(create_dshotFrame((step * i) + start_value, 0));
98  usleep(1);
99  }
100 // stay low for a little while
101  write_frame_continuous(create_dshotFrame(start_value, 0));
102  usleep(150);
103 
104  set_speed(0);
105 
106 }
107 
108 err_t Dshot::write_frame_continuous(uint16_t dshot_frame) {
109  err_t e;
110  pthread_mutex_lock(&write_mut);
111  e = _write_frame_continuous(dshot_frame);
112  pthread_mutex_unlock(&write_mut);
113  return e;
114 }
115 
117  pthread_mutex_destroy(&write_mut);
118 }
119 
121  return frequency;
122 }
123 
125  return bidirectional;
126 }
127 
128 void Dshot::set_bidirectional(bool is_bidirectional) {
129  bidirectional = is_bidirectional;
130 }
uint32_t get_frequency()
get frequency of the driver
Definition: Dshot.cpp:120
Definition: comm.cpp:14
bool bidirectional
Definition: Dshot.h:18
err_t _set(movement::axis_mask_t axisMask, int16_t speed) override
Implementation of axis movement, this function is called from set(...).
Definition: Dshot.cpp:35
static double convert_range(uint16_t input, float range_max=100.f, float range_min=0.f)
Convert uint16 to a new range.
Definition: Actuator.cpp:46
uint16_t T1H_ns
Definition: Dshot.h:58
err_t write_frame_continuous(uint16_t dshot_frame)
Write set Dshot frame continuously on the bus.
Definition: Dshot.cpp:108
const uint32_t frequency
Definition: Dshot.h:17
void add_CRC(uint16_t &bits)
add CRC to end of bit stream.
Definition: Dshot.cpp:62
Dshot(uint32_t speed_hz=150000, bool bidirectional=false)
Dshot parent object.
Definition: Dshot.cpp:13
bool get_bidirectional()
Is this Dshot driver birectional (can spin both ways)
Definition: Dshot.cpp:124
void set_bidirectional(bool is_bidirectional)
Set bidirectional property of the driver.
Definition: Dshot.cpp:128
err_t set_speed(int16_t speed)
Set speed, use negative values to rotate in the other direction if bidirectional is enabled...
Definition: Dshot.cpp:39
virtual err_t _write_frame_continuous(uint16_t dshot_frame)=0
Write set Dshot frame continuously on the bus.
uint16_t T0L_ns
Definition: Dshot.h:59
void arm_ESC()
Call the function after the constructor to arm the ESC.
Definition: Dshot.cpp:83
pthread_mutex_t write_mut
Definition: Dshot.h:16
uint16_t T1L_ns
Definition: Dshot.h:60
uint16_t T0H_ns
Definition: Dshot.h:57
uint16_t create_dshotFrame(uint16_t speed, uint8_t telemetry)
craft dshot package
Definition: Dshot.cpp:75