Arduino小车更换锂电池导致过载的问题分析

一直是用四节镍氢电池来作为小车的电源,某天在网上看到了一个 5V,9V,12V的多用锂电池电源,忍不住就买了个过来,本以为很轻松的换上就可以了,结果当接到12V的电源口子上面的时候,总是自动断开,进入保护模式,感觉很奇怪。

电源图片

image

该电源提供1.5A的极限电流,过流以后会自动切断电源。

感觉尽管小车有四个马达,但是功率不至于达到 12V*1.5A 这么恐怖的地步。

最后用我的直流电源来分析,得到惊人的发现平时的电流也就在300mA左右,但是,某个瞬间,会直接飙升到2.24A以上,这个电流实在是有些恐怖。

直流电源如下:

image

百思不地其解,究竟是为什么导致如此大的瞬间过载电流,幸好电源有过流保护,否则,非出事不可,锂电池可是标准的易燃易爆啊。

细想之下,发觉问题出在如下的代码上面

这段代码看似没有问题,当时也是为了方便才这样写的。

请注意 “停车”这两个字,当时为了使得小车在获得超声传感器的反馈后才会动作,因此要求小车运动一段距离以后就要停下来等待传感器。

但是如此操作导致一个严重的问题,那就是电机的启动负载问题,电机的启动电流非常大,频繁启动,尤其是多电机同步,会导致不可预测的瞬时启动功率过载,非常危险。小车可是有四个驱动电机啊!

虽然知道原因了,但是,却不好解决,原因在于,直流电机的软启动,国内的技术,唉,不提也罢,随便一个配件都是进口的,都要几张红的,关键是还没有给小车这么小的电机的专用的驱动模块,太难了,也不合适。

没办法,不过可以通过降低启动电压的方式来降低瞬时功率,代价就是电机输出功率的下降。于是把电压切换到9V,瞬时最大峰值电流一下子降到了1.2A左右。

勉强凑合。

不过最根本的解决方法,恐怕还是PWM来降低速度,电机一旦启动,就不要停下来,反而是最节能,最不容易烧毁控制芯片的。

的确是个问题。

VBScript 中读取环境变量

最近在编译的时候,需要用到VBScript,发现里面的某些调用路径是写死的实路径,因此修改了一下,提高灵活性一下。

Eclipse使用SVN插件报Failed to load JavaHL Library.错误

最近在使用Eclipse的SVN插件时总是弹出一个大大的对话框,报一个Failed to load JavaHL Library.错误

虽然不是很影响正常使用,但是当你编着编着代码就偶尔弹出这么个大框来着实不爽。

于是在网络上找了答案,按照其中一种方法操作,果然不再报错。

其法为:

1.windows->preferences->Team->SVN->SVN接口

2.选择SVNKit (Pure Java) xxxxxx

如下图所示

image

Android 中的FrameLayout 布局

最近在研究 Cocos2dX ,一直没弄明白 GLSurfaceView 是如何工作的,研究代码发现了动态创建了FrameLayout(单帧布局) ,特意研究了一下这个布局,信息,发现果然比较适合 OpenGL ES 之流的东西的绘制。

FrameLayout是五大布局中最简单的一个布局, 在这个布局中,整个界面被当成一块空白备用区域,所有的子元素都不能被指定放置的位置,它们统统放于这块区域的左上角,并且后面的子元素直接覆盖在前面的 子元素之上,将前面的子元素部分和全部遮挡。显示效果如下,第一个TextView被第二个TextView完全遮挡,第三个TextView遮挡了第二 个TextView的部分位置。

image

参考的XML 信息

这样子,就可以保证,前面的Java控件的绘制,不会阻挡了后面的C++ 代码的绘制,加上JNI 的协助,基本上实现了本地代码跟其他Java的近乎实时的无缝交互。

Subclipse 1.6 卸载后Team菜单仍然存在的解决

最近从Ubuntu 12.04 升级到了 12.10,发现以前在Eclipse下面的SVN Subclipse 插件不能正常运行了。看了看原因,发现系统自带的SVN从1.6X升级到1.7X 了,当年哥在12.04下面折腾了半天,也没能方便升级到1.7X 啊,想不到,想不到。

去Subclipse官网看了下,似乎这个插件N久未曾更新,至少是人气不旺盛啊。于是想更换 成Eclipse自带的subversion,没想到卸载了所有的名字与subversion 相关的东西之后,竟然在Team菜单 中仍然存在快捷方式,另外就是装完subversion 以后在Window->Preferences->Team下面竟然有两个SVN ,明显是Subclipse 没有卸载干净。

找了半天,终于找到一个叫     CollabNet Merge Client    的东东,看名字,没有任何关系与 Subclipse,不过他的简介里面暴露了他,原来这个东东就算与Eclipse菜单对应的东东,吧这个卸载就可以了。

感觉是Eclipse自带的subversion 好些,当时是不知道怎么安装这个,才安装的Subclipse。这个安装完成后会提示安装相应的SVNkit 等等的依赖库,比较方便安装和使用。呵呵,强烈推荐这个。

安装方法:

  • Run Eclipse and select Help > Install New Software... from the main menu.
  • On the dialog that appears, select a pre-configured simultaneous release update site in the Work with combo-box. For example, for the Juno release, select the "Juno - http://download.eclipse.org/releases/juno" update site.
  • Wait a few seconds until the content of the selected update site is displayed under the combo-box.
  • Expand the Collaboration group and select the Subversive features that you would like to install. Certain Subversive features are required if you want to work with SVN, others are optional and offer some additional functionality. You can skip the optional features, if you wish.
  • Follow the next steps to install the selected Subversive features using the standard plug-in installation procedure. Reboot Eclipse after installation is complete.

当下图出现的时候,强烈建议选择SVNkit,请注意 SVNKit 1.3.8 对应的SVN 是 1.6X 的版本,SVNKit 1.7.X 是对应的SVN 1.7X的版本,JavaHL似乎跟不上Java的更新步伐,问题比较多,不推荐。

image

Arduino PWM控制逻辑

对于直流电机的速度控制,目前流行的控制逻辑是PWM,关于 Arduino 的PWM,看看图片

image

板子上标注了“PWM”的区域就是管脚均可以用于这种输出。使用的函数是:

注意value值的范围是0~255。

PWM 英文是“Pulse-width modulation” ,PWM是用占空比不同的方波,来模拟“模拟输出”的一种方式。简而言之就是电脑只会输出0和1,那么想输出0.5怎么办呢?于是输出01010101….,平均之后的效果就是0.5了。

现在看看电机的常规驱动电路,H桥

image

使用单片机来控制直流电机的变速,一般采用调节电枢电压的方式,通过单片机控制PWM1,PWM2,产生可变的脉冲,这样电机上的电压也为宽度可变的脉冲电压。根据公式

U=aVCC

其中:U为电枢电压;a为脉冲的占空比(0<a<1);VCC直流电压源,这里为5V。

电动机的电枢电压受单片机输出脉冲控制,实现了利用脉冲宽度调制技术(PWM)进行直流电机的变速。

image

因为在H桥电路中,只有PWM1与PWM2电平互为相反时电机才能驱动,也就是PWM1与PWM2同为高电平或同为低电平时,都不能工作,所以上图中的实际脉冲宽度为B,

我 们把PWM波的周期定为1ms,占空比分100级可调(每级级差为10%),这样定时器T0每0.01ms产生一次定时中断,每100次后进入下一个 PWM波的周期。上图中,占空比是60%,即输出脉冲的为0.6ms,断开脉冲为0.4ms,这样电枢电压为5*60%=3V。

我们讨论的是可以正转反转的,如果只按一个方向转,我们就只要把PWM1置为高电平或低电平,只改变另一个PWM2电平的脉冲变化即可,,如下图(Q4导通,Q3闭合,电机只能顺时针调整转动速度)

image

下面看看摘抄的部分原理

直流电动机转速n=(U-IR)/Kφ

其中U为电枢端电压,I为电枢电流,R为电枢电路总电阻,φ为每极磁通量,K为电动机结构参数。

直 流电机转速控制可分为励磁控制法与电枢电压控制法。励磁控制法是控制磁通,其控制功率小,低速时受到磁饱和限制,高速时受到换向火花和换向器结构强度的限 制,而且由于励磁线圈电感较大动态响应较差,所以这种控制方法用得很少。大多数应用场合都使用电枢电压控制法。随着电力电子技术的进步,改变电枢电压可通 过多种途径实现,其中PWM(脉宽调制)便是常用的改变电枢电压的一种调速方法。

PWM调速控制的基本原理是按一个固定频率来接通和断开电源,并根据需要改变一个周期内接通和断开的时间比(占空比)来改变直流电机电枢上电压的"占空比",从而改变平均电压,控制电机的转速。在脉宽调速系统中,当电机通电时其速度增加,电机断电时其速度减低。只要按照一定的规律改变通、断电的时间,即可控制电机转速。而且采用PWM技术构成的无级调速系统.启停时对直流系统无冲击,并且具有启动功耗小、运行稳定的特点。

设电机始终接通电源时,电机转速最大为Vmax,且设占空比为D=t/T,则电机的平均速度Vd为:

Vd=VmaxD

由公式可知,当改变占空比D=t/T时,就可以得到不同的电机平均速度Vd,从而达到调速的目的。严格地讲,平均速度与占空比D并不是严格的线性关系,在一般的应用中,可将其近似地看成线性关系。 在直流电机驱动控制电路中,PWM信号由外部控制电路提供,并经高速光电隔离电路、电机驱动逻辑与放大电路后,驱动H桥下臂MOSFET的开关来改变直流电机电枢上平均电压,从而控制电机的转速,实现直流电机PWM调速。

原理知道了,那么看看 Arduino Mega 2560 的PWM控制端口信息

1) Arduino 2560 has 12 pins supporting PWM. They are from 2 to 13 included.
2) the PWM default frequency is 490 Hz for all pins, with the exception of pin 13 and 4,whose frequency is 980 Hz (I checked with an oscilloscope).
3) In order to change frequency on pin 'A', we have to change some value in the timer (or register), controlling pin 'A'. This is the list of timers in Arduino Mega 2560:
timer 0 (controls pin 13, 4);
timer 1 (controls pin 12, 11);
timer 2 (controls pin 10, 9);
timer 3 (controls pin 5, 3, 2);
timer 4 (controls pin 8, 7, 6);

As you can see, a given timer controls more than one pin (every change about a timer will affect all pins depending on it!).

4) You can access a timer simply changing in your code (tipically in the setup()), the value of variable TCCRnB, where 'n' is the number of register. So, if we want  to change the PWM frequency of pins 10 and 9,  we will have to act on TCCR2B .

5) The TCCRnB is a 8 bit number.  The first three bits (from right to left!) are called CS02, CS01, CS00, and they are the bits we have to change.
Those bits in fact represent an integer number (from 0 to 7) called 'prescaler' , that Arduino uses to generate the frequency for PWM.

6) First of all, we have to clear these three bits, i.e they must be all set to 0:

7) now that CS02, CS01, CS00  are clear, we write on them a new value:

now we have a new PWM frequency on pin 9 and 10!

I registered those values on all PWM pins, changing the value of prescaler (the only exception are pins 13 and 14, see later):

prescaler = 1 ---> PWM frequency is 31000 Hz
prescaler = 2 ---> PWM frequency is 4000 Hz
prescaler = 3 ---> PWM frequency is 490 Hz (default value)
prescaler = 4 ---> PWM frequency is 120 Hz
prescaler = 5 ---> PWM frequency is 30 Hz
prescaler = 6 ---> PWM frequency is <20 Hz

(prescalers equal t 0  or 7 are useless).

Those prescaler values are good for all timers (TCCR1B, TCCR2B, TCCR3B, TCCR4B) except for timer 0 (TCCR0B). In this case the values are:

prescaler = 1 ---> PWM frequency is 62000 Hz
prescaler = 2 ---> PWM frequency is 7800 Hz
prescaler = 3 ---> PWM frequency is 980 Hz (default value)
prescaler = 4 ---> PWM frequency is 250 Hz
prescaler = 5 ---> PWM frequency is 60 Hz
prescaler = 6 ---> PWM frequency is <20 Hz

Note that timer 0 is the one on which rely all time functions in Arduino: i.e., if you change this timer, function like delay() or millis() will continue to work but at a different timescale (quicker or slower!!!)

明天修改一下电机的控制代码,把小车代码修改一下,哈哈

Android查看源代码的版本号

确认Android源代码的版本号:

1. 编译的时候在终端中一开始就会打印出来:

2. 直接去make文件中去看:

编写Arduino支持的C++类库

以下为摘抄的例子,已经亲自验证过,例子是正确的

我们在上一讲中实现了一个TN901红外温度传感器51程序到Arduino程序的转换,如果代码越来越多这样程序的可维护性会随之降低,也不适合团度开发。我们应该把常用的文件封装成C++库,这样在复用的时候就会方便很多。
首先让我们来看下官方的C++类库是怎样的结构,以官方的LCD类库为例,如下图所示:

image

上面的文件大体是这样的结构:

文件名 文件类型 文件说明
keywords.txt keywords.txt Arduino库色标文件
LiquidCrystal.h .h C++头文件
LiquidCrystal.cpp .cpp C++程序文件

以下几种文件的作用如下:

.h 头文件:头文件作为一种包含功能函数、数据接口声明的载体文件,用于保存程序的声明(declaration),而定义文件用于保存程序的实现 (implementation)。

.cpp 文件:C++程序源文件主要的逻辑写在这里。

keywords.txt 文件:用来定义库在程序中显示关键字的颜色。

首先我们来尝试下头文件的编写

这样我们一个头文件就写好了.

接下来我们来书写程序的主体,就是CPP文件。

然后我们逐一实现在头文件中定义的方法,注意类型要与定义类型相对应。所有的方法都要属于你定义的类名,格式如下

类名::方法名

另外i啊我们要为程序的封装考虑程序应有的结构,总之是怎样使你的库使用起来最方便,在一般的逻辑中尽量减少调用的次数。我们可以把程序的逻辑分割为几个部分来书写。如:

1.初 始 化
2.实现功能
3.显示数据

当然这个逻辑以具体的程序为准。

我们来尝试写第一个初始化的方法,这样我们可以自己定义程序的端口。

然后我们书写程序的主要逻辑部分

最后我们逐一实现程序的运算过程

之后我们来尝试为我们的库编写一个范例程序来测试我们的程序是否运行正常。

好了,我们看到虽然我们花了一点时间编写了库文件,但是在我们使用程序的时候可以非常方便的调用,而且这样逻辑会比较清晰。呵呵。

最后送给大家一个小礼物,就是如何为我们的库编写色标文件,色标文件就是定义你的库中的方法在编译器中显示的颜色
没有色标文件的库显示起来是这样的:

image

我们可以看到库文件的类名和方法名都是黑色的这样看起来不是很清楚。加上色标文件之后是这样的

image

我们可以看到TN901这样的类名都被加亮了这样看起来要清楚许多。

实现这个需要定义一个色标文件放在库文件的目录中,格式如下

这样我们的色标文件就写好了,我们把它保存成文件名为keywords.txt的文件放在库文件目录下就可以了。

当我们些库文件全部做好了之后我们就可以把这些文件放在,这样的目录下

energia:energia-0101E0008\hardware\msp430\libraries\
arduino:arduino-1.0.1-windows\arduino-1.0.1\libraries\

这样当你重新打开官方编译器的时候可以看到如下的内容

image

python在windows的cmd中打印彩色文字

通过PPA仓库为ubuntu安装Oracle Java 7

首先先介绍一下什么叫PPA

PPA,表示 Personal Package Archives,也就是个人软件包集。

有 很多软件因为种种原因,不能进入官方的 Ubuntu 软件仓库。 为了方便 Ubuntu 用户使用,launchpad.net 提供了 ppa,允许用户建立自己的软件仓库, 自由的上传软件。PPA 也被用来对一些打算进入 Ubuntu 官方仓库的软件,或者某些软件的新版本进行测试。

在ubuntu系统中,和OpenJDK比起来,如果你更偏爱Oracle JDK(前 Sun JDK),我推荐一种很简便的方法给你。通过一个PPA仓库,你可以很容易的进行安装Oracle JDK(包括JRE)并始终保持最新的版本。

Oracle JDK7本身并不存在于该PPA中,这是因为新的Java授权许可证并不允许这么做(这也是Oracle JDK7从ubuntu官方软件仓库中移除的原因)。PPA中的软件程序自动从Oracle官方网站下载Oracle Java JDK7并把它安装到你的电脑中,就像flashplugin-installer软件包那样。

需要注意的是,该软件包当前还是alpha 版本,可能在有些情况下不能正常工作!该软件包支持代理,但是如果你的ISP或者路由器封禁了一些非标准端口,这可能导致安装失败,这是由于Oracle 在Java7二进制安装包的下载链接中使用了许多重定向!如果因此而导致下载失败,亦或你的电脑在防火墙保护之下,你就需要手动安装 Oracle Java 7了。

安装Oracle Java 7

该软件包提供安装Oracle Java JDK 7 (包括 Java JDK, JRE 和 the Java 浏览器插件),如果你只需要安装Oracle JRE,请不要使用该PPA。

运行下述命令,即可完成添加PPA、安装最新版本的Oracle Java 7(支持Ubuntu 12.10,12.04, 11.10, 11.04 and 10.04):

安装完成之后,如果你想看看是否真的安装成功了,你只需运行下面的命令:

命令输出应该包含和下面类似的内容:

注:版本号中的”_04″部分可能会与你的不同,这是由于该PPA总是安装最新的Oracle Java 7版本。

如果由于一些其它的原因,当前的Java版本不是1.7.0,你可以尝试运行下面的命令:

卸载 Oracle Java 7

如果你不再想使用Oracle Java (JDK) 7,想回归OpenJDK了,你只需卸载Oracle JDK7 Installer,这样OpenJDK就又变成当前使用的java了: