Using Arduino as an input trigger to PowerShell

preview

I have previously blogged about using the Arduino as an I/O device to set the output pins to drive camera tally lights.

PowerShell can also read the input status of pins on the Arduino using the Solid.Arduino .Net library.

This is an example of using the Arduino to detect the monitor switch on camera RCP units so that you can switch the signal to a scope or monitor.

I have used this for both Sony RCP-1500 and Panasonic AK-HRP200 RCP’s which provide dry contact closures on monitor selection.

The code is very simple and sets up an event to wait for input pin status changes on the Arduino…


add-type -path '.\Documents\WindowsPowerShell\Solid.Arduino.dll'
$connection = New-Object Solid.Arduino.SerialConnection("COM4",[Solid.Arduino.SerialBaudRate]::Bps_57600)
$session = New-Object Solid.Arduino.ArduinoSession($connection, 2000)
$session.SetDigitalPinMode(4,[Solid.Arduino.Firmata.PinMode]::DigitalInput)
#
# Define the function that is called when a digitial pin event happens
#
function inputevent($event){
    #Write-Host "Something happened on port $($event.value.port) Type $($event.value.pins)"
    if($event.value.pins -band 4) #using binary AND incase multiple inputs are activated
    {
        # put code here to switch ATEM Aux or VideoHub routing
        Write-host "Cam 1 preview selected"
    }
}
#
# set up the event to montor digital pin state change
#
$session.SetDigitalReportMode(0,$true) #enable events for pins on port 0
Unregister-Event -SourceIdentifier eventBitChange #incase we are re-running the script
$ArduinoEvent = Register-ObjectEvent -InputObject $session -EventName DigitalStateReceived -SourceIdentifier eventBitChange -Action {inputevent($eventArgs)}

Blackmagic Decklink Device Information from PowerShell Script

decklinkautomation

I have started working on a providing control of Blackmagic Design Decklink cards from Windows PowerShell scripts.

Just at the initial stage of being able to read the configuration of cards connected to the PC.

Updated: Can now set some card options also. Use $Devices | Get-Member
To find the methods and properties. $devices[0].
Will give you more options for the first device detected.

Example script:

$VideoConnections = @{1 = "SDI"; 2 = "HDMI"; 4 = "Optical SDI"; 8 = "Component"; 16 = "Composit"; 32 = "S-Video" }
$AudioConnections = @{1 = "Embedded" ; 2 = "AESEBU" ; 4 = "Analog"; 8 = "Analog XLR"; 16 = "Analog RCA"; 32 = "Microsophone"; 64 = "Headphones"}
$VideoIOSupport = @{1 = "Capture"; 2 = "Playback"}
add-type -path '\Documents\WindowsPowerShell\decklink.dll'
$cards = new-object VISE_DeckLink.DeckLink
$Devices = $cards.DeckLinkDevices()
write-host "Number of devices detected: $($Devices.Count)"
$devices
foreach ($device in $Devices){
    write-host "$($device.DisplayName)" -ForegroundColor red -BackgroundColor white
    Write-host " IO Support:"
    $VideoIOSupport.Keys | where { $_ -band $device.VideoIOSupport } | foreach { $VideoIOSupport.Get_Item($_)} 
    Write-host " Input Video Connections:"
    $VideoConnections.Keys | where { $_ -band $device.VideoInputConnections } | foreach { $VideoConnections.Get_Item($_)}
    Write-host " Input Audio Connections:"
    $AudioConnections.Keys | where { $_ -band $device.AudioInputConnections } | foreach { $AudioConnections.Get_Item($_)}
    Write-host " Output Video Connections:"
    $VideoConnections.Keys | where { $_ -band $device.VideoOutputConnections } | foreach { $VideoConnections.Get_Item($_)}
    Write-host " Output Audio Connections:"
    $AudioConnections.Keys | where { $_ -band $device.AudioOutputConnections } | foreach { $AudioConnections.Get_Item($_)}

Write-host ""
}

Here is an example the output.

decklinkconfig

Download the decklink.dll file from here https://1drv.ms/u/s!ApGpqMMpRLhijeR1-4SVgqdytAUhmg

Use a Dark PowerShell ISE Theme in Video Production Environment

111116_2128_UseaDarkPow2.png

I use the PowerShell ISE in a lot of dimly lit places and it can be a bit disconcerting to have a very bright computer screen to look at when you are in a dark room.

The default ISE shell supports themes. You can chance to a dark theme from

Which will change the UI to this:

You can also import themes from the Manage Themes dialog box. Here is a nice one I found on GitHub https://github.com/perplexityjeff/PowerShell-ISE-Solarized-Theme

Control Hyperdeck via ATEM with PowerShell script

SwitcherLib now supports Blackmagic Hyperdeck control (version 2.9).

Everything but media file details has been implemented.

Full list of features:
hyperdeckfeatures

Example PowerShell:

add-type -path ‘C:\Users\ian\Documents\WindowsPowerShell\SwitcherLib.dll
$Global:atem = New-Object SwitcherLib.Switcher(“192.168.0.240”)
$atem.Connect()
$HyperDeck=$atem.GetHyperdecks()
$HyperDeck.Capacity
$HyperDeck[0].NetworkAddress
$HyperDeck[0].RemoteAccessEnabled
$HyperDeck[0].Play()
start-sleep 5
$HyperDeck[0].stop()
$HyperDeck[0].CurrentClipTime
Start-Sleep 5
$HyperDeck[0].CurrentClipTime = “00:02:00:25”
start-sleep 5
$HyperDeck[0].Jog(500) #jump 5 seconds (50p)
start-sleep 5
$HyperDeck[0].CurrentClip=1
$HyperDeck[0].Play()
start-sleep 5
$HyperDeck[0].stop()
$HyperDeck[0].CurrentClipTime
$HyperDeck[0].CurrentTimelineTime #time from start of clip 0

 

Control ATEM Multi view layout with PowerShell

multiview

I have updated SwitcherLib.dll to support configuration of the multi view properties.

Example code:


$mv=$atem.GetMultiViews()
$mv.count
$mv[0].Layout
$mv[0].CanRouteInputs
$mv[0].WindowCount
#Get input label for each window
$inputs = $atem.GetInputs()
$lookup = @{} # hashtable for quick lookup of inputID Label
foreach($a in $inputs){
    $lookup.add($a.ID,$a.Label.ToString())
}
$i=0
While ($i -lt $mv[0].WindowCount) {
    Write-host "Window: $($i) InputID: "$mv[0].GetWindowInput($i) $lookup.Get_Item($mv[0].GetWindowInput($i))
    $i ++
}
$mv[0].Layout = "Left"
$mv[0].SetWindowInput(3,1000) #Color Bars in preview window

I  have not been able to test the SetWindowInput function as my TVS doesn’t have this capability (CanRouteInputs returns False)

 

How to set ATEM Mixer Property Values

I have started adding enumerators for some of the mixer properties. This is handy when you can’t remember what the valid parameters are.

For example the Transition Style. The intelli-sense in PowerShell makes it easy to discover the valid values as can be seen in this screen capture (click the image to show full screen):

transitionType

To list all the available values, try this command:


[enum]::GetValues([SwitcherLib.MixerTransitionStyle]) | ?{$_.Value__ }

ISE Load and execute Script on Start-up

To load and execute a script when ISE starts, add the following to the SharePoint profile

Note: Use this snippet of code to open your profile


if (!(test-path $profile )) {
new-item -type file -path $profile -force
}
psEdit $profile

Add the following into the file, save it, and restart ISE

function psedit {
    [CmdletBinding()]
    param([Parameter(Mandatory=$true,ValueFromPipeline=$true)]$filename)
    Process{
    if(test-path $filename -PathType Leaf) {
        $file = Get-ChildItem $filename
        if($file.PSProvider.Name -eq "Filesystem") {
            Start-Process PowerShell_ISE -ArgumentList $file
        }
        else {
            Write-Error "Wrong PSProvider: $($File.PSProvider.Name)"
        }
    }
    else {
        write-error "Bad path: $filename"
        }
}
<# .SYNOPSIS Opens a file in PowerShell ISE for editing.
   .DESCRIPTION Accepts one or more file (as paths) and then checks them to make sure the path exists and it's a file. If any of the files are not already open in PowerShell ISE, the file is opened in a new tab.
   .EXAMPLE PSEdit $Filename Opens the file at $filename in the PowerShell ISE
   .EXAMPLE Get-ChildItem C:\Scripts\ProjectGenesis\*.ps1 | PSEdit Opens all PS1 files in the Project Genesis folder for editing. .LINK http://www.ilovepowershell.com/
#>
#Declare the file you want to edit into a variable (optional)
$FilePath = "C:\Scripts\MyProfile.ps1"
#Run the file
PSEdit $FilePath
#Execute the file
$Tempstringholdingcode = Get-Content $FilePath -Raw
Invoke-Expression $Tempstringholdingcode