Porting MultiWii to Arduino DUE
Arduino
DUE is a microcontroller board based on the Atmel SAM3X8E ARM Cortex-M3 CPU.
It is the next generation of Arduino boards “UNO, Nano, Mini”…etc. It is a very
attractive platform for building quadcopter firmware on for the following
reasons:
- A 32-bit core, that allows operations on 4 bytes wide data within a single CPU clock.
·
CPU Clock at 84Mhz compared
to 16MHz for other Arduino.
- 96 KBytes of SRAM compared to 8Kbytes for Arduino Mega 2560.
- 512 KBytes of Flash memory for codecompared to 256Kbytes for the nearest giant Arduino Mega, and this number is much less in other Arduinos.
- DMA controller, that can relieve the CPU from doing memory intensive tasks.
All these advantages do not come without a cost. The main
two disadvantages from current quadcopters firmware and hardware are:
1- This warning message on Arduino website “Warning:
Unlike other Arduino boards, the Arduino Due board runs at 3.3V. The maximum
voltage that the I/O pins can tolerate is 3.3V. Providing higher voltages, like
5V to an I/O pin could damage the board.” This means that you cannot
just attach your current 5V logic hardware to Arduino DUE.
2- There is EEPROM memory in Arduino DUE L. And this is another very sad
news as you need to have EEPROM in order to be able to save PIDs, sensors calibration
values and many other values used for quadcopters. They need to be saved
somewhere and without EEPROM you need to use external flash memory which is extra
hardware and extra interface.
I can see that these two reasons strongly affected firmware developers to
use Arduino for quadcopters. But as we will see below these were only
illusions.
Problem Solved
Naze32
was the first 32-bit board I see for MultiWii. When I found the code for the
first time, the first thing I searched for is that EEPROM problem and how can
we solve it. Well the solution was obvious; you can use Flash memory instead of
EEPROM. You can store the data together with the code.
WAW; I said to myself. It is very
nice simple approach. So I searched for similar code for Arduino DUE, and I
found one written by cmaglie. That
is 50% of the problem solved J
Now back to the 3.3V issue, well
it seems someone has the courage to try the 3.3V and guess what, it worked J. I contacted Rouan to make sure that there is
no 3.3V tweeks that I need to make, and the answer was no. I believe the 3.3V
works with no problems for the following reasons:
1-
For ESC logical 1 is less
than 3.3V so 3.3V as input signal for ESC is more than enough to control it.
2-
For RX seems that logical 1
is either less than 5V of maybe because the input is a pulse of with 2ms max
with frequency 50Hz makes the average DC is not enough to burn the input pin.
Again the 3.3V is not an issue
anymore J
Why MultiWii?
Well, I am no longer
the first one –I know- to write quadcopter code on Arduino DUE, Rouan has
already made it. So I decided to pick for myself a new challenge, and I chose
to convert MultiWii firmware for the following reasons:
1- It is a very famous firmware, well known and not so complex.
2- It is already built to talk with Arduino boards, so supporting
Arduino DUE is a natural extend for the firmware.
3- Arduino community as well as MultiWii community might find this
conversion useful to start with to build much powerful updates, as the current
code takes only 9% of the available Flash memory.
Steps of porting MultiWii to Arduino DUE
My
target is to build MultiWii code that you can still compile it on 8-bit Arduino
boards. It is not a dedicated version for Arduino DUE –although a next version
might be so-.
So I
first need to figure out where to put changes and where to keep old code. In
the remaining part, I will mention the major changes as well as major
challenges I faced during this process.
#if defined (ARDUINO_DUE)
As in all MultiWii code, you need to define specific code
for specific board, and I have chosen to use ARDUINO_DUE as the mark. All code
under ARDUINO_DUE is specifically compiled when you choose to compile for
Arduino DUE only. Some code in MultiWii is generic for all boards, but I can
only be executed for 8-bit microprocessors not ARM, for these parts I use #if
!defined (ARDUINO_DUE)
Def.H
This is the file you need to edit to define now sensors,
vehicle, board ...etc. It is a core file. I started with it and defined:
1-
When ARDUINO_DUE is active.
#if defined (ARDUINO_ARCH_SAM)
#define ARDUINO_DUE
#endif
ARDUINO_ARCH_SAM
is what you need to look for to detect an ARDUINO_DUE.
2-
Define alternatives for pgmspace
by including <arm/ pgmspace.h>
3-
ARDUINO_DUE board pin
assignments.
THR: PIN
62 - A8
ALE:
PIN 63 - A9
ELE: PIN
64 - A10
RUD: PIN
65 - A11
AUX1: PIN
66 -DAC0
AUX2: PIN
67 - DAC1
Motor 1:
PIN 34
Motor 2:
PIN 36
Motor 3:
PIN 38
Motor 4 / Servo 4:
PIN 40
Other parts of the definition are just
code from ARDUINO_MEGA that will make error if activated as it is not converted
yet.
Code Changes
I used Multiwii version 2.3 as my starting point. Most of the
other code is same as MultiWii, Dramatic changes where in EEPROM.cpp Sensors.cpp,
RX.cpp and Output.cpp
EEPROM.cpp I used cmaglie Flash class –I updated a
paging issue in it- to save configuration structures.
RX.cpp I used Rouan
code, and it was very useful and straight forward.
Output.cpp Again I used Rouan code, but this time it was
more tricky to embed with original code of MultiWii due to logic of motor/servo
selection and different PWM signal generation.
Sensors.cpp I used original
wire.h library, however I renamed it Wire_DUE.h and included as part of the
project as I intend to update it later to make it fast. I replicated the same I2C
functions that is used in MultiWii so that sensors logic stay untouched. Functions
used Wire_DUE.h instead of original code when compiling for Arduino_DUE.
Main Issues I Faced
- I first used __CM3_REV instead of ARDUINO_ARCH_SAM to check for DUE, and it made linking errors. I have not run through the root cause yet, but I took couple of days to solve this issue.
- Types from uint8_t & int16_t in functions _getADC() in sensors.cpp
. You need to make explicit type casting. Without doing so you will get
rubbish data from GYRO. This is due the << operation acts without
caring about the sign.
- Alignment !!!!! This was a very wicked tricky issue that I faced when trying to connect to WiiGUI. The application displays data correctly but gives false alarm of suiting to BARO mode –Altitude Hold- for example. And I found that this error was due to serializing structures in protocol.cpp, and the 32bit compiler stored structure items 4byte-aligned, This makes gaps between different variables and translated wrongly by WinGUI. This is why you found __attribute__ ((packed)) at each and every structure and union. This was a very time consuming bug, and very random and distributed between C# code on PC and C++ code in firmware
- GYRO Hopping.
scale = (currentT - previousT)
* (GYRO_SCALE * 65536);
Scale variable
that is vital for measuring angular velocity of Gyro was giving hopping from 0
to 100 even without touching any sensor. The behavior disappeared when I used
int32_t for both currentT & previousT as used in the main
loop in Multiwii.cpp
Code Status
The
code is not 100% converted i.e. not all features, however you compile it for Quadcopter or Tricopter and
fly in different modes. I have not test GPS, sonar. I only used GY_80 as well as the HK 328 board.
Code is still under development, and as any firmware it can contain serious issues, so fly safe and on your own risk.
Code is still under development, and as any firmware it can contain serious issues, so fly safe and on your own risk.
Good Luck J
This comment has been removed by a blog administrator.
ReplyDeleteThank you .... Kindly check the video.
Delete+1 on the good Job!
ReplyDeleteI think this is good work and i think multiwii should use of this work in multiwii 2.4
ReplyDeleteI hope they do. I have already added a post about it in multiwii forum
Deleteplz send me code of multiwii se 2.5 version
Deletehttps://github.com/HefnySco/MultiWii_DUE
Deleteit exists in the article
thank you.
Can you connect it using Multiwii GUI to calibrate the sensors?
ReplyDeleteyes ... it could be
ReplyDeleteLove this entry.
ReplyDeleteI am looking to get Multiwii operating on an Atmega1284p. Any advice or tutorials you can point me to to help me out at all?
Atmega1284p is 8-bit so original code should work -in general-.
DeleteIt is more pin re-assignment and timers.
Good luck :)
Thanks for that tip. I've got my board working a bit now. Able to get my Bluetooth working, and GPS, and I2C. Not able to get my receiver working on the analog pins yet, as it locks everything up, but still plugging away. ;)
ReplyDeleteHi Mohammad.
ReplyDeleteGreat project!, which uses sensors?, where is defined?. Thank
Hi I am trying to use the modified code. First problem is multiwii gui. gui can connect the due but can not get any information. Second problem is I could not arm motors. Because of the gui did not show anything ı can not understand what is going on. Would you please help me =)
ReplyDeleteU have same problem
DeleteThis comment has been removed by a blog administrator.
ReplyDeleteI have tried to port MULTIWII to STM32F1 since last month, but it failed because the attitude displayed on MULTIWIICONF is not correct.
ReplyDeletemy plan is MULTIWII will finally run on STM32F0 board if I successed on STM32F1, because there is a lots of mini quard boards out there which are STM32F03X or STM32F051 and with RF chip.
then i found your source code, although my MULTIWII2.3 is different from your MULTIWII2.3. it seems there are lots of different 2.3 version online.
the attitube of STM32F1 and STM32F0 is right now after replacing MULTIWII with your source code.
I'm here just to express my gratitue.
I can share my project if you need it.
ooh, for eeprom , I just use a array in sram.
Deleteforgot to put down my email : 215301801 at qq.com.
can u share the modified code
ReplyDeleteI didn't understand what u modified