what ever makes this the simplest for sure!
trying to learn the code stuff and see what megasquirt is outputting at the same time is a lot to chew on.
i think this is about 98% there and i spent over 2 weeks trying to get the MS to just do it on its own
It could be as simple as this (compiles, not tested) with that pin swap:
//ref: sketch_oct25a
//pin definitions
#define TRGA_MASK 0b00000100 //PD2
#define TRGB_MASK 0b00010000 //PD4
#define TRGC_MASK 0b01000000 //PD6
#define COPA_MASK 0b00001000 //PD3
#define COPB_MASK 0b00100000 //PD5
#define COPC_MASK 0b10000000 //PD7
void setup()
{
Serial.begin(9600);
//set triggers as inputs (0), COPs as outputs (1)
DDRD &= ~(TRGA_MASK | TRGB_MASK | TRGC_MASK);
DDRD |= (COPA_MASK | COPB_MASK | COPC_MASK);
}//setup
void loop()
{
PORTD = (PORTD & 0b00000011) | ((PIND << 1) & 0b11111100);
}//loop
Q: Are you driving the IGBTs directly from the Uno ports? You might consider getting proper IGBT drivers. Which IGBTs are you using?
i have a 330 resistor in between the UNO and IGBT. this is how the megasquirt recommends there board so i just followed that.
https://www.digikey.com/product-detail/en/on-semiconductor/FGP3440G2-F085/FGP3440G2-F085-ND/4963380
turbothis:
i have a 330 resistor in between the UNO and IGBT. this is how the megasquirt recommends there board so i just followed that.FGP3440G2-F085 onsemi | Discrete Semiconductor Products | DigiKey
Thanks for the info. Yeah, that looks like it'd be okay.
so far the first code from black fin runs the best. i mean really close but it must advance the timing some with the dwell or something because it will ping just a little if i stall up the motor in low gear.
other wise it cranks right up and i can mash the go pedal as much/fast as i want and it is like a factory car.
i think i can offset the crank input some degrees and win this thing!
with the shorter code "Uno to follow the MS" runs smooth but i get a lot of MS resets and it will easily choke and back fire off idle with moderate gas pedal input
turbothis:
so far the first code from black fin runs the best. i mean really close but it must advance the timing some with the dwell or something because it will ping just a little if i stall up the motor in low gear.
other wise it cranks right up and i can mash the go pedal as much/fast as i want and it is like a factory car.
i think i can offset the crank input some degrees and win this thing!
You may not have to. Can you try this? It's very similar to the "long" code but shuts off the IGBT in sync with the MS while allowing up to a mS of dwell. Because this is based on the long code it uses the original 6/7 wiring:
//ref: sketch_oct24d
#define NUM_CYLINDERS 3 //# of cylinders
#define DWELL_TIME 1000ul //microseconds of dwell time
//pin definitions
const byte sparkA = 2;
const byte sparkB = 4;
const byte sparkC = 7;
const byte copA = 3;
const byte copB = 5;
const byte copC = 6;
//spark control structure
typedef struct structSpkCtl
{
byte pinSpkIn; //pin number for trigger input
byte lastPinSpk; //used for state change detect logic
byte pinCOPOut; //pin number for COP
bool bState; //COP on (true) or off (false)
unsigned long ulDwell; //in theory allows cylinder specific dwell
unsigned long ulTOn;
};
//spark control
structSpkCtl SpkCtl[NUM_CYLINDERS] =
{
{
.pinSpkIn = sparkA,
.lastPinSpk = LOW,
.pinCOPOut = copA,
.bState = false,
.ulDwell = DWELL_TIME,
.ulTOn = 0
},
{
.pinSpkIn = sparkB,
.lastPinSpk = LOW,
.pinCOPOut = copB,
.bState = false,
.ulDwell = DWELL_TIME,
.ulTOn = 0
},
{
.pinSpkIn = sparkC,
.lastPinSpk = LOW,
.pinCOPOut = copC,
.bState = false,
.ulDwell = DWELL_TIME,
.ulTOn = 0
}
};
void setup()
{
Serial.begin(9600);
//setup pins and initialize "last" reading of trigger inputs
for( int i=0; i<NUM_CYLINDERS; i++ )
{
pinMode( SpkCtl[i].pinSpkIn, INPUT );
pinMode( SpkCtl[i].pinCOPOut, OUTPUT );
//
SpkCtl[i].lastPinSpk = digitalRead( SpkCtl[i].pinSpkIn );
}//for
}//setup
void loop()
{
ReadSparkInputs(); //go read a cylinder
CheckCOPOutputs(); //see if a cylinder's dwell time has ended
}//loop
void ReadSparkInputs( void )
{
byte
spkState;
static byte
idxCylinder = 0;
//if COP is now on for this cylinder, skip checking trigger
if( SpkCtl[idxCylinder].bState == false )
{
//read trigger input
spkState = digitalRead( SpkCtl[idxCylinder].pinSpkIn );
//is pin reading now different from last read?
if( spkState != SpkCtl[idxCylinder].lastPinSpk )
{
//yes...make now-reading "last" reading
SpkCtl[idxCylinder].lastPinSpk = spkState;
//if trigger input has gone high...
if( spkState == HIGH )
{
//turn on the COP for that cylinder
digitalWrite( SpkCtl[idxCylinder].pinCOPOut, HIGH );
//log the time of turn-on
SpkCtl[idxCylinder].ulTOn = micros();
//and set on-flag to true
SpkCtl[idxCylinder].bState = true;
}//if
}//if
}//if
//check one cylinder each pass
idxCylinder++;
if( idxCylinder == NUM_CYLINDERS )
idxCylinder = 0;
}//ReadSparkInputs
void CheckCOPOutputs( void )
{
static byte
idxCylinder = 0;
//is COP for this cylinder currently on?
if( SpkCtl[idxCylinder].bState )
{
//yes...has dwell time expired?
if( ((micros() - SpkCtl[idxCylinder].ulTOn) >= SpkCtl[idxCylinder].ulDwell) ||
(digitalRead( SpkCtl[idxCylinder].pinSpkIn == LOW) ) )
{
//yes; set COP output low
digitalWrite( SpkCtl[idxCylinder].pinCOPOut, LOW );
//and clear on-flag
SpkCtl[idxCylinder].bState = false;
}//if
}//if
//check one COP's dwell time per pass
idxCylinder++;
if( idxCylinder == NUM_CYLINDERS )
idxCylinder = 0;
}//CheckCOPOutputs
with the shorter code "Uno to follow the MS" runs smooth but i get a lot of MS resets and it will easily choke and back fire off idle with moderate gas pedal input
re that shorter code: Did you use the "super-short" (single line loop()) and if so, did you swap pins 6 and 7 on the Uno?
BTW, what sort of car is this? An old Geo Metro or similar?
i did not try the super short code but will in a couple hours.
i super glued the male pins together to make a plug on the UNO so i will have to snap them apart to swap 6/7
this is in my supreme cherokee.
so far the super short code seems to be about perfect
i need to test drive around the block some and keep track of IGBT temps
i cant thanks you guys enough
i might need more help in the future though..............
Nice to hear. Thanks for the feedback.
Since the Uno is just acting as a buffer, it seems like your whole Uno and its software could be replaced by a single IC.
In looking at the MS circuit, it looks like they use what is essentially an open-collector drive with an internal pullup to 5V for the sparkX signal. The 4.7K resistor is likely what's preventing the MS from driving it properly.
If you just ran the sparkX signals to the inputs of a buffer and connected the IGBT drive via a 330R resistor to the buffer output you wouldn't need the Uno at all.
e.g. https://www.digikey.ca/product-detail/en/texas-instruments/CD4503BE/296-2071-5-ND/67337
- power it from the MS 5V (VCC) rail and GND
- D1, D2 and D3 to sparkA, sparkB and sparkC respectively
- Q1, Q2 and Q3 through 330R resistors to copA, copB and copC respectively
- unused inputs D4..D6 to GND
- DISA to GND
- DISB to 5V