Beginner help please

Gday Blynk’ers

Excuse me for everything after this. I am excited to find Blynk and need to learn how to use it for a project I need to complete. I am not thick or dumb, but due to an accident I find things I could previously do quite easily like programming which I started in the 90’s, so I am going have to ask for some kind people to be patient with me.

I have been learning Arduino for the past two years and still find it hard. I have got a working sketch for a simple project using a Wemos D1 Mini Pro. I needed to create an autofiller for my Anycubic resin printer. They don’t make one for my model, so I bought the one they have and hacked it but now want to use Blynk to send a push notification to my mobile to notify me when resin runs out with my printer in my back shed. I also want to be able to turn on or off the buzzer in the auto filler.

So I need to learn how to send the notification when the input turns low for the resin bottle and to use a virtual input that will turn on and off the buzzer function.

Can anyone point me in the direction of a project that is similar as find it easier to understand someone when it is close to what I need. I have looked at the tutorials and some code I found but just can’t get my head around it.

See my Arduino sketch below (I was given help with this and don’t understand the spam part of it and some of the logic but will keep working on it. I have also edited it so the spam function(debug) isn’t functioning):

[Blynk code would be- IF NOT bottlecapacity send push notification “Resin Bottle Empty” which will repeat at an interval set in the Blynk app and, IF switch for buzzer is on(in Blynk app) turn buzzer function on, ELSE turn off buzzer function.

# define bottlecapacity_pin 0
# define fullvatswitch_pin 1
# define ps_pin 2
# define resinemptyled_pin 3
# define buzzer_pin 16

unsigned long previousMillis1 = 0UL;
//unsigned long previousMillis2 = 0UL;
unsigned long previousMillis3 = 0UL;
unsigned long previousMillis4 = 0UL;

unsigned long kkInterval1 = 1500UL;  // beep blink duty cycle
//unsigned long kkInterval2 = 3000UL; //spare
unsigned long kkInterval3 = 5000UL; //after vat is full delay pump off
unsigned long kkInterval4 = 60000UL; //pump delay on


void setup()
{
  
  pinMode(bottlecapacity_pin, INPUT);  //bottlecapapcityswitch_pin
  pinMode(fullvatswitch_pin, INPUT);   //fullvatswitch_pin
  pinMode(ps_pin, OUTPUT);   //soleniods and pump on
  pinMode(buzzer_pin, OUTPUT);  //resin bottle empty buzzer
  pinMode(resinemptyled_pin, OUTPUT);  //resin bottle empty led
}

unsigned long now;
# define PRESSED HIGH       // argh! pulled down switches

void loop()
{
  if (millis() > 30000) //30sec delay before code starts operating
 {
  now = millis();
  byte bottlecapacity = digitalRead(bottlecapacity_pin);
  byte vatFull = digitalRead(fullvatswitch_pin);

  **/***
**    blink led and buzzer if green bottle switch not pressed(open)**
**    if green bottle button pressed(closed) then blink led and buzzer stop instantaneously**

**    if vat red button pressed(closed - vat if full) and stays pressed for 5 seconds then ps_pin off(LOW)**

**    if vat red button not pressed(open - vat not full) and the resin bottle(full - green button pressed(on) and both cases are met for 60 seconds then ps_pin on(HIGH)**
**  */**

 **// timer for how long has green button has not been pressed**

  static unsigned long bottlecapacityTimer;
  if (bottlecapacity != PRESSED) {
    if (!bottlecapacityTimer) bottlecapacityTimer = now;
  }
  else bottlecapacityTimer = 0; // 0 -> timer not running



  **// timer for how long has red button been pressed**

  static unsigned long vatFullTimer;
  if (vatFull == PRESSED) {
    if (!vatFullTimer) vatFullTimer = now;
  }
  else vatFullTimer = 0; // 0 -> timer not running



  **// timer for how long has red button been unpressed AND green button has been pressed**

  bool bothConditions = (vatFull != PRESSED) && (bottlecapacity == PRESSED);
  static unsigned long bothConditionsTimer;
  if (bothConditions) {
    if (!bothConditionsTimer) bothConditionsTimer = now;
  }
  else bothConditionsTimer = 0; // 0 -> timer not running


  **/* informational spam**
**    xprintf("vatFull %s ", vatFull == PRESSED ? "pressed " : "not pressed ");**
**    xprintf("botlcap %s\n", bottlecapacity == PRESSED ? "pressed " : "not pressed ");**

    if (vatFullTimer)
    xprintf("vatfull pressed for %lu ms ", now - vatFullTimer);

    if (bothConditionsTimer)
    xprintf("     vatfull unpressed && bottlecapacity pressed for %lu ms ", now - bothConditionsTimer);

  */

  // informational spam
  //xprintf("RED %lu ms      /RED & GREEN %lu ms\n",
   // vatFullTimer ? now - vatFullTimer : 0,
   // bothConditionsTimer ? now - bothConditionsTimer : 0
  //);

  **// if the bottlecapacity button isn't pressed, we should beep and blink**

  static unsigned char toggle;
  if (bottlecapacity != PRESSED) {
    if (now - previousMillis1 >= kkInterval1) {
      if (toggle) {
        digitalWrite(resinemptyled_pin, LOW);
        digitalWrite(buzzer_pin, HIGH);
      }
      else {
        digitalWrite(resinemptyled_pin, HIGH);
        noTone(buzzer_pin);
      }
      toggle = !toggle;
      previousMillis1 = now;
    }
  }
  else {
    digitalWrite(resinemptyled_pin, LOW);
   // noTone(buzzer_pin);
  }


**// if the bottlecapacity condition has been false for enough time**

  if (bottlecapacity != PRESSED) {
    if (now - bottlecapacityTimer > kkInterval3) {  //turn pump off by kkinterval3
      if (1) {
        digitalWrite(ps_pin, LOW);
        bottlecapacityTimer = 0;
      }
    }
  }

**// if the vatFull condition has been true for enough time**

  if (vatFullTimer) {
    if (now - vatFullTimer > kkInterval3) { //turn pump off by kkinterval3
      if (1) {
        digitalWrite(ps_pin, LOW);
        vatFullTimer = 0;
      }
    }
  }

// if the vatFull/bottlecap  condition has been true for enough time
  if (bothConditionsTimer) {
    if (now - bothConditionsTimer > kkInterval4) { //turn pump on by kkinterval4   
      if (1) {
         digitalWrite(ps_pin, HIGH);
        bothConditionsTimer = 0;
      }
    }
  }
 }

}

@RivetingTiger Please edit your post, using the pencil icon at the bottom, and add triple backticks at the beginning and end of your code so that it displays correctly.
Triple backticks look like this:
```

Copy and paste these if you can’t find the correct symbol on your keyboard.

Pete.

Sorry Pete will edit it

I’d say that this sketch isn’t a very good starting point for the type of functionality you are looking for.

Blynk doesn’t like a void loop that is cluttered like this, and checking the millis() time elapsed to see if it’s time to execute a chunk of code isn’t a great way to work.

You’d be far better moving these chunks of code into functions and calling them using BlynkTimer as described here…

To obtain inputs from the widgets attached to virtual datastreams in your Blynk dashboard you need to use BLYNK_WRITE(Vpin) callbacks, which are triggered automatically when a datastream value changes. More on that here…

With Notifications you need to be careful. Notifications are triggered by Events, and there’s a limit of 100 events per 24 hour period.
Here’s some info about how Events/Notifications work in Blynk IoT and how to inadvertently avoid maxing-out your 24 hour allowance…

Pete.

Thanks Pete

I appreciate your time and will look at the links you have suggested.

Kind regards

Kev

Hi Pete

I did try to use multiple voids but it failed and I don’t understand why. I asked on the Arduino Forum but no one responded so I went with the other code. If not too much trouble could you explain where I have gone wrong. I followed the example of Several Things At Once - https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158, I thought I followed it correctly, but obviously I didn’t.

//https://wokwi.com/projects/362063191873613825

//Digispark aAtiny85 project Anycubic Autofill hack so the Anycubic autofiller can be used on other machines

//Sketch to check resin bottle level. If low(and not bottlecapaicty), turn on warning buzzer and led.

//If resin available (bottlecapacity) check vat level. If vat level low for interval6 then turn on pump.

//If resin low (!bottlecapacity) check vat level. If vat level high for interval5 then turn off pump.

# define buzzer_pin 0

# define bottlecapacity_pin 1

# define fullvatswitch_pin 2

# define ps_pin 3

# define resinemptyled_pin 4

unsigned long previousMillis1 = 0UL;  //resin bottle low warning LED timer on

unsigned long previousMillis2 = 0UL;  //resin bottle low warning LED timer off

unsigned long previousMillis3 = 0UL;  //resin bottle low warning buzzer timer on

unsigned long previousMillis4 = 0UL;  //resin bottle low warning buzzer timer off

unsigned long previousMillis5 = 0UL;  //autofill pump off delay timer

unsigned long previousMillis6 = 0UL;  //autofill pump on delay timer

unsigned long previousMillis7 = 0UL;

unsigned long interval1 = 3000UL;   //resin bottle low warning LED timer on

unsigned long interval2 = 5000UL;   //resin bottle low warning LED timer off

unsigned long interval3 = 1000UL;   //resin bottle low warning buzzer timer on

unsigned long interval4 = 10000UL;  //resin bottle low warning buzzer timer off

unsigned long interval5 = 10000UL;  //autofill pump off delay timer

unsigned long interval6 = 60000UL;  //autofill pump on delay timer

unsigned long interval7 = 5000UL;

unsigned long currentMillis = 0;

byte bottlecapacity = digitalRead(bottlecapacity_pin);

byte vatFull = digitalRead(fullvatswitch_pin);

int startDelay = 0;

void setup() {

{

//define pins

pinMode(bottlecapacity_pin, INPUT);  //bottlecapapcityswitch_pin

pinMode(fullvatswitch_pin, INPUT);   //fullvatswitch_pin

pinMode(ps_pin, OUTPUT);   //soleniods and pump on

pinMode(buzzer_pin, OUTPUT);  //resin bottle empty buzzer

pinMode(resinemptyled_pin, OUTPUT);  //resin bottle empty led

}

if (currentMillis - previousMillis7 > interval7)

{ startDelay = HIGH;

previousMillis7 = currentMillis;

}

}

void loop()

{

currentMillis = millis();  

if (startDelay == HIGH)

 

bottlecapacity();

vatcapacity();

//================================================================================================================================================================

//Sketch function 1 - check resin bottle level:

//if bottle is empty do not start pump and recheck bottle level

void bottlecapacity()  {

if (!bottlecapacity)

      {

        if (currentMillis - previousMillis5 >= interval5)

        {

        digitalWrite(ps_pin, LOW);

        }

      }

//low resin bottle warning indicator led and buzzer

    if (!bottlecapacity)

      {

        if (currentMillis - previousMillis1 >= interval1) //if resin bottle is low, turn on low resin bottle indicator led and buzzer after interval 1

            {

              digitalWrite(resinemptyled_pin, HIGH);

         

              previousMillis1 = currentMillis;

            }

 

            if (currentMillis - previousMillis2 >= interval2) //if resin bottle is low, turn off low resin bottle indicator led and buzzer after interval 2

                {

                  digitalWrite(resinemptyled_pin, LOW);

         

                  previousMillis2 = currentMillis;

                }

 

 //if resin bottle is empty turn on empty resin bottle warning buzzer

 

         if (currentMillis - previousMillis3 >= interval3) //if resin bottle is low, turn on low resin bottle indicator led and buzzer after interval 3

         {

           digitalWrite(buzzer_pin, HIGH);

       

            previousMillis3 = currentMillis;

         }

 

             if (currentMillis - previousMillis4 >= interval4)  //if resin bottle is low, turn on low resin bottle indicator led and buzzer after interval 4

              {

                digitalWrite(buzzer_pin, LOW);

       

                previousMillis4 = currentMillis;

              }

       }

}

//============================================================================================================================================================

//Sketch function 2 - autofill pump control

void vatcapacity() {

if (currentMillis - previousMillis5 >= interval5) //if time interval5 has been made then:

  {

    if (vatFull || !bottlecapacity) //if resin bottle low and vat full

    {  

      digitalWrite(ps_pin, LOW); //turn off autofill after interval5  

    }

      previousMillis5 = currentMillis;

  }

     

       else if (currentMillis - previousMillis6 >= interval6) //if time interval6 has been made then:

         {

           if (!vatFull && bottlecapacity) //if resin bottle full and vat low

          {  

            digitalWrite(ps_pin, HIGH); //turn on autofill after interval6

          }

            previousMillis6 = currentMillis;

         }

}

}

Your code doesn’t work because you’ve placed your void bottlecapacity() and void vatcapacity() inside your void loop() function.
C++ doesn’t allow functions within functions.

Also, your if (startDelay == HIGH) command makes no sense, because it’s missing it’s opening and closing curly brackets. It should have brackets like this…

void loop()
{
  currentMillis = millis();
  if (startDelay == HIGH)
  {
    // do the stuff in here that should only execute if start Delay == HIGH evaluates as true
  }
} // end of void loop

I think you’d find your code much easier to follow if you didn’t double-space all of the lines, and used indents and comments in a more sensible way.

Pete.

Thanks Pete I will have another crack at it.

Hi Pete

I got the multiple void version working, well truthfully, a friend told me about Chat GPT and I thought I would see how good it is. We after two goes it spat out the code with changes that works.

[Anycubic Autofill ESP32 version 1 using multiple voids - Wokwi ESP32, STM32, Arduino Simulator](https://Anycubic Autofill ESP32 version 1 using multiple voids)

I now will work on the BLYNK side of it. If you see anything else that might need to be tweaked or cleaned up please let me know. :beers:

Using ChatGPT generated code will probably cost you more time and frustration than writing it yourself.

Look at the Blynk Sketch Builder examples (link at the top of the page) and try to understand how they work, especially the examples that use BlynkTimer.

Pete.

HI Pete,

It was purely a test, I was only told about it by a friend and thought I’d see what it can do. What it showed me was awesomely exciting and scary at the same time. I don’t think there are going to be near enough safe guards and liability. I started coding in the 90’s with PLC for high speed machinery, and was quite proficient with it.
As I explained, since my injury I have become embarrassingly pathetic, I just can’t flow with it and get confused. It takes me ages to see my mistakes and just to learn. Please excuse some, well all my ignorant questions as I find I can’t remember allot of what I read but can after using it a few times.
Thanks

The problem with AI chatbots is that they give very plausible answers, that are delivered in a way which makes them appear to be correct/accurate.
We’re now (mostly) conditioned not to trust the advice we receive on Facebook, forums, online discussion etc, but that level of skepticism doesn’t currently extend to AI chatbots, and that’s where the real problem lies.

Here’s a conversation I just had with an AI bot that calls itself an IoT expert and is powered by GPT-4…

Me : Write a C++ sketch for Blynk IoT that will run on a Wemos D1 Mini, which checks GPIO1 once every second and sends an alert if GPIO1 LOW

Bot : Produces a sketch which uses the Blynk Legacy command Blynk.notify()

Me : This is a Blynk Legacy sketch, not Blynk IoT

Bot : “I apologize for the confusion” Produces a sketch which uses the Blynk Legacy command Blynk.email() and says “Please note that Blynk IoT currently does not support push notifications like Blynk Legacy. Instead, you can use the email widget to receive alerts. Make sure to add the Email widget to your Blynk IoT Template and configure it with your email address”

Me : There is no email widget in Blynk IoT. Blynk.notify() and Blynk.email() are Blynk Legacy commands, not Blynk IoT commands

Bot : “I apologize for the confusion. You are correct that Blynk IoT does not have an email widget or support Blynk.notify() and Blynk.email commands like Blynk Legacy. In this case, you can use a webhook to send alerts through a third-party service like IFTTT or Zapier.” Produces nonsense code that doesn’t use Blynk Webkooks.

Me : It is not necessary to use a webhook and IFTTT or Zapier to send notifications in Blynk IoT

Bot : “You are correct. Blynk IoT supports Eventor, which allows you to create events and send notifications without using webhooks or third-party services like IFTTT or Zapier” Produces more nonsense code, now using delays instead of a timer, so a backward step.

Me : Eventor is a Blynk Legacy concept and is not supported in Blynk IoT. Here’s a clue, use Blynk.logEvent() instead

Bot : “I apologize for the confusion. You are correct that Eventor is not supported in Blynk IoT. Instead, you can use Blynk.logEvent() to log events and send notifications” Produces more nonsense code.

Me : Your sketch is missing #define BLYNK_TEMPLATE_ID and #define BLYNK_TEMPLATE_NAME and used ‘auth’ as a variable instead of#define BLYNK_AUTH_TOKEN. Also, this will attempt to send a notification once every second, when the limit is once per minute. Because there is no logical test to check whether an event has already been logged for this LOW situation, the lasily limit of 100 events per 24 hour period will be exceed in 100 seconds.

Bot : “I apologize for the oversight” Finally produces code that has a chance of working, but certainly not written in the way that I’s do it (although I’m not a programmer).

Pete.

1 Like

ChatGPT knowledge cutoff date is 2021. It knows nothing about Blynk IoT as it wasn’t released yet )

If you give it hints then it will give proper explanations about how to set-up datastreams, events etc, but the information is patchy.

The other day I was using this IoT chat bot and testing its MQTT knowledge. I asked about Blynk IoT and MQTT and it gave me a totally made-up URL to what it described as the Blynk IoT MQTT API

That’s why I find this stuff both scary and frustrating - it makes very believable statements that are not just out of date but totally incorrect.

Pete.

I will soon post a video where chatGPT helped me with quite interesting weekend project. My goal was not to write a single line of code (it worked!)

2 Likes