More elegant way to run output once per state change in the loop

I am in the process of creating setup that would close (opened by default) appropriate blast gates and then turn on dust collector, this is all based on electrical current sensing or manual input(button and/or hall sensor -on/off). Then it will open the gates first and turn on 10sec timer to run dust collection before shutting it down, if no other equipment is powered on.
I am new to this complex thing. I read a lot of forums and by trial and error I arrived here.

Let's imagine a woodworking shop with table saw, planer and edgebander. With one large dust collector, dust collection ductwork that has blast gates driven by compressed air pistons, which in turn controlled by the open/close solenoids.
Current sensor attached to the outlet, senses table saw is on. Arduino sends signal to close all dust collection gates except the one that goes to the table saw and turn on dust collector(.5 second to close or open, not constant on). When table saw is off, Arduino is still running dust collector with corresponding gate open for 5 seconds, later it opens all gates and continues to run dust collector for another 5 seconds. If no other inputs from another machinery is detected - turns off, leaving all gates open. Of course if other equipment is energized during table saw operation it will open corresponding gates, and close others until it is off and then again 5 sec + 5 sec and off.

For the example below I used thermistor instead of current sensor. When temp is more than 30C relay is activated for .5 second to power solenoid that closes the gate and when temp falls below 30C it powers relay for .5second that activates solenoid to open the gate. This sketch works, I arrived here by trial and error. But I have 8-10 blast gates so up to 16-20 relays that have to be activated accordingly for a .5sec. And inputs such as "air pressure sensor", "current sensor", "voltage sensor" and "push button as a backup". If I will write code like this it would be a disaster, I am sure there is a more elegant way of doing it. Maybe declaring Open Gate function and Close gate function and then just use gate+# to cycle. But I need help.

How would it be possible to rewrite "if" part more efficient and without it cycling relays on the loop.

I have pins 9-12 relays for 12v solenoids and pin 2 - relay that drives larger 3phase relay for dust collector. This example is run on Arduino Uno, however I will ultimately use Arduino Mega.
Here is a code:

//temperature sensor
const byte tempPin = A0; //the thermistor
#define beta 4090 //the beta of the thermistor
#define resistance 10 //the value of the pull-up resistor

//two relays control solenoid valves, one to open another to close.
//Energized for .5sec to drive piston with compressed air.
const int gate1Close = 12;
const int gate1Open = 11;
const int gate2Close = 10;
const int gate2Open = 9;
const int DustCollector = 2;

int passFlag = 0;
int passFlag1 = 0;

void setup() {

  //relays driving solenoids
  pinMode(gate1Close, OUTPUT);
  pinMode(gate1Open, OUTPUT);
  pinMode(gate2Close, OUTPUT);
  pinMode(gate2Open, OUTPUT);
  pinMode(DustCollector, OUTPUT);

}

void loop() {

  //read thermistor value
  long a = analogRead(tempPin);
  //temp conversion
  float tempC = beta / (log((1025.0 * 10 / a - 10) / 10) + beta / 298.0) - 273.0;
  float tempF = 1.8 * tempC + 32.0;

//here is a part that needs C++ wizardry

  //close gate when temp is over 30C
  if (tempC >= 30 && passFlag == 0) {
    digitalWrite(gate1Close, HIGH);
    delay(500);
    digitalWrite(gate1Close, LOW);
    passFlag++;
    passFlag1 = 0;
  }

  //open gate when temp is less than 30C
  if (tempC <= 30 && passFlag1 == 0) {
    digitalWrite(gate1Open, HIGH);
    delay(500);
    digitalWrite(gate1Open, LOW);
    passFlag1++;
    passFlag = 0;
  }

}

Thank you all, any input is appreciated!

― ? ―

The problem is just screaming for an object oriented solution.

Meaning button or hall sensor, not electrical current sensor.

How would I go about it in C?

Right. But how does it function? Holding the button is equivalent to activating the current sensor? The button toggles the blast gate? What if a blast gate on the far side of the shop is open and you want it closed? Do you have to walk over then click the button or is there a manual override timeout?

While it is certainly possible I would not recommend it. Why do you ask?

Hello dr_cranii
Of course, you can code it in C, but it make no sense.
You have serveral objects these objects can be handled by common services or/and how ever methods named .
Take some time, study the IPO model and take a piece of paper plus a pencil and design a program structure. Identify modules could to be coded and tested separetly. Merge after sucessfull testing all modules together to the needed project.
Therefore it is recommented to take a view into some powerful C++ instructions like STRUCT, ENUM, ARRAY, CASE/SWITCH,UDT, RANGE-BASED-FOR-LOOP, etc, too.
Have a nice day and enjoy coding in C++.
Дайте миру шанс!

on/off type of switch. I am thinking hall sensor and a magnet (magnet is close = deactivated, magnet 4 inches away = activated). In this case it should turn on Dust Collector and close other blast gates.

Blast gate on the further side of the shop should not be open when dust collector is on, unless there is a machinery running (current sensor).

While it is certainly possible I would not recommend it. Why do you ask?

Well, I am looking for a solution to make it work :slight_smile:

I meant Arduino based C. Unless there is another, better or simpler way of coding it for an Arduino to run.
Thank you!

Дайте миру шанс!

все шансы исчерпаны :slight_smile: кнопка сброс.

I think a state machine were the right implementation, just reflecting the "once per state change". One machine for each blast gate, screaming for an array of structs or an active gate index.

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