Saturday, December 13, 2008

Weeling Project

Based on same HW (XC164CM, see "http://www.ehitex.de/p_info.php?xPD=113_117&products_id=264"), I intend to buid an ECU capable to show me if rear weel is spinning (or weeling: the project name) by flashing a LED. Moreover, this dedicated ECU would have a 7-segment display to show the current inserted Gear. In future I plan to add also a CAN node to communicate to other ECUs and dash-boards.

The SW must do:
1. speed measurement of the front weel
2. speed measurement of the rear weel
3. acquire the current engine speed (RPM)
4. calculate the current inserted gear and shows on 7-segment display
5. calculate the spinning ratio between the rear and the front weel
6. LED must blink (flash) proportionally to the spinning ratio:

  • slow spin -> LED is blinking slow
  • high spin -> LED is blinking very fast


In order to perform the above described operation, I plan to use:
- Timer RTC-T14 for the 1s timebase
- Counter T5 for counting the front weel revolutions (1.), the front weel sensor must be connected to port 5, pin 13 (P5.13)
- Counter T6 for counting the rear weel revolutions (2.), the rear weel sensor must be connected to port 5, pin 12 (P5.12)
- Counter T2 for counting the engine RPM (3.), the engine sensor must be connected to port 3, pin 7 (P3.7)
- Timer T3 for the LED flash (6.), the LED is connected to port 3, pin 6 (P3.6)

RPM meter:
in order to acquire the engine rotating speed, it is necessary to allocate a counter connected to the dedicated Digital Input (P3.7). I use the RTC-T14 (timer 14) to generate a 1sec timebase, at each generated interrupts (every second) the counter T2 is latch, reset and restarted for the next acquisition.

Front Weel meter:
in order to acquire the front weel speed, it is necessary to allocate a counter connected to the dedicated Digital Input (P5.13). I use the same RTC-T14 to generate a 1sec timebase, at each generated interrupts (every second) the counter T5 is latch, reset and restarted for the next acquisition.

Rear Weel meter:
in order to acquire the rear weel speed, it is necessary to allocate a counter connected to the dedicated Digital Input (P5.12). I use the same RTC-T14 to generate a 1sec timebase, at each generated interrupts (every second) the counter T5 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:

if(RTC_ISNC_T14IR) // if counter T14 overflow
{
// USER CODE BEGIN (RTC,3)
iGPT_Counter++;
// Stop Timers
GPT1_vStopTmr(GPT1_TIMER_2);
GPT2_vStopTmr(GPT2_TIMER_5);
GPT2_vStopTmr(GPT2_TIMER_6);

// Read Timer Counters content and save in global variable
uiRPM_ENGINE = GPT1_uwReadTmr(GPT1_TIMER_2);
uiRPM_FRONT = GPT2_uwReadTmr(GPT2_TIMER_5);
uiRPM_REAR = GPT2_uwReadTmr(GPT2_TIMER_6);

// Clear Timers and Start Them !
GPT1_vClearTmr(GPT1_TIMER_2);
GPT1_vStartTmr(GPT1_TIMER_2);
GPT2_vClearTmr(GPT2_TIMER_5);
GPT2_vStartTmr(GPT2_TIMER_5);
GPT2_vClearTmr(GPT2_TIMER_6);
GPT2_vStartTmr(GPT2_TIMER_6);

// USER CODE END

RTC_ISNC_T14IR = 0;
}


LED blinking:
in order to have a blinking LED with a blinking ration proportional to the spinning ration, I use the timer T3, preloading a countdown value proportional to the spinning ratio. It is easier then to explayin it, here the sourcode extract:

void Flash(unsigned int cnt)
{
if (cnt == NONE) {
P1L_P3 = 0; // LED OFF
bT3ISisON = 0;
} else {
// Stop Timer first !
GPT1_vStopTmr(GPT1_TIMER_3);

// Load wait time
GPT12E_T3 = cnt + T3_1s; // load timer 3 register

// Start Timer
bT3ISisON = 0xF;
GPT1_vStartTmr(GPT1_TIMER_3);
}
}

While the Timer 3 interrupt service has only to do:

void GPT1_viTmr3(void) interrupt T3INT using RB_LEVEL3
{
// USER CODE BEGIN (Tmr3,5)
if (bT3ISisON)
P1L_P3 = ~P1L_P3; // Toggle LED only if bT3ISisON is enabled
// USER CODE END
}


Gear Calculation:
in order to calculate the inserted Gear, it is necessary to determine the ration between the rear weel rpm and the engine rpm: the ratio can only be one of the available gear-ratios: for the Yamaha R6 I have calculated the following gear-ratios:

#define Gear_1 41
#define Gear_2 33
#define Gear_3 20
#define Gear_4 16
#define Gear_5 13
#define Gear_6 11
(are multiplied by 10x since I do not like to use special number precision in my SW). Therefore to permit all this, in the main() loop, the following calculation:

// Calculate the actual inserted Gear and Display it
uiGEAR = (uiRPM_ENGINE / uiRPM_REAR) * 10;
if ( uiGEAR != uiOldGEAR )
{
uiOldGEAR = uiGEAR;
Display7seg (uiGEAR);
}


void main(void):
at the end it all quite easy...

// Clear T6 and Start
GPT2_vClearTmr(GPT2_TIMER_6);
GPT2_vStartTmr(GPT2_TIMER_6);

// LED constantly on
P1L_P3 = 1;

while (1)
{
// Skip First 10 execution to stabilize acquisition
if (iGPT_Counter > 10)
{
uiWeeling = (uiRPM_REAR / uiRPM_FRONT) * 10;
// Check if the rear weel is spinnng too much !!!
if (uiWeeling > 10)
Flash (uiWeeling); // LED flashes proportionally to weeling

// Calculate the actual inserted Gear and Display it
uiGEAR = uiRPM_REAR / 10;
uiGEAR = ( uiRPM_ENGINE * 100 ) / uiGEAR;

if ( uiGEAR != uiOldGEAR )
{
uiOldGEAR = uiGEAR;
Display7seg (uiGEAR);
}
}
}


Simulation:
Nowadays, it is more easy to simulate the SW and HW then to debug it in winter time. I have used Keil compiler and debugger (refer to the page LINKS) and I have created a script to generate the input frequencies on the dedicated pins:
- P5.13 for front weel = 9900Hz (= 128KM/h)
- P5.12 for rear weel = 9800Hz (= 128KM/h)
- P3.7 for the engine = 117Hz (= 7000 RPM).
After compiling the project, I run the debugger and open the Logic Analyzer window to show the input signals and the internal variables. Here what happen after 12.79s of execution: the uiGEAR value is 11 indicating that the 6th gear is inserted:

With the following frequencies:
- P5.13 for front weel = 8800Hz (= 109KM/h)
- P5.12 for rear weel = 8400Hz (= 109KM/h)
- P3.7 for the engine = 117Hz (= 7000 RPM).
After running again the debugger, the Logic Analyzer shows (after 12.79s of execution): the uiGEAR value is 13 indicating that the 5th gear is inserted:


For the time being that's all, next step will be to add teh CAN node and transmit the measured and calculated values to dash-board....

3 comments:

Max said...

Nessuno posta commenti !?!
Sopratutto, qualcuno ha idea su come calcolare se la ruota posteriore sta derapando e troppo?
Attendo i vostri suggerimenti

Antonio said...

Si faccia una domanda, si dia una risposta! ;)

Come definiresti la condizione "derapare troppo"? dipende da mjolti fattori, sul dritto la derapata e' negativa (perche' fa perdere velocita' e conssuma inutilmente gomme) ma non e' pericolosa come lo puo' essere in uscita di curva a moto inclinata....credo quindi che tu debba definire una sota di formula dipendente dall'angolo di piega per definire un limite massimo di derapata. Oltre tale limite puoi prevedere l'accensione della spia o un taglio di potenza (non so se sia possibile in qualche modo da fuori la ECU....)

Max said...

Ben Detto!
In realtà non so quando una derapata sia troppo, la mia idea è quella di inizare dandone indicazione, sarà poi l'esperienza a dire come procedere.
Per il taglio della potenza sarebbe possibile farlo in maiera grossolana, ma preferisco evitarlo per non creare qualcosa di pericoloso