基于MobileSDKV4版固件开发大疆无人机手机端遥控器(1)

原创 美男子玩编程 2023-06-05 12:01

点击上方蓝色字体,关注我们

刚刚结束了项目交付,趁热打铁分享一下这次遇到的新东西。首先了解一下大疆的无人机,它大致可以分为三级。

  • 入门级:适合新手,没事干在野外飞一飞拍拍风景啥的。操作也简单,基本上看飞行教程都能懂,也不需要太高的专业性,飞机也相对较小安全系数相对较高。如:御2系列的一些飞机。

  • 消费级:形体上会比入门级的大一点,但是飞机搭载了一些高精度的东西,比如RTK、高精度摄像头、红外镜头等。这类飞机则需要飞手具备一定的专业知识,并且需要考取大疆的初级飞手证书才能上手飞行。如:精灵系列、悟系列的一些飞机。

  • 专业级:形体上更大,操作不当会出现一些严重后果。它的优势在于高续航、高精度定位、热成像镜头、搭载第三方喊话器等。一般用于大型工程作业,使用这个级别的飞机则需要考取大疆专业飞手证书,一般这个会在你购买专业级飞机的时候赠送你培训课程,一般全部听完就能考过。这类飞机的典型代表有:M30系列、M300系列。


1


SDK开发包


大疆的SDK开发包目前分为两个大版本:

v4版

Mobile SDK是一款软件开发套件,旨在让开发者能够访问DJI无人机和手持相机产品的丰富功能。该SDK通过兼顾更底层的功能,诸如飞行稳定,电池管理,信号传输和通信等,简化了应用程序开发的过程。这样,开发者就不需要具备丰富的机器人或嵌入式系统背景知识,而可以专注于DJI产品相关的行业应用开发。

该SDK包括:

  • 可导入Android或iOS应用程序的库/框架,用于访问DJI产品的功能。
  • 飞行模拟器和可视化工具。
  • 适用于iOS的调试工具和远程logger。
  • 示例代码和教程。
  • 开发者指南和API文档。

功能概述

开发者可以通过SDK访问许多DJI产品的功能。开发者可以实现自主飞行,控制相机和云台,接收实时视频图传和传感器数据,下载保存好的媒体文件,以及监听其他组件的状态。

飞行控制

Mobile SDK提供三种控制无人机飞行的方式:

  • 手动操控: 用户使用遥控器操控无人机,而SDK支持监控实时视频流和传感器数据。虚拟摇杆命令: SDK支持产生模拟遥控器摇杆的控制指令。

  • 智能任务: 方便,易于实现无人机的高级控制。例如,可以通过航点任务,让无人机按预定义的飞行路径飞行。

  • 虚拟摇杆命令和智能任务允许对DJI无人机进行简单而功能强大的自主飞行控制。

相机

相机和云台的功能都支持编程调用, 例如:

  • 相机模式: 视频和静态图像拍摄。

  • 曝光: 快门,ISO,光圈和曝光补偿均支持定制,以实现最大的灵活性。

  • 图像参数: 屏幕长宽比,对比度,色相,清晰度,饱和度和滤镜。

  • 视频参数: 分辨率和帧频。

  • 方向: 使用云台时,相机的朝向和运动可以自动控制。

实时视频流

开发者可以通过Mobile SDK获取无人机主摄像头的实时视频流。即使摄像头正在将图像或视频捕获到存储介质中,也可以获取实时视频流。

传感器数据

开发者可以通过SDK获得丰富的传感器数据。GPS位置,指南针,气压计,飞行速度和海拔高度都是通过Mobile SDK获取的一些传感器数据,频率最高可达10 Hz。

下载媒体文件

开发者通过Mobile SDK可以查看和下载保存在相机存储介质(SD卡或固态硬盘)中的照片和视频。预览图和完整的图像数据都可以被访问。

遥控器,电池和无线链路

遥控器,电池和无线链路都可以通过SDK进行访问。通常,这些组件会提供相关的状态信息,但开发者也可以对它们进行一些控制。

连接应用程序和产品

下图说明了Mobile SDK如何与移动应用程序进行融合以及如何与DJI飞行器进行连接。对于手持摄像机产品,遥控器已替换为手持控制器,并且没有飞行器或其他无线链路。

移动应用程序由Mobile SDK,平台SDK(iOS或Android)构建而成,并在移动设备(Apple iPhone,iPad,Nexus手机,Nexus平板电脑等)上运行。

移动设备可以通过WiFi无线连接到DJI产品上,也可以通过USB线缆连接到DJI产品上。

v5版

v5版现在只适用于M30、M300系列,目前还在持续更新,因为是新版的SDK,大疆的工程师也是在不断地再完善里面的内容,这里就不详细说了,之后的文章会详细说这个v5版的SDK。


2


V4版SDK 二次开发


多的不说少的不唠,上主菜。“工欲善其事,必先利其器”,首先准备好开发软件,因为我们使用的是Android版的SDK所以开发软件我们使用Android Studio,本人使用的是Android Studio Fox版,版本之间感觉都一样没有什么开发上的区别。准备好工具之后,先去大疆无人机的开发者官网注册一个开发者账号,并且注册好自己的应用,拿到sdk的专用Key值,申请的方法大疆官网有我就不赘述了。给大家个地址【大疆开发者官网】自己看吧,挺简单的。

注册成为DJI开发者

在注册过程中,需要您提供电子邮件信息和信用卡或手机号码用于注册验证。您所提供的任何信用卡信息将仅用于验证,不会收取任何费用。

本指南假定您使用 Xcode 7.3 以及 Android Studio 2.1.1 以上版本。

生成 App Key

每个应用程序都需要一个唯一的应用程序密钥(App Key)来初始化SDK。

要创建一个应用程序App Key:

请访问DJI开发者网站的 开发者中心

  • 选择左侧栏的 "应用 "。
  • 选择右侧的 “创建应用” 按钮。
  • 输入应用程序的名称, 开发平台, Package Name,分类和描述信息。
  • 会收到一封应用程序激活邮件,以完成App Key的生成。
  • 可以在开发者中心中找到AppKey,复制粘贴到应用程序配置中。

Android 示例代码配置

下载或者克隆Github上的Android示例代码工程。

在Android Studio中打开项目工程,将生成的App Key字符串粘贴到 "AndroidManifest.xml" 文件中 "com.dji.sdk.API_KEY" meda-data element下的 android:value。


    android:name="com.dji.sdk.API_KEY"
    android:value="" />

3


Android Studio项目集成

本节中的屏幕截图是使用Android Studio 4.1生成的。

创建一个新的应用

可以使用一个新的应用程序来演示如何将DJI SDK集成到Android Studio项目中。

  • 打开Android Studio,然后在初始屏幕上选择Start a new Android Studio project

  • 在 New Project 界面:
    • 设置 Application name 为 "ImportSDKDemo"。
    • 设置 Company Domain 和Package name 为 "com.dji.ImportSDKDemo"。

注意:Package name是 生成App Key 所需的标识字符串。在这个工程中Package name为“com.dji.ImportSDKDemo”

  • 在 Target Android Devices 界面:

    • 选择 Phone and Tablet 尺寸。
    • 选择API 23:Android 6.0 (Marshmallow)。
  • 在 Add an Activity to Mobile 界面选择 Empty Activity。


  • 在Configure Activity 界面:
  • 设置 Activity Name: 为 "MainActivity"。
  • 确认勾选Generate Layout File 。
  • 设置Layout Name: 为"activity_main"。
  • 点击Finish 。

配置Gradle 脚本

  • 在Gradle Scripts 中双击 build.gradle (Module: app)

使用以下内容进行更新:

apply plugin: 'com.android.application'

android {

    ...
    defaultConfig {
        ...
    }

    ...

    packagingOptions{
        doNotStrip "*/*/libdjivideo.so"
        doNotStrip "*/*/libSDKRelativeJNI.so"
        doNotStrip "*/*/libFlyForbid.so"
        doNotStrip "*/*/libduml_vision_bokeh.so"
        doNotStrip "*/*/libyuv2.so"
        doNotStrip "*/*/libGroudStation.so"
        doNotStrip "*/*/libFRCorkscrew.so"
        doNotStrip "*/*/libUpgradeVerify.so"
        doNotStrip "*/*/libFR.so"
        doNotStrip "*/*/libDJIFlySafeCore.so"
        doNotStrip "*/*/libdjifs_jni.so"
        doNotStrip "*/*/libsfjni.so"
        exclude 'META-INF/rxjava.properties'
    }
}

dependencies {
   ...
    implementation('com.dji:dji-sdk:4.15', {
    
    exclude module'library-anti-distortion'
    
    })
  compileOnly 'com.dji:dji-sdk-provided:4.15
}

主要变更为:

  • 添加 packagingOptions以防止应用程序意外崩溃。

  • 添加compile和provided依赖项以导入最新的DJIAndroid SDK Maven依赖项。

    选择 Tools -> Android -> Sync Project with Gradle Files 然后等待Gradle项目同步完成。
  • 再次确认 Maven 依赖

    • 在Android Studio菜单中选择File->Project Structure,以打开"Project Structure"界面。然后选择“app”模块,然后单击Dependencies选项卡。

实现应用注册和SDK回调

右键单击com.dji.importSDKDemo,然后选择 New->Java Class以创建一个新的Java类,并将其命名为“MApplication”。


打开MApplication.java文件,并将内容替换为以下内容:

package com.dji.importSDKDemo;

import android.app.Application;
import android.content.Context;

import com.secneo.sdk.Helper;

public class MApplication extends Application {

    @Override
    protected void attachBaseContext(Context paramContext) {
        super.attachBaseContext(paramContext);
        Helper.install(MApplication.this);
    }
}
  • 在这里,重写了attachBaseContext()方法,添加了Helper.install(MApplication.this);代码。

注意:由于某些SDK类现在需要在使用之前进行加载,因此加载过程由Helper.install()完成。开发人员需要在使用任何SDK功能之前调用此方法, 否则可能会导致意外崩溃。


修改完成后需要在AndroidManifest中 配置 Application name。

双击app模块中的MainActivity.java。

MainActivity类需要注册应用程序以获得使用Mobile SDK的授权。它还需要实现SDK回调方法。

  • 首先将MainActivity类修改为包括几个类变量,其中包括mProduct,它是代表连接到移动设备的DJI产品的对象。
  • 另外,onCreate方法将被修改以调用checkAndRequestPermissions方法来检查和请求运行时权限。同样,checkAndRequestPermissions方法将有助于调用startSDKRegistration()方法来注册应用程序。此外,重写onRequestPermissionsResult方法将有助于检查应用程序是否具有足够的权限,如果有,请调用startSDKRegistration()方法来注册应用程序。
  • 最后,将MainActivity类替换为:
public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getName();
    public static final String FLAG_CONNECTION_CHANGE = "dji_sdk_connection_change";
    private static BaseProduct mProduct;
    private Handler mHandler;

    private static final String[] REQUIRED_PERMISSION_LIST = new String[]{
            Manifest.permission.VIBRATE,
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.WAKE_LOCK,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE,
    };
    private List missingPermission = new ArrayList<>();
    private AtomicBoolean isRegistrationInProgress = new AtomicBoolean(false);
    private static final int REQUEST_PERMISSION_CODE = 12345;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // When the compile and target version is higher than 22, please request the following permission at runtime to ensure the SDK works well.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkAndRequestPermissions();
        }

        setContentView(R.layout.activity_main);

        //Initialize DJI SDK Manager
        mHandler = new Handler(Looper.getMainLooper());

    }

    /**
     * Checks if there is any missing permissions, and
     * requests runtime permission if needed.
     */

    private void checkAndRequestPermissions() {
        // Check for permissions
        for (String eachPermission : REQUIRED_PERMISSION_LIST) {
            if (ContextCompat.checkSelfPermission(this, eachPermission) != PackageManager.PERMISSION_GRANTED) {
                missingPermission.add(eachPermission);
            }
        }
        // Request for missing permissions
        if (missingPermission.isEmpty()) {
            startSDKRegistration();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            showToast("Need to grant the permissions!");
            ActivityCompat.requestPermissions(this,
                    missingPermission.toArray(new String[missingPermission.size()]),
                    REQUEST_PERMISSION_CODE);
        }

    }

    /**
     * Result of runtime permission request
     */

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String[] permissions,
                                           @NonNull int[] grantResults)
 
{
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        // Check for granted permission and remove from missing list
        if (requestCode == REQUEST_PERMISSION_CODE) {
            for (int i = grantResults.length - 1; i >= 0; i--) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                    missingPermission.remove(permissions[i]);
                }
            }
        }
        // If there is enough permission, we will start the registration
        if (missingPermission.isEmpty()) {
            startSDKRegistration();
        } else {
            showToast("Missing permissions!!!");
        }
    }
}

DJISDKManager的registerApp()方法具有一个回调,该回调需要处理两种方法:一、用于处理应用程序注册结果。二、用于通知硬件产品和移动设备的连接变更。

继续添加如下所示的 startSDKRegistration() 方法,并实现 onRegister(), onProductDisconnect(), onProductConnect(), onComponentChange(), onInitProcess() and onDatabaseDownloadProgress() 和SDKManagerCallback方法:

private void startSDKRegistration() {
    if (isRegistrationInProgress.compareAndSet(falsetrue)) {
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                showToast("registering, pls wait...");
                DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(), new DJISDKManager.SDKManagerCallback() {
                    @Override
                    public void onRegister(DJIError djiError) {
                        if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
                            showToast("Register Success");
                            DJISDKManager.getInstance().startConnectionToProduct();
                        } else {
                            showToast("Register sdk fails, please check the bundle id and network connection!");
                        }
                        Log.v(TAG, djiError.getDescription());
                    }

                    @Override
                    public void onProductDisconnect() {
                        Log.d(TAG, "onProductDisconnect");
                        showToast("Product Disconnected");
                        notifyStatusChange();

                    }
                    @Override
                    public void onProductConnect(BaseProduct baseProduct) {
                        Log.d(TAG, String.format("onProductConnect newProduct:%s", baseProduct));
                        showToast("Product Connected");
                        notifyStatusChange();

                    }
                    @Override
                    public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent,
                                                  BaseComponent newComponent)
 
{

                        if (newComponent != null) {
                            newComponent.setComponentListener(new BaseComponent.ComponentListener() {

                                @Override
                                public void onConnectivityChange(boolean isConnected) {
                                    Log.d(TAG, "onComponentConnectivityChanged: " + isConnected);
                                    notifyStatusChange();
                                }
                            });
                        }
                        Log.d(TAG,
                                String.format("onComponentChange key:%s, oldComponent:%s, newComponent:%s",
                                        componentKey,
                                        oldComponent,
                                        newComponent));

                    }
                    @Override
                    public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int i) {

                    }

                    @Override
                    public void onDatabaseDownloadProgress(long l, long l1) {

                    }
                });
            }
        });
    }
}

最后需要实现 notifyStatusChange, Runnable 和 showToast 方法:


private void notifyStatusChange() {
    mHandler.removeCallbacks(updateRunnable);
    mHandler.postDelayed(updateRunnable, 500);
}

private Runnable updateRunnable = new Runnable() {

    @Override
    public void run() {
        Intent intent = new Intent(FLAG_CONNECTION_CHANGE);
        sendBroadcast(intent);
    }
};

private void showToast(final String toastMsg) {

    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_LONG).show();
        }
    });

}

必须授予应用程序权限,DJI SDK才能运行。

  • 双击 app 模块中的 AndroidManifest.xml 。

在 package=com.dji.ImportSDKDemo 后,


"android.permission.BLUETOOTH" />
"android.permission.BLUETOOTH_ADMIN" />
"android.permission.VIBRATE" />
"android.permission.INTERNET" />
"android.permission.ACCESS_WIFI_STATE" />
"android.permission.WAKE_LOCK" />
"android.permission.ACCESS_COARSE_LOCATION" />
"android.permission.ACCESS_NETWORK_STATE" />
"android.permission.ACCESS_FINE_LOCATION" />
"android.permission.CHANGE_WIFI_STATE" />
"android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
"android.permission.WRITE_EXTERNAL_STORAGE" />
"android.permission.READ_EXTERNAL_STORAGE" />
"android.permission.SYSTEM_ALERT_WINDOW" />
"android.permission.READ_PHONE_STATE" />

"android.hardware.camera" />
"android.hardware.camera.autofocus" />
    android:name="android.hardware.usb.host"
    android:required="false" />
    android:name="android.hardware.usb.accessory"
    android:required="true" />


  • 在 application 元素的开发添加 android:name=".MApplication" :
    android:name=".MApplication"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme" >
  • 在 android:theme="@style/AppTheme"> 之后,之前插入如下代码:

"com.android.future.usb.accessory" />
    android:name="com.dji.sdk.API_KEY"
    android:value="Please enter your App Key here." />
    android:name="dji.sdk.sdkmanager.DJIAoaControllerActivity"
    android:theme="@android:style/Theme.Translucent" >
    
        "android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
    

            android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
        android:resource="@xml/accessory_filter" />

"dji.sdk.sdkmanager.DJIGlobalService" >


  • 如下所示,在activity元素中插入android:configChanges ="orientation"和android:screenOrientation ="portrait",以防止在屏幕方向变更时重启activity,并将activity的屏幕方向设置为纵向模式 :
".MainActivity"
          android:configChanges="orientation"
          android:screenOrientation="portrait">
    
        "android.intent.action.MAIN" />

        "android.intent.category.LAUNCHER" />
    


生成App Key, 然后用App Key 字符串替换AndroidManifest.xml文件内Please enter your App Key here. 字段。

往期推荐


点击阅读原文,更精彩~

美男子玩编程 多领域、有深度的开发者交流平台
评论
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 70浏览
  • 当前,智能汽车产业迎来重大变局,随着人工智能、5G、大数据等新一代信息技术的迅猛发展,智能网联汽车正呈现强劲发展势头。11月26日,在2024紫光展锐全球合作伙伴大会汽车电子生态论坛上,紫光展锐与上汽海外出行联合发布搭载紫光展锐A7870的上汽海外MG量产车型,并发布A7710系列UWB数字钥匙解决方案平台,可应用于数字钥匙、活体检测、脚踢雷达、自动泊车等多种智能汽车场景。 联合发布量产车型,推动汽车智能化出海紫光展锐与上汽海外出行达成战略合作,联合发布搭载紫光展锐A7870的量产车型
    紫光展锐 2024-12-03 11:38 65浏览
  • 11-29学习笔记11-29学习笔记习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-02 23:58 51浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 106浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 98浏览
  • 遇到部分串口工具不支持1500000波特率,这时候就需要进行修改,本文以触觉智能RK3562开发板修改系统波特率为115200为例,介绍瑞芯微方案主板Linux修改系统串口波特率教程。温馨提示:瑞芯微方案主板/开发板串口波特率只支持115200或1500000。修改Loader打印波特率查看对应芯片的MINIALL.ini确定要修改的bin文件#查看对应芯片的MINIALL.ini cat rkbin/RKBOOT/RK3562MINIALL.ini修改uart baudrate参数修改以下目
    Industio_触觉智能 2024-12-03 11:28 41浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 83浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 86浏览
  • 作为优秀工程师的你,已身经百战、阅板无数!请先醒醒,新的项目来了,这是一个既要、又要、还要的产品需求,ARM核心板中一个处理器怎么能实现这么丰富的外围接口?踌躇之际,你偶阅此文。于是,“潘多拉”的魔盒打开了!没错,USB资源就是你打开新世界得钥匙,它能做哪些扩展呢?1.1  USB扩网口通用ARM处理器大多带两路网口,如果项目中有多路网路接口的需求,一般会选择在主板外部加交换机/路由器。当然,出于成本考虑,也可以将Switch芯片集成到ARM核心板或底板上,如KSZ9897、
    万象奥科 2024-12-03 10:24 37浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 102浏览
  • 概述 说明(三)探讨的是比较器一般带有滞回(Hysteresis)功能,为了解决输入信号转换速率不够的问题。前文还提到,即便使能滞回(Hysteresis)功能,还是无法解决SiPM读出测试系统需要解决的问题。本文在说明(三)的基础上,继续探讨为SiPM读出测试系统寻求合适的模拟脉冲检出方案。前四代SiPM使用的高速比较器指标缺陷 由于前端模拟信号属于典型的指数脉冲,所以下降沿转换速率(Slew Rate)过慢,导致比较器检出出现不必要的问题。尽管比较器可以使能滞回(Hysteresis)模块功
    coyoo 2024-12-03 12:20 70浏览
  •         温度传感器的精度受哪些因素影响,要先看所用的温度传感器输出哪种信号,不同信号输出的温度传感器影响精度的因素也不同。        现在常用的温度传感器输出信号有以下几种:电阻信号、电流信号、电压信号、数字信号等。以输出电阻信号的温度传感器为例,还细分为正温度系数温度传感器和负温度系数温度传感器,常用的铂电阻PT100/1000温度传感器就是正温度系数,就是说随着温度的升高,输出的电阻值会增大。对于输出
    锦正茂科技 2024-12-03 11:50 66浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦