7866|10

9714

帖子

24

TA的资源

版主

楼主
 

sensorTag活动之智能水平尺方案 [复制链接]

本帖最后由 littleshrimp 于 2014-3-21 08:28 编辑

智能水平尺
就要到提交方案的截止时间了,在qq群和论坛里看到很多人提到这次活动太难了,大部分人应该都不能准时提交方案。
的确,这里边涉及的技术太多了,要熟悉单片机开发、射频PCB设计、蓝牙协议栈还有IOS/ANDROID,一个人要在短时间内掌握这么多的技术是非常困难的。

还好,论坛里相信应该会有和我一样,半道出家又喜欢钻研朋友,我们就是喜欢技术,得什么学什么,什么都会,但又什么都不精通。所以我想,这次活动应该是专门为我们这样的小面面设计的吧。

因为什么都会,又什么都会一点,想完成这个方案从头至尾扣完里边的所有内容是不现实的,所以只好走捷径。怎么走?改现成的代码。这是我的一贯风格,管它是不是呢,反正我把它叫做“架构设计”。
我的项目名称是“智能水平尺”,本来提交了一个功能比较全面的,后来发现难的方案都让其它朋友们提前申请了,没办法,我只好做个简单的,也亏了做个简单的,要不然这还真不好实现。
因为自己提交的周计划时间分配不太合理,后来没有按照,也无法按照周计划进行,就穿插着在论坛里发了一些贴子来展示项目的进度。最近因为时间比较紧,只顾写代码没来得及发贴,就等这一次全都得了出来吧。
我的“智能水平尺”的项目要实现的内容是,通过一个包含有CC2541模块的普通水平尺采集尺子所测平面的水平角度。然后通过ANDROID手机中的APP显示实际测量到的水平角度和模拟尺子的真实状态。

项目中用到的东西包括一部在市面上比较便宜的ANDROID4.3MOTO G手机, CC2540DK开发板(主要当CCDEGUGGER来用),CC2541,加速度传感器,电阻,电容,巴伦电路等元件,在京东上花我25洋买来的破水平尺(从单们没拿到家就发现一面的堵头丢了),PCB打样等。

我的思路是这样的,单片机程序通过改C254X协议栈里的SimpleBLEPeripheral例程(C:\TexasInstruments\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral),ANDROID程序通过改android4.4里的BluetoothLeGatt例程(可以在安卓开发环境ADT中依次点击File->New->Other


                              

打开New对话框,找到AndroidSample Project下一步



选择andoid4.3或以上版本下一步


选择BluetoothLeGatt完成,建立一个例程



找到)【这样附图太费劲了,这么简单的问题也许只有我才不懂,以后就不贴这么面的东西了。】

这个例程本来可以直接测试SENSORTAG。但因为SENSOT TAG需要设置对应传感器的CONF来使能相应的服务,比如要启用加速度需要给UUID_ACC_CONF= fromString("f000aa12-0451-4000-b000-000000000000")的Characteristic传递1,让加速度传感器工作,然后CC2541会通过CharacteristicNotification把读取到的数值传递给手机。而这个例程里并没有实现writeCharacteristic功能,想测试的朋友可以在googleplay里找一个叫BLE Scanner的程序,界面和功能基本和这个例程一样。

建立好项目后,我还自己用VISIO画了一个水平尺的图标


,个人感觉还是挺像那么回事儿的,然后我也在京东上买了一个同样颜色的水平尺。


在SensorTag.java(Ti官方SensorTagAndroidAppSource-1_1_0-windows-installer.zip中可以找到 [file1]SensorTagAndroidAppSource-1_1_0-windows-installer.zip (9.61 MB, 下载次数: 43) )的代码中有这些内容,指示加速度服务和特性对应的UUID
      UUID_ACC_SERV = fromString("f000aa10-0451-4000-b000-000000000000"),
      UUID_ACC_DATA = fromString("f000aa11-0451-4000-b000-000000000000"),
      UUID_ACC_CONF = fromString("f000aa12-0451-4000-b000-000000000000"), // 0: disable, 1: enable
UUID_ACC_PERI = fromString("f000aa13-0451-4000-b000-000000000000"),// Period in tens of milliseconds
将这些内容复制到
/BluetoothLeGatt/src/com/example/bluetooth/le/DeviceControlActivity.java
文件中,在这个文件中有一个
private voiddisplayGattServices(List gattServices)
函数,通过在
for (BluetoothGattCharacteristicgattCharacteristic : gattCharacteristics) {
}
循环内判断加速度的UUID来保存想要操作的Characteristic
if(uuid.equals(UUID_ACC_DATA.toString())){                 
    accCharacteristic[0]= gattCharacteristic;
}
if(uuid.equals(UUID_ACC_CONF.toString())){                 
    accCharacteristic[1]= gattCharacteristic;
}
if(uuid.equals(UUID_ACC_PERI.toString())){                 
    accCharacteristic[2]= gattCharacteristic;
}
然后添加一个按钮,在按钮的事件中加入
if (accCharacteristic[1]!= null){
    byte[] data = new byte[1];
    data[0]= 1;
    accCharacteristic[1].setValue(data);                mBluetoothLeService.writeCharacteristic(accCharacteristic[1]);
}
这样在点击按钮后就会告诉SensorTag开启加速度测量,然后再通过循环执行下边的代码来读取加速度的数据,再做计算。
if (accCharacteristic[0]!= null){
    mBluetoothLeService.readCharacteristic(accCharacteristic[0]);
    buffer = accCharacteristic[0].getValue();

if (buffer != null&& buffer.length > 0) {

//处理从SensorTag读取的3个字节数据,分别表示8位的x,y,z
}
}
大概就是这么回事儿,代码挺乱将就着看,哈哈。
[file2]BluetoothLeGatt(智能水平尺 完成).rar (287.63 KB, 下载次数: 42)
这样就可以过通过SensorTag实现我的水平尺啦,见视频
因为在周计划中提到要自己画PCB,所以又根据TI官方的一些设计参考( [file3]CC2540 USB Dongle Reference Design.zip (584 KB, 下载次数: 12) [file4]CC2541_Sensor_Tag swrr109b.zip (1.36 MB, 下载次数: 11) [file5]GasSensor.zip (619.17 KB, 下载次数: 12) )画了一个PCB,在淘宝上打个样。水平尺的PCB和原理图 [file6]水平尺PCB原理图.rar (96.54 KB, 下载次数: 14) ,因为在50mm*50mm的做了几个拼板,PCB有一点点乱。另外还有一个问题,如果用CR2032的电池片,VCCGND被我搞反了。
加速度传感器原来使用和SensorTag一样的KXTJ9-1007。我想这样代码可以使用现成的,程序可以不改。下面是做好的PCB,焊接了一个cc2540 usb dongle测试信号非常好。
后来发现KXTJ9-1007的分辨率只有8位,感觉太低,没啥意思,将KXTJ9-1007改成飞思卡尔的FXOS8700,有加速度还有地磁,14位加速度16位地磁,很爽的。重新画板淘宝打样,因为上次的打样感觉PCB胶水味太大,这回就换了另一家。
相信你见过拼板的,肯定没见过这么拼板的,一个100mm*100mm的板上我拼了12块,我的口号就是“爱拼才会赢”。
智能水平尺PCB和原理图V2 [file7]水平尺PCB原理图V2.rar (79.32 KB, 下载次数: 13)
接下来是焊接好的水平尺模块,本人比较邋遢,模块焊接时使用了很多焊膏,没舍得清洗,看起来很脏。
其实我的焊工也不错,一次成功,遗憾的是,这次的信号非常不好,距离只有几米,因为基本电路没有做过太多改动,原件也是同一批,PCB厚度都是0.8mm,那我只好怪PCB厂的板材不给力了,不过距离虽短,实现我的水平尺还是够用滴。
下进去写好的程序: [file8]SimpleBLEPeripheral 智能水平尺.rar (4.94 MB, 下载次数: 35)
本来是使用SensorTag官方代码中的I2C来读FXOS8700的,但是发现怎么也没成功,幸好每次都会预先想好怎么应对意外,在画板时我还画了MSP430G2553版本的水平尺和FXOS8700的最小电路,也在CC2541中预留了I2C的测试点,因为对CC254X的开发没把握,MSP430才是我的专项,后来证明FXOS8700是没有问题的,而SensorTag的代码读MAG3100也没问题,奇了怪了,纠结我足足两天,最后在一个网站上找到解释,和I2CSR信号有关,把代码扒下来测试通过,时间关系就直接拿来人家的东西使用了。
因为论坛发链接需要审核,我把网址和相关代码写到文件里了:
[file9]cc2541 hardware i2c fxo8700 ok .rar (750 Bytes, 下载次数: 17)
下面是调试程序的视频:

焊上电池座的图片(这回没用电池片,那个太难买,淘宝上卖电池片的几乎都不卖其它元件,单买几个电池片花十几元邮费觉得不值得,这回才用到这种电池座。):
装上电池的效果
从上边的图片能看出来我买的水平尺质量有多么差劲,那个小水泡的东西一碰就掉,因为水平尺是金属的,导电,所以我用SensorTag的塑料壳装上焊好的PCB
也挺帅的,我的miniSensorTag
然后把它装到折好的水平尺里,用海绵胶粘好。
使用android手机测试视频和照片

数学不好,角度计算没弄明白,上边的视频实际上不能超过±90度,后来做了修改。 [file10] BluetoothLeGatt 水平尺.rar (343.39 KB, 下载次数: 21)


这就是我的“智能水平尺”项目,功能虽然有点简单,个人感觉还是很实用的。花了很多精力也花了一些银子去做,收获也非常大,这是我第一次画射频板,也有几年没写JAVA程序了,还有蓝牙协议栈,OSAL都是第一次接触。磕磕绊绊最后也算完满收工。
    也幸亏有这个活动,我想,如果是自己主动去学的话可能不会投入这么多精力,也可能中途因为一些技术和时间的问题就早早放弃了。经过参与这次活动让我学到很多东西,至少BLE对我来说是入门了,以后的工作相信也肯定能够用的到。
    最后还得感谢TI也感谢EEWORLD经常举办这样的活动,让我们收获很多。

此帖出自无线连接论坛

最新回复

楼主写的很棒,谢谢!我把你用KXTJ9计算角度的函数完善了下,增加里SCALE,希望能帮助到大家。         Handler handler=new Handler(){                 public void handleMessage(android.os.Message msg) {                         if(msg.what==0){                                                                                        if (accCharacteristic[0] != null) {                                 mBluetoothLeService.readCharacteristic(accCharacteristic[0]);                                 buffer = accCharacteristic[0].getValue();                     if (buffer != null && buffer.length > 0) {                         final StringBuilder stringBuilder = new StringBuilder(buffer.length);                         for(byte byteChar : buffer)                             stringBuilder.append(String.format("%02X ", byteChar));                                                  // Range 2G                                     final float SCALE = (float) 16.0;                                                                             mDataField.setText("x:" + Byte.toString(buffer[0]) + " y:" + Byte.toString(buffer[1]) + " z:" + Byte.toString(buffer[2]));                                                             Integer x = (int) (buffer[0] / SCALE);                                       Integer y = (int) (buffer[1] / SCALE);                                       Integer z = (int) (buffer[2] * -1 / SCALE);                                                                             double anglex = y / Math.sqrt(x * x + z * z);                                         anglex = -(Math.atan(anglex) * 180 / Math.PI);                                         double angley = x / Math.sqrt(y * y + z * z);                                         angley = -(Math.atan(angley) * 180 / Math.PI);                                         double angle = 0;                                         if (Math.abs(anglex) < Math.abs(angley))                                                 angle = anglex;                                         else {                                                 angle = 90 - angley;                                                 if (anglex < 0)                                                         angle = -angle;                                         }                         Log.d(TAG, "angle=" + Double.toString(angle));                                                      Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.horizontal);                             // Getting width & height of the given image.                             int w = bmp.getWidth();                             int h = bmp.getHeight();                             // Setting post rotate to 90                             Matrix mtx = new Matrix();                             mtx.setTranslate(w, h);                             //mtx.setScale(1, 1);                             if(Double.isNaN(angle))                             {                               angle = 0;                             }                             mtx.postRotate((float)angle);                             // Rotating Bitmap                             Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);                             BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);                             imageView.setImageDrawable(bmd);                             Spannable WordtoSpan = new SpannableString(String.format("%.2f", angle)+"度");                                      WordtoSpan.setSpan(new AbsoluteSizeSpan(150), 0, WordtoSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);                             tv.setText(WordtoSpan);                     }                         }                                 if (fff5 != null) {                                 mBluetoothLeService.readCharacteristic(fff5);                                  buffer = fff5.getValue();                     if (buffer != null && buffer.length > 0) {                         final StringBuilder stringBuilder = new StringBuilder(buffer.length);                         for(byte byteChar : buffer)                             stringBuilder.append(String.format("%02X ", byteChar));                         tv.append(stringBuilder.toString());                     }                         }                         }                 };         };   详情 回复 发表于 2015-9-17 12:50
点赞 关注(1)
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 

回复
举报

4

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
最近也在学习2541的开发,有一个模板,代码和Gerber都有,也做了些板子,用途感觉和你的很近似,但是硬件一直没调试好,能识别到芯片,但是无法点亮LED,能说下该怎么排障吗
此帖出自无线连接论坛
 
 
 

回复

9714

帖子

24

TA的资源

版主

板凳
 
cc2540/cc2541 只有两个I/O口有20mA的驱动能力。看看是不是I/O口没接对。
此帖出自无线连接论坛

点评

很久没上线了,后来因为怀疑是硬件原因又新打了板子,焊接了新的,程序写入了,led也亮了,不过用usb dongle 搜索不到设备,能不能留个联系方式,或者在这里交流也行,详细请教一下,谢了,拖了好长时间一直没解决  详情 回复 发表于 2014-9-5 17:06
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

4
 
这个真厉害
此帖出自无线连接论坛
 
 
 

回复

4

帖子

0

TA的资源

一粒金砂(中级)

5
 
littleshrimp 发表于 2014-3-24 09:00
cc2540/cc2541 只有两个I/O口有20mA的驱动能力。看看是不是I/O口没接对。

很久没上线了,后来因为怀疑是硬件原因又新打了板子,焊接了新的,程序写入了,led也亮了,不过用usb dongle 搜索不到设备,能不能留个联系方式,或者在这里交流也行,详细请教一下,谢了,拖了好长时间一直没解决
此帖出自无线连接论坛
 
 
 

回复

9714

帖子

24

TA的资源

版主

6
 
群名称是EEW-BLE4.0蓝牙技术交流 303514407
加这个QQ群吧,这个论坛BLE相关的人都在这里。
此帖出自无线连接论坛
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复

21

帖子

0

TA的资源

一粒金砂(中级)

7
 
楼主真厉害!
此帖出自无线连接论坛
 
 
 

回复

21

帖子

0

TA的资源

一粒金砂(中级)

8
 
楼主,accCharacteristic[0],accCharacteristic[1],accCharacteristic[2]分别存的什么?转化成角度只用的accCharacteristic[0]么?
此帖出自无线连接论坛
 
 
 

回复

21

帖子

0

TA的资源

一粒金砂(中级)

9
 
楼主在群里么?昵称是多少?我在群里,能不能问点问题。我的qq:919989579.求楼主qq。
此帖出自无线连接论坛
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

10
 
楼主写的很棒,谢谢!我把你用KXTJ9计算角度的函数完善了下,增加里SCALE,希望能帮助到大家。

        Handler handler=new Handler(){
                public void handleMessage(android.os.Message msg) {
                        if(msg.what==0){                       
                               
                                if (accCharacteristic[0] != null) {

                                mBluetoothLeService.readCharacteristic(accCharacteristic[0]);
                                buffer = accCharacteristic[0].getValue();
                    if (buffer != null && buffer.length > 0) {
                        final StringBuilder stringBuilder = new StringBuilder(buffer.length);
                        for(byte byteChar : buffer)
                            stringBuilder.append(String.format("%02X ", byteChar));
                        
                        // Range 2G
                                    final float SCALE = (float) 16.0;
                                   
                                        mDataField.setText("x:" + Byte.toString(buffer[0]) + " y:" + Byte.toString(buffer[1]) + " z:" + Byte.toString(buffer[2]));
                                   
                        Integer x = (int) (buffer[0] / SCALE);
                                      Integer y = (int) (buffer[1] / SCALE);
                                      Integer z = (int) (buffer[2] * -1 / SCALE);

                                     
                                      double anglex = y / Math.sqrt(x * x + z * z);
                                        anglex = -(Math.atan(anglex) * 180 / Math.PI);
                                        double angley = x / Math.sqrt(y * y + z * z);
                                        angley = -(Math.atan(angley) * 180 / Math.PI);

                                        double angle = 0;
                                        if (Math.abs(anglex) < Math.abs(angley))
                                                angle = anglex;
                                        else {
                                                angle = 90 - angley;
                                                if (anglex < 0)
                                                        angle = -angle;
                                        }

                        Log.d(TAG, "angle=" + Double.toString(angle));
                        
                            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.horizontal);
                            // Getting width & height of the given image.
                            int w = bmp.getWidth();
                            int h = bmp.getHeight();
                            // Setting post rotate to 90
                            Matrix mtx = new Matrix();
                            mtx.setTranslate(w, h);
                            //mtx.setScale(1, 1);
                            if(Double.isNaN(angle))
                            {
                              angle = 0;
                            }
                            mtx.postRotate((float)angle);
                            // Rotating Bitmap
                            Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
                            BitmapDrawable bmd = new BitmapDrawable(rotatedBMP);
                            imageView.setImageDrawable(bmd);
                            Spannable WordtoSpan = new SpannableString(String.format("%.2f", angle)+"度");         
                            WordtoSpan.setSpan(new AbsoluteSizeSpan(150), 0, WordtoSpan.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                            tv.setText(WordtoSpan);
                    }

                        }

                                if (fff5 != null) {

                                mBluetoothLeService.readCharacteristic(fff5);
                                 buffer = fff5.getValue();
                    if (buffer != null && buffer.length > 0) {
                        final StringBuilder stringBuilder = new StringBuilder(buffer.length);
                        for(byte byteChar : buffer)
                            stringBuilder.append(String.format("%02X ", byteChar));
                        tv.append(stringBuilder.toString());
                    }
                        }
                        }
                };
        };
此帖出自无线连接论坛
 
 
 

回复

9714

帖子

24

TA的资源

版主

11
 
joytak 发表于 2015-9-17 12:50
楼主写的很棒,谢谢!我把你用KXTJ9计算角度的函数完善了下,增加里SCALE,希望能帮助到大家。

        Handler ...

此帖出自无线连接论坛
个人签名虾扯蛋,蛋扯虾,虾扯蛋扯虾
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表