Mirror Input to Output

Hi I'm fairly inexperienced when it comes to programming so forgive me if this is really obvious. I have done a few basic projects in the past though so am familiar with arduino.

I have 4 square wave inputs, that will range from 3 to 150hz. Am i able to have the arduino mirror the inputs so that for example: when input 1 is low for 3ms (this will vary in duration) output 1 is high for the same time period?

I'm assuming interrupts and timers will have something to do with this but need some guidance.

Thanks

Which controller are You using?
Some of the common Arduinos use D0 and D1 for downloads and debugging.
An I/O pin us usually either used as input, or output, not both at the same time.

The simple question is if it can be done. That answer is yes.

The harder answer is if it can be done in REAL TIME.
Real Time is an Exact thing.
You need to look it up.

So far, you have not explained anything for which interrupts - or timers - would be involved.

Copying inputs to outputs at less than 1 kHz is in itself, trivial. the question is - what else do you really want to do? :astonished:

Railroader:
Which controller are You using?
Some of the common Arduinos use D0 and D1 for downloads and debugging.
An I/O pin us usually either used as input, or output, not both at the same time.

I haven't decided yet, I've got a few. Probably a mega 2560. I didn't mean the same pin as in and out. I should have worded the example something like when d13 is low d14 is high etc.

Paul__B:
So far, you have not explained anything for which interrupts - or timers - would be involved.

Copying inputs to outputs at less than 1 kHz is in itself, trivial. the question is - what else do you really want to do? :astonished:

That's the question, is it possible to do in real time? And what functions should I be looking at? I'm guessing interrupts for the inputs, but have no idea how to match the outputs to that.

Edit: clarification and spelling

No, you need to answer my question.

Copying inputs to outputs at anything less than 1 kHz is completely trivial. The question is - what do you really want to do in addition to mirroring inputs to outputs because I am quite sure you have something else in mind that you expect the Arduino to do but have failed to explain? :roll_eyes:

What is the significance of "for 3ms" in your question? Is the Arduino supposed to make some decision based on the duration?

Talking about interrupts is nonsense.



As a beginner, it is incredibly unlikely that interrupts will be useful to you.

A common "newbie" misunderstanding is that an interrupt is a mechanism for altering the flow of a program - to execute an alternate function. Nothing could be further from the truth! :astonished:

An interrupt is a mechanism for performing an action which can be executed in "no time at all" with an urgency that it must be performed immediately or else data - information - will be lost or some harm will occur. It then returns to the main task without disturbing that task in any way though the main task may well check at the appropriate point for a "flag" set by the interrupt.

Now these criteria are in a microprocessor time scale - microseconds. This must not be confused with a human time scale of tens or hundreds of milliseconds or indeed, a couple of seconds. A switch operation is in this latter category and even a mechanical operation perhaps several milliseconds; the period of a 6000 RPM shaft rotation is ten milliseconds.

Unless it is a very complex procedure, you would expect the loop() to cycle many times per millisecond. If it does not, there is most likely an error in code planning; while the delay() function is provided for testing purposes, its action goes strictly against effective programming methods. The loop() will be successively testing a number of contingencies as to whether each requires action, only one of which may be whether a particular timing criteria has expired. Unless an action must be executed in the order of microseconds, it will be handled in the loop().

So what sort of actions do require such immediate attention? Well, generally those which result from the computer hardware itself, such as high speed transfer of data in UARTs(, USARTs) or disk controllers.

An alternate use of interrupts, for context switching in RTOSs, is rarely relevant to this category of microprocessors as it is more efficient to write cooperative code as described above.

People not knowing much about interrupts tend ti be keen at using it.
For that low frequency loop is likely fast enough. Sime controllers don't have 4 interrupts either.

Railroader:
People not knowing much about interrupts tend to be keen at using it.

Thus the reason for inserting my "stock" explanation whenever the fatal word is thrown about. :grinning:

Working with real time matters for a long time, we know...

tehboris:
I haven't decided yet, I've got a few. Probably a mega 2560. I didn't mean the same pin as in and out. I should have worded the example something like when d13 is low d14 is high etc.
That's the question, is it possible to do in real time? And what functions should I be looking at? I'm guessing interrupts for the inputs, but have no idea how to match the outputs to that.

So one is low makes another high, and (near) real time?

Simple. Use a 74HC04. Beats an Arduino hands down in speed (and cost).

const byte InputPin = 4;
const byte OutputPin = 5;

void setup()
{
  pinMode(InputPin, INPUT);
  pinMode(OutputPin, OUTPUT);
}

void loop()
{
  digitalWrite(OutputPin, ! digitalRead(InputPin));
}

Yep , I’d go down the logic gate too - really do t need an Arduino to invent a signal

There is almost no bebifit in using an arduino for something like this.
Except for the bits you have not mentioned.

There are chips that can invert the input at near the speed of light.
Or mirror it .

Now that we have that out Of the way....

Let us know the goal.

Don't forget to send the non-inverting signal through a circuit that will create the same signal propagation delay as the signal inverter does.

Paul__B:
No, you need to answer my question.

Copying inputs to outputs at anything less than 1 kHz is completely trivial. The question is - what do you really want to do in addition to mirroring inputs to outputs because I am quite sure you have something else in mind that you expect the Arduino to do but have failed to explain? :roll_eyes:

What is the significance of "for 3ms" in your question? Is the Arduino supposed to make some decision based on the duration?

Talking about interrupts is nonsense.

It's for the purpose of controlling the ignition coils on a beach buggy, the other function I will be performing is cutting the signal to limit rpm so the younger kids can drive it. 3 inputs are coil signals, 1 is rpm. The current setup already has an inverting gate driver setup that replaces the stock ignition drivers so the use of 'smart' coils is available. The arbitrary 3ms i mentioned before is dwell time, which varies with battery voltage and rpm.
If not using interrupts to control the outputs what functions should I research?

You could have a look at something like the following:

/*
 * Sketch: inv_gpios.ino
 * Target: Mega2560
 *
 */

const uint8_t   pinRPM = 49;                //PL0, ICP4
//
const uint8_t   pinCyl1In = 37;             //PC0
const uint8_t   pinCyl2In = 36;             //PC1
const uint8_t   pinCyl3In = 35;             //PC2
const uint8_t   pinCyl1Out = 33;            //PC4
const uint8_t   pinCyl2Out = 32;            //PC5
const uint8_t   pinCyl3Out = 31;            //PC6

const bool      K_SPARK_MASK = true;        //true = AND mask, false = OR mask
const uint16_t  REV_LIMIT_PERIOD = 5000;    //whatever period on PL0 equates to the limit you want

volatile uint8_t
    sparkCtlMask;

void setup() 
{
    //arrange physical inputs for easy/quick port manipulation
    //set PC4..6 as outputs
    DDRC = _BV(PC4) | _BV(PC5) | _BV(PC6);      //set 4..6 as outputs
    PORTC = _BV(PC0) | _BV(PC1) | _BV(PC2);     //set input pullups on 0..2

    //set up timer 4 for RPM sensing
    TCCR4A = 0; //setup as required for input captures on ICP4
    TCCR4B = 0; //prescaler as required for RPM sensing
    TIMSK4 |= _BV(ICIE4);
    
    //enable spark control pass-thru
    sparkCtlMask = K_SPARK_MASK ? 0b01110000 : 0b00000000;      //enable spark outputs for now
        
}//setup

void loop() 
{
    //read spark input pins and mask them:  PINC & 0b00000111
    //invert the bits with an XOR:          ^ 0b00000111 
    //shift them to the output positions:   << 4
    //and apply the RPM limiting mask:      & sparkCtlMask      (NOTE: Assumes a low output turns off coils; if high, use "| sparkCtlMask")
    //
    if( K_SPARK_MASK )
        PORTC = (((PINC & 0b00000111) ^ 0b00000111) << 4) & sparkCtlMask;   //if LOW output turns off coils
    else
        PORTC = (((PINC & 0b00000111) ^ 0b00000111) << 4) | sparkCtlMask;   //if HIGH output turns off coils

}//loop

ISR( TIMER4_CAPT_vect )
{
    uint16_t
        period;
        
    //compute RPM from latest period
    //...

#if 0
    //segment disabled 
    //if RPM is too high, set limiter mask
    if( period <= REV_LIMIT_PERIOD )
    //                                  AND mask    OR mask
        sparkCtlMask = K_SPARK_MASK ? 0b00000000 : 0b01110000;      //disable outputs
    else
    //                                  AND mask    OR mask
        sparkCtlMask = K_SPARK_MASK ? 0b01110000 : 0b00000000;      //enable inputs
   
#endif
    
}//TIMER4 input cap vector

It's "mostly there" in theory (I have not tried to compile it as it's incomplete.)

With direct port manipulation and strategically placed I/O pin placements (all one port, accessible via easy shifts and other logical operations) it should pass the spark control signals with little delay that won't massively affect spark timing or dwell.

The RPM input goes to an input capture pin (an interrupt!) It would be used to measure the engine speed; if the speed is too high a byte is modified to shut down the outputs for as long as the RPM signal shows the crank speed is too high.

Without specifics (what level on the output turns the coils on? what is the relationship between the period of the RPM input and engine speed?) it's not easy to proceed much further but with some basic assumptions, it could produce something with a decent chance of working.

Blackfin:
It's "mostly there" in theory (I have not tried to compile it as it's incomplete.)

With direct port manipulation and strategically placed I/O pin placements (all one port, accessible via easy shifts and other logical operations) it should pass the spark control signals with little delay that won't massively affect spark timing or dwell.

The RPM input goes to an input capture pin (an interrupt!) It would be used to measure the engine speed; if the speed is too high a byte is modified to shut down the outputs for as long as the RPM signal shows the crank speed is too high.

Without specifics (what level on the output turns the coils on? what is the relationship between the period of the RPM input and engine speed?) it's not easy to proceed much further but with some basic assumptions, it could produce something with a decent chance of working.

Thanks heaps, I'll start doing some reading on port manipulation, most of that code is above my understanding. It's 5V to charge the coils, they fire when that signal goes low. The rpm signal is 5V square wave to the tacho but thats about all i know about it so far.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.