Jump to content
abecedarian

How fast does this execute?

Recommended Posts

// Crankshaft / camshaft rotation simulation
// Engine is V-twin with cylinders at 80 degrees opposed
// Connecting rods share a common crankshaft journal
// Code is based on a full camshaft cycle (720 degrees rotation)
// and when spark plugs should fire. Actual ignition advance is
// not factored in yet since advance would move right and left cylinders'
// 'trigger' points accordingly and that would cause the right
// cylinder to be less than zero. So until I work in that logic,
// as of now, both cylinders fire spark plugs with 0 degrees ignition advance.
// This means right spark plug would fire when the cam trigger occurs and
// left spark plug would fire 440 degrees later:
// Left cylinder fires 360 + 80 = 440;
// right cylinder would fire 280 degrees afterwards:
// 440 + 280 = 720 (or 0 if you prefer). 
//
// Target in Energia IDE is MSP430G2553 @ 16MHz
//


const uint16_t t1 = 0;  //  right cylinder baseline spark
const uint16_t t2 = 440; // left cylinder baseline spark relative right cylinder
const uint8_t cam = 0; // camshaft trigger relative right cylinder TDC

const uint8_t AMBER_LED = 5;  // LP pin indicating camshaft trigger signal occurrence
// I am using existing RED_LED, GREEN_LED for right and left cylinder TDC indicators


uint32_t degree = 0; // counter for crankshaft rotation in degrees

void setup()
{
  pinMode(RED_LED, OUTPUT);
  pinMode(GREEN_LED,OUTPUT);
  pinMode(AMBER_LED, OUTPUT);
}

void loop()
{
  for (degree = 0; degree < 72000; degree+= 1125)  {
// 11.25 = spacing between tooth centers on a 32 tooth wheel
// changed to 1125 to get rid of decimals and work without floats

// Camshaft:
    digitalWrite(AMBER_LED,degree == cam);

// Right cylinder:
    digitalWrite(RED_LED, degree == t1);

// Left cylinder:
    digitalWrite(GREEN_LED, degree == t2);

  }
}
I don't have a scope here so I hope that it can toggle any one of the LED's at greater than 5KHz.

 

And then... anyone have any good advice relating to getting this into a timer / interrupt handler?

Share this post


Link to post
Share on other sites

I think you've reached a fundamental design decision here.

Energia is a copy of a framework designed for a more capable processor (more RAM and flash, HW multiplier) than the G2553.

If you are dead set on using the G2553, abandon Energia, since it will eat into your RAM and performance (look into the source and see how much code and time it takes to do digitalWrite, analogRead, etc).

If your priority is to use Energia, upgrade to a different board (Tiva or F5529).

 

Anyway hope this helps and good luck.

Share this post


Link to post
Share on other sites

@@David Bender - Yep, I'm aware of that. Funny thing is the G2553 is faster than the processor used in the fuel injection ECU I'm replacing by a factor of at least 2. Also, getting the timer running and generating interrupts will likely mean using C/C++ or assembly which would bypass the Energia overhead. And that's where I'm stuck. ;)

 

All I want to do is generate two signals representing the crankshaft and camshaft triggers, and a handful of DC voltages with DAC's. The crankshaft trigger is a 32 tooth gear and the camshaft is a single tooth. So, at a maximum of around 11000 RPM, that's 352000 crank signals and 5500 cam signals per minute, or around 5900 / 100 signals per second- definitely well within the range of human hearing.

 

This seems perfectly well within the capabilities of the G2553. And if need be, I have several G2553's laying around so could put 2 or 3 on a board. A Tiva C, or even F5529 seems like overkill to me.

 

The ECU itself will likely be running a TMS570 processor, maybe in concert with a P8X32A, so no problems with speed there.

Share this post


Link to post
Share on other sites

Wasn't considering PWM. The cam/crank signals are interpreted by the ECU as straight up high/low toggles, like one would get from Hall effect sensors. They are variable reluctance sensors that will be processed by a MAX9926 chip. The 9926 outputs are pulled up to 3v3/5v (haven't decided yet) and the chip pulls them down to indicate a signal.

 

Trying to get any chip to generate a +/- 300V peak to peak signal is a bit of a stretch, and not necessary within this context.

Share this post


Link to post
Share on other sites

Another thing I have to consider is that although 'my' trigger is a 32 tooth gear, others may have 9, 36 or 60 teeth, and I have to accommodate those as well.

 

My "for" loop used an unsigned 32 bit long with an increment of 1125; 1125 = 36000 / 32 simply because an unsigned 16 bit can't account for anything greater than 65536. and I needed to count to 72000 to keep floats out: I multiplied 360 by 100 to get the decimal out of 11.25: 32 teeth over 360 degrees equals... yeah, you get it. 9 teeth is 40; 36 is 10; 60 is 6.. or 4000; 1000; 600... respectively, factoring out the fractional part.

 

The ECU itself will be running a timer between teeth to interpolate angles between teeth. Yeah, I'm rambling. ;)

 

As mentioned, there are 11.25 degrees between the tooth centers on my trigger, so a timer will reset with each tooth detection, and run from zero. The intent is to get at least 1024 'ticks' between teeth, which would result in an approximate accuracy of better than 0.05 degrees, even with a 9 tooth trigger. Ideally, the ECU will try to get at least 1024 ticks between tooth events, even with a 60 tooth wheel, for a theoretical accuracy of better than 0.001 degrees. If the 'ticks' cannot be actualized, as in more or less ticks occur before the next tooth event occurs, the counter will speed up or slow down as necessary and lost or necessary additional 'ticks' will be added or subtracted so that the overall positional certainty does not drift too much. In any case, any accumulated drift will be eliminated after two crankshaft revolutions because the camshaft signal will occur and timers / counters will be reset.

Share this post


Link to post
Share on other sites

Oh OK, I didn't realize this was a simulator (duh, you said so). I see what you are doing now; the important thing is to have these impulses at the proper phase from each other.

 

Since you have a bunch of G2553 chips, devote one to just the simulated crankshaft.

The reason being is you should simulate the "speed" of your crankshaft by changing the speed of the DCO.

You can scale the DCO speed/up down, refer to  https://github.com/analog10/UART_DCO_Calibrator

As long as your signals are in the proper phase for 1 frequency, this should work for all frequencies

Share this post


Link to post
Share on other sites

Those old 8 bit ECUs have support chips that help with all the timing critical stuff. With a G2553 you have a faster CPU, but only wo very basic timers. Each can only do two full featured compare outputs, so your need for three outputs is just beyond what it can easily do. The F5529 has a timer A with five outputs, and a timer B with 7 outputs, so it is much better able to do what you need.

Share this post


Link to post
Share on other sites

Sorry if I sound frustrated: it's not my intent to be such. Sometimes I don't explain things well and other times I go into far too much detail. ;)

 

A full engine cycle takes two crankshaft revolutions. The engine has a gear on the end of the crankshaft, and that gear has 32 teeth. There are two variable reluctance sensors around that gear, but I am only using one of those. Therefore, I am going to be getting 32 'pulses' from the VR sensor for each crankshaft revolution. The fact there are 32 teeth results in there being 11.25 degrees of rotation between adjacent teeth. The camshaft is driven at 1/2 crankshaft speed and has a single tooth trigger. Consequentially, one full engine cycle, two crankshaft revolutions, means I will have 64 crankshaft signals and 1 camshaft signal occurring.

 

These sensors can, by their nature, generate in excess of +/- 18v for the camshaft and +/- 200v for the crankshaft, but I'm not worried about that: the MAX9926 chip will be handling that, and its output coincides with the 'positive voltage going negative zero crossing' of those sensors. This is what I want to simulate, and as such only need to provide a roughly square wave signal for each sensor, with periods equivalent to the 32 tooth and single tooth wheels- the 32 tooth would be a nearly true square wave of 50% duty; the 1 tooth would be akin to a one-shot happening once every 64 pulses from the crankshaft.

 

 

 

I don't deny the old ECU's had support chips. It's fascinating enough for me to think that this old ECU could take a V2 up to over 10000 RPM, and accommodate turbocharging to well over 18PSI in the manifold- making a 500CC engine breathe nearly 1300CC's of air. But, that ECU only did fueling so only had the camshaft sensors to use for timing / triggering purposes.

 

In the end, the goal is to generate the crank/cam signals, and the other few sensors' signals: manifold pressure and temperature, coolant temperature, throttle position (it's a simple linear potentiometer)... to feed into the new ECU and see how it responds, as in can it track RPM up to > 10000; does it do proper table look-ups based on throttle position or manifold pressure, and can it adequately work up the air and coolant temperature compensations... maybe even run a PID for fuel mixture lean/rich compensation.

 

So what I want to do is actually fairly simple, or at least I feel it should be simple: run a timer that toggles a couple GPIO pins in the background, and a foreground task driving a few DAC's for voltage outputs. But, I have to make sure this simulator is as true / proper as possible, within certain limits. I don't expect it to behave exactly like an engine proper would, for instance. I don't expect to do things like tweak the TPS setting and have the unit increase RPM, decrease manifold pressure and such like a real engine would. It's more for validating the ECU functions, as in the ECU sees changes in this or that and we can see it's referencing the tables and such, as it should, trying to come up with realistic values for things.

 

I'd like to have something with a serial / terminal window open where I could type in something like "R1400" and have the unit output crank / cam signals equivalent to 1400 RPM, for instance. I could type in "M100" and have the unit set the manifold pressure to 100 kilo-pascal, absolute; type "A150" and have air temperature set to 150C or type "C0" or "C50" and the coolant temperature is set to 0C or 50C, just to see what the ECU does with those values.

Share this post


Link to post
Share on other sites

The DAC's I have are PDIP MCP4922, SPI interface, and can reference an external V source, so I think I'm set there.

Well, at least they'll output a voltage referencing the ECU source... which is what I want, though I can't guarantee a match with the source / sensor impedance.

Share this post


Link to post
Share on other sites

If you want to see how fast the loop is going then refer to the UART DCO Calibrator timer interrupt; it is recording the time between pulses. If you run at 16MHz, those pulses will be DCO clock counts. If you output those pulses to the UART (at 115200 you should be able to keep up) then you'll know the period between pulses.

 

As for the other stuff I apologize I still lost about whether you are generating crank/cam pulses or cylinder firing (code seems to be cylinder but your explanation was about crank/cam?) I don't understand why you chose your units to be degrees when you are counting gear tooth pulses, why not base everying on gear teeth?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×