Dear Ardupilot community, hello!
I am currently using a Notch Filter based on an RPM sensor, which has largely solved my problem - I have 48-inch props! However, my copter has 8 motors, and when my drone is moving, the motor speeds are definitely not equal, but I only detect the speed of one motor!
My ESC and motor were sold together, they are very expensive and I cannot consider replacing them. I have currently made an RPM collector that collects the speed of 8 speed sensors and sends it to the FC via serial port at 100Hz.
But I encountered difficulties in Lua. My RPM collector continuously sends the measured speed, but I don’t know how to use Lua to read it! This is too different from C#, I have no clue.
The protocol output by my RPM collector is like this: first send FFFFFFFF as the packet header, then send the low 8 bits and high 8 bits of 8 motors in turn, and repeat sending at a frequency of 100Hz and 115200bps.
his is the program I tried to write.
– Define serial port
local port = assert(serial:find_serial(0),“Could not find scripting serial port!”)
port:begin(115200)
port:set_flow_control(0)
– Define packet header
local header = “\xFF\xFF\xFF\xFF”
– Define the number of motors
local num_motors = 8
– Define the time when the last valid data was received
local last_valid_data_time = millis()
– Define a function to read and parse serial data
function read_data()
local delay = 12 – Default delay of 12 milliseconds
– Check if there is at least 20 bytes of available data
if port:available() >= 20 then
– Read data from the serial port
local data = port:read()
– Find the packet header
local start_index = string.find(data, “\xFF\xFF\xFF\xFF”)
if start_index then
– Check if there is enough data in the buffer
if string.len(data) - start_index + 1 >= 20 then
– Extract the packet
data = string.sub(data, start_index, start_index + 20 - 1)
– Update the time when the last valid data was received
last_valid_data_time = millis()
– Extract motor speed data
local motor_speeds = {}
for i = 1, num_motors do
local low_byte = string.byte(data, 4 + (i - 1) * 2)
local high_byte = string.byte(data, 5 + (i - 1) * 2)
motor_speeds[i] = low_byte + high_byte * 256
end
– Update esc*_rpm values
for i = 1, num_motors do
esc_telem:update_rpm(i - 1, motor_speeds[i], 0)
end
delay = 10 -- If a packet was successfully processed, delay for 10 milliseconds
end
end
end
-- Check if no valid data has been received for more than 1 second
if millis() - last_valid_data_time > 1000 then
-- Send warning text to ground station
gcs:send_text(4, "no_rpm_data")
last_valid_data_time = millis()
end
return read_data, delay
end
return read_data, 10
I tried to debug this program. After adding else gcs:send_text(6, “err”) after if start_index then, I found that the problem was here: the program found the data, but could not find the packet header. After I tried to print the data directly to the gcs, I found 4 consecutive 255s in the data - it could see my packet header, but couldn’t find it?
After I tried adjusting the loop time and changing the packet header format, the program still stalled at this point.
After waiting for a long time, I also found that the data printed to the gcs all turned into 255. Does this mean that the buffer overflowed? How can I solve this problem?
Please help me, I really have no clue! Thank you for your help and have a nice day.