Arduino Shield Thread

Questions about ATEM Switchers, Camera Converter and everything live!
  • Author
  • Message
Offline
User avatar

Benjamin Higginbotham

  • Posts: 286
  • Joined: Sun Aug 26, 2012 1:47 pm
  • Location: Anaheim, CA

Re: Arduino Shield Thread

PostThu Mar 02, 2017 7:34 pm

Wait... so I *can* read incoming camera info?

Scenario: I have 4 cameras in one location and 8 more in a remote location about 4000 km away. All of them are BMD cams of sorts and I want to use one switcher interface to paint them all. Can I use one shield at the origin site to read all of the camera settings for all cameras, sling that down the wire over a private WAN and have a shield on the other end spit out commanding for distribution to my cameras via SDI?

I was under the impression this was not possible?
Benjamin Higginbotham
TMRO - Making Space Commonplace
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostThu Mar 02, 2017 9:19 pm

Well iT is. Skaarhoj already does this with there sdi tally iris Control box.. :)

What you are suggesting should be possible.. Takes à lot of programming. Also there are issues that the shield is missing incoming packets.. Tally is data that is send 10 times à second.. But shading data like step up gain.. Could be lost in the process.. So it is not het completely Foolproof :D ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline
User avatar

Baz

  • Posts: 622
  • Joined: Wed Aug 22, 2012 5:06 am
  • Location: Sydney, Australia

Re: Arduino Shield Thread

PostThu Mar 02, 2017 9:39 pm

Then of course you must be able to extract the ch15/16 talkback.

MISC
U/S Express, SmartviewDuo, SmartScopeDuo, Teranex 2D, Web Pres, 5/7 Vid Assists
VIDEOHUB
Smart 12x12
12x24
72x144
HYPERDECK
Studio, Shuttle, Studio Mini
ATEM
2me4K, 2me, TVS, TVS HD, CamConvs, StudioConvs, Studio Cams, Micro Studio Cam
Offline
User avatar

Benjamin Higginbotham

  • Posts: 286
  • Joined: Sun Aug 26, 2012 1:47 pm
  • Location: Anaheim, CA

Re: Arduino Shield Thread

PostThu Mar 02, 2017 9:42 pm

Baz wrote:Then of course you must be able to extract the ch15/16 talkback.

We don't need comms, only control. My cameras are in areas where... uh... people can't really be.
Benjamin Higginbotham
TMRO - Making Space Commonplace
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostThu Mar 02, 2017 9:48 pm

Bug Benjamin. What you want To do could have been done since the release of the shield and an atmega plus ethernet shield..
Sending off the network protocol of atem to the Remote arduino and use that as a converter......
Mark Gilbert from Strata had No problem taking over My atem by the internet from Engeland..

So atem Control over the internet has been done before...
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline
User avatar

Benjamin Higginbotham

  • Posts: 286
  • Joined: Sun Aug 26, 2012 1:47 pm
  • Location: Anaheim, CA

Re: Arduino Shield Thread

PostThu Mar 02, 2017 9:51 pm

We control over our network today. That's not in question. The part in question is input from our current switcher which is something we don't do. Instead we have a second system that we control and send the commanding out. Not desired.

So have the shield take SDI input from the ATEM, convert the commands it reads to IP, send it to the remote side and from there we're already OK converting back to commanding on SDI. It's that input side we always seemed to be missing.
Benjamin Higginbotham
TMRO - Making Space Commonplace
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostTue Mar 14, 2017 10:57 pm

AFAIK reading camera settings is not possible. You can controll as many as 253 or 254 cameras simultaneously connected to single SDI network with one SDI controller. You can upload and synchronize all settings to all or some of cameras, but you can not read current camera settings via SDI Shield. It is one directional communication (you can pickup some information from incoming signal - wchich usualy comes from mixer)

Am I wrong? Is there any possibility to read camera settings? Am I missing a part of documentation? It could be great expansion for my SDI Remote&Sequencer prototype.
Attachments
swq.jpg
swq.jpg (193.42 KiB) Viewed 19361 times
SDI Remote for Blackmagic cameras
sdiremote.com
Offline
User avatar

Baz

  • Posts: 622
  • Joined: Wed Aug 22, 2012 5:06 am
  • Location: Sydney, Australia

Re: Arduino Shield Thread

PostWed Mar 15, 2017 4:49 am

This is a box that displays program and preview tally from the ATEM SDI output....

https://www.facebook.com/photo.php?fbid=1437911942905835&set=gm.448186322191437&type=3&theater

Baz

MISC
U/S Express, SmartviewDuo, SmartScopeDuo, Teranex 2D, Web Pres, 5/7 Vid Assists
VIDEOHUB
Smart 12x12
12x24
72x144
HYPERDECK
Studio, Shuttle, Studio Mini
ATEM
2me4K, 2me, TVS, TVS HD, CamConvs, StudioConvs, Studio Cams, Micro Studio Cam
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostThu Mar 16, 2017 7:29 pm

Just finished prototype development SDI Remote. Proud :-D
sdiremote_small.jpg
sdiremote_small.jpg (306.76 KiB) Viewed 19316 times
SDI Remote for Blackmagic cameras
sdiremote.com
Offline

Anna Woodson

  • Posts: 3
  • Joined: Mon Mar 20, 2017 8:01 pm

Re: Arduino Shield Thread

PostMon Mar 20, 2017 8:10 pm

Anyone have a recommendation for a power supply to be used with this shield? I thought I could use the same as my Arduino, but it has a different size barrel. I'm not seeing the barrel size anywhere in the manual.
Thanks!
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostMon Mar 20, 2017 10:35 pm

Mine from Arduino fits.
SDI Remote for Blackmagic cameras
sdiremote.com
Offline

Håvard Njåstad

  • Posts: 54
  • Joined: Wed Sep 18, 2013 9:23 am

Re: Arduino Shield Thread

PostMon Mar 20, 2017 11:11 pm

Most stuff (arduino) tend to use 5.5 X 2.1mm barrels, but all blackmagic equipment (blackmagic arduino shield) use 5.5 X 2.5mm, so any generic 12v adapter with those dimensions will fit
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostThu Mar 23, 2017 8:49 am

Is Ursa Mini Pro compatible with SDI Shield?
SDI Remote for Blackmagic cameras
sdiremote.com
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostThu Mar 23, 2017 9:50 am

Offcoarse it is. The protocol Didnt change..
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostFri Mar 24, 2017 11:51 pm

Hello! I am back with technical question. Is Message grouping working OOB with high level commands like sdiCameraControl.writeVarType? I need to change a lot of camera params in short periods of time (perfectly every frame) - will they group automatically in send buffer before sending or should I use low level commands to fill send buffer manually before sending them to camera on next frame?

Regrads
SDI Remote for Blackmagic cameras
sdiremote.com
Offline

Anna Woodson

  • Posts: 3
  • Joined: Mon Mar 20, 2017 8:01 pm

Re: Arduino Shield Thread

PostWed Mar 29, 2017 7:31 pm

Has anyone used this shield with an Arduino Mega? Since it's communicating through I2C, it should all be the same code. But I seem to be missing something.
Offline

Gary Adams

Blackmagic Design

  • Posts: 1383
  • Joined: Sat Aug 25, 2012 6:14 am

Re: Arduino Shield Thread

PostWed Mar 29, 2017 11:21 pm

Hello Anna. The Shield will work with the Mega. You will need to jumper A4 to SDA and A5 to SLL on the Mega.

Regards, Gary
Gary Adams
Blackmagic Design
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostFri Mar 31, 2017 1:07 pm

And you need to bend the i2c pins on the shield to prevent they connect to other pins on the mega.. otherwise those ports Will block the i2c.
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline
User avatar

Radosław Przybył

  • Posts: 13
  • Joined: Wed Feb 22, 2017 1:13 am
  • Location: Echternach, Luxembourg

Re: Arduino Shield Thread

PostTue May 23, 2017 12:50 pm

I have no URSA Mini, could you help me with shutter settings? When sending a message in group "Video" no 6 (shutter speed (ordinal)) to Ursa - will it iterate through all 10 shutter settings only? From 360 to 45 degree?
SDI Remote for Blackmagic cameras
sdiremote.com
Offline

Jakob Hansen

  • Posts: 1
  • Joined: Fri Jun 09, 2017 11:27 am

Using SKAARHOJ Kit - Joystick and LCD

PostFri Jun 09, 2017 12:44 pm

Hi all,

We have a BMD Studio Micro camera, that we wanted to control for shading.
The otherwise fantastic SKAARHOJ CCU controllers were out of range given our budget.

Instead we decided to try our luck with the BMD Shield, combined with the nice little DIY kit from SKAARHOJ (FaderBoard & Joystick add-on for the Shield).

Initially, we tried going with the faderboard, which connects directly to the top of the shield.
The idea was to switch to different operating modes via the 3 buttons.

But - that doesn't work very well when you want to control different parameters with a fixed encoding fader/rotary knob, as we soon discovered!

Instead, I decided to try and use the Joystick, combined with a LCD for parameter readout.
To get the extra connections required for combining the BMD Shield, SKAARHOJ Joystick and LCD, we had to upgrade to a Arduino Mege (2560).
Thanks to a couple of posts on this forum, we managed to sort the wiring properly.
If you look at the schematic, you get a crude idea of the required wiring.
CCU_Controller_Schema.jpg
CCU_Controller_Schema.jpg (283.74 KiB) Viewed 18571 times


Please note, that the BMD Shield is connected directly to the top of the Mega! So all wiring runs between Shield, JoystickBoard and LCD.

The LCD unit is just the model (LCM1602C) which was supplied in our Arduino Starterkit. It's a 16X2LCD.
Mega_Shield_LCD.jpg
Mega_Shield_LCD.jpg (138.03 KiB) Viewed 18571 times


The code is based on the BMD library's example, "CustomJoystickControl".

As a cheap solution to a shading controller for the Micro, this setup performs great.
Ikegami_vs_DIY.jpg
DIY-project vs Ikegami CCP
Ikegami_vs_DIY.jpg (45.45 KiB) Viewed 18571 times



Code: Select all
#include <BMDSDIControl.h>
#include <LiquidCrystal.h>
#include <math.h>   
#include <Wire.h>

/**
Blackmagic Design 3G-SDI Shield Sketch
Joystick control - JAHA 2017-05-05

This sketch controls a BMD cam via a BMD 3G-SDI shield,
which supports a SKAARHOJ joystick&buttons PCB and controls a SDI-connected BMD-camera.

The three buttons are mapped as follows:
- Button 1, which selects WB-mode
- Button 2, which selects and cycles through black/gamma/gain adj modes
- Button 3, which selects focus-mode on the camera

The joystick is mapped as follows:
- X axis adjusts the mode X parameter
- Y axis adjusts the mode Y parameter
- Pressing the Joystick resets all correction parameters.
*/

// Camera#
const int cameraNumber = 2;

// LCD pin mappings
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

// Hardware pin mappings
const int             joystickButtonPin = A0;
const int             joystickXPin = A1;
const int             joystickYPin = A2;
const int             button1Pin = 5;
const int             button2Pin = 6;
const int             button3Pin = 7;

// Blackmagic Design SDI control shield globals
const int                 shieldAddress = 0x6E;
BMD_SDITallyControl_I2C   sdiTallyControl(shieldAddress);
BMD_SDICameraControl_I2C  sdiCameraControl(shieldAddress);

// Button debouncing globals
unsigned long         lastStableButtonTime[32];
int                   rawButtonLevels[32];
int                   stableButtonLevels[32];

// Joystick sample rate limiter globals
unsigned long         lastJoystickUpdateTime;

// Global joystick detection parameters
int                   currentJoystickX = 0;
int                   currentJoystickY = 0;

// Camera parameter adjustment-state, globals
// Manual WhiteBalance
float                 manualWbValueController = 6; //4000
const float           manualWbValueSensHigh = 0.2;  // joy max deflection adjust
const float           manualWbValueSensNormal = 0.05;  // joy normal deflection adjust
const float           manualWbFloor = 0; // 2500
const float           manualWbTop = 17;  // 8000
const int16_t        manualWbValues[18] = { 2500, 2800, 3000, 3200, 3400, 3600, 4000, 4500, 4800, 5000, 5200, 5400, 5600, 6000, 6500, 7000, 7500, 8000 };
int16_t              manualWbValueSendToDevice;

// Lift/Blacklevel
float                 liftValue = 0;
const float           liftValueSensHigh = 0.005;
const float           liftValueSensNormal = 0.001;
float              liftValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           liftFloor = -2;
const float           liftTop = 2;

// Gamma
float                 gammaValue = 0;
const float           gammaValueSensHigh = 0.005;
const float            gammaValueSensNormal = 0.001;
float              gammaValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           gammaFloor = -4;
const float           gammaTop = 4;

// Gain
float                 gainValue = 1;
const float           gainValueSensHigh = 0.03;
const float           gainValueSensNormal = 0.01;
float                 gainValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           gainFloor = 0;
const float           gainTop = 16;

// MasterGain
float                 masterGainValueController = 1.0;
const float           masterGainSensHigh = 0.1;
const float           masterGainSensNormal = 0.05;
const int           masterGainValues[5] = { 1, 2, 4, 8, 16 };  // gain x1, x2, x4, x8, x16
const int             masterGainFloor = 0; //x1
const int             masterGainTop = 4;   //x16
int                 masterGainSendToDevice;

// Focus
float                 focusValue = 0.5;
const float           focusValueSensHigh = 0.01;
const float           focusValueSensNormal = 0.002;
const float           focusFloor = 0.0;
const float           focusTop = 1.0;


// ModeSelect - global parameter, determines operation-mode
// 1 - Whitebalance
// 2 - Lift (CC) & mastergain
// 3 - Gamma (CC) & mastergain
// 4 - Gain (CC) & mastergain
// 5 - Focus
int ModeSelect = 0;   // current mode
int previousMode = 0; // previous mode

// ColorCorrection-mode
int                   currentCCMode = 1;       // current ColorCorrectionMode: Lift, Gamma, Gain
bool              ccMode;               // flag true if CCmode is active

void setup() {

   Serial.begin(9600);
   Serial.println("startup");

   lcd.begin(16, 2);
   lcd.print("CCU controller");

   // Configure digital inputs
   pinMode(joystickButtonPin, INPUT_PULLUP);
   pinMode(button1Pin, INPUT_PULLUP);
   pinMode(button2Pin, INPUT_PULLUP);
   pinMode(button3Pin, INPUT_PULLUP);

   // Set up the BMD SDI control library
   sdiTallyControl.begin();
   sdiCameraControl.begin();

   // The shield supports up to 400KHz, use faster
   // I2C speed to reduce latency
   Wire.setClock(400000);

   // Enable both tally and control overrides
   sdiTallyControl.setOverride(true);
   sdiCameraControl.setOverride(true);

   // reset camera to defaults
   DoParameterUpdateResetAll();

   // display welcome message
   lcd.setCursor(0, 0);
   lcd.print("CCU controller");
}

void loop() {

   DetectOperationMode();
   ReadJoystickInput();
   DoParameterUpdate();
}

void DetectOperationMode() {

   // Detect button1 - WhiteBalance

   if (getButtonStableEdge(button1Pin) == true && getButtonStableLevel(button1Pin) == LOW) {
      // When the button is low (pressed) the WB-mode is activated
      ModeSelect = 1;
      ccMode = false;

      Serial.println("Mode1 detected"); //debug only

      CheckDisplayClear();
   }



   // Detect button2, cycle through black/gamma/gain adjustment modes
   if (getButtonStableEdge(button2Pin) == true && getButtonStableLevel(button2Pin) == LOW) {
      // detect if we should step to next cc-mode
      if (ccMode) {
         currentCCMode = currentCCMode + 1;
         if (currentCCMode > 3)
            currentCCMode = 1;
      }
      ccMode = true;

      if (currentCCMode == 1) {
         ModeSelect = 2;   // Lift
      }
      else if (currentCCMode == 2) {
         ModeSelect = 3;   // Gamma
      }
      else if (currentCCMode == 3) {
         ModeSelect = 4;        // Gain
      }

      Serial.println("Mode2, 3 or 4 detected");  // debug only
      Serial.println(ModeSelect);

      CheckDisplayClear();
   }



   // Detect button3, select focus mode
   if (getButtonStableEdge(button3Pin) == true && getButtonStableLevel(button3Pin) == LOW) {
      ModeSelect = 5;    // Focus
      ccMode = false;

      Serial.println("Mode5 detected");  // debug only

      CheckDisplayClear();
   }


   // If the reset button is pressed, clear all color correction values
   if (getButtonStableEdge(joystickButtonPin) == true && getButtonStableLevel(joystickButtonPin) == LOW) {
      DoParameterUpdateResetAll();
      Serial.println("Reset detected");
   }
}

void ReadJoystickInput() {
   if (getJoystickUpdateReady() == true) {

      switch (ModeSelect) {

      case (0): // ignore
         break;

      case (1): // Whitebalance
         Serial.println("ReadJoy > case 1");

         // joystick Y = whitebalance K
         currentJoystickY = getJoystickAxisPercent(joystickYPin);
         if (currentJoystickY > 80) {
            manualWbValueController = manualWbValueController + manualWbValueSensHigh; // using wb sensitivity-constant
         }
         else if (currentJoystickY > 0) {
            manualWbValueController = manualWbValueController + manualWbValueSensNormal;
         }
         else if (currentJoystickY < -80) {
            manualWbValueController = manualWbValueController - manualWbValueSensHigh;
         }
         else if (currentJoystickY < 0) {
            manualWbValueController = manualWbValueController - manualWbValueSensNormal;
         }

         // Don't allow the values to exceed the minimum/maximum
         manualWbValueController = constrain(manualWbValueController, manualWbFloor, manualWbTop);

         break;


      case (2): // CC Lift
         Serial.println("ReadJoy > case 2");

         // joystick Y = lift
         currentJoystickY = getJoystickAxisPercent(joystickYPin);
         if (currentJoystickY > 80) {
            liftValue = liftValue + liftValueSensHigh; // using lift sensitivity-constant
         }
         else if (currentJoystickY > 0) {
            liftValue = liftValue + liftValueSensNormal;
         }
         else if (currentJoystickY < -80) {
            liftValue = liftValue - liftValueSensHigh;
         }
         else if (currentJoystickY < 0) {
            liftValue = liftValue - liftValueSensNormal;
         }

         ReadJoystickInputMasterGain();

         // Don't allow the values to exceed the minimum/maximum
         liftValue = constrain(liftValue, liftFloor, liftTop);

         break;


      case (3): // CC Gamma
         Serial.println("ReadJoy > case 3");

         // joystick Y = gamma
         currentJoystickY = getJoystickAxisPercent(joystickYPin);
         if (currentJoystickY > 80) {
            gammaValue = gammaValue + gammaValueSensHigh; // using gamma sensitivity-constant
         }
         else if (currentJoystickY > 0) {
            gammaValue = gammaValue + gammaValueSensNormal;
         }
         else if (currentJoystickY < -80) {
            gammaValue = gammaValue - gammaValueSensHigh;
         }
         else if (currentJoystickY < 0) {
            gammaValue = gammaValue - gammaValueSensNormal;
         }

         ReadJoystickInputMasterGain();

         // Don't allow the values to exceed the minimum/maximum
         gammaValue = constrain(gammaValue, gammaFloor, gammaTop);

         break;


      case (4): // CC Gain
         Serial.println("ReadJoy > case 4");

         // joystick Y = gain
         currentJoystickY = getJoystickAxisPercent(joystickYPin);
         if (currentJoystickY > 80) {
            gainValue = gainValue + gainValueSensHigh; // use gain sensitivity-constant
         }
         else if (currentJoystickY > 0) {
            gainValue = gainValue + gainValueSensNormal;
         }
         else if (currentJoystickY < -80) {
            gainValue = gainValue - gainValueSensHigh;
         }
         else if (currentJoystickY < 0) {
            gainValue = gainValue - gainValueSensNormal;
         }

         ReadJoystickInputMasterGain();

         // Don't allow the values to exceed the minimum/maximum
         gainValue = constrain(gainValue, gainFloor, gainTop);

         break;


      case (5): // Focus
         Serial.println("ReadJoy > case 5");

         // joystick Y
         currentJoystickY = getJoystickAxisPercent(joystickYPin);
         if (currentJoystickY > 80) {
            focusValue = focusValue + focusValueSensHigh; // use focus sensitivity-constant
         }
         else if (currentJoystickY > 0) {
            focusValue = focusValue + focusValueSensNormal;
         }
         else if (currentJoystickY < -80) {
            focusValue = focusValue - focusValueSensHigh;
         }
         else if (currentJoystickY < 0) {
            focusValue = focusValue - focusValueSensNormal;
         }

         // Don't allow the values to exceed the minimum/maximum
         focusValue = constrain(focusValue, focusFloor, focusTop);

         break;
      }
   }
}

void ReadJoystickInputMasterGain() {

   // joystick X = masterGain
   currentJoystickX = getJoystickAxisPercent(joystickXPin);
   if (currentJoystickX > 80) {
      masterGainValueController = masterGainValueController + masterGainSensHigh;
   }
   else if (currentJoystickX > 0) {
      masterGainValueController = masterGainValueController + masterGainSensNormal;
   }
   else if (currentJoystickX < -80) {
      masterGainValueController = masterGainValueController - masterGainSensHigh;
   }
   else if (currentJoystickX < 0) {
      masterGainValueController = masterGainValueController - masterGainSensNormal;
   }

   // Don't allow the values to exceed the minimum/maximum   
   masterGainValueController = constrain(masterGainValueController, masterGainFloor, masterGainTop);
}

void DoParameterUpdate() {
   // Send new parameter adjustment to the camera

   switch (ModeSelect) {

   case (0): // ignore
      break;

   case (1): // Whitebalance
           // joystick Y (manualWbValue)

      DoParameterUpdateWhiteBalance();

      break;

   case (2): // CC Lift
           // joystick Y = lift (liftValue)
           // joystick X = masterGain

      DoParameterUpdateLift();
      DoParameterUpdateMasterGain();

      break;

   case (3): // CC Gamma
           // joystick Y = gamma
           // joystick X = masterGain

      DoParameterUpdateGamma();
      DoParameterUpdateMasterGain();

      break;

   case (4): // CC Gain
           // joystick Y = gain
           // joystick X = masterGain

      DoParameterUpdateGain();
      DoParameterUpdateMasterGain();

      break;

   case (5): // Focus
           // joystick X

      DoParameterUpdateFocus();

      break;
   }
}

void DoParameterUpdateWhiteBalance() {

   Serial.println("ParameterUpdate > case 1");

   manualWbValueSendToDevice = manualWbValues[round(manualWbValueController)];

   sdiCameraControl.writeCommandInt16(
      cameraNumber,         // Destination:    Camera number
      1,                    // Category:       Video
      2,                    // Param:          White balance
      0,                    // Operation:      Set Absolute,
      manualWbValueSendToDevice    // manualWbValue
   );

   UpdateDisplay(5, "WhiteBalance", manualWbValueSendToDevice);
}

void DoParameterUpdateLift() {
   Serial.println("ParameterUpdate > Lift");

   liftValueArray[0] = liftValue;
   liftValueArray[1] = liftValue;
   liftValueArray[2] = liftValue;
   liftValueArray[3] = liftValue;

   // set lift values
   sdiCameraControl.writeCommandFixed16(
      cameraNumber,         // Destination:    Camera number
      8,                    // Category:       Color Correction
      0,                    // Param:          Offset Adjust
      0,                    // Operation:      Set Absolute,
      liftValueArray        // lift values
   );

   UpdateDisplay(5, "Black", liftValue);
}

void DoParameterUpdateGamma() {
   Serial.println("ParameterUpdate > Gamma");

   gammaValueArray[0] = gammaValue;
   gammaValueArray[1] = gammaValue;
   gammaValueArray[2] = gammaValue;
   gammaValueArray[3] = gammaValue;

   // set gamma values
   sdiCameraControl.writeCommandFixed16(
      cameraNumber,         // Destination:    Camera number
      8,                    // Category:       Color Correction
      1,                    // Param:          Gamma adjust
      0,                    // Operation:      Set Absolute,
      gammaValueArray       // gamma value
   );

   UpdateDisplay(5, "Gamma", gammaValue);
}

void DoParameterUpdateGain() {
   Serial.println("ParameterUpdate > Gain");

   gainValueArray[0] = gainValue;
   gainValueArray[1] = gainValue;
   gainValueArray[2] = gainValue;
   gainValueArray[3] = gainValue;

   // set gain values
   sdiCameraControl.writeCommandFixed16(
      cameraNumber,         // Destination:    Camera number
      8,                    // Category:       Color Correction
      2,                    // Param:          Gain adjust
      0,                    // Operation:      Set Absolute,
      gainValueArray        // gain value
   );

   UpdateDisplay(5, "Gain", gainValue);
}

void DoParameterUpdateFocus() {
   Serial.println("ParameterUpdate > focus");

   // set focus values
   sdiCameraControl.writeCommandFixed16(
      cameraNumber,         // Destination:    Camera number
      0,                    // Category:       Lens
      0,                    // Param:          Focus
      0,                    // Operation:      Set Absolute,
      focusValue            // focus value
   );

   UpdateDisplay(1, "Focus", focusValue);
   UpdateDisplay(3, "", focusValue);

}

void DoParameterUpdateResetAll() {
   // Reset color correction

   for (int i = 0; i < 10; i++) {
      Serial.println("Reset camera parameters");  // looping to increase readability in serial-monitor
   }

   manualWbValueController = 6; //4000K
   liftValue = 0.02;
   gammaValue = 0.15;
   gainValue = 1.4;
   focusValue = 0.52;
   masterGainValueController = 3;

   DoParameterUpdateWhiteBalance();
   DoParameterUpdateLift();
   DoParameterUpdateGamma();
   DoParameterUpdateGain();
   DoParameterUpdateMasterGain();
   DoParameterUpdateFocus();
   lcd.clear();

   /*
   // Reset all color correction parameters in the camera
   sdiCameraControl.writeCommandVoid(
   cameraNumber,        // Destination:    Camera
   8,                   // Category:       Color Correction
   7                    // Param:          Reset Defaults
   );

   // Request auto-iris adjustment in the camera
   sdiCameraControl.writeCommandVoid(
   cameraNumber,        // Destination:    Camera
   0,                   // Category:       Lens
   5                    // Param:          Auto Iris
   );
   */
}

void DoParameterUpdateMasterGain() {

   masterGainSendToDevice = masterGainValues[round(masterGainValueController)];

   sdiCameraControl.writeCommandInt8(
      cameraNumber,         // Destination:    Camera number
      1,                    // Category:       Video
      1,                    // Param:          Sensor gain
      0,                    // Operation:      Set Absolute,
      masterGainSendToDevice       // masterGainValue
   );

   UpdateDisplay(6, "mGain", masterGainSendToDevice);
}

bool getJoystickUpdateReady() {
   // Determines if we are ready for another joystick update (this is
   // a rate limiter to ensure that the user can slowly adjust the
   // parameters easily with the joystick)

   unsigned long currentTime = millis();
   if ((lastJoystickUpdateTime - currentTime) > 100) {
      lastJoystickUpdateTime = currentTime;
      return true;
   }

   return false;
}

int getJoystickAxisPercent(int analogPin) {
   // Reads the joystick axis on the given analog pin as a [-100 - 100] scaled value

   int rawAnalogValue = analogRead(analogPin);
   int scaledAnalogValue = map(rawAnalogValue, 0, 1023, -100, 100);

   // Consider values close to zero as zero, so that when the joystick is
   // centered it reports zero even if it is slightly mis-aligned
   if (abs(scaledAnalogValue) < 10) {
      scaledAnalogValue = 0;
   }

   return scaledAnalogValue;
}

bool getButtonStableEdge(int digitalPin) {
   // Detects debounced edges (i.e. presses and releases) of a button

   bool previousLevel = stableButtonLevels[digitalPin];
   bool newLevel = getButtonStableLevel(digitalPin);

   return previousLevel != newLevel;
}

int getButtonStableLevel(int digitalPin) {
   // Reads a digital pin and filters it, returning the stable button position

   int           pinLevel = digitalRead(digitalPin);
   unsigned long currentTime = millis();

   // If the button is rapidly changing (bouncing) during a press, keep
   // resetting the last stable time count
   if (pinLevel != rawButtonLevels[digitalPin]) {
      lastStableButtonTime[digitalPin] = currentTime;
      rawButtonLevels[digitalPin] = pinLevel;
   }

   // Once the button has been stable for
   if ((currentTime - lastStableButtonTime[digitalPin]) > 20) {
      stableButtonLevels[digitalPin] = pinLevel;
   }

   return stableButtonLevels[digitalPin];
}

void UpdateDisplay(int _position, char _text[], float _value) {
   // split lcd-display into 6 areas:
   // upper-left = 1
   // upper-right = 2
   // lower-left = 3
   // lower-right = 4
   // left upper+lower = 5
   // right upper+lower = 6

   if (_position <= 0 || _position > 6) {
      Serial.print("lcd-position out of bounds");
      return;
   }

   // /*
   Serial.print(_text);
   Serial.print(" ");
   Serial.println(_value);
   // */

   switch (_position) {

   case (1): // row = 0, column = 0, upper left
      lcd.setCursor(0, 0);
      if (_text == "") {
         lcd.print(_value);
      }
      else {
         lcd.print(_text);
      }

      break;

   case (2): // row = 7, column = 0, upper right
      lcd.setCursor(7, 0);
      if (_text == "") {
         lcd.print(_value);
      }
      else {
         lcd.print(_text);
      }

      break;

   case (3): // row = 0, column = 1, lower left
      lcd.setCursor(0, 1);
      if (_text == "") {
         lcd.print(_value);
      }
      else {
         lcd.print(_text);
      }

      break;

   case (4): // row = 7, column = 1, lower right
      lcd.setCursor(7, 1);
      if (_text == "") {
         lcd.print(_value);
      }
      else {
         lcd.print(_text);
      }

      break;

   case (5): // text + value, left part of lcd
      lcd.setCursor(0, 0);
      lcd.print(_text);
      lcd.setCursor(0, 1);
      lcd.print(_value);
      break;

   case (6): // text + value, right part of lcd
      lcd.setCursor(7, 0);
      lcd.print(_text);
      lcd.setCursor(7, 1);
      lcd.print(_value);
      break;
   }
}

void CheckDisplayClear() {
   if (previousMode != ModeSelect) {
      lcd.clear();
      Serial.print("CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR");
   }
   previousMode = ModeSelect;
}
Offline

Denny Smith

  • Posts: 13131
  • Joined: Thu Aug 01, 2013 4:19 pm
  • Location: USA, Northern Calif.

Re: Arduino Shield Thread

PostMon Jun 12, 2017 4:43 pm

Nice job, looks good, and it works!
Cheers
Denny Smith
SHA Productions
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostSun Sep 17, 2017 8:48 pm

hello Jakob i am trying to use 3g-sdi shield with an i2c display (with controller HD44780) but when sketch runs the sdiCameraControl.begin () command; the display will no longer work and even Serial.print commands will not work. You have some solution. thank you.
Offline

Marc Briede

  • Posts: 1
  • Joined: Tue Sep 26, 2017 10:14 am

Micro Studio Master/Slave via Arduino

PostTue Sep 26, 2017 10:24 am

I am thinking about a master/slave configuration for a micro studio 4k camera. I'd like to read camera data (gain, iris, white balance, shutter speed) from one micro studio via the arduino shield and push the values to other micro studios.
But as far as I read there is no possibility to read out camera data. Is there a chance to work around?
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostTue Sep 26, 2017 11:10 am

Someone knows if I can use the 3G-SDI Arduino Shield with Arduino Due ?
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostTue Sep 26, 2017 4:15 pm

No,

The shield is 5V and the due is 3,3v. So without the propper level schifting you Will blow up your Due processor.
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Kasper Skaarhoj

  • Posts: 6
  • Joined: Fri Aug 31, 2012 7:01 pm

Re: Arduino Shield Thread

PostThu Sep 28, 2017 7:34 pm

It's actually fairly tricky, more than just level shifting. We have found a way, we have also found out why it doesn't work with such as Arduino Due and another fast 3V3 processor we tried. It's actually a timing issue in BMDs implementation, so ideally they fix it in a new firmware. We should write a mail to Hersh about it I think...
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostThu Oct 12, 2017 11:22 am

hello Jakob, I'm taking inspiration from your project and I am controlling with LCD menus and rotary encoders to vary the parameters of Gain, Gamma, Lift (R G B Y separately) Iris, Zoom, Focus, Hue - Sat, MasterGain and Lift Master.
Last edited by Marco Monaldi on Thu Oct 12, 2017 7:30 pm, edited 1 time in total.
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostThu Oct 12, 2017 7:00 pm

English please!!!
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostFri Oct 13, 2017 11:23 am

I'm sorry Xtreemtec. I speak Italian and I do not speak English well. in the last post I forgot to post in English.
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostFri Oct 13, 2017 4:21 pm

Marco Monaldi wrote:I'm sorry Xtreemtec. I speak Italian and I do not speak English well. in the last post I forgot to post in English.

No problem.. But this is an English only forum. ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostSun Oct 15, 2017 6:42 pm

work in progress :D
Attachments
Test10.jpg
Test10.jpg (266.07 KiB) Viewed 17265 times
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostSat Mar 24, 2018 1:45 pm

Hello everyone. I can not find the shutter command. I saw in the manual
Blackmagic_3G-SDI_Arduino_Shield_Manual.pdf without finding it.
Can anyone help me ?
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostSat Mar 24, 2018 2:41 pm

Camera manual page 227 http://documents.blackmagicdesign.com/C ... Manual.pdf

1.11 Shutter Angle
1.12 Shutter Speed
And keep in mind that you set 1.10 in 0 mode (Manual exposure instead of auto)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostSat Mar 24, 2018 4:15 pm

thank you very much for your reply.
Offline

JoshGarcia

  • Posts: 4
  • Joined: Tue Apr 03, 2018 9:14 pm
  • Real Name: Joshua Garcia

Re: Arduino Shield Thread

PostThu Apr 12, 2018 3:51 pm

Hi everybody. I was completely new to Arduino and C. I took some online courses and 3 months later I was able to complete version 1 of my controller. I used push buttons to change the parameters I set for different camera control. I want to change everything over to be controller via rotary encoder with push button. I Googled many different codes for rotary encoder with menus, but I can't seem to get them to work. If anybody could help me a small example of how you could send commands to the camera via rotary encoder that would be amazing. Anything to help me is appreciated. Until then I will continue to try and figure it out.
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostThu Apr 12, 2018 5:23 pm

Rotary encoders in Arduino are much harder to work with.. They depend on interrupts and you need some coding skills to understand how that works and how not to break your code by using them.. Not for the novice users.. ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostFri Apr 27, 2018 1:07 pm

Hello everyone

in an old post I asked for the shutter command and thanks to Xtreemtec who provided the documentation I tried to make the control.
but my camera does not respond to commands.

I have a Blackmagic Micro Studio Camera 4K
in the documentation provided on the site (Blackmagic_3G-SDI_Arduino_Shield_Manual.pdf) there is no Shutter Speed ​​and Exposure Mode command.

in the doubling (Blackmagic URSA Broadcast Manual.pdf) there are the commands.


so I tried this way

int cameraNumber = 1;

int8_t SetAutoExposureMode;

SetAutoExposureMode = 0;

cameraControl.writeCommandInt8 (
      cameraNumber, // Destination: Camera number
      1, // Category: Video
      10, // Param: Auto Exposure Mode
      0, // Operation: Set Absolute,
      SetAutoExposureMode // exposure mode
   );

const int ShutterSpeedValue [15] = {50, 60, 75, 90, 100, 120, 150, 180, 250, 360, 500, 725, 1000, 1450, 2000};

int32_t ShutterSpeedSendtoDevice;

ShutterSpeedSendtoDevice = ShutterSpeedValue [0]; // for 1/50

cameraControl.writeCommandInt32 (
      cameraNumber, // Destination: Camera number
      1, // Category: Video
      12, // Param: Shutter speed
      0, // Operation: Set Absolute,
      ShutterSpeedSendtoDevice // Shutter speed

   );

I tried but it does not work
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostSat Apr 28, 2018 9:25 pm

The 3G sdi shield docu is outdated Protocol v1.1 While we are at a higher version now.. ;)

Loose the 0 for absolute.. The index shows a "-" So i think the 0 for Absolute is misplaced.. 1,12,Shutterspeed i think that will be it looking at the manual..

Also be sure you have the latest FW running on the camera ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

Marco Monaldi

  • Posts: 9
  • Joined: Sun Sep 17, 2017 8:21 pm

Re: Arduino Shield Thread

PostThu May 03, 2018 4:32 pm

thank you Xtreemtec.
I found an update for the Blackmagic Micro Studio Camera 4K on the site.
Blackmagic Camera 4.7 Update
Can I install the latest version 5.0.1? I do not know if the latest version also includes the functions of 4.7.
I will try to install the 4.7 to see if I can remote the Shutter.
Thanks for your help.
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostMon May 07, 2018 3:05 pm

It will always install the latest available version on the camera. Even if it is 2 versions back of the current fw. (happens a lot to older Ursa models)

BMD almost always only add and improve functions.. Never pull out functions.. (or at least very rare to do so) ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

aislaih

  • Posts: 2
  • Joined: Fri Jul 06, 2018 1:31 pm
  • Real Name: Ahmed Islaih

Re: Arduino Shield Thread

PostFri Jul 06, 2018 2:03 pm

Hey there,

I'm trying to add the ability to control shutter speed with my Arduino shield I'm using a similar code to one of the projects that can be found in an earlier post (the one with an LCD display). My code displays all the shutter speed values on the LCD display. but for some reason it is not sending the data to the controller. I am pretty confident that I did everything the way I'm supposed to. I even updated My camera to the most recent version but I still have no idea why it's not working.

Any help or tips would be greatly appreciated!

PARTIAL CODE: (let me know if you require full code)

Code: Select all
// shutter speed
float                 shutterSpeedValueController = 1;
const float           shutterSpeedSensHigh = 0.1;
const float           shutterSpeedSensNormal = 0.05;
const float           shutterSpeedFloor = 0; // 50
const float           shutterSpeedTop = 14;  // 2000
const int32_t         shutterSpeedValues[15] = {50, 60, 75, 90, 100, 120, 150, 180, 250, 360, 500, 725, 1000, 1450, 2000};
int32_t               shutterSpeedValueSendToDevice;

..........

  if (getButtonStableEdge(button6Pin) == true && getButtonStableLevel(button6Pin) == LOW) {
    ModeSelect = 8;    // Shutter Speed
    ccMode = false;

    Serial.println("Mode8 detected");  // debug only
    DoParameterUpdateShutterSpeed();
    CheckDisplayClear();
  }


.............

case (8): // Shutter Speed
        Serial.println("ReadJoy > case 8");

        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          shutterSpeedValueController = shutterSpeedValueController + shutterSpeedSensHigh;
        }
        else if (currentJoystickY > 0) {
          shutterSpeedValueController = shutterSpeedValueController + shutterSpeedSensNormal;
        }
        else if (currentJoystickY < -80) {
          shutterSpeedValueController = shutterSpeedValueController - shutterSpeedSensHigh;
        }
        else if (currentJoystickY < 0) {
          shutterSpeedValueController = shutterSpeedValueController - shutterSpeedSensNormal;
        }

        // Don't allow the values to exceed the minimum/maximum
        shutterSpeedValueController = constrain(shutterSpeedValueController, shutterSpeedFloor, shutterSpeedTop);

        break;

................

case (8): //Shutter Speed
      Serial.println("CLICKED>>>>>>>>>");
      DoParameterUpdateShutterSpeed();
      break;

..............

void DoParameterUpdateShutterSpeed() {

  Serial.println("ParameterUpdate > case 8");

  shutterSpeedValueSendToDevice = shutterSpeedValues[round(shutterSpeedValueController)];

  sdiCameraControl.writeCommandInt32(
    cameraNumber,         // Destination:    Camera number
    1,                    // Category: Video
    12,                   // Param: Shutter speed
    0,                    // Operation: Set Absolute,
    shutterSpeedValueSendToDevice    // shutterSpeedValue
  );

  UpdateDisplay(5, "ShutterSpeed", shutterSpeedValueSendToDevice);

}


THANKS!!
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostWed Jul 11, 2018 10:55 am

UPDATE Arduino Shield Software Version 1.1 is released.
See link for more information>> https://www.blackmagicdesign.com/developer/product/arduino

@ Ahmed, Without the full code we can not check the issue. Reading trough the posted bits don't put a red flag up directly..
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

aislaih

  • Posts: 2
  • Joined: Fri Jul 06, 2018 1:31 pm
  • Real Name: Ahmed Islaih

Re: Arduino Shield Thread

PostMon Jul 16, 2018 3:54 pm

Thanks for the timely reply @Xtreemtec

I just updated my shield to the latest version. Thanks for the link :)
I still cannot seem to get the shutter speed values to send to the Camera. Everything else in the code works perfectly.

Here is the full code:

Code: Select all
#include <BMDSDIControl.h>
#include <LiquidCrystal_I2C.h>
#include <math.h>
#include <Wire.h>

/**
  Blackmagic Design 3G-SDI Shield Sketch
  Joystick control - JAHA 2017-05-05

  This sketch controls a BMD cam via a BMD 3G-SDI shield,
  which supports a SKAARHOJ joystick&buttons PCB and controls a SDI-connected BMD-camera.

  The three buttons are mapped as follows:
  - Button 1, which selects WB-mode
  - Button 2, which selects and cycles through black/gamma/gain adj modes
  - Button 3, which selects focus-mode on the camera
  - Button 4, which switches between 3 frame rates
  - Button 5, which switches between 8 camera numbers

  The joystick is mapped as follows:
  - X axis adjusts the mode X parameter
  - Y axis adjusts the mode Y parameter
  - Pressing the Joystick resets all correction parameters.
*/



// LCD pin mappings

//const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
//LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE );

//LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

// Hardware pin mappings
const int             joystickButtonPin = A0;
const int             joystickXPin = A1;
const int             joystickYPin = A2;
const int             button1Pin = 2;
const int             button2Pin = 3;
const int             button3Pin = 4;
const int             button4Pin = 5;
const int             button5Pin = 6;
const int             button6Pin = 7;

// Blackmagic Design SDI control shield globals
const int                 shieldAddress = 0x6E;
BMD_SDITallyControl_I2C   sdiTallyControl(shieldAddress);
BMD_SDICameraControl_I2C  sdiCameraControl(shieldAddress);

// Button debouncing globals
unsigned long         lastStableButtonTime[32];
int                   rawButtonLevels[32];
int                   stableButtonLevels[32];

// Joystick sample rate limiter globals
unsigned long         lastJoystickUpdateTime;

// Global joystick detection parameters
int                   currentJoystickX = 0;
int                   currentJoystickY = 0;

// Camera parameter adjustment-state, globals
// Manual WhiteBalance
float                 manualWbValueController = 6; //4000
const float           manualWbValueSensHigh = 0.2;  // joy max deflection adjust
const float           manualWbValueSensNormal = 0.05;  // joy normal deflection adjust
const float           manualWbFloor = 0; // 2500
const float           manualWbTop = 17;  // 8000
const int16_t         manualWbValues[18] = { 2500, 2800, 3000, 3200, 3400, 3600, 4000, 4500, 4800, 5000, 5200, 5400, 5600, 6000, 6500, 7000, 7500, 8000 };
int16_t               manualWbValueSendToDevice;

// Lift/Blacklevel
float                 liftValue = 0;
const float           liftValueSensHigh = 0.005;
const float           liftValueSensNormal = 0.001;
float                 liftValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           liftFloor = -2;
const float           liftTop = 2;

// Gamma
float                 gammaValue = 0;
const float           gammaValueSensHigh = 0.005;
const float           gammaValueSensNormal = 0.001;
float                 gammaValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           gammaFloor = -4;
const float           gammaTop = 4;

// Gain
float                 gainValue = 1;
const float           gainValueSensHigh = 0.03;
const float           gainValueSensNormal = 0.01;
float                 gainValueArray[4] = { 0.0, 0.0, 0.0, 0.0 };
const float           gainFloor = 0;
const float           gainTop = 16;

// MasterGain
float                 masterGainValueController = 1.0;
const float           masterGainSensHigh = 0.1;
const float           masterGainSensNormal = 0.05;
const int             masterGainValues[5] = { 1, 2, 4, 8, 16 };  // gain x1, x2, x4, x8, x16
const int             masterGainFloor = 0; //x1
const int             masterGainTop = 4;   //x16
int                   masterGainSendToDevice;

// dimention
float                 dimentionValueController = 1.0;
const float           mdimentionSensHigh = 0.1;
const float           dimentionSensNormal = 0.05;
const int             dimentionValues[2] = { 1080, 4 };  // gain x1, x2, x4, x8, x16
const int             dimentionFloor = 0; //x1
const int             dimentionTop = 4;   //x16
int                   dimentionSendToDevice;

//frame rate
int rate = 0;
int d = 3;
int fr = 30;

// Camera#
int cameraNumber;
int camNum;

// Focus
float                 focusValue = 0.5;
const float           focusValueSensHigh = 0.01;
const float           focusValueSensNormal = 0.002;
const float           focusFloor = 0.0;
const float           focusTop = 1.0;

// shutter speed
float                 shutterSpeedValueController = 1;
const float           shutterSpeedSensHigh = 0.1;
const float           shutterSpeedSensNormal = 0.05;
const float           shutterSpeedFloor = 0; // 50
const float           shutterSpeedTop = 14;  // 2000
const int32_t         shutterSpeedValues[15] = {50, 60, 75, 90, 100, 120, 150, 180, 250, 360, 500, 725, 1000, 1450, 2000};
int32_t               shutterSpeedValueSendToDevice;

// ModeSelect - global parameter, determines operation-mode
// 1 - Whitebalance
// 2 - Lift (CC) & mastergain
// 3 - Gamma (CC) & mastergain
// 4 - Gain (CC) & mastergain
// 5 - Focus
int ModeSelect = 0;   // current mode
int previousMode = 0; // previous mode

// ColorCorrection-mode
int                   currentCCMode = 1;       // current ColorCorrectionMode: Lift, Gamma, Gain
bool                  ccMode;               // flag true if CCmode is active

void setup() {

  Serial.begin(9600);
  Serial.println("startup");

  lcd.begin(20, 4);
  lcd.setCursor(0, 0);
  lcd.print("CCU controller");

  // Configure digital inputs
  pinMode(joystickButtonPin, INPUT_PULLUP);
  pinMode(button1Pin, INPUT_PULLUP);
  pinMode(button2Pin, INPUT_PULLUP);
  pinMode(button3Pin, INPUT_PULLUP);
  pinMode(button4Pin, INPUT_PULLUP);
  pinMode(button5Pin, INPUT_PULLUP);
  pinMode(button6Pin, INPUT_PULLUP);
  //
  //   // Set up the BMD SDI control library
  sdiTallyControl.begin();
  sdiCameraControl.begin();
  //
  //   // The shield supports up to 400KHz, use faster
  //   // I2C speed to reduce latency
  Wire.setClock(400000);
  //
  //   // Enable both tally and control overrides
  sdiTallyControl.setOverride(true);
  sdiCameraControl.setOverride(true);
  //
  //   // reset camera to defaults
  DoParameterUpdateResetAll();
  //
  //   // display welcome message
  lcd.setCursor(0, 0);
  lcd.print("CCU controller");
}

void loop() {

  DetectOperationMode();
  ReadJoystickInput();
  DoParameterUpdate();

}

void DetectOperationMode() {

  // Detect button1 - WhiteBalance

  if (getButtonStableEdge(button1Pin) == true && getButtonStableLevel(button1Pin) == LOW) {
    // When the button is low (pressed) the WB-mode is activated
    ModeSelect = 1;
    ccMode = false;

    Serial.println("Mode1 detected"); //debug only

    CheckDisplayClear();
  }



  // Detect button2, cycle through black/gamma/gain adjustment modes
  if (getButtonStableEdge(button2Pin) == true && getButtonStableLevel(button2Pin) == LOW) {
    // detect if we should step to next cc-mode
    if (ccMode) {
      currentCCMode = currentCCMode + 1;
      if (currentCCMode > 3)
        currentCCMode = 1;
    }
    ccMode = true;

    if (currentCCMode == 1) {
      ModeSelect = 2;   // Lift
    }
    else if (currentCCMode == 2) {
      ModeSelect = 3;   // Gamma
    }
    else if (currentCCMode == 3) {
      ModeSelect = 4;        // Gain
    }


    Serial.println("Mode2, 3 or 4 detected");  // debug only
    Serial.println(ModeSelect);

    CheckDisplayClear();
  }



  // Detect button3, select focus mode
  if (getButtonStableEdge(button3Pin) == true && getButtonStableLevel(button3Pin) == LOW) {
    ModeSelect = 5;    // Focus
    ccMode = false;

    Serial.println("Mode5 detected");  // debug only

    CheckDisplayClear();
  }

  if (getButtonStableEdge(button4Pin) == true && getButtonStableLevel(button4Pin) == LOW) {
    ModeSelect = 6;    // FrameRate
    ccMode = false;

    Serial.println("Mode6 detected");  // debug only
    DoParameterUpdateFrameRate();
    CheckDisplayClear();
  }

  if (getButtonStableEdge(button5Pin) == true && getButtonStableLevel(button5Pin) == LOW) {
    ModeSelect = 7;    // FrameRate
    ccMode = false;

    Serial.println("Mode7 detected");  // debug only
    DoParameterUpdateCameraNumber();
    CheckDisplayClear();
  }

  if (getButtonStableEdge(button6Pin) == true && getButtonStableLevel(button6Pin) == LOW) {
    ModeSelect = 8;    // FrameRate
    ccMode = false;

    Serial.println("Mode8 detected");  // debug only
    DoParameterUpdateShutterSpeed();
    CheckDisplayClear();
  }


  // If the reset button is pressed, clear all color correction values
  if (getButtonStableEdge(joystickButtonPin) == true && getButtonStableLevel(joystickButtonPin) == LOW) {
    DoParameterUpdateResetAll();
    Serial.println("Reset detected");
  }
}

void ReadJoystickInput() {
  if (getJoystickUpdateReady() == true) {

    switch (ModeSelect) {

      case (0): // ignore
        break;

      case (1): // Whitebalance
        Serial.println("ReadJoy > case 1");

        // joystick Y = whitebalance K
        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          manualWbValueController = manualWbValueController + manualWbValueSensHigh; // using wb sensitivity-constant
        }
        else if (currentJoystickY > 0) {
          manualWbValueController = manualWbValueController + manualWbValueSensNormal;
        }
        else if (currentJoystickY < -80) {
          manualWbValueController = manualWbValueController - manualWbValueSensHigh;
        }
        else if (currentJoystickY < 0) {
          manualWbValueController = manualWbValueController - manualWbValueSensNormal;
        }

        // Don't allow the values to exceed the minimum/maximum
        manualWbValueController = constrain(manualWbValueController, manualWbFloor, manualWbTop);

        break;


      case (2): // CC Lift
        Serial.println("ReadJoy > case 2");

        // joystick Y = lift
        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          liftValue = liftValue + liftValueSensHigh; // using lift sensitivity-constant
        }
        else if (currentJoystickY > 0) {
          liftValue = liftValue + liftValueSensNormal;
        }
        else if (currentJoystickY < -80) {
          liftValue = liftValue - liftValueSensHigh;
        }
        else if (currentJoystickY < 0) {
          liftValue = liftValue - liftValueSensNormal;
        }

        ReadJoystickInputMasterGain();

        // Don't allow the values to exceed the minimum/maximum
        liftValue = constrain(liftValue, liftFloor, liftTop);

        break;


      case (3): // CC Gamma
        Serial.println("ReadJoy > case 3");

        // joystick Y = gamma
        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          gammaValue = gammaValue + gammaValueSensHigh; // using gamma sensitivity-constant
        }
        else if (currentJoystickY > 0) {
          gammaValue = gammaValue + gammaValueSensNormal;
        }
        else if (currentJoystickY < -80) {
          gammaValue = gammaValue - gammaValueSensHigh;
        }
        else if (currentJoystickY < 0) {
          gammaValue = gammaValue - gammaValueSensNormal;
        }

        ReadJoystickInputMasterGain();

        // Don't allow the values to exceed the minimum/maximum
        gammaValue = constrain(gammaValue, gammaFloor, gammaTop);

        break;


      case (4): // CC Gain
        Serial.println("ReadJoy > case 4");

        // joystick Y = gain
        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          gainValue = gainValue + gainValueSensHigh; // use gain sensitivity-constant
        }
        else if (currentJoystickY > 0) {
          gainValue = gainValue + gainValueSensNormal;
        }
        else if (currentJoystickY < -80) {
          gainValue = gainValue - gainValueSensHigh;
        }
        else if (currentJoystickY < 0) {
          gainValue = gainValue - gainValueSensNormal;
        }

        ReadJoystickInputMasterGain();

        // Don't allow the values to exceed the minimum/maximum
        gainValue = constrain(gainValue, gainFloor, gainTop);

        break;


      case (5): // Focus
        Serial.println("ReadJoy > case 5");

        // joystick Y
        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          focusValue = focusValue + focusValueSensHigh; // use focus sensitivity-constant
        }
        else if (currentJoystickY > 0) {
          focusValue = focusValue + focusValueSensNormal;
        }
        else if (currentJoystickY < -80) {
          focusValue = focusValue - focusValueSensHigh;
        }
        else if (currentJoystickY < 0) {
          focusValue = focusValue - focusValueSensNormal;
        }

        // Don't allow the values to exceed the minimum/maximum
        focusValue = constrain(focusValue, focusFloor, focusTop);
        break;

      case (6): // ignore
        break;

      case (7): // ignore
        break;

      case (8): // Shutter Speed
        Serial.println("ReadJoy > case 8");

        currentJoystickY = getJoystickAxisPercent(joystickYPin);
        if (currentJoystickY > 80) {
          shutterSpeedValueController = shutterSpeedValueController + shutterSpeedSensHigh;
        }
        else if (currentJoystickY > 0) {
          shutterSpeedValueController = shutterSpeedValueController + shutterSpeedSensNormal;
        }
        else if (currentJoystickY < -80) {
          shutterSpeedValueController = shutterSpeedValueController - shutterSpeedSensHigh;
        }
        else if (currentJoystickY < 0) {
          shutterSpeedValueController = shutterSpeedValueController - shutterSpeedSensNormal;
        }

        // Don't allow the values to exceed the minimum/maximum
        shutterSpeedValueController = constrain(shutterSpeedValueController, shutterSpeedFloor, shutterSpeedTop);

        break;

    }
  }
}

void ReadJoystickInputMasterGain() {

  // joystick X = masterGain
  currentJoystickX = getJoystickAxisPercent(joystickXPin);
  if (currentJoystickX > 80) {
    masterGainValueController = masterGainValueController + masterGainSensHigh;
  }
  else if (currentJoystickX > 0) {
    masterGainValueController = masterGainValueController + masterGainSensNormal;
  }
  else if (currentJoystickX < -80) {
    masterGainValueController = masterGainValueController - masterGainSensHigh;
  }
  else if (currentJoystickX < 0) {
    masterGainValueController = masterGainValueController - masterGainSensNormal;
  }

  // Don't allow the values to exceed the minimum/maximum
  masterGainValueController = constrain(masterGainValueController, masterGainFloor, masterGainTop);
}

void DoParameterUpdate() {
  // Send new parameter adjustment to the camera

  switch (ModeSelect) {

    case (0): // ignore
      break;

    case (1): // Whitebalance
      // joystick Y (manualWbValue)

      DoParameterUpdateWhiteBalance();

      break;

    case (2): // CC Lift
      // joystick Y = lift (liftValue)
      // joystick X = masterGain

      DoParameterUpdateLift();
      DoParameterUpdateMasterGain();

      break;

    case (3): // CC Gamma
      // joystick Y = gamma
      // joystick X = masterGain

      DoParameterUpdateGamma();
      DoParameterUpdateMasterGain();

      break;

    case (4): // CC Gain
      // joystick Y = gain
      // joystick X = masterGain

      DoParameterUpdateGain();
      DoParameterUpdateMasterGain();

      break;

    case (5): // Focus
      // joystick X
      DoParameterUpdateFocus();

      break;

    case (6): //Do nothing
      break;

    case (7): //Do nothing
      break;

    case (8): //Shutter Speed
      Serial.println("CLICKED>>>>>>>>>");
      DoParameterUpdateShutterSpeed();
      break;
  }
}

void DoParameterUpdateWhiteBalance() {

  Serial.println("ParameterUpdate > case 1");

  manualWbValueSendToDevice = manualWbValues[round(manualWbValueController)];

  sdiCameraControl.writeCommandInt16(
    cameraNumber,         // Destination:    Camera number
    1,                    // Category:       Video
    2,                    // Param:          White balance
    0,                    // Operation:      Set Absolute,
    manualWbValueSendToDevice    // manualWbValue
  );

  UpdateDisplay(5, "WhiteBalance", manualWbValueSendToDevice);
}

void DoParameterUpdateLift() {
  Serial.println("ParameterUpdate > Lift");

  liftValueArray[0] = liftValue;
  liftValueArray[1] = liftValue;
  liftValueArray[2] = liftValue;
  liftValueArray[3] = liftValue;

  // set lift values
  sdiCameraControl.writeCommandFixed16(
    cameraNumber,         // Destination:    Camera number
    8,                    // Category:       Color Correction
    0,                    // Param:          Offset Adjust
    0,                    // Operation:      Set Absolute,
    liftValueArray        // lift values
  );

  UpdateDisplay(5, "Black", liftValue);
}

void DoParameterUpdateGamma() {
  Serial.println("ParameterUpdate > Gamma");

  gammaValueArray[0] = gammaValue;
  gammaValueArray[1] = gammaValue;
  gammaValueArray[2] = gammaValue;
  gammaValueArray[3] = gammaValue;

  // set gamma values
  sdiCameraControl.writeCommandFixed16(
    cameraNumber,         // Destination:    Camera number
    8,                    // Category:       Color Correction
    1,                    // Param:          Gamma adjust
    0,                    // Operation:      Set Absolute,
    gammaValueArray       // gamma value
  );

  UpdateDisplay(5, "Gamma", gammaValue);
}

void DoParameterUpdateGain() {
  Serial.println("ParameterUpdate > Gain");

  gainValueArray[0] = gainValue;
  gainValueArray[1] = gainValue;
  gainValueArray[2] = gainValue;
  gainValueArray[3] = gainValue;

  // set gain values
  sdiCameraControl.writeCommandFixed16(
    cameraNumber,         // Destination:    Camera number
    8,                    // Category:       Color Correction
    2,                    // Param:          Gain adjust
    0,                    // Operation:      Set Absolute,
    gainValueArray        // gain value
  );

  UpdateDisplay(5, "Gain", gainValue);
}

void DoParameterUpdateFocus() {
  Serial.println("ParameterUpdate > focus");

  // set focus values
  sdiCameraControl.writeCommandFixed16(
    cameraNumber,         // Destination:    Camera number
    0,                    // Category:       Lens
    0,                    // Param:          Focus
    0,                    // Operation:      Set Absolute,
    focusValue            // focus value
  );

  UpdateDisplay(1, "Focus", focusValue);
  UpdateDisplay(3, "", focusValue);

}

void DoParameterUpdateResetAll() {
  // Reset color correction

  for (int i = 0; i < 10; i++) {
    Serial.println("Reset camera parameters");  // looping to increase readability in serial-monitor
  }

  manualWbValueController = 6; //4000K
  shutterSpeedValueController = 1;
  liftValue = 0.02;
  gammaValue = 0.15;
  gainValue = 1.4;
  focusValue = 0.52;
  masterGainValueController = 3;
  d = 3;
  fr = 30;
 
  //
  DoParameterUpdateWhiteBalance();
  DoParameterUpdateLift();
  DoParameterUpdateGamma();
  DoParameterUpdateGain();
  DoParameterUpdateMasterGain();
  DoParameterUpdateFocus();
  DoParameterUpdateShutterSpeed();
  DoParameterUpdateFrameRate();
  lcd.clear();
  delay(200);

  /*
    // Reset all color correction parameters in the camera
    sdiCameraControl.writeCommandVoid(
    cameraNumber,        // Destination:    Camera
    8,                   // Category:       Color Correction
    7                    // Param:          Reset Defaults
    );

    // Request auto-iris adjustment in the camera
    sdiCameraControl.writeCommandVoid(
    cameraNumber,        // Destination:    Camera
    0,                   // Category:       Lens
    5                    // Param:          Auto Iris
    );
  */
}

void DoParameterUpdateMasterGain() {

  masterGainSendToDevice = masterGainValues[round(masterGainValueController)];

  sdiCameraControl.writeCommandInt8(
    cameraNumber,         // Destination:    Camera number
    1,                    // Category:       Video
    1,                    // Param:          Sensor gain
    0,                    // Operation:      Set Absolute,
    masterGainSendToDevice       // masterGainValue
  );

  UpdateDisplay(6, "mGain", masterGainSendToDevice);
}



void checkRate(int r) {
  if (r > 2) {
    rate = 0;
  }
}

void DoParameterUpdateFrameRate() {
  Serial.print("rate=   ");
  Serial.println(rate);

  switch (rate) {

    case (0): //
      {
        d = 3;
        fr = 30;
        UpdateDisplay(1, "fRate", 0.0);
        UpdateDisplay(3, "1080p   30fps", 0.0);
        ++rate;
        checkRate(rate);
        break;
      }
    case (1): //
      d = 3;
      fr = 60;
      UpdateDisplay(1, "fRate", 90000);
      UpdateDisplay(3, "1080p   60fps", 900);
      ++rate;
      checkRate(rate);
      break;

    case (2): //
      d = 6;
      fr = 30;
      UpdateDisplay(1, "fRate", 90000);
      UpdateDisplay(3, "4K   30fps     ", 900);
      ++rate;
      checkRate(rate);
      break;

      //    case (3): //
      //      d = 6;
      //      fr = 60;
      //      UpdateDisplay(1, "fRate", 90000);
      //      UpdateDisplay(3, "4K   60fps      ", 900);
      //      ++rate;
      //      checkRate(rate);
      //      break;

  }
  int8_t settings[] =
  {
    fr, // Frame rate 50
    0, // M-Rate Regular
    d, // Dimensions UHD
    0, // Progressive
    0 // Color Space YUV
  };


  sdiCameraControl.writeCommandInt8(
    cameraNumber, // Camera 1
    1, // Catergory Video
    0, // Param Video Mode
    0, // Operation: Assign Value
    settings
  );

}

void checkCamNum(int c) {
  if (c > 7) {
    camNum = 0;
  }
}

void DoParameterUpdateCameraNumber() {
  Serial.print("Cam# ");
  Serial.println(camNum);

  switch (camNum) {

    case (0): //
      {
        cameraNumber = 1;
        UpdateDisplay(7, "Cam# ", cameraNumber);
        ++camNum;
        checkCamNum(camNum);
        break;
      }
    case (1): //
      cameraNumber = 2;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (2): //
      cameraNumber = 3;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (3): //
      cameraNumber = 4;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (4): //
      cameraNumber = 5;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (5): //
      cameraNumber = 6;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (6): //
      cameraNumber = 7;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

    case (7): //
      cameraNumber = 8;
      UpdateDisplay(7, "Cam# ", cameraNumber);
      ++camNum;
      checkCamNum(camNum);
      break;

  }
}

void DoParameterUpdateShutterSpeed() {

  Serial.println("ParameterUpdate > case 8");

  shutterSpeedValueSendToDevice = shutterSpeedValues[round(shutterSpeedValueController)];

  sdiCameraControl.writeCommandInt32(
    cameraNumber,         // Destination:    Camera number
    1,                    // Category: Video
    12,                   // Param: Shutter speed
    0,                    // Operation: Set Absolute,
    shutterSpeedValueSendToDevice    // shutterSpeedValue
  );

  UpdateDisplay(5, "ShutterSpeed", shutterSpeedValueSendToDevice);
 

 ////_____________________________/////////
 
//  cameraControl.writeCommandInt32 (
//    cameraNumber, // Destination: Camera number
//    1, // Category: Video
//    12, // Param: Shutter speed
//    0, // Operation: Set Absolute,
//    ShutterSpeedSendtoDevice // Shutter speed
//
//  );
}


bool getJoystickUpdateReady() {
  // Determines if we are ready for another joystick update (this is
  // a rate limiter to ensure that the user can slowly adjust the
  // parameters easily with the joystick)

  unsigned long currentTime = millis();
  if ((lastJoystickUpdateTime - currentTime) > 100) {
    lastJoystickUpdateTime = currentTime;
    return true;
  }

  return false;
}

int getJoystickAxisPercent(int analogPin) {
  // Reads the joystick axis on the given analog pin as a [-100 - 100] scaled value

  int rawAnalogValue = analogRead(analogPin);
  int scaledAnalogValue = map(rawAnalogValue, 0, 1023, -100, 100);

  // Consider values close to zero as zero, so that when the joystick is
  // centered it reports zero even if it is slightly mis-aligned
  if (abs(scaledAnalogValue) < 10) {
    scaledAnalogValue = 0;
  }

  return scaledAnalogValue;
}

bool getButtonStableEdge(int digitalPin) {
  // Detects debounced edges (i.e. presses and releases) of a button

  bool previousLevel = stableButtonLevels[digitalPin];
  bool newLevel = getButtonStableLevel(digitalPin);

  return previousLevel != newLevel;
}

int getButtonStableLevel(int digitalPin) {
  // Reads a digital pin and filters it, returning the stable button position

  int           pinLevel = digitalRead(digitalPin);
  unsigned long currentTime = millis();

  // If the button is rapidly changing (bouncing) during a press, keep
  // resetting the last stable time count
  if (pinLevel != rawButtonLevels[digitalPin]) {
    lastStableButtonTime[digitalPin] = currentTime;
    rawButtonLevels[digitalPin] = pinLevel;
  }

  // Once the button has been stable for
  if ((currentTime - lastStableButtonTime[digitalPin]) > 20) {
    stableButtonLevels[digitalPin] = pinLevel;
  }

  return stableButtonLevels[digitalPin];
}

void UpdateDisplay(int _position, char _text[], float _value) {
  // split lcd-display into 6 areas:
  // upper-left = 1
  // upper-right = 2
  // lower-left = 3
  // lower-right = 4
  // left upper+lower = 5
  // right upper+lower = 6

  if (_position <= 0 || _position > 7) {
    Serial.print("lcd-position out of bounds");
    return;
  }

  // /*
  Serial.print(_text);
  Serial.print(" ");
  Serial.println(_value);
  // */

  switch (_position) {

    case (1): // row = 0, column = 0, upper left
      lcd.setCursor(0, 0);
      if (_text == "") {
        lcd.print(_value);
      }
      else {
        lcd.print(_text);
      }

      break;

    case (2): // row = 7, column = 0, upper right
      lcd.setCursor(7, 0);
      if (_text == "") {
        lcd.print(_value);
      }
      else {
        lcd.print(_text);
      }

      break;

    case (3): // row = 0, column = 1, lower left
      lcd.setCursor(0, 1);
      if (_text == "") {
        lcd.print(_value);
      }
      else {
        lcd.print(_text);
      }

      break;

    case (4): // row = 7, column = 1, lower right
      lcd.setCursor(7, 1);
      if (_text == "") {
        lcd.print(_value);
      }
      else {
        lcd.print(_text);
      }

      break;

    case (5): // text + value, left part of lcd
      lcd.setCursor(0, 0);
      lcd.print(_text);
      lcd.setCursor(0, 1);
      lcd.print(_value);
      break;

    case (6): // text + value, right part of lcd
      lcd.setCursor(7, 0);
      lcd.print(_text);
      lcd.setCursor(7, 1);
      lcd.print(_value);
      break;

    case (7): // text + value, right part of lcd
      lcd.setCursor(0, 2);
      lcd.print(_text);
      lcd.setCursor(0, 3);
      lcd.print((int)_value);
      break;
  }
}

void CheckDisplayClear() {
  if (previousMode != ModeSelect) {
    lcd.clear();
    delay(200);
    Serial.print("CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR CLEAR");
  }
  previousMode = ModeSelect;
}


[img]
20180716_115021.jpg
20180716_115021.jpg (908.05 KiB) Viewed 13582 times

[/img]

Any help would be greatly appreciated.

Thanks.
Offline

JoshGarcia

  • Posts: 4
  • Joined: Tue Apr 03, 2018 9:14 pm
  • Real Name: Joshua Garcia

Re: Arduino Shield Thread

PostThu Jul 19, 2018 9:52 pm

Hi all,

I'm trying to control the Recorded Channel 1 and Recorded Channel 2 levels in the audio menu on a URSA Broadcast. From what I can tell it looks like I should be writing the code to change the input levels under the audio parameter (sdiCameraControl.writeCommandFixed16(1, 2, 5, 0, val)). I wrote that code, and it seems to work fine on a Micro Studio 4k, but nothing changes on the URSA. There is no other parameter under the audio section that looks like it would work. I'm wondering if this is something that can be controlled on the URSA. Hopefully somebody can shed some light on this. Thanks in advance.
Offline

Denny Smith

  • Posts: 13131
  • Joined: Thu Aug 01, 2013 4:19 pm
  • Location: USA, Northern Calif.

Re: Arduino Shield Thread

PostSun Jul 22, 2018 1:05 am

I do not think the audio levels can be controlled remotely on the Ursa Broadcast. The Micro Studio has SBus control of the audio when using the camera mic Ir an external mic, but not lone inputs.
The Broadcast audio levels can be controlled from the camera on the Mic Oreamps, but not the line level, which goes to Unity when Line inout is selected.
Cheers
Denny Smith
SHA Productions
Offline

JepperTV

  • Posts: 3
  • Joined: Wed Jan 30, 2019 11:47 pm
  • Real Name: Christopher Jepsen

Re: Arduino Shield Thread

PostWed Feb 20, 2019 12:48 am

Hello,

I am trying to use the 3G SDI shield to manually Tally all four quadrants on a Multiview 4.
I figured out how to modify the "All Blink" test sketch so that all four tallies blink at the same time.
Now I need to figure out how to trigger that same quad tally with the flip of a dry switch.
Any help with the code and the wiring would be much appreciated.


Thank you!
Chris
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostWed Feb 20, 2019 4:32 pm

Hi Chris,
I posted a code for this in this exact topic.
Here is the link. Have fun> viewtopic.php?f=4&t=48175#p325706
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
Offline

JepperTV

  • Posts: 3
  • Joined: Wed Jan 30, 2019 11:47 pm
  • Real Name: Christopher Jepsen

Re: Arduino Shield Thread

PostWed Feb 20, 2019 6:31 pm

Thank you Xtreemtec!

I had read that post but wasn't sure it was what I needed.

Does this code refer to each pin number that gets pulled to ground?
And if so, are they digital pins or analog?

Code: Select all
int PGM1 = 2;
int PRV1 = 3;

int PGM2 = 4;
int PRV2 = 5;

int PGM3 = 6;
int PRV3 = 7;

int PGM4 = 8;
int PRV4 = 9;




Thank you,
Chris
Offline

JepperTV

  • Posts: 3
  • Joined: Wed Jan 30, 2019 11:47 pm
  • Real Name: Christopher Jepsen

Re: Arduino Shield Thread

PostWed Feb 20, 2019 7:49 pm

Figured it out...digital pins.

Works like a charm!

Thank You!!
Offline
User avatar

Xtreemtec

  • Posts: 5387
  • Joined: Wed Jan 02, 2013 11:48 am
  • Location: The Netherlands

Re: Arduino Shield Thread

PostWed Feb 20, 2019 8:20 pm

The numbers are the Arduino pin numbers. As labeled on the Arduino.
Image

These are digital pins, And pull up in the processor is turned on. So when you make a connection from pin 2 (PGM1) to GND The red square will appear in Window 1.
if you make a connection between pin 7 and ground Green box will appear on window 3. :)

I see i have 1 small add on to this code.
Code: Select all
sdiTallyControl.setCameraTally( 4, ( !digitalRead(PGM4)) , ( !digitalRead(PRV4)) );


Add this line below the others. Otherwise channel 4 wont go ;)
Daniel Wittenaar .:: Xtreemtec Media Productions ::. -= www.xtreemtec.nl =-
4K OBV Trailer, ATEM TVS HD, 4M/E Broadcast Studio 4K, Constelation 8K, Hyperdeck Studio 12G, Ursa Broadcast 4K, 4K fiber converters with Sony Control
PreviousNext

Return to Live Production

Who is online

Users browsing this forum: No registered users and 24 guests