当前位置:首页 > 嵌入式 > 嵌入式教程
[导读]基于Android嵌入式平台传感器应用开发水平仪

摘要:详细介绍了如何利用Android系统的传感器开发水平仪应用的全过程。通过对该案例开发的讲解,介绍了传感器应用的开发方法以及通过Eclipse开发Android应用程序的过程。

1Android平台简介

互联网巨头Google公司于2007年11月5日推出了全新的嵌入式软件平台---Android,该平台由操作系统、中间件、用户界面以及应用软件组成,是一个真正开放的移动应用开发平台。

2007年11月初,Google与其他33家手机厂商、软硬件供应商、手机芯片供应商、移动运营商联合组成了开放手机联盟(OpenHandsetAlliance),发布了名为Android的手机软件平台,并宣布该平台完全开放。同时Google希望Android平台成为一套标准化、开放式的移动嵌入式软件平台。

由于Android系统具有开发性、平等性、无界性以及方便性等优点,所以很快被业界所接受。从2008年初开始,越来越多的开发人员投身到Android应用的开发当中。

而Android系统的一大亮点之一就是传感器的使用,利用传感器可以开发出很多新奇有趣的应用程序。例如计步器、水平仪,甚至在很多游戏中都可以使用传感器来操作游戏。传感器的种类有很多种,其中包括加速度传感器、姿态传感器、磁场传感器、温度传感器以及光传感器等,介绍的水平仪应用就是使用姿态传感器的。

2案例功能

将结合水平仪案例的开发详细介绍如何在Android平台下开发传感器应用,下面首先对水平仪的功能及界面进行简单的介绍。

2。1程序界面

程序运行后的效果如图1所示,用户可以通过调整手机的姿态来控制界面中各个气泡的位置。与真正的水平仪一样,在使用手机水平仪时,需要将手机平放到某个平面上才可以。

 

图1 水平仪应用程序界面

2。2软件功能

运行该程序,当改变手机的姿态时,界面中的气泡便会根据手机的姿态向高处进行相应的移动。

当手机所处的平面水平时,各个气泡都应该位于中间的指定区域。

3开发环境搭建

正式进入代码开发之前,首先需要对开发环境进行搭建,其搭建步骤如下所列。

(1)安装Java开发环境JDK。

(2)从网上下载Android开发环境SDK的压缩包,并将其解压到磁盘上的某个位置。

(3)将SDK解压目录中的tools目录添加到系统的PATH环境变量中。

(4)下载并安装Eclipse集成开发环境。

(5)为Eclipse安装Android开发插件ADT,并在Eclipse的Preferences中配置Android插件的SDKLocation。

(6)在Eclipse的AVDManager中创建Android虚拟设备(AVD),并启动模拟器。

(7)下载并安装用来调试Android传感器应用的Sensorsimulator传感器模拟器软件。

(8)在模拟器中安装Sensorsimulator所对应的apk文件并对其进行调试使Sensorsimulator应用程序能够与Android模拟器进行通信。

4开发前的准备

前面完成了开发环境的搭建,但在正式进行代码开发之前,还需要再做一些开发前的准备工作,其步骤如下:

(1)首先启动之前安装好Eclipse。

(2)然后依次点击File|New|Other|Android|AndroidProject进入项目的创建界面。

(3)在项目创建界面中,输入项目的名称、所使用的目标平台、所在的包名等信息,如图2所示。

图2 在Eclipse 中创建Android 项目

(4)点击"Finish"完成项目的创建。

(5)在程序中将会用到的图片资源存放到项目文件夹的res/drawable-mdpi目录下,如图3所示。

图3 图片资源

(6)为应用程序引入调试时使用的Sensorsimulator支持jar包,该jar包位于Sensorsimulator安装目录中的bin目录下:

5自定义View的开发

本案例需要自定义一个View来绘制水平仪的用户界面,首先需要在项目文件夹的src/wyf/ytl目录下创建一个名为Main-View的java类,并使其继承自View类,其代码框架如下:

packagewyf。ytl;//声明所在包

importandroid。content。Context;//引入Context类

importandroid。graphics。Bitmap;//引入Bitmap类

importandroid。graphics。BitmapFactory;//引入相关类

importandroid。graphics。Canvas;//引入Canvas类

importandroid。graphics。Color;//引入Color类

importandroid。graphics。Paint;//引入Paint类

importandroid。graphics。RectF;//引入RectF类

importandroid。graphics。Paint。Style;//引入Style类

importandroid。util。AttributeSet;//引入AttributeSet类

importandroid。view。View;//引入View类

publicclassMainViewextendsView{

Paintpaint=newPaint();//画笔

//图片资源的声明

BitmapshangBitmap1;//上面的大矩形图

BitmapshangBitmap2;//上面的气泡

BitmapzuoBitmap1;//左面的大矩形图

BitmapzuoBitmap2;//左面图的气泡

BitmapzhongBitmap1;//中间的大圆图

BitmapzhongBitmap2;//中间的小气泡

BitmapxiaBitmap1;//右下的矩形图[!--empirenews.page--]

BitmapxiaBitmap2;//右下的气泡

//背景矩形的位置声明

intshang1_X=60;//上面的大矩形图

intshang1_Y=12;

intzuo1_X=12;//左面的大矩形图

intzuo1_Y=60;

intzhong1_X=65;//中间的大圆图

intzhong1_Y=65;

intxia1_X=145;//右下的矩形图

intxia1_Y=145;//水泡的位置声明

intshang2_X;//上面的气泡XY坐标

intshang2_Y;

intzuo2_X;//左面图的气泡XY坐标

intzuo2_Y;

intzhong2_X;//中间的小气泡XY坐标

intzhong2_Y;

intxia2_X;//右下的气泡XY坐标

intxia2_Y;

publicMainView(Contextcontext,AttributeSetattrs){

super(context,attrs);

initBitmap();//初始化图片资源

initLocation();//初始化气泡的位置

}

privatevoidinitBitmap(){//初始化图片的方法

…//该处省略了部分代码,将在后面进行介绍

}

privatevoidinitLocation(){//初始化气泡位置的方法

…//该处省略了部分代码,将在后面进行介绍

}

@Override

protectedvoidonDraw(Canvascanvas){//重写的绘制方法

super。onDraw(canvas);

…//该处省略了部分代码,将在后面进行介绍

}

}

上述代码中的initBitmap以及initLocation方法是对界面进行初始化方法,而onDraw方法会根据需要绘制整个界面。

MainView类构造器中调用了两个单独的方法对整个界面进行了初始化,这是一种非常好的编程习惯。因为把不同功能的代码各自编写成独立的方法可以使主逻辑清晰,且各个方法中的代码都不是很长,会大大提高代码的可读性以及可维护性。

完成了代码框架的开发后就可以对其中各个方法进行开发了,首先开发的是图片资源的初始化方法,其代码如下:

privatevoidinitBitmap(){//初始化图片资源的方法

shangBitmap1=BitmapFactory。decodeResource(getResources(),R。drawable。shang1);

shangBitmap2=BitmapFactory。decodeResource(getResources(),R。drawable。shang2);

zuoBitmap1=BitmapFactory。decodeResource(getResources(),R。drawable。zuo1);

zuoBitmap2=BitmapFactory。decodeResource(getResources(),R。drawable。zuo2);

zhongBitmap1=BitmapFactory。decodeResource(getResources(),R。drawable。zhong1);

zhongBitmap2=BitmapFactory。decodeResource(getResources(),R。drawable。zhong2);

xiaBitmap1=BitmapFactory。decodeResource(getResources(),R。drawable。xia1);

xiaBitmap2=BitmapFactory。decodeResource(getResources(),R。drawable。xia2);

}

上述代码为initBitmap方法的全部代码,其作用是对程序中所有的图片资源进行初始化,在开发该方法之前,应该确保所有的图片资源已经存放到了指定的目录下。

完成了图片资源初始化方法的开发后,便可对气泡位置初始化方法initLocation进行开发了,其代码如下:

privatevoidinitLocation(){//初始化气泡位置的方法

shang2_X=shang1_X+shangBitmap1。getWidth()/2-shangBitmap2。getWidth()/2;

shang2_Y=shang1_Y+shangBitmap1。getHeight()/2-shangBitmap2。getHeight()/2;

zuo2_X=zuo1_X+zuoBitmap1。getWidth()/2-zuoBitmap2。getWidth()/2;

zuo2_Y=zuo1_Y+zuoBitmap1。getHeight()/2-zuoBitmap2。getHeight()/2;

zhong2_X=zhong1_X+zhongBitmap1。getWidth()/2-zhongBitmap2。getWidth()/2;

zhong2_Y=zhong1_Y+zhongBitmap1。getHeight()/2-zhongBitmap2。getHeight()/2;

xia2_X=xia1_X+xiaBitmap1。getWidth()/2-xiaBitmap2。getWidth()/2;

xia2_Y=xia1_Y+xiaBitmap1。getHeight()/2-xiaBitmap2。getHeight()/2;

}

在该方法中通过相应图片的宽度和高度动态计算气泡的初始坐标,采用此方法动态计算气泡坐标的好处是当日后更改图片资源后,不需要重写修改源代码即可正常运行,大大提高了程序的可维护性。

在完成了各个初始化方法的开发后就可以对绘制方法onDraw进行开发,该方法主要负责界面的绘制工作,其代码如下:

@Override

protectedvoidonDraw(Canvascanvas){//界面绘制方法super。onDraw(canvas);

canvas。drawColor(Color。WHITE);//设置背景色为白色

paint。setColor(Color。BLUE);//设置画笔颜色

paint。setStyle(Style。STROKE);//设置画笔为不填充

canvas。drawRect(5,5,315,315,paint);//绘制外边框矩形

//画背景矩形

canvas。drawBitmap(shangBitmap1,shang1_X,shang1_Y,paint);//上

canvas。drawBitmap(zuoBitmap1,zuo1_X,zuo1_Y,paint);//左

canvas。drawBitmap(zhongBitmap1,zhong1_X,zhong1_Y,paint);//中

canvas。drawBitmap(xiaBitmap1,xia1_X,xia1_Y,paint);//下

//开始绘制气泡

canvas。drawBitmap(shangBitmap2,shang2_X,shang2_Y,paint);//上

canvas。drawBitmap(zuoBitmap2,zuo2_X,zuo2_Y,paint);//左

canvas。drawBitmap(zhongBitmap2,zhong2_X,zhong2_Y,paint);//中

canvas。drawBitmap(xiaBitmap2,xia2_X,xia2_Y,paint);//下

paint。setColor(Color。GRAY);//设置画笔颜色用来绘制刻度

//绘制上面方框中的刻度

canvas。drawLine(shang1_X+shangBitmap1。getWidth()/2-7,shang1_Y,shang1_X+shangBitmap1。getWidth()/2-7,shang1_Y+shangBitmap1。getHeight()-2,paint);

canvas。drawLine(shang1_X+shangBitmap1。getWidth()/2+7,shang1_Y,shang1_X+shangBitmap1。getWidth()/2+7,shang1_Y+shangBitmap1。getHeight()-2,paint);[!--empirenews.page--]

//绘制左面方框中的刻度

canvas。drawLine(zuo1_X,zuo1_Y+zuoBitmap1。getHeight()/2-7,zuo1_X+zuoBitmap1。getWidth()-2,zuo1_Y+zuoBitmap1。getHeight()/2-7,paint);canvas。drawLine(zuo1_X,zuo1_Y+zuoBitmap1。getHeight()/2+7,zuo1_X+zuoBitmap1。getWidth()-2,zuo1_Y+zuoBitmap1。getHeight()/2+7,paint);

//绘制下面方框中的刻度

canvas。drawLine(xia1_X+xiaBitmap1。getWidth()/2-10,xia1_Y+xiaBitmap1。getHeight()/2-20,xia1_X+xiaBitmap1。getWidth()/2+20,xia1_Y+xiaBitmap1。getHeight()/2+10,paint);

canvas。drawLine(xia1_X+xiaBitmap1。getWidth()/2-20,xia1_Y+xiaBitmap1。getHeight()/2-10,xia1_X+xiaBitmap1。getWidth()/2+10,xia1_Y+xiaBitmap1。getHeight()/2+20,paint);

//中间圆圈中的刻度(小圆)

RectFoval=newRectF(zhong1_X+zhongBitmap1。getWidth()/2-10,zhong1_Y+zhongBitmap1。getHeight()/2-10,zhong1_X+zhongBitmap1。getWidth()/2+10,zhong1_Y+zhongBitmap1。getHeight()/2+10);

canvas。drawOval(oval,paint);//绘制基准线(圆)

}

在该方法中,根据相应图片的X、Y坐标将图片绘制到屏幕中,在图片的绘制过程中,同样动态根据相应图片的宽和高计算需要绘制到的位置坐标,以提高程序的可维护性与灵活性。

6相关XML文件的编写

完成了用于显示水平仪界面的自定义View的Java代码开发之后,就应该对布局XML资源文件进行编写,以将之前开发的自定义View添加到用户界面中。打开项目中res/layout目录下的main。xml,在其中编写如下的xml代码:

<?xmlversion="1。0"encoding="utf-8"?><!--编码格式-->

 

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"><!--线性布局-->

 

android:id="@+id/mainView"

android:layout_width="fill_parent"

android:layout_height="fill_parent"/><!--自定义

View-->

</LinearLayout>

编写完布局文件main。xml后,还需要开发字符串资源文件strings。xml。打开res/values下的strings。xml文件,编写如下的代码:

<?xmlversion="1。0"encoding="utf-8"?><!--编码方式-->

水平仪

在该文件中只是对字符串app_name进行了定义,在开发Android应用程序时,将字符串资源统一定义到一个xml文件中是一个很好的编程习惯。

编写完上述的xml资源文件后,为了调试还需要为此应用程序添加网络权限,打开项目根目录下的AndroidManifest。xml文件,在""标签之前加入下列代码:

 

上述代码的功能为此应用程序添加了访问网络的权限。

7Activity类的开发

完成了自定义View以及XML文件的开发后,就可以对用户界面对应的Activity类进行开发,首先开发该类的代码框架,其代码如下:

packagewyf。ytl;//声明所在包

importandroid。app。Activity;//引入相关类

importandroid。hardware。SensorListener;

importandroid。hardware。SensorManager;

importandroid。os。Bundle;

publicclassSPYActivityextendsActivity{//继承ActivityMainViewmv;//主View

intk=45;//灵敏度

//SensorManagermySensorManager;

//真机

SensorManagerSimulatormySensorManager;//测试时@Override

publicvoidonCreate(BundlesavedInstanceState){super。onCreate(savedInstanceState);

setContentView(R。layout。main);//设置当前用户界面

mv=(MainView)findViewById(R。id。mainView);

mySensorManager=SensorManagerSimulator。getSystemService(this,SENSOR_SERVICE);//测试时

mySensorManager。connectSimulator();//测试时

//mySensorManager=(SensorManager)

//getSystemService(SENSOR_SERVICE);//真机

}

privatefinalSensorListenermSensorLisener=newSensorListener(){//传感器监听

//器类

…//该处省略了部分代码,将在后面进行介绍

};

@Override

protectedvoidonResume(){//添加监听

mySensorManager。registerListener(mSensorLisener,SensorManager。SENSOR_ORIENTATION);

super。onResume();

}

@Override

protectedvoidonPause(){//取消监听

mySensorManager。unregisterListener(mSensorLisener);

super。onPause();

}

}

上述代码中除了重写了onCreate方法外,还重写了onRe-sume以及onPause方法为mySensorManager添加或删除监听,并且定义了传感器监听器类mSensorLisener。

在完成了Activity类代码框架的开发后就可以对其中传感器的监听类进行开发,首先给出监听器类的代码框架:

privatefinalSensorListenermSensorLisener=

newSensorListener(){//传感器监听器类

publicvoidonSensorChanged(intsensor,float[]values){…//该处省略了部分代码,将在后面进行介绍

}

@Override

publicvoidonAccuracyChanged(intsensor,intaccuracy){}

publicbooleanisContain(intx,inty){//判断点是否在圆内

inttempx=(int)(x+mv。zhongBitmap2。getWidth()/2。0);

[!--empirenews.page--]

inttempy=(int)(y+mv。zhongBitmap2。getWidth()/2。0);

intox=(int)(mv。zhong1_X+mv。zhongBitmap1。getWidth()/2。0);

intoy=(int)(mv。zhong1_X+mv。zhongBitmap1。getWidth()/2。0);

if(Math。sqrt((tempx-ox)*(tempx-ox)+(tempy-oy)*(tempy-oy))>(mv。zhongBitmap1。getWidth()/2。0-mv。zhongBitmap2。getWidth()/2。0)){//不在圆内returnfalse;

}else{//在圆内时

returntrue;

}

}

};

在传感器监听类中,onSensorChanged方法用于监听传感器采样值的变化,例如手机姿态的改变等。上述代码中的is-Contain方法用于判断界面中间的气泡是否出界,若出界则返回false。

完成了代码框架的开发后,便可以对传感器的监听方法onSensorChanged进行开发了,其详细代码如下:

publicvoidonSensorChanged(intsensor,float[]values){

if(sensor==SensorManager。SENSOR_ORIENTATION){

doublepitch=values[SensorManager。DATA_Y];

doubleroll=values[SensorManager。DATA_Z];

intx=0;inty=0;//临时变量,算中间水泡坐标时用

inttempX=0;inttempY=0;//下面气泡的临时变量

//开始调整x的值

if(Math。abs(roll)<=k){

mv。shang2_X=mv。shang1_X//上面的

+(int)(((mv。shangBitmap1。getWidth()

-mv。shangBitmap2。getWidth())/2。0)

-(((mv。shangBitmap1。getWidth()

-mv。shangBitmap2。getWidth())/2。0)*roll)/k);

x=mv。zhong1_X//中间的

+(int)(((mv。zhongBitmap1。getWidth()

-mv。zhongBitmap2。getWidth())/2。0)

-(((mv。zhongBitmap1。getWidth()

-mv。zhongBitmap2。getWidth())/2。0)*roll)/k);

}elseif(roll>k){

mv。shang2_X=mv。shang1_X;x=mv。zhong1_X;

}else{

mv。shang2_X=mv。shang1_X+

mv。shangBitmap1。getWidth()

-mv。shangBitmap2。getWidth();

x=mv。zhong1_X+mv。zhongBitmap1。getWidth()

-mv。zhongBitmap2。getWidth();

}

//开始调整y的值

if(Math。abs(pitch)<=k){

mv。zuo2_Y=mv。zuo1_Y//左面的

+(int)(((mv。zuoBitmap1。getHeight()

-mv。zuoBitmap2。getHeight())/2。0)

+(((mv。zuoBitmap1。getHeight()

-mv。zuoBitmap2。getHeight())/2。0)*pitch)/k);

y=mv。zhong1_Y+//中间的

(int)(((mv。zhongBitmap1。getHeight()

-mv。zhongBitmap2。getHeight())/2。0)

+(((mv。zhongBitmap1。getHeight()

-mv。zhongBitmap2。getHeight())/2。0)*pitch)/k);

}elseif(pitch>k){

mv。zuo2_Y=mv。zuo1_Y

+mv。zuoBitmap1。getHeight()

-mv。zuoBitmap2。getHeight();

y=mv。zhong1_Y+mv。zhongBitmap1。getHeight()

-mv。zhongBitmap2。getHeight();

}else{

mv。zuo2_Y=mv。zuo1_Y;y=mv。zhong1_Y;

}

//下面的

tempX=-(int)(((mv。xiaBitmap1。getWidth()/2-28)*roll

+(mv。xiaBitmap1。getWidth()/2-28)*pitch)/k);

tempY=-(int)((-(mv。xiaBitmap1。getWidth()/2-28)*roll

-(mv。xiaBitmap1。getWidth()/2-28)*pitch)/k);

//限制下面的气泡范围

if(tempY>mv。xiaBitmap1。getHeight()/2-28){

tempY=mv。xiaBitmap1。getHeight()/2-28;

}

if(tempY<-mv。xiaBitmap1。getHeight()/2+28){

tempY=-mv。xiaBitmap1。getHeight()/2+28;

}

if(tempX>mv。xiaBitmap1。getWidth()/2-28){

tempX=mv。xiaBitmap1。getWidth()/2-28;

}

if(tempX<-mv。xiaBitmap1。getWidth()/2+28){

tempX=-mv。xiaBitmap1。getWidth()/2+28;

}

mv。xia2_X=tempX+mv。xia1_X

+mv。xiaBitmap1。getWidth()/2

-mv。xiaBitmap2。getWidth()/2;

mv。xia2_Y=tempY+mv。xia1_Y

+mv。xiaBitmap1。getHeight()/2

-mv。xiaBitmap2。getWidth()/2;

if(isContain(x,y)){//中间的水泡在圆内才改变坐标

mv。zhong2_X=x;mv。zhong2_Y=y;

}

mv。postInvalidate();//重绘MainView

}

}

在onSensorChanged方法中首先得到pitch轴以及roll轴的数值,然后根据该数值的大小调整水泡在屏幕中的位置,同时需要对水泡的坐标进行判断,使其保持在自身所在外框的范围内。

此时运行该程序,并保证测试工具Sensorsimulator与Android模拟器的连通,便会观察到如图1所示的效果,通过Sensorsimulator工具模拟手机的姿态的改变,屏幕中的水泡便随之向高处运动。

8程序发布

完成了所有代码的开发后,就可以将应用程序打包发布了。本案例中只需将Eclipse工具自动生成的apk文件拷出即可,按如下步骤操作。

(1)进行正式发布之前首先需要将代码中注释为"测试时使用"的两处代码删掉,并将注释为"真机使用"代码的注释去掉。

(2)完成代码的修改后重新构建项目。

(3)打开项目文件夹下的bin目录,其中名为SPY的apk文件便为本应用程序的安装包。

(4)将SPY。apk文件拷贝到支持传感器的Android手机中运行即可完成本应用程序的安装。

9结语

通过开发基于Android平台的传感器应用---水平仪程序,读者应该对Android程序的开发有了一定的了解,同时读者也应该了解到在Android平台下使用传感器来丰富自己软件的功能是十分方便的。[!--empirenews.page--]

另外,本案例虽然只对姿态传感器进行了应用,但相信通过对本案例的学习,读者已经有能力对其他传感器进行应用,开发出更具新意的吸引人的其他应用程序。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭