Multiple Joystick widgets

Fellow Blynkers,

After trying and adjusting I finally managed to move 1 pan-tilt bracket, using a Joystick widget.

In my Python code I included 1 Vpin. The Joystick widget uses the merge function, so I use V1 tot write my code and merge the x and y axis.

Today I wanted to use 3 brackets at the same time. I got 3 joystick widgets within the same project. And started to create a V1, V2 and V3 pin code in my existing script. The experienced Blynkers already see it coming: that did not work out… I tested all kinds of ways, without the desired outcome. I did learn and see al kinds of combinations that result in all three brackets moving the same way for example. However, it is always nice to see “a” result!

Can somebody steer me into the right direction? I have 3 brackets. I want 1 project with 3 joystick widgets. Every widget should solely move 1 bracket.

Should I continue working on the python code,or do I have to look at multile devices? It does seem strange to get 3 auth tokens for 3 different brackets.

My biggest hurdle is the main code for the Joystick widget. I have devided my x en y axis into JoystickX en JoystickY. This results in me placing this basic code under every Vpin (1,2,3). But because there is no further distinction between JoystickX and JoystickY these terms are the same for every Vpin I use. At the end it seems that only the last code written under V3 is being processed, so only bracket 3 moves. I even saw 3 widgets move solely bracket 3.

As you can read I am pretty stuck and not very experencied. Can somebody help me out?

Using: Raspberry Pi zero, Pi servo pHAT (v2).

Code:

import busio
import adafruit_pca9685
i2c = busio.I2C(board.SCL, board.SDA)
hat = adafruit_pca9685.PCA9685(i2c)
hat.frequency = 50

import time
from adafruit_servokit import ServoKit

kit = ServoKit(channels=16)

angleX = 0
angleY = 1
kit.servo[0].angleX = 0
kit.servo[1].angleY = 0

import blynklib
from BlynkTimer import BlynkTimer
timer = BlynkTimer()

def limit(value, lower, upper):
    if value < lower:
        value = lower
    elif value > upper:
        value = upper
    return value

auth_token = 'XXX'

# Initialize Blynk

blynk = blynklib.Blynk(auth_token)

@blynk.handle_event('write V1')  # Joystick
def V1_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))
    
def panTiltMove():
    global angleX, angleY
    kit.servo[0].angle = limit(kit.servo[0].angle - angleX, 0, 180)
    kit.servo[1].angle = limit(kit.servo[1].angle - angleY, 0, 180)
 
timer.set_interval(0.1, panTiltMove)    # 100ms
    
try:
    while True:
        blynk.run()
        timer.run()

except KeyboardInterrupt:
    print("Quit")```

I’m no Python expert at all, but your code seems odd to me.

Where is the V2 and V3 coding?

I’d have expected you to be calling panTiltMove from your V1_write_handler_pin_handler so that it is triggered whenever the value of V1 changes, rather than with a 100ms timer.

Also, I’d have expected to see separate functions for Pan, Tilt and Zoom (assuming that is what your 3 joysticks are meant to control) called from the V1, V2 and V3 handlers.

Pete.

Dear Pete,

Very Sharp!

I placed my original code for 1 bracket. This is the ‘WORKING’ code. I thought it would be a good idea to show what I am working with.

The other scripts I tried I did not add, indeed. I will add these as soon as I am home.

! Thanks for the timer.set comment. I am gonna try this out for sure.

Well, if your 1-axis code works, but you are looking for assistance about why your 3-asis code doesn’t work then you’re not likely to get that help unless you post the code that goes with these comments…

Pete.

Dear Pete,

Hereby the code that resulted me having 3 widgets that individually move all 3 brackets.

I think my mistake is that do not specify the 3 widgets to an individual bracket. To me a bracket in the code represents the combination of servo.0 and servo.1 for example. So I assumed that describing the specific servos used per Vpin would result in that widget controlling specificly those 2 servos. But I do include the exact same standard joystick commands under eacht Vpin. I think this messes up the overall outcome.

At the beginner fase I am in I do not know for sure if there subjects that I am not aware of. I have been reading about bridges today during lunch. Or combining devices.

import busio
import adafruit_pca9685
i2c = busio.I2C(board.SCL, board.SDA)
hat = adafruit_pca9685.PCA9685(i2c)
hat.frequency = 50

import time
from adafruit_servokit import ServoKit

kit = ServoKit(channels=16)

angleX = 0
angleY = 1
kit.servo[0].angleX = 0
kit.servo[1].angleY = 0
kit.servo[2].angleX = 0
kit.servo[3].angleY = 0
kit.servo[4].angleX = 0
kit.servo[5].angleY = 0

import blynklib
from BlynkTimer import BlynkTimer
timer = BlynkTimer()

def limit(value, lower, upper):
    if value < lower:
        value = lower
    elif value > upper:
        value = upper
    return value

auth_token = 'XXX'

# Initialize Blynk

blynk = blynklib.Blynk(auth_token)

@blynk.handle_event('write V1')  # Joystick
def V1_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))

def panTiltMove():
    global angleX, angleY
    kit.servo[0].angle = limit(kit.servo[0].angle - angleX, 0, 180)
    kit.servo[1].angle = limit(kit.servo[1].angle - angleY, 0, 180)

timer.set_interval(0.1, panTiltMove)    # 100ms

@blynk.handle_event('write V2')  # Joystick
def V2_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))

def panTiltMove():
    global angleX, angleY
    kit.servo[2].angle = limit(kit.servo[2].angle - angleX, 0, 180)
    kit.servo[3].angle = limit(kit.servo[3].angle - angleY, 0, 180)

timer.set_interval(0.1, panTiltMove)    # 100ms
    
@blynk.handle_event('write V3')  # Joystick
def V3_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))

def panTiltMove():
    global angleX, angleY
    kit.servo[4].angle = limit(kit.servo[4].angle - angleX, 0, 180)
    kit.servo[5].angle = limit(kit.servo[5].angle - angleY, 0, 180)
   
timer.set_interval(0.1, panTiltMove)    # 100ms
    
try:
    while True:
        blynk.run()
        timer.run()

except KeyboardInterrupt:
    print("Quit")```

This same function name appears three times.
I’d expect you to have three functions, one for each bracket (pan, tilt, zoom?)
The function would then be called directly by the write_handler for that joystick, not by a timer.

Pete.

Dear Pete,

Without knowing you I recognize a certain experience and level of knowledge! I fixed it within minutes. I just put my phone away, after turning the individual brackers arround for like a thousand times!!!

Thanks for your time and effort.

1 Like

Excellent, glad it’s sorted.
Do you want to share your code for others to use?

Pete.

Dear Pete,

Sorry for the late response.

I am enjoying some well-earned time off!!! I was happily offline! As soon as I am back behind my desk at home I will upload the document.

Sincere,

Raoul.

1 Like

Dear Blynkers,

Hereby the code I use to move 3 pan/tilt brackets at the same time. Keep in my mind that I am a novice with no experience.

import busio
import adafruit_pca9685
i2c = busio.I2C(board.SCL, board.SDA)
hat = adafruit_pca9685.PCA9685(i2c)
hat.frequency = 50

import time
from adafruit_servokit import ServoKit

kit = ServoKit(channels=16)

angleX = 0
angleY = 1
kit.servo[0].angleX = 0
kit.servo[1].angleY = 0
kit.servo[2].angleX = 0
kit.servo[3].angleY = 0
kit.servo[4].angleX = 0
kit.servo[5].angleY = 0

import blynklib
from BlynkTimer import BlynkTimer
timer = BlynkTimer()

def limit(value, lower, upper):
    if value < lower:
        value = lower
    elif value > upper:
        value = upper
    return value

auth_token = 'XXX'

# Initialize Blynk

blynk = blynklib.Blynk(auth_token)

@blynk.handle_event('write V1')  # Joystick
def V1_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    kit.servo[0].angle = limit(kit.servo[0].angle - angleX, 0, 180)
    kit.servo[1].angle = limit(kit.servo[1].angle - angleY, 0, 180)
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))

@blynk.handle_event('write V2')  # Joystick
def V2_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    kit.servo[2].angle = limit(kit.servo[2].angle - angleX, 0, 180)
    kit.servo[3].angle = limit(kit.servo[3].angle - angleY, 0, 180)
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))
    
@blynk.handle_event('write V3')  # Joystick
def V3_write_handler_pin_handler(pin, value):
    global joystick_mode, angleX, angleY
    joystickX = int(value[0])
    joystickY = int(value[1])
    
    kit.servo[4].angle = limit(kit.servo[4].angle - angleX, 0, 180)
    kit.servo[5].angle = limit(kit.servo[5].angle - angleY, 0, 180)
    
    # PanTilt
    if   joystickX >  30: angleX =  4
    elif joystickX < -30: angleX = -4
    else:                 angleX =  0
    if   joystickY >  30: angleY =  4
    elif joystickY < -30: angleY = -4
    else:                 angleY =  0
    print("angle {} {} ".format(angleX,angleY))
    
try:
    while True:
        blynk.run()
        timer.run()

except KeyboardInterrupt:
    print("Quit")```