What's wrong with my simple program?

Here is my simple program in Arduino, I tried to use app inventor to control the arduino to water the flowers. But it works only for several seconds after I connect the bluetooth (I use HC-05 module). Then, it will be stuck. I don't know why.

You are missing a Clock Timer to keep polling for input on the AI2 side.
You can't inhale data out of BlueTooth on a button click. The data arrives when it arrives.


global message
(draggable)

Hi kittyqian

The above code is setting the servo motor original position every second, not a good idea :koala: You should only reset the servo position after it has moved.

Using delay() in your code is not a good idea because it blocks everything - that is a problem because your sensor gets blocked - it should be allowed to transmit continuously for accurate values. So use milliseconds elapsed instead. Do you really need to check moisture every second? That seems rather frequent - may be it should be several minutes?

You need a separate button in the App for moisture send and as AGB has shown, use a ClockTimer to receive the moisture value. The ClockTimer interval should be set approx 20% faster than the Arduino send interval to prevent the App locking up.

Thank you ABG and ChrisWard. I will try to modify my program.

I deleted the "delay(1000)", and I found that every time when I reconnect the Bluetooth, it will work for several seconds. This made me guess there is something wrong with the Bluetooth module, not the program itself.

Is it possible not to add the clock timer to complete the program?

If you remove the delay(1000) on the Arduino side, what prevents your Arduino from flooding the AI2 side with messages?

You can slow down your message transmission rate by counting milliseconds from last transmission, and not transmitting until enough time has elapsed.

That still allows you to loop quickly, to service incoming messages.

Hello, sorry,I don't understand what is “flooding the AI2 side with messages”.......

My best explanation ...

1 Like

Hello, I understand the “flooding the AI2 side with messages” now.
Can I make the program work without using a clock timer?

Hello Kitty :relaxed:

You can use milliseconds elapsed, like this:

ServoMotor.txt (1.5 KB)

#include<Servo.h>
Servo servomotor1;
//833 air
//632 water

//vars
char    IncomingValue = 0;
const int    AirValue = 833; //you need to change this value that you had recorded in the air
const int  WaterValue = 632; //you need to change this value that you had recorded in the water
int         intervals = (AirValue - WaterValue) / 3;
int soilMoistureValue = 0;

unsigned int igUpdateTime;

void setup()
{
         servomotor1.attach(12);
              Serial.begin(9600); // open serial port, set the baud rate to 9600 bps
         igUpdateTime = millis();
}

void loop()
{
         //Excute loop every 10 seconds
	     if((millis() - igUpdateTime) > 10000)
         {
               igUpdateTime = millis();

               if(Serial.available() > 0)
               {
                     IncomingValue = Serial.read();

                     switch (IncomingValue)
                     {
                       case '1':
                                servomotor1.write(0);//watering
                                break;
                       case '0':
                                servomotor1.write(120);//original position
                                break;
                       case 'M':
                                soilMoistureValue = analogRead(A0);
                                Serial.print(soilMoistureValue);
                                Serial.println();
                                break;
                     }
               }
         }
}

Hello, ChrisWard , Thank you very much for your code! I tested it on my Arduino. It works for several seconds and then became no response. After I reconnect the Bluetooth, it will work again for several seconds. So does it mean the problem is from the Bluetooth module?

Hi Kitty

Not necessarily. What sort of environment do you have? It's important that the Arduino and the servo motor do not get too hot.

Also, the servo position is controlled by the App - which means the App User has to remember what the previous position was? What if we changed the code to return the Servo to the original position automatically? That way, it never gets sent to either position incorrectly.

How long does the watering take? Is a 10 second wait for it to finish adequate? Perhaps the loop interval should be greater - a least 1 minute?

#include<Servo.h>
Servo servomotor1;
//833 air
//632 water

//vars
char    IncomingValue = 0;
const int    AirValue = 833; //you need to change this value that you had recorded in the air
const int  WaterValue = 632; //you need to change this value that you had recorded in the water
int         intervals = (AirValue - WaterValue) / 3;
int soilMoistureValue = 0;
int     ServoPosition = 1; //1 = original home position, 0 = watering

unsigned int igUpdateTime;

void setup()
{
         servomotor1.attach(12);
              Serial.begin(9600); // open serial port, set the baud rate to 9600 bps
         igUpdateTime = millis();
}

void loop()
{
         //Excute loop every 1 minute
	     if((millis() - igUpdateTime) > 60000)
         {
               igUpdateTime = millis();

               if(Serial.available() > 0)
               {
                     IncomingValue = Serial.read();

                     if(ServoPosition == 0)
                     {
                         servomotor1.write(120);//original position
                         ServoPosition = 1;
                     }

                     switch (IncomingValue)
                     {
                         case '1':
                                  servomotor1.write(0);//watering
                                  ServoPosition = 0;
                                  break;
                         case 'M':
                                  soilMoistureValue = analogRead(A0);
                                  Serial.print(soilMoistureValue);
                                  Serial.println();
                                  break;
                     }
               }
         }
}

I think I may need to take a quick look at you App Inventor project too, but try the above Sketch first to see if it makes a difference.

Hi, ChrisWard , I tried your new code(the 60 seconds one), but it is worse than the old code. I can't control the servo by app fluently even at the beginning of the reconnection (reconnection of the Bluetooth).

The environment is normal, the Arduino and the servo will not get too hot.

Yes, at the present stage, I want to control the servo just like a switch button. Turn on and off fluently.

the watering takes about 5 seconds.

Well, it reduces User control to requesting watering or a moisture value.

Let's see your App Inventor Project (.aia)

waterplant (1).aia (2.5 KB)

I can see that my semi-auto Sketch version is missing a line in setup:

void setup()
{
         servomotor1.attach(12);
         servomotor1.write(120);//set @ home position 
              Serial.begin(9600); // open serial port, set the baud rate to 9600 bps
         igUpdateTime = millis();
}

OK, little issues in your App Code. Try this:

waterplant_ed.aia (4.7 KB)

I'm out now till the evening (UK time)

Hello ChrisWard, I tried your app code , and it shows error after I press the watering and off button.

Hi Kitty

With which Sketch? I disabled the "off" button (return to home position - technically, that is not 'off' :koala:) in the App Code and the semi-auto Sketch, which requires the amendment shown in my earlier post.

Hi,ChrisWard,
With the 10 seconds one, (Does the "Sketch" mean the Arduino code?)
Actually, I enable the "off" button after I found it was disabled............