Just started checking out the Arduino, I have this block of code that i'm trying to understand.
If someone could explain what the functions achieve/how they interact etc, it would be much appreciated.
I'm trying to get my head around different projects that i've come across so I can implement some and create my own for work.
So it's for a water tank with 2 pumps, and high/low sensors.
One pump is supposed to come on, then a second will come on if it's been going for too long.
The pumps are supposed to alternate, so pump 1 will start one time, then the next time pump 2 will start etc
int i = 0;
int j = 2;
int k = 1;
const int Highpin = 7;
const int Lowpin = 6;
int Highstate = LOW;
int Lowstate = LOW;
void setup() {
pinMode(8, OUTPUT);
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
pinMode(Lowpin, INPUT);
pinMode(Highpin, INPUT);
}
void loop() {
Highstate = digitalRead(Highpin);
Lowstate = digitalRead(Lowpin);
if (Highstate == HIGH && j > k) {
k = k + 1;
while (Lowstate == LOW) {
digitalWrite(10, HIGH);
if (i >= 30) {
digitalWrite(13, HIGH);
}
if (i >= 60) {
digitalWrite(8, HIGH);
}
delay(1000);
i = i + 1;
Highstate = digitalRead(Highpin);
Lowstate = digitalRead(Lowpin);
}
digitalWrite(10, LOW);
digitalWrite(13, LOW);
digitalWrite(8, LOW);
i = 0;
}
if (Highstate == HIGH && j == k) {
k = k - 1;
while (Lowstate == LOW) {
digitalWrite(13, HIGH);
if (i >= 30) {
digitalWrite(10, HIGH);
}
if (i >= 60) {
digitalWrite(8, HIGH);
}
delay(1000);
i++;
Highstate = digitalRead(Highpin);
Lowstate = digitalRead(Lowpin);
}
digitalWrite(10, LOW);
digitalWrite(13, LOW);
digitalWrite(8, LOW);
i = 0;
}
delay(100);
}
Some of it makes sense, but i'm struggling to wrap my head around the highstate/lowstate = low aspects and the I J K parts.
Thanks in advance.
Why
Why on earth would you want to understand such code. I would never write such code. Someone has a specific meaning for it, and then implemented it in a bad way. Without explanation what it should do, it is just some random lines of code.
It should have a reference or a header, explaining that leds will turn on when signals are low or high for a longer time.
Let me ask the others:
It is a good sketch, I know what the variables i, j and k do.
It might need some polishing, it needs more explanation.
Worse is trying to figure out what something does, with no description of what is it supposed to do.
@daymanssky who wrote this and what did s/he say it is supposed to do?
If we knew what it is supposed to do, we could probably tell you how it either is or is not succeeding in doing.
As it is it has enough wrong with it from a purely aesthetic point of view that it does not invite spending time figuring out what it is meant to be used for.
But let's have fun guessing!
It obvsly (!) is control software for a tank that variously fills and empties as valves are opened and closed and the level changes therefor, or due to rain or evaporate, or similar external causes.
So it's for a water tank with 2 pumps, and high/low sensors.
One pump is supposed to come on, then a second will come on if it's been going for too long.
The pumps are supposed to alternate, so pump 1 will start one time, then the next time pump 2 will start etc.
I do apologise with my lack of explanation.
I was expecting this to be fairly simple but just saw a whole bunch of things I couldn't make sense of.
This sounds completely familiar and a recent thread on these fora went into great detail about a reasonably good program to do exactly what is required.
Mind you that was long enough ago so I may be tots wrong. I'm good at forgetting.
Maybe this
I don't think reading that thread would be a waste of time, certainly not the same kinda waste as trying to figure out or fix the code you presented.
The original sketch might might be clearer if the variable names were indicative of their function in the algorithm, and the output pins were named so it was clear what they were outputs for.
It has two pumps but three output pins? What does the third pin control?
It appears that 'i' is used as a (very) crude timer, incremented after each of the 1-second delays.
The variable 'j' is never changed so it is a poorly-named synonym for the constant 2.
The variable 'k' toggles between 1 and 2 to indicate which order the pumps should operate.
It appears that "Highstate == HIGH" means it's time to start the pumps and "Lowstate == HIGH means it's time to turn off the pumps. That sounds reversed. I think you would turn on the pumps when the water isn't reaching the LOW switch and turning the pumps off when the water reaches the HIGH switch. It looks like "Highpin" connects to the low level switch and "Lowpin" connects to the high level switch.
If I have to figure out what the code does, I will breadboard some leds and switches and to see if it meet the requirement of what the code is suppose to do.
I did read both links regarding a similarity of this current tread. It look like a "little" challenge assignment. Good practice I will try. But I will not use the OP code. I will follow one of the tread Flow Chart of the assignment. I will need 3 leds, and 2 switches to simulate the Low / High water level and the leds for motors and alarm. I will code from scratch and I will use millis() for the 30 second time check. Beside, it is going to be a little side project.
So I got this from my apprentice, who in turn got it from a physics forum.
Looks like an assignment question, (she's not doing a course in this, it's purely learning for the workplace).
The third output is supposed to be an alarm that's triggered 30 seconds after the second pump kicks in.
You should not use it as an example, and I advise to not even try to understand it.
There is a delay of 1 second and a counter. But that delay is inside if-statements, so it is not clear when that delay is used. The variables i, j, and k are still unclear to me.
A good sketch starts with a good description. That is also the hardest part. If a problem from the real world is well described in a logical way, then half the sketch is already written.
I've recently completed this problem as part of my electronic engineering course.
As @alto777 linked above that thread has a lot of guidance and help to start understanding the solution. though took a lot of time to get my head around some concepts such as using arrays etc.
but here's the final code that I used as the solution in the end and hopefully helps with a bit more explanation around it.
/*
The circuit uses two LEDs Connected to an Arduino UNO board in order to simulate the two water pumps,
A third LED is used in order to simulate an Alarm signal.
The Two different Water Level Sensors are simulated using two digital Slide Switches wired using the
Arduinos internal Pullup resistors.
*/
const int pump_1 = 3;
const int pump_2 = 4;
const int waterLow = 8;
const int waterHigh = 9;
const int alarm = 2;
const unsigned long pumpInterval = 30000; // Declare interval before second pump starts (30s)
const unsigned long alarmInterval = 30000; //Declare time before alarm state (30s)
unsigned long pumpOnTime;
int lowSensor = LOW; // declare initial state of low water sensor
int highSensor = LOW; // declare initial state of High level water sensor
unsigned int nextPumpFlag; // variable to indicate which pump will be primary and which is back-up
int nextState;
int currentState;
//possible states of the state-machine
typedef enum {TankFilling,
FirstPumpOn,
SecondPumpOn,
AlarmOn,
TankWaiting} states;
void setup(){
Serial.begin(9600);
nextState = TankFilling;
currentState = nextState;
//set pin modes for each pin:
pinMode(pump_1, OUTPUT);
pinMode(pump_2, OUTPUT);
pinMode(alarm, OUTPUT);
pinMode(waterLow, INPUT_PULLUP);
pinMode(waterHigh, INPUT_PULLUP);
}
//Set Alarm function
void TurnOnAlarm(){
digitalWrite (alarm, HIGH);
Serial.println ("Alarm On");
}
//set Empty tank Function (switch all pumps and alarm off)
void TankEmpty(){
digitalWrite(pump_1, LOW);
digitalWrite(pump_2, LOW);
digitalWrite(alarm, LOW);
Serial.println("Tank Empty");
}
//Set first pump function
void turnOnFirstPump(){
turnOnNextPump();
nextPumpFlag++;
}
//Set Second pump function
void turnOnSecondPump(){
turnOnNextPump();
}
//Set function for next pump. primary and backup pump to alternate
void turnOnNextPump(){
if(nextPumpFlag & 0x1){
digitalWrite(pump_1, HIGH);
Serial.println("Pump 2 Running");
}else{
digitalWrite(pump_2, HIGH);
Serial.println("Pump 1 Running");
}
}
//main program loop using Switch..Case statements
void loop(){
const unsigned long currentTime = millis(); // set current time
int tankFull;
lowSensor = digitalRead(waterLow);
highSensor = digitalRead(waterHigh);
tankFull = lowSensor + highSensor;
switch(currentState){
//Only Start first pump when both Sensors are HIGH,
case TankFilling:
if(tankFull == 2){
Serial.println("Water High");
nextState = FirstPumpOn;
}else if(tankFull <= 1){
Serial.println("Water Low");
}
break;
//Switch on first pump in sequence move to next state
case FirstPumpOn:
if(tankFull >= 1){
turnOnFirstPump();
pumpOnTime = currentTime;
Serial.println("Pump 1 start time: ");
Serial.print(currentTime);
Serial.println(" ");
nextState = SecondPumpOn;
}else if(tankFull == 0){
TankEmpty();
nextState = TankFilling;
}
break;
/*If both Sensors are not LOW switch second pump on after 30s
move to monitor for Alarm signal, If both Sensors Read LOW
go switch pump off and go back to starting state*/
case SecondPumpOn:
if(tankFull >=1){
if(currentTime - pumpOnTime >= pumpInterval){
turnOnSecondPump();
pumpOnTime = currentTime;
nextState = AlarmOn;
}
}else if(tankFull == 0){
TankEmpty();
nextState = TankFilling;
}
break;
/*If both sensors are not LOW with both pumps running after 30s
Switch Alarm signal on and move to monitor water level,
If both Sensors Read Low before 30s switch all pumps off
and go back to starting state in sequence*/
case AlarmOn:
if(tankFull >= 1){
if(currentTime - pumpOnTime >= alarmInterval){
TurnOnAlarm();
Serial.println("Alarm start time:");
Serial.print(currentTime);
Serial.println("");
nextState = TankWaiting;
}
}else if(tankFull == 0){
TankEmpty();
nextState = TankFilling;
}
break;
/* monitor Tank Sensor Readings and only switch pumps and Alarm off
When Both Sensors read LOW, once LOW go to first state in sequence*/
case TankWaiting:
if(tankFull == 0){
TankEmpty();
nextState = TankFilling;
}
break;
}
currentState = nextState; // declare how to move to next state
}//close Loop