Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to figure out how to implement this at my church #1

Open
dmanderson22 opened this issue May 2, 2023 · 3 comments
Open

Trying to figure out how to implement this at my church #1

dmanderson22 opened this issue May 2, 2023 · 3 comments

Comments

@dmanderson22
Copy link

My name is David and I am in charge of media at my church. I have two of the Bescor MP 101 heads in use currently. We are moving our control booth to another part of the building and I am looking for a way to control the MP 101 (pan/Tilt) and the zoom (LANC) over ethernet. I would love to have a physical controller connected that would allow me to switch between cameral 1 and 2. Possible Controller

I am sorry if this is not the best way to contact you but I am desperately looking for help with this project.

If you need to contact me in some other way that is fine with me.

@dgatwood
Copy link
Owner

dgatwood commented May 3, 2023

Another David. I think Dr. Seuss wrote a poem about that. 🤣

The controller you're linking to there is serial-only. You would need to use something more like

to get IP communication.

Or for a cheaper solution, you could comment out all of the video playback parts of the code and use my NDI Camera Control project on a Pi-like device plus a Pimoroni I/O Expander for analog inputs. Without the display or pushbuttons, using a NanoPi NEO3 as the board, you could probably build that for somewhere around $50–60. It doesn't support controlling multiple devices, but that ought to be pretty straightforward to add, at least in theory. 😁

Anyway, I can see a lot of possible approaches.

  1. If you aren't married to the idea of using Arduino, you could probably easily get the actual VISCAPTZ code running on a NanoPi NEO3 (only slightly more expensive than a knock-off of an Arduino 2560). I'm not sure how hard it would be to get bit-banged LANC working reliably on Pi-family hardware without dedicating a core with interrupts turned off, though, so that part is a bit of a question mark.

  2. You could use that approach, but connect the UART lines to an Arduino, and use the Arduino code for actually driving the LANC hardware by sending newline-separated commands. I'm pretty sure somebody has the Arduino part of this by now already. But now you have two single-board computers, which also isn't ideal.

  3. You could write partial support for interpreting VISCA-over-IP traffic on Arduino. As a starting point, I wrote a rudimentary VISCA-over-IP camera-side implementation in my VISCAPTZ project.

The only fully working version of that code is written for Raspberry Pi, but when I first started writing that code, I started out writing it for Arduino. I abandoned that effort because I was building something that needed to support absolute positioning, and a single-threaded Arduino can't possibly reliably listen for VISCA commands, query a network-attached camera for its current zoom position via HTTP, ask rotary encoders for the pan and tilt position, and compute the correct speed to set the motors in real time while recalling a preset position. But for what you're doing, I think an Arduino would be more than adequate.

Anyway, I left the original Arduino sketch (in a badly incomplete state) at the top level of that project, and that would probably be a much easier starting point than trying to write your own VISCA-over-PTZ camera-side listener stack from scratch, with the caveat that I never finished it far enough to actually test it, and I'm not 100% sure it even compiles, so you may be flipping back and forth between that and the Pi version to get it working. 😁

  1. Forget the commercial PTZ controller, forget VISCA, and build something super-simple and bespoke. If I were doing what you're describing, unless you're planning to add some actual VISCA-based PTZ cameras to your rig in the future, that's what I would do.

Basically:

  • Get three Arduino devices with Ethernet add-on boards.
  • Assign all three devices a static IP (and separate MAC addresses if your Ethernet hardware requires it).
  • Build one into the controller, with the joystick driving three analog inputs (pan, tilt, zoom), plus a toggle switch driving a digital input.
    • Read the digital input to determine which IP to use when sending packets.
    • Continuously send stop commands to one device while sending the actual commands to the other device, depending on the switch position.
    • Add delays as needed to avoid overwhelming the receiving side. 😁
  • Wire up the motor drivers and LANC controller to the other two Arduino devices.
    • Listen for packets on a specific port.

Keep the protocol simple. On the controller side, in place of the code that sets the motor and LANC speed, send a single UDP packet to a specific port at a particular IP address, and make that packet contain exactly three bytes:

  • The raw pan value that should be sent to the motor controller (0-255)
  • The raw tilt value that should be sent to the motor controller (0-255)
  • The +/- zoom speed value that should be sent to the LANC code (-8 to 8, or 0 to 16 if you prefer unsigned numbers)

Optionally add a fixed 8-byte value at the start of each packet as a sanity check.

On the decode side, rip out all the input handling code, and instead listen for packets on that port. When you get a packet, update the pan, tilt, and zoom speeds by calling the existing functions.

Be sure to use a short-ish timeout of maybe a second in your packet listening code, and if you time out waiting for another packet, set all speed values to zero. That way, a network failure can't cause your camera to keep moving until it points in a dangerous direction (though at least the Bescor has physical stops that likely limit this risk somewhat).

That approach ought to be fairly straightforward using just this project and maybe a dozen extra lines of code to send and receive the packets. You can even look at the preliminary draft of that Arduino-based VISCAPTZ code as a starting point to see how to receive UDP packets.

Hope that helps.

@dgatwood
Copy link
Owner

dgatwood commented May 3, 2023

One more thing. If you do this, make your changes flag-guarded with something like

#define ENABLE_NETWORK 0  // 0 for disabled, 1 for sending side, 2 for receiving side

#if ENABLE_NETWORK == 1
...
#endif

and then send a pull request so that it can be merged in.

Architecturally, at a high level, I'd suggest something like:

  • If the networking flags are enabled, add global axis speed variables (e.g. gTiltAxisSpeed, gPanAxisSpeed, gZoomAxisSpeed).
  • At the top of loop() on the receiving side, read UDP packets from the network and update the global axis speed variables, or set them to 0 in the event of a timeout.
  • In the handleMotorControl() and handleLANC() functions, if the network flag is set, either store the values in global variables and return (sending side), or synchronously read the values from global variables instead of from sensor hardware (receiving side).
  • At the bottom of loop() on the sending side, call a function that reads the toggle switch value and passes the IP address of each device, along with either the current speed (for the active device) or all zeros (for the inactive device) to a second function that sends the actual packet (synchronously) to the specified IP address over UDP.
  • Put the new functions down at the bottom, and flag-guard them appropriately, and maybe add a "#pragma mark - Networking support" line before them.
  • Hard-code the IP address of the current device (maybe with a #define) at the top for both the sending and receiving side.
  • Hard-code the IP address of both receivers (maybe with a #define) at the top for the sending side.

But feel free to disregard that if some other approach seems easier to implement.

@dmanderson22
Copy link
Author

Ok. Wow. I appreciate your input so much. I am looking for the best method to control these for the most budget friendly price. What Arduino devices and joystick hardware would you recommend? Your final setup made the most sense to use and seemed the simplest. I need a controller on one end that could control each of the two pan/tilt heads and the zoom over LANC.

I have no experience with coding other than looking at some coding here and there. I am sure I can get a rudimentary understanding of what is going on by studying your code.

Any help you can point me to would be awesome as well. I had thought about seeking out someone to write the code on a freelance website but I am not sure where I could find the best person for the job as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants