Page 1 of 1

SDI Shield with Arduino uno wifi rev2

PostPosted: Fri Sep 27, 2019 9:36 am
by PI3RRE
Hi,

I'm currently integrating an SDI BlackMagic Shileds on an Arduino uno wifi rev2

I'have issue to detect the SDI Shields. I tried default sketch provided and it's not working.
Each time I start the sketch there are an infinite loop on sdiTallyControl.begin() (regRead32())

I tried those connection with the Shiels :
1) SDA, SCL pinout of the wifi rev2
2) A4, A5 pinout of the wifi rev2
3) 0(RX), 1(TX) Serial port of the wifi rev2 (Adapting code to use BMD_SDITallyControl_Serial
4) SDA, SCL pinout of the wifi rev2 remap physically to the pin A4, A5 of the SDI Shields

The Shield is power by an 12V 1A alimentation.
During the boot the Shileds LEDs 2,3,4,5,6 light up very quickly and than only the LED 1 stay on.

The SDI Shileds is correctly detected on the compture via USB and it's configured in 1080i50 at 0x65 default adress

I tried to run I2C scanner with in the 1, 2, 3 connectivity scenario. The only detected address is 0x60 (even if I remove the SDI shield) which I suppose to be the Wifi module.

Does anyone have idea why the SDI Shiled does not reply over I2C or Serial ?

Regards

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Sat Nov 02, 2019 11:57 am
by PI3RRE
Hi,

I finnaly found a workaround by using Serial port on the Uno Wifi Rev2.
We need to adjust the library file BMDSerialPhysical.h to make it working with Hardware Serial port "Serial1"
diffchecker.com/LKpuNLZi


After updated file BMDSerialPhysical.h you can use it in project :
Code: Select all
BMD_SDITallyControl_Serial sdiTallyControl(Serial1);
BMD_SDICameraControl_Serial sdiCameraControl(Serial1);


Exemple :
Code: Select all
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
*/

#include "Arduino.h"
#include <BMDSDIControl.h>                                // need to include the library

BMD_SDITallyControl_Serial sdiTallyControl(Serial1);

// the setup function runs once when you press reset or power the board
void setup()
{
  pinMode(LED_BUILTIN, OUTPUT);                                     // initialize digital pin 13 as an output
  digitalWrite(LED_BUILTIN, HIGH);
 
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  delay(1000);
  Serial.println("tally begin");
  sdiTallyControl.begin();                                 // initialize tally control
  Serial.println("tally setOverride");
  sdiTallyControl.setOverride(true);                       // enable tally override 

}

// the loop function runs over and over again forever
void loop()
{
  digitalWrite(LED_BUILTIN, HIGH);                                  // turn the LED ON
  Serial.println("setCameraTally 1 programm on");
  sdiTallyControl.setCameraTally(                          // turn tally ON
    1,                                                     // Camera Number
    true,                                                  // Program Tally
    false                                                  // Preview Tally
  );

  delay(1000);                                             // leave it ON for 1 second

  digitalWrite(LED_BUILTIN, LOW);                                   // turn the LED OFF
  Serial.println("setCameraTally 1 programm off");
  sdiTallyControl.setCameraTally(                          // turn tally OFF
    1,                                                      // Camera Number
    false,                                                 // Program Tally
    false                                                  // Preview Tally
  );

  delay(1000);                                             // leave it OFF for 1 second
}


BMDSerialPhysical.h :
Code: Select all
/* -LICENSE-START-
 ** Copyright (c) 2016 Blackmagic Design
 **
 ** Permission is hereby granted, free of charge, to any person or organization
 ** obtaining a copy of the software and accompanying documentation covered by
 ** this license (the "Software") to use, reproduce, display, distribute,
 ** execute, and transmit the Software, and to prepare derivative works of the
 ** Software, and to permit third-parties to whom the Software is furnished to
 ** do so, all subject to the following:
 **
 ** The copyright notices in the Software and this entire statement, including
 ** the above license grant, this restriction and the following disclaimer,
 ** must be included in all copies of the Software, in whole or in part, and
 ** all derivative works of the Software, unless such copies or derivative
 ** works are solely in the form of machine-executable object code generated by
 ** a source language processor.
 **
 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 ** DEALINGS IN THE SOFTWARE.
 ** -LICENSE-END-
 */

#pragma once

#include <stdint.h>
#include <Arduino.h>

namespace BMD
{
   template <typename T>
   class SerialPhysical : public T
   {
   public:
      SerialPhysical(void) {}
      SerialPhysical(HardwareSerial &serialClass) : //Type UartClass for other UNO
         m_serial(&serialClass)
      {}
      
      // Inherits from T
      virtual void      begin();
      virtual uint32_t   regRead32(uint16_t address) const;
      virtual void      regWrite32(uint16_t address, uint32_t value) const;
      virtual uint16_t   regRead16(uint16_t address) const;
      virtual void      regWrite16(uint16_t address, uint16_t value) const;
      virtual uint8_t      regRead8(uint16_t address) const;
      virtual void      regWrite8(uint16_t address, uint8_t value) const;
      virtual void      regRead(uint16_t address, uint8_t values[], int length) const;
      virtual void      regWrite(uint16_t address, const uint8_t values[], int length) const;

   private:
      enum
      {
         kSync1Value = 0xDC,
         kSync2Value = 0x42,
      };
      HardwareSerial *m_serial = &Serial; //Type UartClass for other UNO
   };

   template <typename T>
   void SerialPhysical<T>::begin()
   {
      m_serial->begin(38400);

      T::begin();
   }

   template <typename T>
   uint32_t SerialPhysical<T>::regRead32(uint16_t address) const
   {
      uint8_t regBytes[4];

      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'R',
         4,
         0
      };
      m_serial->write(request, sizeof(request));

      m_serial->flush();

      while (m_serial->available() < 4);
      regBytes[0] = m_serial->read();
      regBytes[1] = m_serial->read();
      regBytes[2] = m_serial->read();
      regBytes[3] = m_serial->read();

      return ((uint32_t)regBytes[3] << 24) | ((uint32_t)regBytes[2] << 16) | ((uint32_t)regBytes[1] << 8) | regBytes[0];
   }

   template <typename T>
   void SerialPhysical<T>::regWrite32(uint16_t address, uint32_t value) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'W',
         4,
         0
      };
      m_serial->write(request, sizeof(request));
      m_serial->write(value >> 0);
      m_serial->write(value >> 8);
      m_serial->write(value >> 16);
      m_serial->write(value >> 24);

      m_serial->flush();
   }

   template <typename T>
   uint16_t SerialPhysical<T>::regRead16(uint16_t address) const
   {
      uint8_t regBytes[2];

      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'R',
         2,
         0
      };
      m_serial->write(request, sizeof(request));

      m_serial->flush();

      while (m_serial->available() < 2);
      regBytes[0] = m_serial->read();
      regBytes[1] = m_serial->read();

      return ((uint16_t)regBytes[1] << 8) | regBytes[0];
   }

   template <typename T>
   void SerialPhysical<T>::regWrite16(uint16_t address, uint16_t value) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'W',
         2,
         0
      };
      m_serial->write(request, sizeof(request));
      m_serial->write(value >> 0);
      m_serial->write(value >> 8);

      m_serial->flush();
   }

   template <typename T>
   uint8_t   SerialPhysical<T>::regRead8(uint16_t address) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'R',
         1,
         0
      };
      m_serial->write(request, sizeof(request));

      m_serial->flush();

      while (m_serial->available() < 1);
      return m_serial->read();
   }

   template <typename T>
   void SerialPhysical<T>::regWrite8(uint16_t address, uint8_t value) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'W',
         1,
         0
      };
      m_serial->write(request, sizeof(request));
      m_serial->write(value);

      m_serial->flush();
   }

   template <typename T>
   void SerialPhysical<T>::regRead(uint16_t address, uint8_t values[], int length) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'R',
         (uint8_t)length,
         0
      };
      m_serial->write(request, sizeof(request));

      m_serial->flush();

      for (int i = 0; i < length; i++)
      {
         while (m_serial->available() < 1);
         values[i] = m_serial->read();
      }
   }

   template <typename T>
   void SerialPhysical<T>::regWrite(uint16_t address, const uint8_t values[], int length) const
   {
      uint8_t request[] = {
         kSync1Value,
         kSync2Value,
         (uint8_t)(address & 0xFF),
         (uint8_t)(address >> 8),
         'W',
         (uint8_t)length,
         0
      };
      m_serial->write(request, sizeof(request));
      m_serial->write(values, length);

      m_serial->flush();
   }
}

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Mon Nov 11, 2019 7:12 pm
by Leoseona
The only detected address is 0x60 (even if I remove the SDI shield) which I suppose to be the Wifi module.

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Mon Nov 11, 2019 7:12 pm
by Leoseona
The only detected address is 0x60 (even if I remove the SDI shield) which I suppose to be the Wifi module.

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Wed Jan 04, 2023 5:14 pm
by Leu-Wenn Delabie
Hello, I'm digging up this thread a bit, but I'm trying to run the shields on an arduino UNO wifi rev 2 board, and all the leds are flashing simultaneously, is there anyone with a beginning of a solution?
I specify that the same shield works on an arduino uno card first or second generation (not rev3), I manage to take control of the tally.
Regards,

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Wed Jan 04, 2023 5:30 pm
by Xtreemtec
Sounds like a power issue.

Do you power the shield with a 12V power supply?

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Wed Jan 04, 2023 5:33 pm
by Leu-Wenn Delabie
Yes, i used the BMCC power suplly (DC12V 2,5A) and the HyperDeck Shuttle HD power supply (DC12V 3A) both work withe the Arduino UNO.

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Wed Jan 04, 2023 5:36 pm
by Xtreemtec
Does it also only flash when you detach it from the Uno? Like first check if your shield is good. There is 1 led that will light up on power. If that is not going steady you have a problem.

Did you mount the headers on the shield yourself? Could it be that there is a short somewhere between 2 pins that will trigger a power shutdown protection?

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Wed Jan 04, 2023 6:12 pm
by Leu-Wenn Delabie
When detached the shield works with only one LED on, and attached to the arduino UNO (powered only by the shield) it works perfectly.
I soldered the board myself.

Re: SDI Shield with Arduino uno wifi rev2

PostPosted: Mon Mar 27, 2023 6:42 pm
by Mike Ambrose
Leu-Wenn Delabie wrote:When detached the shield works with only one LED on, and attached to the arduino UNO (powered only by the shield) it works perfectly.
I soldered the board myself.


I've noticed this as well. I believe the shield depends on the Arduino to provide 5v back up to power other SoCs used for serial & I2C (the 3.3v pin doesn't seem to connect to anything).

I'm having the same struggle as well. I'm wanting to use an ESP32 but haven't had any luck getting it to work. Works perfectly when mounted on an Arduino.

Edit: I should have posted sooner because of course as soon as I post I finally find the solution.

Turns out, no you don't need to supply 5v to the shield. Although the Arduino has pins labelled SCL and SDA (next to AREF) and the manual for the shield calls these out as well, I didn't have any success until I used the other pins labelled in the manual (corresponding to A4 and A5).

Naturally, you'll also need a level converter if you're working with a 3.3v SoC like the ESP32.