Karimwassef:
Thanks for the support, guys.
In terms of operating logic, do most arduino codes basically loop continuously looking for flags to take action, or do they process a series of commands in time that could delay the processor from capturing relevant events that also require its action?
I guess I’m curious about the programming philosophy for a real time response system that is receiving multiple inputs and taking numerous actions near simultaneously.
I don’t know much about Arduino common practice but if you need to process inputs while an action is in process (like the example you’re building), there are various techniques to accomplish this. Hard real-time software is an engineering discipline all its own with rigorous analytical methods available to be sure all operations are done on schedule.
The basic method I think you’re asking about is to be sure that your input checks run at least fast enough so the program always knows their state. In this code I accomplish it by not using any blocking calls except the delay(1) at the top of the loop. Code is rather long and untested, but let me know if it works.
/*********************************************************************************************
This reads a set of input pins and activates actuators depending on the last state transition detected
on the inputs.
HIGH->LOW: activate actuator reverse direction for preset time
LOW->HIGH: activate actuator forward direction for preset time
Note that the code assumes the LOW/HIGH signal lasts a longer period than the actuation time.
Otherwise the actuator will change direction as soon as the signal changes state
**********************************************************************************************/
// Constants
const int NUMBER_OF_CHANNELS = 4;
// Arduino pins used for input
const int _inputs[] = {1, 2, 3, 4};
// Pins for forward output control
const int _forward[] = {5, 6, 7, 8};
// Pins for reverse output control
const int _reverse[] = {9, 10, 11, 12};
// Time intervals for forward motion per channel
const int _forwardTime[] = {1000, 1000, 1000, 1000};
// Time intervals for reverse motion per channel
const int _reverseTime[] = {1500, 1500, 1500, 1500};
// Global state
int _inMotion[NUMBER_OF_CHANNELS];
bool _lastState[NUMBER_OF_CHANNELS];
void setup()
{
for (int i=0; i < NUMBER_OF_CHANNELS; i++)
{
pinMode(_inputs[i], INPUT_PULLUP);
pinMode (_forward[i], OUTPUT);
pinMode (_reverse[i], OUTPUT);
digitalWrite(_forward[i], LOW);
digitalWrite(_reverse[i], LOW);
_lastState[i] = digitalRead(_inputs[i]);
}
}
void loop()
{
bool currentState = LOW;
int trigger[NUMBER_OF_CHANNELS];
// 1 ms loop interval
delay(1);
for (int i=0; i < NUMBER_OF_CHANNELS; i++)
{
// Detect an edge
currentState = digitalRead(_inputs[i]);
if (digitalRead(currentState != _lastState[i]) )
{
// Is it a rising edge?
if (currentState == HIGH)
{
// Go forward
digitalWrite(_forward[i], HIGH);
digitalWrite(_reverse[i], LOW);
// Set forward time
_inMotion[i] = _forwardTime[i];
}
// Falling edge
else
{
// Reverse
digitalWrite(_forward[i], LOW);
digitalWrite(_reverse[i], HIGH);
// Set reverse time
_inMotion[i] = _reverseTime[i];
}
}
// Update previous state
_lastState[i] = currentState;
// Now update motions
if (_inMotion[i] > 0 )
{
// Decrement motion timer
if ( --_inMotion[i] == 0 )
{
// Timed out. Stop
digitalWrite(_forward[i], LOW);
digitalWrite(_reverse[i], LOW);
}
}
}
}