Hi,
I have a project involving 9 solenoids. I open this topic in General electronics to get help for the solenoids driver circuit.
This topic I'm writing here is not about the electronics of the project in which the other topic was for. This topic is for help with the code for the project.
I want the code to be as much modular as possible - meaning - easy to make a change in the timing of each solenoid.
Hello hk_jh
Post your current sketch, well formated, with comments and in so called code tags "</>" and a schematic, not a Fritzy diagram, to see how we can help.
Have a nice day and enjoy coding in C++.
Дайте миру шанс
I was going to suggest you look into arrays, but then realised I might be misunderstanding what you mean by "between every x-y seconds" here: seems to me that it's variable, random? Does it mean that that led comes on somewhere between 7 and 9 seconds after it went off? Where does that choice come from (if I'm right in my understanding)? Or, if I'm wrong in my understanding can you explain it please?
edit: I see I'm not the only one who doesn't understand that
I see that's your go-to response, and maybe it's appropriate in the Programming Questions board. But this is Project Guidance and the OP's looking for exactly that: guidance on how to go about this.
looking at solenoid 2 for example:
"1:30: solenoid2 is joining - one pulse between every 9 - 25 seconds"
"20:00: solenoid 2 is turning off"
What I mean is that one pulse (ON state for 30ms than OFF) will be generated randomly between 9 - 25 seconds so if 1:30 minute has elapsed a random number will be generated - assuming number 10 - so at 1:40 one pulse of solenoid2 is generated. after that pulse is happen another random number will be generated (between 9-25 seconds). assuming the number 15 - at 1:55 another one pulse of that solenoid 2 will be generated and so on so on until the time 20:00 minute that this solenoid will stop completly.
I would suggest a structure to represent each of the solenoids, then create an array of these.
struct Solenoid
{
unsigned long startTime; // The time this solenoid is first active
unsigned long stopTime; // The time this solenoid becomes inactive
unsigned long minPulse; // The minimum time the next pulse is generated
unsigned long maxPulse; // The maximum time the next pulse is generated
unsigned long nextPulseStart; // The time of the next pulse starts
unsigned long nextPulseStop; // The time of the next pulse stops
};
Solenoid mySolenoids[9]= { 50000, 600000, 5000, 10000, 0, 0,
90000, 1200000, 9000, 25000, 0, 0};
Then something like this... (untested)
void loop()
{
startSequence();
}
void startSequence()
{
unsigned long currentMillis = millis();
for(uint8_t x = 0; x < 9; x++)
{
// Is this solenoid active
if (mySolenoids[x].startTime < currentMillis && mySolenoids[x].stopTime > currentMillis)
{
// Do we need to calculate a next pulse time?
if (mySolenoids[x].nextPulseStop < currentMillis)
{
// Turn off solenoid
// Calculate nextPulseStart & nextPulseStop
}
// Are we currently in the middle of a pulse?
if (mySolenoids[x].nextPulseStart < currentMillis &&
mySolenoids[x].nextPulseStop > currentMillis)
{
// Turn on solenoid
}
}
}
}
Just add to the struct, and define when you define each solenoid.
struct Solenoid
{
unsigned long startTime; // The time this solenoid is first active
unsigned long stopTime; // The time this solenoid becomes inactive
unsigned long minPulse; // The minimum time the next pulse is generated
unsigned long maxPulse; // The maximum time the next pulse is generated
unsigned long nextPulseStart; // The time of the next pulse starts
unsigned long nextPulseStop; // The time of the next pulse stops
int pin; // The pin of the solenoid.
};
my_solenoid:23:25: error: request for member 'pin' in 'mySolenoids', which is of non-class type 'Solenoid [9]'
pinMode(mySolenoids.pin[i],OUTPUT);
^~~
exit status 1
request for member 'pin' in 'mySolenoids', which is of non-class type 'Solenoid [9]'
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
here is the code:
#define NUM_SOLENOIDS 9
struct Solenoid
{
unsigned long startTime; // The time this solenoid is first active
unsigned long stopTime; // The time this solenoid becomes inactive
unsigned long minPulse; // The minimum time the next pulse is generated
unsigned long maxPulse; // The maximum time the next pulse is generated
unsigned long nextPulseStart; // The time of the next pulse starts
unsigned long nextPulseStop; // The time of the next pulse stops
uint8_t pin;
};
Solenoid mySolenoids[9]= { 50000, 600000, 5000, 10000, 0, 0,
90000, 1200000, 9000, 25000, 0, 0};
void setup()
{
for (uint8_t i=0; i < NUM_SOLENOIDS; i++)
{
pinMode(mySolenoids.pin[i],OUTPUT);
}
}
void loop()
{
startSequence();
}
void startSequence()
{
unsigned long currentMillis = millis();
for(uint8_t x = 0; x < 9; x++)
{
// Is this solenoid active
if (mySolenoids[x].startTime < currentMillis && mySolenoids[x].stopTime > currentMillis)
{
// Do we need to calculate a next pulse time?
if (mySolenoids[x].nextPulseStop < currentMillis)
{
// Turn off solenoid
// Calculate nextPulseStart & nextPulseStop
}
// Are we currently in the middle of a pulse?
if (mySolenoids[x].nextPulseStart < currentMillis &&
mySolenoids[x].nextPulseStop > currentMillis)
{
// Turn on solenoid
}
}
}
}
solenoid number 9: start at 5 second, stop at minute 6, first pules after 5 sencond minimum and after 10 second maximum?
0 - don't start a new pulse? second 0 means?
Each row relates to 1 solenoid... remember you need to add the pin at the end now.
So row 2 relates to the example you gave:
On at 1:30 (90000 ms)
Off at 20min(120000ms)
Minimum next pulse 9 seconds(9000 ms)
Maximum next pulse 25 seconds (25000ms)
Next 2 variables get set in program // Calculate nextPulseStart & nextPulseStop
and then you need to add the pin number.
Where the length of the pulse is determined? the solenoid should have a pulse of around 30ms (due to change) at is onTime (transient from off to on for 30ms to off)
can I try it with few solenoids (lets say 2) - so can I not fill all the 9 rows?
Is the pulse always the same for all solenoids? If it is then just create a global constant. It will be used when calculating nextPulseStart and nextPulseStop. If the pulse length is different for each solenoid then add another variable to the struct and initialise when you initialise the array.
Yes you can start with 2 solenoids... just use NUM_SOLENOIDS instead of hard coding "9".