Monday, December 8, 2008

First Project (the simplest!)


My aim is to develop an ECU dedicated to control the intake air system ram.


Short air rams allow fast intake, while long air rams allow slow air wave.
Yamaha with its YCC-I, now available on R1 and R6, controls the air rams lenghts.
As example, some R1 engine tests show:
- long rams: at high regimes the output power would be reduced to 145,1 CV (at 10.250 rpm), while at lower regimes it is increased
- short rams: above 10.000 rpm the output power is increased to 160 CV (at 10.250 rpm)



Thenrefore I need a dedicated ECU able to:
1. acquire the current engine speed
2. acquire the throttle position
3. control a servo-motor to move the air rams




Since nowadays ECUs have CAN bus, for tasks 1 and 2, I plan to get the engine rotation speed (rpm) and throttle position by CAN messages. Therefore the only task to be performed by MaxECU is to control the servo-motor. After some internet searches, I got the idea to reuse a standard and robust servo-motor: the one used for RC models!


MaxECU system description:
- XC164CM from Infineon, 16-bit CPU and various peripherals (see http://www.ehitex.de/p_info.php?xPD=113_117&products_id=264)
- 2xCAN nodes
- 1xADC channel (in case the throttle position is not available via CAN message)
- 1xDigital Input (in case RPM is not available via CAN message)
- 1xDigital Output (PWM) to drive the servo-motor position


Software:


the project is quite simple, infact the XC164CM is providing several peripherals to easy the task.


RPM meter:


in order to acquire the engine rotating speed, it is necessary to allocate one timer and a counter connected to the Digital Input. I use the RTC-T14 (timer 14) to generate a 1sec timebase, at each generated interrupts (every second) the counter T6 is latch, reset and restarted for the next acquisition. Mainly there is no CPU load to perform such operations, here the Interrupt Service Routine example:




GPT2_vStopTmr(GPT2_TIMER_6);
// Read T6 Counter content and save in global variable
uiRPM_REAR = GPT2_uwReadTmr(GPT2_TIMER_6);
// Clear T6
GPT2_vClearTmr(GPT2_TIMER_6);
GPT2_vStartTmr(GPT2_TIMER_6);



where the global variable "uiRPM_REAR" contains the latest acquired engine rotation speed. Since our bike has already an ECU, it is fairly simple to get access to the "RPM signal", on Yamaha R6 is available on ECU cabling.


Servo-motor control:
a servo-motor for RC models is very simple to be controlled. In fact, it has a 3 wire cable as:


where the position is controlled by the pulse width on the signal cable:


the relationship between pulse width to rotor position is quite easy:
- 1.0 msec <-> 0% position
- 1.5 msec <-> 50% position
- 2.0 msec <-> 100% position (where position could be 180 ° or less depending on the servo-motor model. See: http://www.futaba-rc.com/servos/digitalservos.html)

To generate such waveforms, I have used 2 timers: T3 and T4. T3 is used for the 10 usec timebase, while T4 is used for generating the delay between consecutive pulses. Software is quite simple:



iPosition = 50; // x% of Zero position
GPT12E_T4= T4_15ms;

while (1) {
// Start only if Timer T4 gives the signal
if (bStartPulseModulation == 0xF)
{
bStartPulseModulation = 0;
// Pulse starts with 1msec HIGH signal even if iPosition = 0%
P1L_P0 = 1; // DIO1 == P1L.0 = HIGH for 1msec
GPT1_Wait(T3_1ms); // Wait 1msec

// Enlarge the pulse time depending on iPosition
if ( iPosition != 0)
{
cnt = (iPosition * 50) - 1;
GPT1_Wait(cnt);
}

// Pulse LOW: Stop !
P1L_P0 = 0; // DIO1 == P1L.0 = LOW
}
}

The output waveforms are:



2 comments:

Anonymous said...

massimo,
ma dove lo trovi il tempo di smanettare con la centralina della moto? sei un grande!
Ciaooo

Bonny

Max said...

Grazie Bonny, ti ho mandato l'invito così se vuoi partecipare sei il ben accetto!