6 years, 1 month ago.

New to mbed, request for help with programming

HI all,

Sorry if this is the wrong place to post this. As the title suggests, I'm very new to using mbeds and how to program them. My project is an automatic watering sensor that determines when to water a plant based upon the light levels (no point watering during the night) and the moisture levels of the soil. However, I do not know how to write this up as code.

Below is a simple attempt that I have made. It is most likely wrong! I have not included pinouts as of yet, I will sort that later on, it is mainly the basic principles that I am asking for help with.

#include "mbed.h"

char	<LDR>
char	<Pump>

int main() {

while{
	if	<LDR> < 10%;
		<Pump> = 0;

	else	
		<LDR> > 10%;
		<Moisture> < 40%;
		<Pump> = 1;
		wait (60);
		<Pump> = 0;
		wait (10800);
	}
}

In my mind, the <Pump> will only turn on when the light levels are greater than 10% of the range of the LDR, implying daylight, even if very cloudy, and the moisture levels are less than 40% of the moisture sensor range. The pump will then turn on for 1 minute, and then wait for 3 hours before repeating the loop.

Any help will be greatly appreciated!

Thanks, Equinnox

2 Answers

6 years ago.

Hi Matthew,

To me your logic looks correct, however I think you can simplify it a bit considering the <Pump> will only be turning on IFF (if and only if) <LDR> is > 10% AND <Moisture> is < 40%. You can also simplify your code by setting your <Pump> to zero during initialization:

#include "mbed.h"

<LDR>;
<Pump> = 0; // set to starting value here
<Moisture>;

int main() {
    while(1) {
        if ((<LDR> > 10%) && (<Moisture> < 40%)) { 
        // In English: "If LDR is greater than 10% AND Moisture is less than 40%, then do this..."
            <Pump> = 1;
            wait(60);
            <Pump> = 0;
        }
        wait(10800);
    }
}

Let me know if you have any questions, and welcome to Mbed!

- Jenny, team Mbed

Accepted Answer

Hi Jenny,

Thank you for your reply and for the warm welcome! I have modified the code slightly with my pinouts and finally have a starting point! Along with Andy A's reply below, I should be able to get a significant move on with my project.

Thanks again and kind regards,

Matt

posted by Matthew Belcher 29 Mar 2018
6 years ago.

A few pointers on the code:

As Jenny indicated the logic can be simplified a little, due to the location of the wait her version only checks the sensors every 3 hours, this one will check constantly unless it's run the pump at which point it will wait 3 hours.

Rather than using the char <something> place holders you may as well put in a best guess for the variables in the code. I'm guessing that the LDR and the moisture sensor will be connected to an analog input of some sort and the pump control will be a digital output.

Comments in the code are always good.

And when you have fixed thresholds or times it's always a good idea to define them as constants at the start of the code rather than a number hidden in the middle of the code. It makes them easier to change in the future and ensures that it will always be consistent if you use the same value in multiple locations.

#include "mbed.h"

#define _MinimumLightLevel 10 // %
#define _MinimumMoistureLevel 40 // %
#define _PumpOnTime 60 // seconds
#define _PumpMinimumOffTime (3*60*60) // seconds

 
AnalogIn LDR(<PinName>);
AnalogIn Moisture(<PinName>);
DigitalOut Pump(<PinName>);
 

int main() {
  Pump = 0;  // turn the pump off on startup.

  while (true) { // loop forever

    // AnalogIn will give a value between 0 and 1 so multiply by 100 to get percent.
    if (  ((LDR*100) > _MinimumLightLevel) && ((Moisture*100) < _MinimumMoistureLevel)) {
      Pump = 1;
      wait (_PumpOnTime );
      Pump = 0;
      wait (_PumpMinimumOffTime);
    }

  }

}

Two things to watch out for:

Firstly some mbed time functions have a maximum time of around half an hour (35.79 minutes to be more precise, it's 2^31 us), I know tickers and timeouts have this issue, I don't know about wait. If you find that your wait for 3 hours isn't working correctly then you may want to write a function to do this e.g.

// function definition goes before the start of main()
// split a wait into blocks of under 35 minutes
void waitALongTime(int hours, int minutes, int seconds) {
  int halfHourLoops = hours*2;  // calculate the number of half hours
  if (minutes >= 30) {    // check if minutes is over half an hour
    halfHourLoops++;
    minutes -= 30;
  }
  while (halfHourLoops) {   // loop waiting for 30 minutes each time
    wait(30*60);
    halfHourLoops--;
  }
  wait(minutes*60 + seconds);  // wait for the remaining time.
}

// the line 
#define _PumpMinimumOffTime (3*60*60) // seconds
// becomes
#define _PumpMinimumOffHours 3

// and the line
      wait (_PumpMinimumOffTime);
// becomes 
      waitALongTime(_PumpMinimumOffHours, 0 , 0)


Secondly you will notice that when comparing the sensor inputs (a float between 0 to 1) to the percentage levels (0 to 100) I did ((sensor*100) > level) rather than (sensor > (level/100)). The reason for this is something that catches out a lot of people who are new to c programming. If I had done this the other way around it would have ended up as being 40/100 which has a value of 0 not 0.4.

In c (or c++) an integer divided by an integer will always result in an integer not a floating point number. Any fractional part will be discarded rather than rounded so 99/100 will be 0 not 1. If you want to force the result to being a floating point number then you need to force one of the numbers used to being a floating point. e.g. 99/100 = 0 but 99/100.0 = 0.99

I'm mentioning this now because it catches everyone out at some point and this way when it does get you you'll at least know what's going on rather than getting very confused as to why two apparently identical calculations are giving you different results.

Hi Andy,

Thank you for your reply, the tips and your addition to the code that Jenny wrote above. The comments about wait times and percentages are definitely worth knowing for the future, and I'm sure the problems that you highlighted would have come up, so thank you for the heads up with that! I will definitely reorganise my code as you have suggested, by laying out more of the information at the top of the program, rather than within the program.

Thanks again and kind regards,

Matt

posted by Matthew Belcher 29 Mar 2018