need help with digital input to digital output function

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