This article explains the structure of Fuelino software. The software source code, which is available on GitHub at this link, is composed by many "cpp" and "h" C++ language files divided into sub-folders. In order to understand the software behavior, it is necessary to have a look at the "ino" file, which is the Arduino IDE sketch containing the "setup()" and "loop()" functions.
The source code below is copy-pasted from the latest software release available at the moment, Fuelino SW 1.00 beta 5. As shown below, the main sketch is composed by the following parts:
- The "include" of header files of additional software modules (libraries).
- Declaration of global variables used inside the Arduino sketch.
- Declaration of "yield()" function, which is executed during SD card writing dead times (by "SDfat" library), or inside the main loop, during idle time.
- setup() is executed before the main loop, and has the purpose of setting up: Serial communications, fuel injection management, EEPROM memory management, ADC acquisition manager, IMU manager (MPU-6050).
In the last part of the sketch, there is a loop() function which I would like to describe in detail. It does the following:
- Initializing the GPS (Ublox Neo 6M), only at first loop execution.
- Performing injector safety check, to make sure that the injector is not continuously commanded "open". In case the injector is not driven OFF at least one time inside a specific amount of time, the injector command is turned OFF.
- Engine steady state check evaluation, to understand when it is possible to perform a lambda sensor signal "screenshot", and when the engine has completed the cranking phase.
- IMU manager, to acquire data from MPU-6050.
- GPS manager, to send and acquire data from Ublox Neo 6M.
- Analog and digital signals acquisition, for data logging.
- Data logging into micro SD memory card
- Idling time
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
// Created by Davide Cavaliere // E-mail: dadez87@gmail.com // Website: www.monocilindro.com // 28 February 2017 // Fuelino SW1.0 beta5 // Compiles successfully with Arduino IDE 1.8.0 #include "src/compile_options.h" // Compile options #include "src/EEPROMmgr/EEPROMmgr.h" // EEPROM memory management #include "src/INJmgr/INJmgr.h" // Injection and physical input/outputs management (except for A0 - A7) #include "src/COMMmgr/COMMmgr.h" // Serial Ports Communication management #include "src/SDmgr/SDmgr.h" // SD memory management #include "src/GPSmgr/GPSmgr.h" // GPS manager #include "src/ADCmgr/ADCmgr.h" // ADC manager (Analog Inputs A0 - A7) #include "src/MPU6050mgr/MPU6050mgr.h" // IMU module (if present) bool first_loop=true; // first time to execute the loop uint16_t time_last_gate = 0; // for loop minimum time check // Function called during SD card write idling, and in Main Loop while waiting void fuelino_yield(unsigned long time_now_ms){ INJmgr.safety_check(time_now_ms); // Safety checks (checks if, from last function call, the injector has been deactivated at least one time) MPU6050mgr.manager(time_now_ms); // IMU communication manager INJmgr.analog_digital_signals_acquisition(); // Acquires throttle position sensor and lambda signals //delay(1); } void setup(){ COMM_begin(); // Initializes serial communication ports INJmgr.begin(); // Injection and signal IO management EEPROM_initialize(); // EEPROM memory check, loads calibration maps and config word ADCmgr_init(); // Initializes the ADC MPU6050mgr.begin(); // Initializes IMU module } void loop() { // This part is executed only at first cycle loop if (first_loop == true){ #if (GPS_PRESENT == 1) && (FUELINO_HW_VERSION >= 2) && (BLUETOOTH_PRESENT == 0) GPS_initialize(); // Initializes GPS module communication (this function uses "delays"), this is why it is put here and not in "Setup" #endif first_loop = false; } unsigned long time_now_tmp = millis(); // Time entering the loop // Scheduled functions INJmgr.safety_check(time_now_tmp); // Safety checks (checks if, from last function call, the injector has been deactivated at least one time) INJmgr.steady_state_eval(time_now_tmp); // Evaluates if engine is working in steady state conditions, to enable Lambda sensor signal logging MPU6050mgr.manager(time_now_tmp); // IMU communication manager COMM_receive_check(); // Serial Communication manager #if (GPS_PRESENT == 1) && (FUELINO_HW_VERSION >= 2) && (BLUETOOTH_PRESENT == 0) GPS_manager(); // GPS communication manager #endif INJmgr.analog_digital_signals_acquisition(); // Acquires throttle position sensor signal SDmgr.log_SD_data(); // SD card data logging, as last, after checking all data // Loop time check (waiting cycles) time_now_tmp = millis(); // read present time again uint16_t time_now_tmp_16bit = (uint16_t)(time_now_tmp & 0x0000FFFF); // read present time while((time_now_tmp_16bit - time_last_gate) < (uint16_t)LOOP_MIN_EXEC_TIME){ // Dead time from last time still has to expire fuelino_yield(time_now_tmp); // Execution takes some ms time_now_tmp = millis(); // read present time (32 bits) time_now_tmp_16bit = (uint16_t)(time_now_tmp & 0x0000FFFF); // read present time (16 bits) } time_last_gate = time_now_tmp_16bit; // Save the time when this "while gate" was crossed } |
In the main folder of the project, there is a sub-folder called "src", which contains the following files and folders. Each folder corresponds to a software module (library). What each library does can be easily understood from the name of its folder.
- ADCmgr library. Manages analog inputs (A0 - A7) acquisition by using Atmel ATmega328p "ADC_vect" interrupts.
- COMMmgr library. It manages the communication using UART. There are 2 types of Serial communication. One is the hardware serial which connects Arduino to the PC (57600 baud), for service communication and calibration purposes. An other one is the software serial "SWseriale" port (9600 baud) which is managed using interrupts "INT0_vect" and "TIMER2_COMPA_vect".
- Display_Mgm library. Not used at the moment. Under development.
- EEPROMmgr library. It manages EEPROM memory reading and writing.
- GPSmgr library. It manages the communication, using SWseriale, with Ublox Neo 6M GPS module.
- INJmgr library. It manages the electronic fuel injection timing, using "PCINT2_vect" and Timer1 interrupts.
- MPU6050mgr library. It manages the measurements coming from MPU-6050, which is connected to the Atmega328p using I2C communication protocol.
- SDmgr librady. It manages the micro SD card writing, by using SPI communication protocol. Files handling is done by using the SDFat library, available on GitHub.
There is also a configuration file called "compile_options.h" (the file shown below), which contains the compiling options to enable/disable some parts of the source code, depending on the presence/absence of additional modules. You should check and correct the values of these flags, before compiling the software for your Fuelino: in case in your application some modules, such as GPS, Bluetooth, IMU, micro SD card, are not connected to Fuelino, you should set their flags to 0. This will help reducing Flash and RAM memory consumption. In particular, in case SD card is not connected to Fuelino, you should set its flag to zero, otherwise the program will keep trying to write data via SPI, locking the loop() iterations execution for some hundreds of milliseconds.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#ifndef CompileOptions_h #define CompileOptions_h // Arduino internal options #define FUELINO_HW_VERSION 2 // HW version of Fuelino. Fuelino V1 does not have SWseriale, and also, for injector management, input and output pins are different. For Fuelino Proto3, please enter "2" #define ENABLE_BUILT_IN_HW_SERIAL 1 // Enables the communication HW Serial port (USB connection with PC) on pins 0 and 1. Default is "1". I suggest to keep it as "1", since it does not create problems. // External modules #define SD_MODULE_PRESENT 1 // SD Card module present #define DISPLAY_PRESENT 0 // Display module on I2C #define MPU6050_PRESENT 1 // IMU module on I2C #define GPS_PRESENT 1 // GPS module on SW Serial #define BLUETOOTH_PRESENT 0 // Enables packets forwarding (sending and receiving) through SW Serial, in case FUELINO_HW_VERSION>=2, and a Bluetoooth (or Wifi module) is connected on SWseriale // Main Loop execution time #define LOOP_MIN_EXEC_TIME 25 // Main Loop minimum execution time [ms] #endif |
Hello sir i'm very interested by your work. I would like to remplace membrane carburator in my big rc plane by efi. Do you think that possible with your system?
No, it is not enough. Fuelino can work with an existing EFI. Actually, the HW might work, but you need to change the SW to handle the speed input. You need somehow to understand the position of the crank, to schedule the injection. Usually EFI systems have 1 injection per 1 engine revolution.
Prima di tutto congratulazioni per il bellissimo lavoro. Ora, qual è la possibilità di utilizzare questa ECU con i motori Kart poiché non abbiamo adattato alcun supporto elettronico come in CG125?
Ciao. Fuelino funziona in generale con qualunque centralina con controllo ad iniezione elettronica. Devi gia' avere un motore che supporti l'iniezione elettronica ed abbia la sua centralina originale. Quello che Fuelino fa e' mettersi in mezzo tra il comando della centralina, e l'iniettore, e modificare questo comando a piacere. Giusto per sapere, che kart hai? E' 2 tempi o 4 tempi? Quanti cilindri? Carburatore o iniezione elettronica?
SWserialeのBAUDRATE 9600を変更したいのですが、どこを変更すればいいでしょうか?
GPSがBAUDRATE 38400または57600 なのでそれにあわせて変更したいです。
こんにちは。SWseriale.hの下記の箇所を修正して下さい。
「#define BAUDRATE 9600」
返信ありがとうございます。
「#define ONE_BIT_CYLES (uint8_t)((2000000 / BAUDRATE) - 1) // -> pre-scaler set to 0.5us - Example: at 9600 baud, this is 208 (208.3333...)」
こちらは修正しなくてよいでしょうか?
可能であればBAUDRATE 115200をつかいたいです。
「#define BAUDRATE 115200」
だけで良いのでしょうか?
他に修正が必要な場合はアドバイスください。
感謝します。
ONE_BIT_CYCLESはBAUDRATEを使って計算されるから、変更する必要はありません。
115200baudは早すぎて、SWで処理できないと思います。
そんなに早い通信速度を使うには、HWシリアルポートを使う必要があります。