Hello all, could you please help me to understand my mistake? I bought a semi-commercial shield and
edited the scrip they provided. The problem seems to be in missing bracket but I'm pretty sure I closed everything. I would be happy to hear any feedback from you.
// set all moisture sensors PIN ID
int moisture1 = A0;
int moisture2 = A1;
int moisture3 = A2;
int moisture4 = A3;
// set water relays
int relay1 = 3;
int relay2 = 4;
int relay3 = 5;
int relay4 = 6;
//init valve nr
int x = 0;
// set water pump PIN ID
int pump = 2;
//Safety function - closing all walves
void closeAll() { // turn pump & valves off just to be sure.
Serial.println("Closing pump + valves!");
digitalWrite(pump, LOW);
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
}
//Water dried plant
void waterPlant(int x) {
Serial.print("Opening: ");
Serial.print(x);
digitalWrite(x, HIGH); //Open valve x ==> x will contain value of correct relay[1-4]
delay(500); //We wait 0.5 seconds before opening pump so we are sure relay is open.
digitalWrite(pump, HIGH); //Open pump for 1,5 seconds
delay(1500);
digitalWrite(pump, LOW); //Close pump
delay(500);
digitalWrite(x, LOW);
closeAll(); //Make sure all valves are closed again.
}
void setup() {
// declare relay as outputs
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(pump, OUTPUT); // declare pump as output
Serial.begin(9600);
}
///////////////////////////////////////////////// MAIN /////////////////////////////////////////////////
void loop() {
//print sensor values
Serial.print(F("Sensor 1: "));
Serial.println(analogRead(moisture1));
Serial.print(F("Sensor 2: "));
Serial.println(analogRead(moisture2));
Serial.print(F("Sensor 3: "));
Serial.println(analogRead(moisture3));
Serial.print(F("Sensor 4: "));
Serial.println(analogRead(moisture4));
Serial.println("Check moisture");
//Moisture checkup function to see if plants need watering
void checkMoisture() {
if (analogRead(moisture1) <= 450) {
waterPlant(relay1);
}
if (analogRead(moisture2) <= 450) {
waterPlant(relay2);
}
if (analogRead(moisture3) <= 450) {
waterPlant(relay3);
}
if (analogRead(moisture4) <= 450) {
waterPlant(relay4);
}
closeAll()
// wait 8 hours and repeat the process
Serial.println("Waiting 8 hours \n ++++++++++++++ END +++++++++++++ \n");
delay(28800000);
}
}
Error codes: Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Uno" In function 'void loop()': watersys:74: error: a function-definition is not allowed here before '{' token
void checkMoisture() {*
^* watersys:99: error: expected '}' at end of input
}*
^* exit status 1 a function-definition is not allowed here before '{' token This report would have more information with "Show verbose output during compilation" option enabled in File -> Preferences.
A very useful troubleshooting tool is to do a Tools > Auto Format in the Arduino IDE and then check the resulting indentation to see if it matches your expected program structure. I think that will make the issue quite obvious.
Another feature of the Arduino IDE is that if you place the cursor next to one bracket, a box appears around the matching bracket. In the case of the cursor being next to a closing bracket where the opening bracket is off the screen, it will display that line in a tooltip after a short delay.
The code you posted definitely was not auto formatted.
Techion:
I believe my last } is closing loop function.
You're right, but is that how it should be? Take a close look at the code between the opening and closing brackets of loop(), remembering that you should not define a function inside of another function.
wildbill:
There is no closing bracket for the loop function.
I can see one - line 99, but the problem is the "Moisture checkup function" is being declared as a function (void checkMoisture) when it is actually part of and inside void loop().
Remove line 74 completely. (comment it out for now, so the next 2 solutions don't move line numbers).
Line 92 needs a closing ";" after CloseAll()
Line 99 is a closing "}", but nothing open, delete it.
Make those changes and your sketch compiles with zero errors or warnings
Thanks a lot! I simply didn't know that I cannot define functions in void loop.
I re-arranged it a bit and declared this function outside the loop. It compiles. Hopefully it will fly now
Thanks for all your time and help!
The code just for the sake of any followers:
// set all moisture sensors PIN ID
int moisture1 = A0;
int moisture2 = A1;
int moisture3 = A2;
int moisture4 = A3;
// set water relays
int relay1 = 3;
int relay2 = 4;
int relay3 = 5;
int relay4 = 6;
//init valve nr
int x = 0;
// set water pump PIN ID
int pump = 2;
//Safety function - closing all walves and pump
void closeAll() {
Serial.println("Closing pump + valves!");
digitalWrite(pump, LOW);
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
}
//Water dried plant
void waterPlant(int x) {
Serial.print("Opening: ");
Serial.print(x);
digitalWrite(x, HIGH); //Open valve x ==> x will contain value of correct relay[1-4]
delay(500); //We wait 0.5 seconds before opening pump so we are sure relay is open.
digitalWrite(pump, HIGH); //Open pump for 1,5 seconds
delay(1500);
digitalWrite(pump, LOW); //Close pump
delay(500);
digitalWrite(x, LOW);
closeAll(); //Make sure all valves are closed again.
}
//Moisture checkup function to see if plants need watering
void checkMoisture() {
if (analogRead(moisture1) <= 450) {
waterPlant(relay1);
}
if (analogRead(moisture2) <= 450) {
waterPlant(relay2);
}
if (analogRead(moisture3) <= 450) {
waterPlant(relay3);
}
if (analogRead(moisture4) <= 450) {
waterPlant(relay4);
}
}
void setup() {
// declare relay as outputs
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(pump, OUTPUT); // declare pump as output
Serial.begin(9600);
}
///////////////////////////////////////////////// MAIN /////////////////////////////////////////////////
void loop() {
//print sensor values
Serial.print(F("Sensor 1: "));
Serial.println(analogRead(moisture1));
Serial.print(F("Sensor 2: "));
Serial.println(analogRead(moisture2));
Serial.print(F("Sensor 3: "));
Serial.println(analogRead(moisture3));
Serial.print(F("Sensor 4: "));
Serial.println(analogRead(moisture4));
Serial.println("Check moisture");
//Calling functions
checkMoisture();
closeAll();
// wait 8 hours and check moisture sensors again
Serial.println("Waiting 8 hours \n ++++++++++++++ END +++++++++++++ \n");
delay(28800000);
}
You might want to consider taking moisture readings more frequently than every 8 hours.
One single reading could be subjected to all sorts of error due to noise, wind in the wrong direction, an "R" in the month, etc.
What I would probably do is wait 7 hours, then sample into an array[10] every 6 minutes. Use an average of the array as the "filtered" value.
In fact a better approach would be to average, say, only the middle 6 or 8 of the last 10 readings, after sorting them into magnitude order.
That way you would be automatically rejecting any spurious high or low readings.
Since you have plenty of time on your hands, a simple but inefficient "bubble-sort" would fit the bill.
Go through the array, inspecting each value against the next one, swapping them if reading[n] > reading[n+1]. Do this the same number of times as there are elements in the array, and the array would be sorted.
This is good idea! The reason of this project is that I'm frequently leaving home and all my flowers are dying. I will test this code for a bit. If it will not work as intented I follow way you pointed