BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

[SOLVED] Need guidance in understanding the flow of a Blynk Function

I needed to smoothly control a servo, without the Servo library (as it blocks PWM on a few needed pins… as does Servo2). While Arduino forum was uninformative on the topic (just a lot of “use other pins” :unamused: ), I did find some interesting info, via Google, that I used to make up my own method… And it works perfectly, outside of Blynk, as it is shown here:

// Manual servo control - Without Library
// Quick and minimal jitters.
//
// Currently using a potentiometer, but could be fed a number from
// 0-1023 that then gets mapped to microsecond pulses for the servo.
// My servo worked best with 690-2350 (0.69ms - 2.35ms) for a 180 deg range.
// Adjust accordingly to fit your servo.
//
// Gunner.

#define SERVO_PIN 5
#define POT_PIN A2
int ServoPos;

void setup()
{
  pinMode(SERVO_PIN, OUTPUT);
}

void ServoMove()
{
  ServoPos = map(analogRead(POT_PIN), 0, 1023, 2350, 690);  // Map to microsecond pulse (i.e. 2.35*1000=2350)
  digitalWrite(SERVO_PIN, HIGH);  // Activate servo pin.
  delayMicroseconds(ServoPos);  // Delay for the length of the pulse.
  digitalWrite(SERVO_PIN, LOW);  // Deactivate to servo pin.
  delay(5);  // Just a little extra delay seemed necessary to stabilize everything.
}

void loop()
{
  ServoMove();
}

So, on with my question… In order to get this to work as a Blynk function (as it only moved part way, requiring multiple touches in the same spot of the slider to complete the move), I found I needed to add Blynk.syncVirtual(V12); right after the delayMicroseconds(ServoPos);

Now the servo goes where it should… it is almost as smooth and sometimes buzzes for a few seconds once it gets there, but it technically works.

The Blynk code is here:

BLYNK_WRITE(V12)  // Slider set on V12 with 0-1023 range - Works with or without Send on Release.
{
  SrvoPos = map(param.asInt(), 0, 1023, 2350, 690);  // Convert input to microsec output.
  digitalWrite(SRVO, HIGH);  // Activate servo pin.
  delayMicroseconds(SrvoPos);  // Delay for the length of the pulse.
  Blynk.syncVirtual(V12);  // *** Needed to complete pulse for some reason? ***
  digitalWrite(SRVO, LOW);  // Deactivate to servo pin.
  delay(5);  // Just a little extra delay seemed necessary to stabilize everything.
}

Now… what I don’t understand is why? Shouldn’t the flow of action in a Blynk Function be just the same as a Void outside of Blynk? i.e. Enter Void/Function - Get Delay Time - Turn ON Pin - Wait Specified Delay Time - Turn OFF Pin - Exit Void/Function.

Better minds needed in-order to answer this Life Saving question :smiley:

Why is that?

@Dmitriy
Exactly my question :)… why should I require that in order for it to work (but with additional buzzing at end), as it does outside of Blynk.

Maybe it adds some delay that makes you fill that “all is alright”. However I don’t see any reason for this line to make it work :slight_smile:.

if you have a servo handy, please try both codes and let me know if it is only an issue in my universe (as seems to happen all too frequently :confused: )

@GunnerTechTools why use the map when you can simply put 2350 to 690 in the slider range?

I left it in there due to a technical term call laziness :wink:

I actualy just quickly ported over the code I had written for general arduino use… where the mapping was required.

And honestly, the real technical term is “Doh”. Even though I did have to adjust the slider from 0-255 to 0-1023, I just hadn’t realized I could eliminate the map() until you mentioned it :blush:

Still doesn’t explain the real question… I just hope that answer isn’t another “Doh” :smiley:

Might be worth trying.

I presume you have the slider set as Send On Release as ON.

Can’t see why you need the virtualWrite. I don’t have any servos but I’ll think if there is a way of simulating one in code.

Thanks :slight_smile:

but is it set as ON or OFF?

OFF is not recommended if you want a stable system or you code around the flood you cause.

I have used both options (but usually set to ON)… as it doesn’t affect my overall project either way, even while polling sensors and simultaneously BlinkenDasRGBLights :slight_smile:

Without the virtualWrite() it does “technically” work; IF I keep touching the slider at the desired end point, until the servo position matches (it takes 8-9 touches to go end to end with Send on Release; And 3-4 touches without Send on Release - however when slowly dragging the slider, the servo ‘usually’ keeps up).

Almost like Blynk is somehow interrupting it’s own function before the delayMicroseconds() runs it’s course, and the Blynk.syncVirtual() is required to keep putting it back on track, until truly finished.

Also, I should add that the ‘buzzing’ at the end (with the virtualWrite() “fix”) will usually coincide with disruption in the link between server and app (up-timer display and other data pauses for a few seconds). Again, it is like Blynk is now playing catch-up, after the fact, due to the “fix”.

@GunnerTechTools try this with slider set from 2350 to 690:

unsigned long start;
unsigned long finish;

BLYNK_WRITE(V12) 
{
 start = micros();
 SrvoPos = param.asInt();
 delayMicroseconds(SrvoPos);
 finish = micros();
 Serial.println(finish - start);
} 

for me a move to a slider position of 958 gives Serial Monitor output of 972, so pretty accurate.

Some more data shown as slider value and Serial Monitor Micros:

1841 : 1860
828 : 846
2079 : 2098
933 : 952

So around 20 microseconds overhead, which could be covered by a minor coding mod.

@Costas

I guess I am not clearly explaining what I am seeing?

The issue is not the value of the microsecond pulse… that works perfectly (even with the unnecessary map()… which I since removed and used the slider settings instead.

Rather something acts like it is interrupting the simple flow of the Blynk function process (perhaps microseconds are too fast??):

Pin HIGH - Wait Xms - Pin LOW.

Which does not work ‘properly’ in a Blynk function (as compared to a normal loop).

But with the added and seemingly unnecessary Blynk.syncVirtual(V12); I get something more like:

Pin HIGH - Wait Xms - “Go check the slider and make sure you are not forgetting something ;)” - Pin LOW.

Which does work properly, but then causes other minor delays in the rest of the project.

It is late (early) here… so I will sleep on it… but I think will simply re-code so I can still use the Blynk slider, but redirect the microsecond data to a normal loop instead of a Blynk function.

I truly thank you for your time! but no sense in beating this poor dead :horse: much more :slight_smile:

I have added digitalWrite’s high and low to an LED and using 10 x the slider value the LED responds as expected.

I think the issue is specific to your set up as you shouldn’t need any virtualWrite’s

@Costas @Dmitriy

Finally, after many tests, widgets, dual servos, odd commands that shouldn’t but do effect outcomes, and USB links that shouldn’t and probably don’t, effect the transmission of a single integer and it’s interpretation by hardware. I have proven to myself the following:

It seems since Blynk is constantly in it’s own master loop, something as precise as a microseconds() loop gets lost in the shuffle… needs a servo to really notice, LED’s and data displays don’t tell the whole story.

Adding Blynk.syncVirtual(Vx); resolves the loss by keeping the Blynk Function attentive to the microseconds() loop request. Doesn’t matter if it makes sense or not, it worked :wink:

Unfortunately after job done, the Blynk function in question sometimes gets stuck in an endless loop, until another call comes along (in my case a timer); This was all confirmed with counters on hardware side. And that explains the servo chattering and timeouts I experienced.

Solution… I must stop doing nit-picky, sub-timey, non IoT things while running Blynk… and stick with servo libraries when possible :stuck_out_tongue_winking_eye:

So, I believe I answered my own question about the flow of a Blynk Function :relieved:

Thank you for bearing with me on this journey of WTF?!