项目和团队背景
首先给大家说明一下项目背景,以便各位对此项目有更清晰的了解:
1.该项目是一个二次开发项目,第一个基础版本(打印申报系统)也由我带领开发。
2.系统是需要和国家系统对接,有三条主流程。
3.需求频繁变化,由于系统需要对接国家系统,需求方对需求也不甚了解。曾在5月份一个月内需求变更超过8次,都是主流程变更。
4.项目大小按照最初需求估算,约在100人天左右。
5.项目两条主流程无法测试,依赖于外部U盾,但开发过程中并没有U盾。
6.客户现场使用U盾调试和开发时间约为20天左右。
7.我当时同时负责大大小小4个项目,没有进入开发,仅管控进度。
8.团队成员共3名,其中两名是当时开发基础版本的项目成员,他们对此项目较为熟悉。
9.项目推进过程中,需要多次去现场调试测试,由团队中的两名工程师共同前去。阅读全文
首先给大家说明一下项目背景,以便各位对此项目有更清晰的了解:
1.该项目是一个二次开发项目,第一个基础版本(打印申报系统)也由我带领开发。
2.系统是需要和国家系统对接,有三条主流程。
3.需求频繁变化,由于系统需要对接国家系统,需求方对需求也不甚了解。曾在5月份一个月内需求变更超过8次,都是主流程变更。
4.项目大小按照最初需求估算,约在100人天左右。
5.项目两条主流程无法测试,依赖于外部U盾,但开发过程中并没有U盾。
6.客户现场使用U盾调试和开发时间约为20天左右。
7.我当时同时负责大大小小4个项目,没有进入开发,仅管控进度。
8.团队成员共3名,其中两名是当时开发基础版本的项目成员,他们对此项目较为熟悉。
9.项目推进过程中,需要多次去现场调试测试,由团队中的两名工程师共同前去。阅读全文
以前买了本书,一直没看,趁上个周末从纸箱里看了本叫《管理十诫》的书,结合自己经历过的环境还是颇有感触,尤其是对官僚作风的描述可堪称为金典,它就是管理十诫第八诫:
行政作风盛行,团队臃肿:作者刚刚从休斯敦到搬到亚特兰大的时候(刚从可口可乐分公司调任到可口可乐总部)发生在秘书身上的事情,也让我感到目前一些公司的官僚和制度化所带来的负面的影响。事情是这样的,作者的秘书在作者去总部上班之前,去总部帮助作者布置办公室,秘书被急哭了。为什么呢?因为他没有办法继续他的工作,因为即使要找一个简单的文具,也需要先填写申请单,然后由相关经手的人去处理,就为了布置办公室一连忙了很多天还无法进展下去。“如果你想让你一事无成,就让官僚主义盛行”。一个人所拥有的任何影响和权力都来自月他名片上方的职位,而不是他的名字。每个组织都有外人难以逾越的障碍。其实并不是作者的秘书周围的同事不够友好,在一个巨大的官僚机构里,人们永远都不会对你说不,但是你想要的东西,却不一定能够拿到。员工的离职其中一个很重要的原因并不是薪酬不够,而是他们在开展工作的时候收到掣肘。作为管理者最应该做的就是让你的员工能够顺顺利利的完成工作。
——————————————————————————————————————————————————————
“官僚”本意是指官员的办公室,而“主义”指的是规矩。
在现代社会中,如果没有官僚主义,就不可能支撑起这么井然有序的生活。但是,如同机械一样精妙的组织架构不应该成为阻碍个人发挥创造力和生产力的兰路虎。
个性,个人的创造力,个人感触,个人的情感投入,个人的想象力,这些都是开展每项工作不可或缺的品质,在整个组织中我们必须提供这些品质成长所需的沃土。
但,有时候恰恰相反,在每个公司中,为了使一起都变得井井有条,就必须有各式各样的规定和惯例。长此以往,规定和惯例在变成了冰冷,陈旧的条条框框,反而成了扼杀组织活力的绊脚石。而控制这些条条框框的人却死守着自己的一亩三分地,借助这些条条框框来维护自己的权威。这些官僚们整天表现出一副忙得昏天黑地的样子,但其实连一丁点的有创造性的工作都没有做。
必须要对那些尾大不掉,积习难改的臃肿公司进行大刀阔斧的精简改革。因为机构僵化的的官僚体制是很让人受挫的,这些官僚不但自己不作为,而且显然还阻碍其他人的进步。
唐纳德基奥坚信,只要公司的上上下下都有一个信念——推销自己公司的产品和品牌,那么公司肯定会经营的不错。这就是以销售为出发点的思考模式。公司的管理层的主要任务就是让各个部门之间能够尽快的配合顺利完成工作。
管理大师德鲁克说过,卓越的公司从来不会陷于微观管理,从来都不会让员工的每分每秒都有疲于奔命的感觉。尽量扁平化公司的内部结构,那些不涉及到公司利益的部门(比如后勤部门等)就可以外包给其他供应商,这样既提高效率,又不会浪费精力。
公司里的人才越多,那么官僚主义的决定要么就是把好点子扼杀了,要么就会体现一种从众心态。毕竟没有人愿意扫大家的兴。
公司的扁平化运作有助于提高效率,但同时也必须有一些规定来保证基本的工作秩序。所以,这之间的平衡关系要根据公司的规模制定。
行政作风盛行,团队臃肿:作者刚刚从休斯敦到搬到亚特兰大的时候(刚从可口可乐分公司调任到可口可乐总部)发生在秘书身上的事情,也让我感到目前一些公司的官僚和制度化所带来的负面的影响。事情是这样的,作者的秘书在作者去总部上班之前,去总部帮助作者布置办公室,秘书被急哭了。为什么呢?因为他没有办法继续他的工作,因为即使要找一个简单的文具,也需要先填写申请单,然后由相关经手的人去处理,就为了布置办公室一连忙了很多天还无法进展下去。“如果你想让你一事无成,就让官僚主义盛行”。一个人所拥有的任何影响和权力都来自月他名片上方的职位,而不是他的名字。每个组织都有外人难以逾越的障碍。其实并不是作者的秘书周围的同事不够友好,在一个巨大的官僚机构里,人们永远都不会对你说不,但是你想要的东西,却不一定能够拿到。员工的离职其中一个很重要的原因并不是薪酬不够,而是他们在开展工作的时候收到掣肘。作为管理者最应该做的就是让你的员工能够顺顺利利的完成工作。
——————————————————————————————————————————————————————
“官僚”本意是指官员的办公室,而“主义”指的是规矩。
在现代社会中,如果没有官僚主义,就不可能支撑起这么井然有序的生活。但是,如同机械一样精妙的组织架构不应该成为阻碍个人发挥创造力和生产力的兰路虎。
个性,个人的创造力,个人感触,个人的情感投入,个人的想象力,这些都是开展每项工作不可或缺的品质,在整个组织中我们必须提供这些品质成长所需的沃土。
但,有时候恰恰相反,在每个公司中,为了使一起都变得井井有条,就必须有各式各样的规定和惯例。长此以往,规定和惯例在变成了冰冷,陈旧的条条框框,反而成了扼杀组织活力的绊脚石。而控制这些条条框框的人却死守着自己的一亩三分地,借助这些条条框框来维护自己的权威。这些官僚们整天表现出一副忙得昏天黑地的样子,但其实连一丁点的有创造性的工作都没有做。
必须要对那些尾大不掉,积习难改的臃肿公司进行大刀阔斧的精简改革。因为机构僵化的的官僚体制是很让人受挫的,这些官僚不但自己不作为,而且显然还阻碍其他人的进步。
唐纳德基奥坚信,只要公司的上上下下都有一个信念——推销自己公司的产品和品牌,那么公司肯定会经营的不错。这就是以销售为出发点的思考模式。公司的管理层的主要任务就是让各个部门之间能够尽快的配合顺利完成工作。
管理大师德鲁克说过,卓越的公司从来不会陷于微观管理,从来都不会让员工的每分每秒都有疲于奔命的感觉。尽量扁平化公司的内部结构,那些不涉及到公司利益的部门(比如后勤部门等)就可以外包给其他供应商,这样既提高效率,又不会浪费精力。
公司里的人才越多,那么官僚主义的决定要么就是把好点子扼杀了,要么就会体现一种从众心态。毕竟没有人愿意扫大家的兴。
公司的扁平化运作有助于提高效率,但同时也必须有一些规定来保证基本的工作秩序。所以,这之间的平衡关系要根据公司的规模制定。
对系统定下几个标准,而这也成了我们做的最正确决策之一。
第一个,系统必须集成化。我们不允许有各种各样独立的零散系统,所以可以看到现在一个系统里面有供应商、采购、仓储、配送、客服、价格、类目管理和营销管理等各种大小模块。这样就保证所有系统用的数据都是一样的,供应链和配送等各种信息也都是透明的。
第二,系统一定要实时。我们一定要实时地看到所有资源的使用情况,这个要求比较高一点。
第三,这个系统一定要是柔性的。它要允许我们不断地去尝试新的商务模式,允许做错的时候可以改。
第四,这个系统一定要是可扩的。现在看起来,这个标准越来越发重要,因为当我们流量、销售、商品越来越多越来越大的时候,我们不需要改基础架构,只需增加模块和服务器就行了。
阅读全文
第一个,系统必须集成化。我们不允许有各种各样独立的零散系统,所以可以看到现在一个系统里面有供应商、采购、仓储、配送、客服、价格、类目管理和营销管理等各种大小模块。这样就保证所有系统用的数据都是一样的,供应链和配送等各种信息也都是透明的。
第二,系统一定要实时。我们一定要实时地看到所有资源的使用情况,这个要求比较高一点。
第三,这个系统一定要是柔性的。它要允许我们不断地去尝试新的商务模式,允许做错的时候可以改。
第四,这个系统一定要是可扩的。现在看起来,这个标准越来越发重要,因为当我们流量、销售、商品越来越多越来越大的时候,我们不需要改基础架构,只需增加模块和服务器就行了。
阅读全文
http://www.36kr.com/p/207155.html
下载PDf:
http://ishare.iask.sina.com.cn/f/37411096.html
Axure RP 6原型设计精髓》是一本结合UX系统阐述Axure原型设计的书。
先介绍Axure的界面、术语、功能,然后以一个中型示例项目为背景依次探讨UX项目的创建流程和Axure的使用技巧。出于简洁性考虑,《Axure RP 6原型设计精髓》对原型设计过程进行了简化,但依旧由易到难完整地阐述了一个UX项目的要素,如定义商业和技术需求、建立用例和流程图、构建高(低)保真线框图、设计交互、编注说明、产出详细UX规格文档及追踪迭代。
摘录自:
http://baike.baidu.com/link?url=D9lcTE2DmCN9GLPPUKa--XqzvN_EGqqRWaMH4GeI3xNpQFM8-k9NZteaezEN1qMdDue1IfhRbkbXUtN2QGI9lq
http://ishare.iask.sina.com.cn/f/37411096.html
Axure RP 6原型设计精髓》是一本结合UX系统阐述Axure原型设计的书。
先介绍Axure的界面、术语、功能,然后以一个中型示例项目为背景依次探讨UX项目的创建流程和Axure的使用技巧。出于简洁性考虑,《Axure RP 6原型设计精髓》对原型设计过程进行了简化,但依旧由易到难完整地阐述了一个UX项目的要素,如定义商业和技术需求、建立用例和流程图、构建高(低)保真线框图、设计交互、编注说明、产出详细UX规格文档及追踪迭代。
摘录自:
http://baike.baidu.com/link?url=D9lcTE2DmCN9GLPPUKa--XqzvN_EGqqRWaMH4GeI3xNpQFM8-k9NZteaezEN1qMdDue1IfhRbkbXUtN2QGI9lq
核心:颠覆性创新的几个最重要的特征:
1)你把一个很贵的东西做的很便宜。
2)你把一个要钱的东西做成了不要钱的。
3)你把一个很难获得的东西变得很容易获得。
4)你把原来一个很难用的一个东西变得非常的简单。
你能带Ipad,绝不带笔记本。
我买了一个单反相机,而每天出门还是拿个手机拍照,是吧?这在人性中,人是最懒惰的,人是最图省事儿的,最后,你所发现成功的,都跟人性中的七宗罪......
就是把别人收费的版本,迅速降低成本(到互联网时代直接免费了,免费是是互联网的精髓。)
视频:http://www.geekpark.net/cast/view/172119
1)你把一个很贵的东西做的很便宜。
2)你把一个要钱的东西做成了不要钱的。
3)你把一个很难获得的东西变得很容易获得。
4)你把原来一个很难用的一个东西变得非常的简单。
你能带Ipad,绝不带笔记本。
我买了一个单反相机,而每天出门还是拿个手机拍照,是吧?这在人性中,人是最懒惰的,人是最图省事儿的,最后,你所发现成功的,都跟人性中的七宗罪......
就是把别人收费的版本,迅速降低成本(到互联网时代直接免费了,免费是是互联网的精髓。)
视频:http://www.geekpark.net/cast/view/172119
I’ve been very happy with the results from my Raspberry Pi controlled water bath for sous vide cooking, but I knew that the control loop could be improved. Past runs show fairly continued oscillation:
Roast beef temps2
Roast beef run at 60C
I’ve been keeping track of the average power for my control loop, which has been coming out at 22%. So i modified the code to have a bias of 22%, and here’s the result:
Test run at 55C
Test run at 55C
Overall much more stable. The occasional hiccups are probably caused by the remote socket failing to receive off commands. There’s a 3C overshoot at the start, which I hope to have fixed by entering the control loop from initial warm up 3C earlier.
http://blog.thestateofme.com/2013/05/12/improved-temperature-control-for-raspberry-pi-sous-vide/
Temperature control for a sous vide water bath is a popular application for hobbyist microcontroller kits, with lots of well documented projects out there. My favourite is the Sous Vader – if only for the attention to detail in the decal on the box.
I’ve been planning my own for a little while, and got some DS18B20 temperature probes a little while ago. The long Easter weekend break finally brought me some time to progress the project.
Danger – High Voltage
I have an old slow cooker that’s perfectly good for doing pot roast. It’s been falling to bits for some time, and I’ve patched it up with a Sugru sample I got at Monkigras. I had thoughts of hacking it directly (and perhaps even building in a Raspberry Pi), but common sense took hold and I decided on a route that didn’t involve directly manipulating mains electricity.
To turn the slow cooker on and off I got hold of a radio controlled mains socket from Maplin – they’re available without the controller (which I didn’t need) for £7.99.
I found a library to control the remote socket on github – Raspberry Strogonanoff (thanks Duncan McGregor, and a clever choice of project name). This uses a Sparkfun 434MHz RF Link Transmitter (which as suggested by Duncan I got from Protopic).
Getting Raspberry Strogonanoff working was the easier part of the whole set up. Having looked at the socket to establish that it was set to channel 4 button 1 I simply ran this line to turn it on:
sudo ./strogonanoff_sender.py --channel 4 --button 1 --gpio 0 on
and this to turn it off again:
sudo ./strogonanoff_sender.py --channel 4 --button 1 --gpio 0 off
Getting control
A water bath is a good example of a control system. The water and pot collectively have quite a high specific heat capacity, and there’s quite a bit of latency between turning off power and the rise in temperature stopping. The standard way of dealing with this is to use a PID Controller (see this explanation for a BBQ application for something more straightforward than the Wikipedia article). The Sous Vader seems to have worked with just a PI controller (effectively D=0), so I tried that first. There is a python implementation of a PID controller, which I didn’t spend the time to integrate.
Tuning the control loop
This is the tricky and time consuming part. In theory there should be a nice library out there that figures out correct settings for P, I and D based on observed data, but in practice it seems that most people resort to manual tuning.
The hardware
I started out with things on a breadboard using my usual home made Pi Cobbler, but as I want to use this in the kitchen I’ve created a more permanent setup using a Ciseco Slice of Pi, which at £3.90 is a very inexpensive small project board. I used one of the header strips in the Slice of Pi kit as a place to plug in the 434MHz transceiver and the temperature probes (so it would be easy to use parts in other projects). It was then simply a case of soldering some connecting wires to the appropriate power (5v for the transceiver and 3.3v for the DS18B20), GPIO (0 for the transceiver and 7 for the DS18B20) and GND:
The system pictured above has an Edimax WiFi dongle so that I can control and monitor the whole thing when it’s in the kitchen..
The software
Update 14 Apr 2013 – the code (slightly improved over what’s below) is now available on GitHub along with (hopefully comprehensive) installation instructions.
It’s not especially pretty, but seems to be doing the job:
Conclusion
I’ve not had the chance to use the water bath for cooking yet, but I’m very much looking forward to trying out a few steaks and maybe some Sunday roasts. I’ll report back on the results.
来自:http://blog.thestateofme.com/2013/03/31/raspberry-pi-sous-vide-water-bath/
参考:
http://blog.thestateofme.com/2013/01/28/ds18b20-rpi/
http://www.flashingleds.net/sousvader/sousvader.html
自己参考:
(1)Raspberry Pi PWM编写的方法:
http://jackxiang.com/post/6591/
(2)树莓派Raspberry和ds18B20接合,可以接多个Ds18B20:http://jackxiang.com/post/6588/
Roast beef temps2
Roast beef run at 60C
I’ve been keeping track of the average power for my control loop, which has been coming out at 22%. So i modified the code to have a bias of 22%, and here’s the result:
Test run at 55C
Test run at 55C
Overall much more stable. The occasional hiccups are probably caused by the remote socket failing to receive off commands. There’s a 3C overshoot at the start, which I hope to have fixed by entering the control loop from initial warm up 3C earlier.
http://blog.thestateofme.com/2013/05/12/improved-temperature-control-for-raspberry-pi-sous-vide/
Temperature control for a sous vide water bath is a popular application for hobbyist microcontroller kits, with lots of well documented projects out there. My favourite is the Sous Vader – if only for the attention to detail in the decal on the box.
I’ve been planning my own for a little while, and got some DS18B20 temperature probes a little while ago. The long Easter weekend break finally brought me some time to progress the project.
Danger – High Voltage
I have an old slow cooker that’s perfectly good for doing pot roast. It’s been falling to bits for some time, and I’ve patched it up with a Sugru sample I got at Monkigras. I had thoughts of hacking it directly (and perhaps even building in a Raspberry Pi), but common sense took hold and I decided on a route that didn’t involve directly manipulating mains electricity.
To turn the slow cooker on and off I got hold of a radio controlled mains socket from Maplin – they’re available without the controller (which I didn’t need) for £7.99.
I found a library to control the remote socket on github – Raspberry Strogonanoff (thanks Duncan McGregor, and a clever choice of project name). This uses a Sparkfun 434MHz RF Link Transmitter (which as suggested by Duncan I got from Protopic).
Getting Raspberry Strogonanoff working was the easier part of the whole set up. Having looked at the socket to establish that it was set to channel 4 button 1 I simply ran this line to turn it on:
sudo ./strogonanoff_sender.py --channel 4 --button 1 --gpio 0 on
and this to turn it off again:
sudo ./strogonanoff_sender.py --channel 4 --button 1 --gpio 0 off
Getting control
A water bath is a good example of a control system. The water and pot collectively have quite a high specific heat capacity, and there’s quite a bit of latency between turning off power and the rise in temperature stopping. The standard way of dealing with this is to use a PID Controller (see this explanation for a BBQ application for something more straightforward than the Wikipedia article). The Sous Vader seems to have worked with just a PI controller (effectively D=0), so I tried that first. There is a python implementation of a PID controller, which I didn’t spend the time to integrate.
Tuning the control loop
This is the tricky and time consuming part. In theory there should be a nice library out there that figures out correct settings for P, I and D based on observed data, but in practice it seems that most people resort to manual tuning.
The hardware
I started out with things on a breadboard using my usual home made Pi Cobbler, but as I want to use this in the kitchen I’ve created a more permanent setup using a Ciseco Slice of Pi, which at £3.90 is a very inexpensive small project board. I used one of the header strips in the Slice of Pi kit as a place to plug in the 434MHz transceiver and the temperature probes (so it would be easy to use parts in other projects). It was then simply a case of soldering some connecting wires to the appropriate power (5v for the transceiver and 3.3v for the DS18B20), GPIO (0 for the transceiver and 7 for the DS18B20) and GND:
The system pictured above has an Edimax WiFi dongle so that I can control and monitor the whole thing when it’s in the kitchen..
The software
Update 14 Apr 2013 – the code (slightly improved over what’s below) is now available on GitHub along with (hopefully comprehensive) installation instructions.
It’s not especially pretty, but seems to be doing the job:
Conclusion
I’ve not had the chance to use the water bath for cooking yet, but I’m very much looking forward to trying out a few steaks and maybe some Sunday roasts. I’ll report back on the results.
来自:http://blog.thestateofme.com/2013/03/31/raspberry-pi-sous-vide-water-bath/
参考:
http://blog.thestateofme.com/2013/01/28/ds18b20-rpi/
http://www.flashingleds.net/sousvader/sousvader.html
自己参考:
(1)Raspberry Pi PWM编写的方法:
http://jackxiang.com/post/6591/
(2)树莓派Raspberry和ds18B20接合,可以接多个Ds18B20:http://jackxiang.com/post/6588/
Raspberry Pi 使用DS18B20:
一、硬件准备
1、树莓派(Raspberry Pi)一个
2、DS18B20温度传感器一个(淘宝大概5元左右)
3、4.7kΩ电阻一个 或 DS18B20模块一个(笔者用,淘宝1.5元一个,其实就是店家帮忙把电阻焊好了,接线稍好看些)。
4、杜邦线三根(双头母)
二、接线方式(如图所示)
Raspberry <wbr>Pi <wbr>使用DS18B20温度传感器
三、确认硬件接线是否正确并生效,并读取温度
1、首先升级内核(可忽略,但如果版本较老,可能影响设备读取)
apt-get update
apt-get upgrade
2、确认设备是否生效
sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices/
ls
显示结果:
pi@raspberrypi:~$ cd /sys/bus/w1/devices/
pi@raspberrypi:/sys/bus/w1/devices$ ls
28-00000494cb79 w1_bus_master1
28-00000494cb79就是笔者外接的温度传感器设备,但并不是每个客户端都显示一样的,这个是传感器的序列号。
3、查看当前温度
cd 28-00000494cb79
cat w1_slave
显示结果:
70 01 4b 46 7f ff 10 10 e1 : crc=e1 YES
70 01 4b 46 7f ff 10 10 e1 t=23000
第二行的t=23000就是当前的温度值,要换算成摄氏度,除以1000,即当前温度为23000/1000=23摄氏度。
四、用python读取温度值
文件存放:/home/pi/temperature.py
内容如下:
#/home/pi/temperature.py
#打开温度传感器文件
tfile = open("/sys/bus/w1/devices/28-00000494cb79/w1_slave")
#读取文件所有内容
text = tfile.read()
#关闭文件
tfile.close()
#用换行符分割字符串成数组,并取第二行
secondline = text.split("\n")[1]
#用空格分割字符串成数组,并取最后一个,即t=23000
temperaturedata = secondline.split(" ")[9]
#取t=后面的数值,并转换为浮点型
temperature = float(temperaturedata[2:])
#转换单位为摄氏度
temperature = temperature / 1000
#打印值
print temperature
在命令行运行,即可得出结果数值:
python /home/pi/temperature.py
五、上报到yeelink
yeelink是国内比较知名的免费物联网数据平台,国外有COSM(https://cosm.com)。
申请yeelink账号及添加设备和传感器,以及API的学习,本文跳过,请大家自行去学习一下。
根据yeelink API的规则,我们需要提供一个文本文件,内容为一段JSON,如下:
{
“timestamp”:”2012-03-15T16:13:14″,
“value”:294.34
}
若未指定timestamp, 服务器会自动加上当前时间,所以本文的操作不添加该字段
1、修改python,将温度值用JSON格式保存到一个文本文件,全部如下:
#/home/pi/temperature.py
tfile = open("/sys/bus/w1/devices/28-00000494cb79/w1_slave")
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
res = '{"value":%f}' %temperature
output = open('/home/pi/datafile.txt', 'w')
output.write(res)
output.close
python将温度值写入:/home/pi/datafile.txt
2、新增yeelink.sh脚本
文件位置:/home/pi/yeelink.sh
内容如下:
sudo python /home/pi/temperature.py
curl --request POST --data-binary @"/home/pi/datafile.txt" --header"U-ApiKey:XXXXXXXXXXXXXXXX"http://api.yeelink.net/v1.0/device/1969/sensor/2533/datapoints
将U-ApiKey:XXXXXXXXXXXXXXXX替换为自已账户的API Key。
后面的URL也需要替换为自己申请的传感器URL。
3、添加到计划任务
#为脚本增加可执行权限
sudo chmod +x yeelink.sh
#将脚本加入cronjob(计划任务)
sudo crontab -e
#在cornjob文件中添加下面一行,并保存(表示10分钟执行一下脚本,时间可自行修改)
*/10 * * * * /home/pi/yeelink.sh
完了!
我的温度传感器数据展示页面:http://www.yeelink.net/devices/1969
参考文档:
http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/temperature/
http://blog.turningdigital.com/2012/09/raspberry-pi-ds18b20-temperature-sensor-rrdtool/
http://webshed.org/wiki/RaspberryPI_DS1820
http://baike.baidu.com/view/1341776.htm
以上来自:http://blog.sina.com.cn/s/blog_3cb6a78c0101a46w.html
————————————————————————————————————————————————
有画图程序值得参考:
blog.turningdigital.com/2012/09/raspberry-pi-ds18b20-temperature-sensor-rrdtool/
一:首先升级内核(可忽略,但如果版本较老,可能影响设备读取)
apt-get update
apt-get upgrade
二:
温度传感器用的是DS18B20,由于树莓派是工作在linux下,所以无法直接使用C来做驱动,因此我使用的是国外大牛做好的驱动,直接编译进内核
具体方式,进入命令行(通过ssh或者直接连显示器)
输入如下命令
sudo wget http://www.frank-buss.de/raspberrypi/kernel-rpi-w1.tgz
sudo tar -xzf kernel-rpi-w1.tgz
sudo rm -f kernel-rpi-w1.tgz
sudo cd /lib/modules
sudo wget http://www.frank-buss.de/raspberrypi/modules-rpi-w1.tgz
sudo tar -xzf modules-rpi-w1.tgz
sudo rm -f modules-rpi-w1.tgz
sudo sync
sudo reboot
然后等待机器重启重新加载1-wire设备的驱动,也就是给18b20的驱动。
重启完成之后,按图所示连接18B20和树莓派:来自:http://www.guokr.com/post/438477/
http://img1.guokr.com/thumbnail/SCe-ZqjIdJeTog3r28g8Ji5COD9U1lS3vnoHAB13aIvdAwAAYAIAAEpQ_590x362.jpg
http://www.guokr.com/post/438477/
The response will either have YES or NO at the end of the first line. If it is yes, then the temperature will be at the end of the second line, in 1/000 degrees C. So, in the example above, the temperature is actually read as 20.687 and then 26.125 degrees C.
If you have more than one Sensor connected, you'll see multiple 28-xxx files. Each one will have the unique serial number so you may want to plug one in at a time, look at what file is created, and label the sensor!
摘录来自:http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/ds18b20
参考:http://www.2fz1.com/?tag=ds18b20
PWM输出:http://www.eeboard.com/bbs/thread-7174-1-1.html
以上就可以实现一个温度控制了。
背景:前面我用过at89s52和ds18B20做过温度传感器,也用tsic506做过,发现单片机里的线太多了(因为有按钮什么的接线,控制电路接通和断开的线等),这个raspberry pi可以通过触摸屏来实现这个按钮,也就减少了线,而且不用com口接至上位机,也就是说可以直接显示出来温度曲线,再就是这个linux有一个watchdog,不用单片机那样用上那个硬件看门狗都可以保证系统不会死,死了linux会拉起来的,稳定性增强了(这块要注意5V的电源一定要好,否则系统一样不稳定,我用欧版I9000的原装电源发现很不错。),外加上一个wifi的usb无线网卡,可以实现发到任何互联网的地方(用php或python等)。
阅读全文
一、硬件准备
1、树莓派(Raspberry Pi)一个
2、DS18B20温度传感器一个(淘宝大概5元左右)
3、4.7kΩ电阻一个 或 DS18B20模块一个(笔者用,淘宝1.5元一个,其实就是店家帮忙把电阻焊好了,接线稍好看些)。
4、杜邦线三根(双头母)
二、接线方式(如图所示)
Raspberry <wbr>Pi <wbr>使用DS18B20温度传感器
三、确认硬件接线是否正确并生效,并读取温度
1、首先升级内核(可忽略,但如果版本较老,可能影响设备读取)
apt-get update
apt-get upgrade
2、确认设备是否生效
sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices/
ls
显示结果:
pi@raspberrypi:~$ cd /sys/bus/w1/devices/
pi@raspberrypi:/sys/bus/w1/devices$ ls
28-00000494cb79 w1_bus_master1
28-00000494cb79就是笔者外接的温度传感器设备,但并不是每个客户端都显示一样的,这个是传感器的序列号。
3、查看当前温度
cd 28-00000494cb79
cat w1_slave
显示结果:
70 01 4b 46 7f ff 10 10 e1 : crc=e1 YES
70 01 4b 46 7f ff 10 10 e1 t=23000
第二行的t=23000就是当前的温度值,要换算成摄氏度,除以1000,即当前温度为23000/1000=23摄氏度。
四、用python读取温度值
文件存放:/home/pi/temperature.py
内容如下:
#/home/pi/temperature.py
#打开温度传感器文件
tfile = open("/sys/bus/w1/devices/28-00000494cb79/w1_slave")
#读取文件所有内容
text = tfile.read()
#关闭文件
tfile.close()
#用换行符分割字符串成数组,并取第二行
secondline = text.split("\n")[1]
#用空格分割字符串成数组,并取最后一个,即t=23000
temperaturedata = secondline.split(" ")[9]
#取t=后面的数值,并转换为浮点型
temperature = float(temperaturedata[2:])
#转换单位为摄氏度
temperature = temperature / 1000
#打印值
print temperature
在命令行运行,即可得出结果数值:
python /home/pi/temperature.py
五、上报到yeelink
yeelink是国内比较知名的免费物联网数据平台,国外有COSM(https://cosm.com)。
申请yeelink账号及添加设备和传感器,以及API的学习,本文跳过,请大家自行去学习一下。
根据yeelink API的规则,我们需要提供一个文本文件,内容为一段JSON,如下:
{
“timestamp”:”2012-03-15T16:13:14″,
“value”:294.34
}
若未指定timestamp, 服务器会自动加上当前时间,所以本文的操作不添加该字段
1、修改python,将温度值用JSON格式保存到一个文本文件,全部如下:
#/home/pi/temperature.py
tfile = open("/sys/bus/w1/devices/28-00000494cb79/w1_slave")
text = tfile.read()
tfile.close()
secondline = text.split("\n")[1]
temperaturedata = secondline.split(" ")[9]
temperature = float(temperaturedata[2:])
temperature = temperature / 1000
res = '{"value":%f}' %temperature
output = open('/home/pi/datafile.txt', 'w')
output.write(res)
output.close
python将温度值写入:/home/pi/datafile.txt
2、新增yeelink.sh脚本
文件位置:/home/pi/yeelink.sh
内容如下:
sudo python /home/pi/temperature.py
curl --request POST --data-binary @"/home/pi/datafile.txt" --header"U-ApiKey:XXXXXXXXXXXXXXXX"http://api.yeelink.net/v1.0/device/1969/sensor/2533/datapoints
将U-ApiKey:XXXXXXXXXXXXXXXX替换为自已账户的API Key。
后面的URL也需要替换为自己申请的传感器URL。
3、添加到计划任务
#为脚本增加可执行权限
sudo chmod +x yeelink.sh
#将脚本加入cronjob(计划任务)
sudo crontab -e
#在cornjob文件中添加下面一行,并保存(表示10分钟执行一下脚本,时间可自行修改)
*/10 * * * * /home/pi/yeelink.sh
完了!
我的温度传感器数据展示页面:http://www.yeelink.net/devices/1969
参考文档:
http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/temperature/
http://blog.turningdigital.com/2012/09/raspberry-pi-ds18b20-temperature-sensor-rrdtool/
http://webshed.org/wiki/RaspberryPI_DS1820
http://baike.baidu.com/view/1341776.htm
以上来自:http://blog.sina.com.cn/s/blog_3cb6a78c0101a46w.html
————————————————————————————————————————————————
有画图程序值得参考:
blog.turningdigital.com/2012/09/raspberry-pi-ds18b20-temperature-sensor-rrdtool/
一:首先升级内核(可忽略,但如果版本较老,可能影响设备读取)
apt-get update
apt-get upgrade
二:
温度传感器用的是DS18B20,由于树莓派是工作在linux下,所以无法直接使用C来做驱动,因此我使用的是国外大牛做好的驱动,直接编译进内核
具体方式,进入命令行(通过ssh或者直接连显示器)
输入如下命令
sudo wget http://www.frank-buss.de/raspberrypi/kernel-rpi-w1.tgz
sudo tar -xzf kernel-rpi-w1.tgz
sudo rm -f kernel-rpi-w1.tgz
sudo cd /lib/modules
sudo wget http://www.frank-buss.de/raspberrypi/modules-rpi-w1.tgz
sudo tar -xzf modules-rpi-w1.tgz
sudo rm -f modules-rpi-w1.tgz
sudo sync
sudo reboot
然后等待机器重启重新加载1-wire设备的驱动,也就是给18b20的驱动。
重启完成之后,按图所示连接18B20和树莓派:来自:http://www.guokr.com/post/438477/
http://img1.guokr.com/thumbnail/SCe-ZqjIdJeTog3r28g8Ji5COD9U1lS3vnoHAB13aIvdAwAAYAIAAEpQ_590x362.jpg
http://www.guokr.com/post/438477/
The response will either have YES or NO at the end of the first line. If it is yes, then the temperature will be at the end of the second line, in 1/000 degrees C. So, in the example above, the temperature is actually read as 20.687 and then 26.125 degrees C.
If you have more than one Sensor connected, you'll see multiple 28-xxx files. Each one will have the unique serial number so you may want to plug one in at a time, look at what file is created, and label the sensor!
摘录来自:http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/ds18b20
参考:http://www.2fz1.com/?tag=ds18b20
PWM输出:http://www.eeboard.com/bbs/thread-7174-1-1.html
以上就可以实现一个温度控制了。
背景:前面我用过at89s52和ds18B20做过温度传感器,也用tsic506做过,发现单片机里的线太多了(因为有按钮什么的接线,控制电路接通和断开的线等),这个raspberry pi可以通过触摸屏来实现这个按钮,也就减少了线,而且不用com口接至上位机,也就是说可以直接显示出来温度曲线,再就是这个linux有一个watchdog,不用单片机那样用上那个硬件看门狗都可以保证系统不会死,死了linux会拉起来的,稳定性增强了(这块要注意5V的电源一定要好,否则系统一样不稳定,我用欧版I9000的原装电源发现很不错。),外加上一个wifi的usb无线网卡,可以实现发到任何互联网的地方(用php或python等)。
阅读全文
矩阵键盘是单片机编程中所使用的键盘.
1.矩阵式键盘的结构与工作原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程方法如下所述。
2、矩阵式键盘的按键识别方法
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。
行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。
1、判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
下面给出一个具体的例子:
图仍如上所示。8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0-P1.3分别接有4个上拉电阻到正电源+5V,并把列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。4根行线和4根列线形成16个相交点。
1、检测当前是否有键被按下。检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。
2、去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。
3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.7按下述4种组合依次输出:
P1.7 1 1 1 0
P1.6 1 1 0 1
P1.5 1 0 1 1
P1.4 0 1 1 1
在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值
4、为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。
键盘扫描程序:
从以上分析得到键盘扫描程序的流程图如图2所示。程序如下
SCAN: MOV P1,#0FH
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT1
SJMP NEXT3
NEXT1: ACALL D20MS
MOV A,#0EFH
NEXT2: MOV R1,A
MOV P1,A
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,KCODE;
MOV A,R1
SETB C
RLC A
JC NEXT2
NEXT3: MOV R0,#00H
RET
KCODE: MOV B,#0FBH
NEXT4: RRC A
INC B
JC NEXT4
MOV A,R1
SWAP A
NEXT5: RRC A
INC B
INC B
INC B
INC B
JC NEXT5
NEXT6: MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT6
MOV R0,#0FFH
RET
键盘处理程序就作这么一个简单的介绍,实际上,键盘、显示处理是很复杂的,它往往占到一个应用程序的大部份代码,可见其重要性,但说到,这种复杂并不来自于单片机的本身,而是来自于操作者的习惯等等问题,因此,在编写键盘处理程序之前,最好先把它从逻辑上理清,然后用适当的算法表示出来,最后再去写代码,这样,才能快速有效地写好代码。
键盘是由一组规则排列的按键组成,一个按键实际上是一个开关元件,也就是说键盘是一组规则排列的开关。
键盘工作原理
1.按键的分类
按键按照结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关等;另一类是无触点开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最常见的是触点式开关按键。
按键按照接口原理可分为编码键盘与非编码键盘两类,这两类键盘的主要区别是识别键符及给出相应键码的方法。编码键盘主要是用硬件来实现对键的识别,非编码键盘主要是由软件来实现键盘的定义与识别。
全编码键盘能够由硬件逻辑自动提供与键对应的编码,此外,一般还具有去抖动和多键、窜键保护电路,这种键盘使用方便,但需要较多的硬件,价格较贵,一般的单片机应用系统较少采用。非编码键盘只简单地提供行和列的矩阵,其它工作均由软件完成。由于其经济实用,较多地应用于单片机系统中。下面将重点介绍非编码键盘接口。
2.键输入原理
在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其它按键都是以开关状态来设置控制功能或输入数据。当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入是与软件结构密切相关的过程。
对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将键输入并检查是哪一个键按下,将该键号送入累加器ACC,然后通过跳转指令转入执行该键的功能程序,执行完后再返回主程序。
3.按键结构与特点
微机键盘通常使用机械触点式按键开关,其主要功能是把机械上的通断转换成为电气上的逻辑关系。也就是说,它能提供标准的TTL逻辑电平,以便与通用数字系统的逻辑电平相容。
机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。其抖动过程如图7.2所示,抖动时间的长短与开关的机械特性有关,一般为5~10ms。
左图 按键触点的机械抖动
在触点抖动期间检测按键的通与断状态,可能导致判断出错。即按键一次按下或释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取去抖动措施,可从硬件、软件两方面予以考虑。在键数较少时,可采用硬件去抖,而当键数较多时,采用软件去抖。
在硬件上可采用在键输出端加R-S触发器(双稳态触发器)或单稳态触发器构成去抖动电路,图7.3是一种由R-S触发器构成的去抖动电路,当触发器一旦翻转,触点抖动不会对其产生任何影响。
电路工作过程如下:按键未按下时,a = 0,b = 1,输出Q = 1,按键按下时,因按键的机械弹性作用的影响,使按键产生抖动,当开关没有稳定到达b端时,因与非门2输出为0反馈到与非门1的输入端,封锁了与非门1,双稳态电路的状态不会改变,输出保持为1,输出Q不会产生抖动的波形。当开关稳定到达b端时,因a = 1,b = 0,使Q = 0,双稳态电路状态发生翻转。当释放按键时,在开关未稳定到达a端时,因Q = 0,封锁了与非门2,双稳态电路的状态不变,输出Q保持不变,消除了后沿的抖动波形。当开关稳定到达b端时,因a = 0,b = 0,使Q = 1,双稳态电路状态发生翻转,输出Q重新返回原状态。由此 右图 双稳态去抖电路
可见,键盘输出经双稳态电路之后,输出已变为规范的矩形方波。
软件上采取的措施是:在检测到有按键按下时,执行一个10ms左右(具体时间应视所使用的按键进行调整)的延时程序后,再确认该键电平是否仍保持闭合状态电平,若仍保持闭合状态电平,则确认该键处于闭合状态;同理,在检测到该键释放后,也应采用相同的步骤进行确认,从而可消除抖动的影响。
4.按键编码
一组按键或键盘都要通过I/O口线查询按键的开关状态。根据键盘结构的不同,采用不同的编码。无论有无编码,以及采用什么编码,最后都要转换成为与累加器中数值相对应的键值,以实现按键功能程序的跳转。
5.编制键盘程序
一个完善的键盘控制程序应具备以下功能:
(1)检测有无按键按下,并采取硬件或软件措施,消除键盘按键机械触点抖动的影响。
(2)有可靠的逻辑处理办法。每次只处理一个按键,其间对任何按键的操作对系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序。
(3)准确输出按键值(或键号),以满足跳转指令要求。
独立式按键
单片机控制系统中,往往只需要几个功能键,此时,可采用独立式按键结构。
1.独立式按键结构
独立式按键是直接用I/O口线构成的单个按键电路,其特点是每个按键单独占用一根I/O
左图 独立式按键电路
口线,每个按键的工作不会影响其它I/O口线的状态。独立式按键的典型应用如图7.4所示。
独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。
图7.4中按键输入均采用低电平有效,此外,上拉电阻保证了按键断开时,I/O口线有确定的高电平。当I/O口线内部有上拉电阻时,外电路可不接上拉电阻。
2.独立式按键的软件结构
独立式按键软件常采用查询式结构。先逐位查询每根I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。图7.4中的I/O口采用P1口,请读者自行编制相应的软件。
7.1.3 矩阵式按键
单片机系统中,若使按键较多时,通常采用矩阵式(也称行列式)键盘。
1.矩阵式键盘的结构及原理
矩阵式键盘由行线和列线组成,按键位于行、列线的交叉点上,其结构如下图所示。
由图可知,一个4×4的行、列结构可以构成一个含有16个按键的键盘,显然,在按键数量较多时,矩阵式键盘较之独立式按键键盘要节省很多I/O口。
矩阵式键盘中,行、列线分别连接到按键开关的两端,行线通过上拉电阻接到+5V上。当无键按下时,行线处于高电平状态;当有键按下时,行、列线将导通,此时,行线电平将由与此行线相连的列线电平决定。这是识别按键是否按下的关键。然而,矩阵键盘中的行线、列线和多个键相连,各按键按下与否均影响该键所在行线和列线的电平,各按键间将相互影响,因此,必须将行线、列线信号配合起来作适当处理,才能确定闭合键的位置。
2.矩阵式键盘按键的识别
识别按键的方法很多,其中,最常见的方法是扫描法。下面以图7.5中8号键的识别为例来说明扫描法识别按键的过程。
按键按下时,与此键相连的行线与列线导通,行线在无键按下时处在高电平,显然,如果让所有的列线也处在高电平,那么,按键按下与否不会引起行线电平的变化,因此,必须使所有列线处在低电平,只有这样,当有键按下时,该键所在的行电平才会由高电平变为低电平。CPU根据行电平的变化,便能判定相应的行有键按下。8号键按下时,第2行一定为低电平,然而,第2行为低电平时,能否肯定是8号键按下呢?回答是否定的,因为9、10、11号键按下同样使第2行为低电平。为进一步确定具体键,不能使所有列线在同一时刻都处在低电平,可在某一时刻只让一条列线处于低电平,其余列线均处于高电平,另一时刻,让下一列处在低电平,依此循环,这种依次轮流每次选通一列的工作方式称为键盘扫描。采用键盘扫描后,再来观察8号键按下时的工作过程,当第0列处于低电平时,第2行处于低电平,而第1、2、3列处于低电平时,第2行却处在高电平,由此可判定按下的键应是第2行与第0列的交叉点,即8号键。
3.键盘的编码
对于独立式按键键盘,因按键数量少,可根据实际需要灵活编码。对于矩阵式键盘,按键的位置由行号和列号唯一确定,因此可分别对行号和列号进行二进制编码,然后将两值合成一个字节,高4位是行号,低4位是列号。如图7.5中的8号键,它位于第2行,第0列,因此,其键盘编码应为20H。采用上述编码对于不同行的键离散性较大,不利于散转指令对按键进行处理。因此,可采用依次排列键号的方式对安排进行编码。以图7.5中的4×4键盘为例,可将键号编码为:01H、02H、03H…0EH、0FH、10H等16个键号。编码相互转换可通过计算或查表的方法实现。
4.键盘的工作方式
在单片机应用系统中,键盘扫描只是CPU的工作内容之一。CPU对键盘的响应取决于键盘的工作方式,键盘的工作方式应根据实际应用系统中CPU的工作状况而定,其选取的原则是既要保证CPU能及时响应按键操作,又不要过多占用CPU的工作时间。通常,键盘的工作方式有三种,即编程扫描、定时扫描和中断扫描。
1)编程扫描方式
编程扫描方式是利用CPU完成其它工作的空余调用键盘扫描子程序来响应键盘输入的要求。在执行键功能程序时,CPU不再响应键输入要求,直到CPU重新扫描键盘为止。
键盘扫描程序一般应包括以下内容:
(1)判别有无键按下。
(2)键盘扫描取得闭合键的行、列值。
(3)用计算法或查表法得到键值。
(4)判断闭合键是否释放,如没释放则继续等待。
(5)将闭合键键号保存,同时转去执行该闭合键的功能。
1.矩阵式键盘的结构与工作原理
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图1所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程方法如下所述。
2、矩阵式键盘的按键识别方法
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。
行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。
1、判断键盘中有无键按下 将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
下面给出一个具体的例子:
图仍如上所示。8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。列线P1.0-P1.3分别接有4个上拉电阻到正电源+5V,并把列线P1.0-P1.3设置为输入线,行线P1.4-P.17设置为输出线。4根行线和4根列线形成16个相交点。
1、检测当前是否有键被按下。检测的方法是P1.4-P1.7输出全“0”,读取P1.0-P1.3的状态,若P1.0-P1.3为全“1”,则无键闭合,否则有键闭合。
2、去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。
3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P1.4-P1.7按下述4种组合依次输出:
P1.7 1 1 1 0
P1.6 1 1 0 1
P1.5 1 0 1 1
P1.4 0 1 1 1
在每组行输出时读取P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值
4、为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。
键盘扫描程序:
从以上分析得到键盘扫描程序的流程图如图2所示。程序如下
SCAN: MOV P1,#0FH
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT1
SJMP NEXT3
NEXT1: ACALL D20MS
MOV A,#0EFH
NEXT2: MOV R1,A
MOV P1,A
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,KCODE;
MOV A,R1
SETB C
RLC A
JC NEXT2
NEXT3: MOV R0,#00H
RET
KCODE: MOV B,#0FBH
NEXT4: RRC A
INC B
JC NEXT4
MOV A,R1
SWAP A
NEXT5: RRC A
INC B
INC B
INC B
INC B
JC NEXT5
NEXT6: MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT6
MOV R0,#0FFH
RET
键盘处理程序就作这么一个简单的介绍,实际上,键盘、显示处理是很复杂的,它往往占到一个应用程序的大部份代码,可见其重要性,但说到,这种复杂并不来自于单片机的本身,而是来自于操作者的习惯等等问题,因此,在编写键盘处理程序之前,最好先把它从逻辑上理清,然后用适当的算法表示出来,最后再去写代码,这样,才能快速有效地写好代码。
键盘是由一组规则排列的按键组成,一个按键实际上是一个开关元件,也就是说键盘是一组规则排列的开关。
键盘工作原理
1.按键的分类
按键按照结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关等;另一类是无触点开关按键,如电气式按键,磁感应按键等。前者造价低,后者寿命长。目前,微机系统中最常见的是触点式开关按键。
按键按照接口原理可分为编码键盘与非编码键盘两类,这两类键盘的主要区别是识别键符及给出相应键码的方法。编码键盘主要是用硬件来实现对键的识别,非编码键盘主要是由软件来实现键盘的定义与识别。
全编码键盘能够由硬件逻辑自动提供与键对应的编码,此外,一般还具有去抖动和多键、窜键保护电路,这种键盘使用方便,但需要较多的硬件,价格较贵,一般的单片机应用系统较少采用。非编码键盘只简单地提供行和列的矩阵,其它工作均由软件完成。由于其经济实用,较多地应用于单片机系统中。下面将重点介绍非编码键盘接口。
2.键输入原理
在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其它按键都是以开关状态来设置控制功能或输入数据。当所设置的功能键或数字键按下时,计算机应用系统应完成该按键所设定的功能,键信息输入是与软件结构密切相关的过程。
对于一组键或一个键盘,总有一个接口电路与CPU相连。CPU可以采用查询或中断方式了解有无将键输入并检查是哪一个键按下,将该键号送入累加器ACC,然后通过跳转指令转入执行该键的功能程序,执行完后再返回主程序。
3.按键结构与特点
微机键盘通常使用机械触点式按键开关,其主要功能是把机械上的通断转换成为电气上的逻辑关系。也就是说,它能提供标准的TTL逻辑电平,以便与通用数字系统的逻辑电平相容。
机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的触点机械抖动,然后其触点才稳定下来。其抖动过程如图7.2所示,抖动时间的长短与开关的机械特性有关,一般为5~10ms。
左图 按键触点的机械抖动
在触点抖动期间检测按键的通与断状态,可能导致判断出错。即按键一次按下或释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖动所致的检测误判,必须采取去抖动措施,可从硬件、软件两方面予以考虑。在键数较少时,可采用硬件去抖,而当键数较多时,采用软件去抖。
在硬件上可采用在键输出端加R-S触发器(双稳态触发器)或单稳态触发器构成去抖动电路,图7.3是一种由R-S触发器构成的去抖动电路,当触发器一旦翻转,触点抖动不会对其产生任何影响。
电路工作过程如下:按键未按下时,a = 0,b = 1,输出Q = 1,按键按下时,因按键的机械弹性作用的影响,使按键产生抖动,当开关没有稳定到达b端时,因与非门2输出为0反馈到与非门1的输入端,封锁了与非门1,双稳态电路的状态不会改变,输出保持为1,输出Q不会产生抖动的波形。当开关稳定到达b端时,因a = 1,b = 0,使Q = 0,双稳态电路状态发生翻转。当释放按键时,在开关未稳定到达a端时,因Q = 0,封锁了与非门2,双稳态电路的状态不变,输出Q保持不变,消除了后沿的抖动波形。当开关稳定到达b端时,因a = 0,b = 0,使Q = 1,双稳态电路状态发生翻转,输出Q重新返回原状态。由此 右图 双稳态去抖电路
可见,键盘输出经双稳态电路之后,输出已变为规范的矩形方波。
软件上采取的措施是:在检测到有按键按下时,执行一个10ms左右(具体时间应视所使用的按键进行调整)的延时程序后,再确认该键电平是否仍保持闭合状态电平,若仍保持闭合状态电平,则确认该键处于闭合状态;同理,在检测到该键释放后,也应采用相同的步骤进行确认,从而可消除抖动的影响。
4.按键编码
一组按键或键盘都要通过I/O口线查询按键的开关状态。根据键盘结构的不同,采用不同的编码。无论有无编码,以及采用什么编码,最后都要转换成为与累加器中数值相对应的键值,以实现按键功能程序的跳转。
5.编制键盘程序
一个完善的键盘控制程序应具备以下功能:
(1)检测有无按键按下,并采取硬件或软件措施,消除键盘按键机械触点抖动的影响。
(2)有可靠的逻辑处理办法。每次只处理一个按键,其间对任何按键的操作对系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序。
(3)准确输出按键值(或键号),以满足跳转指令要求。
独立式按键
单片机控制系统中,往往只需要几个功能键,此时,可采用独立式按键结构。
1.独立式按键结构
独立式按键是直接用I/O口线构成的单个按键电路,其特点是每个按键单独占用一根I/O
左图 独立式按键电路
口线,每个按键的工作不会影响其它I/O口线的状态。独立式按键的典型应用如图7.4所示。
独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一根I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。
图7.4中按键输入均采用低电平有效,此外,上拉电阻保证了按键断开时,I/O口线有确定的高电平。当I/O口线内部有上拉电阻时,外电路可不接上拉电阻。
2.独立式按键的软件结构
独立式按键软件常采用查询式结构。先逐位查询每根I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。图7.4中的I/O口采用P1口,请读者自行编制相应的软件。
7.1.3 矩阵式按键
单片机系统中,若使按键较多时,通常采用矩阵式(也称行列式)键盘。
1.矩阵式键盘的结构及原理
矩阵式键盘由行线和列线组成,按键位于行、列线的交叉点上,其结构如下图所示。
由图可知,一个4×4的行、列结构可以构成一个含有16个按键的键盘,显然,在按键数量较多时,矩阵式键盘较之独立式按键键盘要节省很多I/O口。
矩阵式键盘中,行、列线分别连接到按键开关的两端,行线通过上拉电阻接到+5V上。当无键按下时,行线处于高电平状态;当有键按下时,行、列线将导通,此时,行线电平将由与此行线相连的列线电平决定。这是识别按键是否按下的关键。然而,矩阵键盘中的行线、列线和多个键相连,各按键按下与否均影响该键所在行线和列线的电平,各按键间将相互影响,因此,必须将行线、列线信号配合起来作适当处理,才能确定闭合键的位置。
2.矩阵式键盘按键的识别
识别按键的方法很多,其中,最常见的方法是扫描法。下面以图7.5中8号键的识别为例来说明扫描法识别按键的过程。
按键按下时,与此键相连的行线与列线导通,行线在无键按下时处在高电平,显然,如果让所有的列线也处在高电平,那么,按键按下与否不会引起行线电平的变化,因此,必须使所有列线处在低电平,只有这样,当有键按下时,该键所在的行电平才会由高电平变为低电平。CPU根据行电平的变化,便能判定相应的行有键按下。8号键按下时,第2行一定为低电平,然而,第2行为低电平时,能否肯定是8号键按下呢?回答是否定的,因为9、10、11号键按下同样使第2行为低电平。为进一步确定具体键,不能使所有列线在同一时刻都处在低电平,可在某一时刻只让一条列线处于低电平,其余列线均处于高电平,另一时刻,让下一列处在低电平,依此循环,这种依次轮流每次选通一列的工作方式称为键盘扫描。采用键盘扫描后,再来观察8号键按下时的工作过程,当第0列处于低电平时,第2行处于低电平,而第1、2、3列处于低电平时,第2行却处在高电平,由此可判定按下的键应是第2行与第0列的交叉点,即8号键。
3.键盘的编码
对于独立式按键键盘,因按键数量少,可根据实际需要灵活编码。对于矩阵式键盘,按键的位置由行号和列号唯一确定,因此可分别对行号和列号进行二进制编码,然后将两值合成一个字节,高4位是行号,低4位是列号。如图7.5中的8号键,它位于第2行,第0列,因此,其键盘编码应为20H。采用上述编码对于不同行的键离散性较大,不利于散转指令对按键进行处理。因此,可采用依次排列键号的方式对安排进行编码。以图7.5中的4×4键盘为例,可将键号编码为:01H、02H、03H…0EH、0FH、10H等16个键号。编码相互转换可通过计算或查表的方法实现。
4.键盘的工作方式
在单片机应用系统中,键盘扫描只是CPU的工作内容之一。CPU对键盘的响应取决于键盘的工作方式,键盘的工作方式应根据实际应用系统中CPU的工作状况而定,其选取的原则是既要保证CPU能及时响应按键操作,又不要过多占用CPU的工作时间。通常,键盘的工作方式有三种,即编程扫描、定时扫描和中断扫描。
1)编程扫描方式
编程扫描方式是利用CPU完成其它工作的空余调用键盘扫描子程序来响应键盘输入的要求。在执行键功能程序时,CPU不再响应键输入要求,直到CPU重新扫描键盘为止。
键盘扫描程序一般应包括以下内容:
(1)判别有无键按下。
(2)键盘扫描取得闭合键的行、列值。
(3)用计算法或查表法得到键值。
(4)判断闭合键是否释放,如没释放则继续等待。
(5)将闭合键键号保存,同时转去执行该闭合键的功能。
巨额外债是发展中国家陷入危机的主要原因。治国与治家其实是同样的道理,高负债必然导致经济健康状态的脆弱,当外界金融环境完全不可控的情况下,得以生存只能凭侥幸。在现实世界中,国际银行家操纵着国际地缘政治的走势,可以轻易使原来看起来很可靠的金融环境突然逆转,从而大幅度地增加发展中国家债务的负担,金融黑客再乘势发动猛攻,得手的概率相当大。
完全没有风险意识,尤其是对可能遭到巨大而无形的伦敦-华尔街势力的不宣而战毫无心理准备。这是泰国金融战败的第二个重要原因。
对敌人的主攻方向判断完全错误,导致先败于金融黑客,后惨遭IMF 宰割,相当于失败了两次。东南亚国家普遍重复了泰国的金融战败的过程。
发动一场亚洲货币绞杀战旨在达到的主要战略目的是:敲碎“亚洲发展模式”这个招牌,让亚洲货币对美元严重贬值,既压低了美国的进口价格以便于操控通货膨胀率,又可将亚洲国家的核心资产贱价抛售给欧美公司,加快“有控制的解体”的执行进度。还有一个非常重要的目的,那就是刺激亚洲国家对美元的需求。对经历过金融风暴的亚洲国家来说,美元储备在关键时刻是何等“宝贵”,惨痛的教训会让他们永远不敢动抛弃美元储备的念头。
货币战争(十二):http://blog.eastmoney.com/huangxingyuan/blog_100171444.html
完全没有风险意识,尤其是对可能遭到巨大而无形的伦敦-华尔街势力的不宣而战毫无心理准备。这是泰国金融战败的第二个重要原因。
对敌人的主攻方向判断完全错误,导致先败于金融黑客,后惨遭IMF 宰割,相当于失败了两次。东南亚国家普遍重复了泰国的金融战败的过程。
发动一场亚洲货币绞杀战旨在达到的主要战略目的是:敲碎“亚洲发展模式”这个招牌,让亚洲货币对美元严重贬值,既压低了美国的进口价格以便于操控通货膨胀率,又可将亚洲国家的核心资产贱价抛售给欧美公司,加快“有控制的解体”的执行进度。还有一个非常重要的目的,那就是刺激亚洲国家对美元的需求。对经历过金融风暴的亚洲国家来说,美元储备在关键时刻是何等“宝贵”,惨痛的教训会让他们永远不敢动抛弃美元储备的念头。
货币战争(十二):http://blog.eastmoney.com/huangxingyuan/blog_100171444.html
今天在新浪微博上看到@朱志一条微博:
听到一个真事,腾讯pony晚上一点在微信群里面提了一个小bug,下属立即组织行动小组,第二天6点解决了问题。360,新浪大都这样。以前总觉得大公司官僚,执行力低下,现在看看,能超越大公司执行力的创业公司寥寥无几。要在大公司夹缝中生存,只能模式创新。
然后看到@胡宁一条转发评论:
这段子表现出国内公司典型的敬畏上司,无原则讨领导欢心的倾向。回国这些年,感觉下属们普遍很"乖"。老板提出的意见,即使再微不足道甚至可能是错的,优先级自然是最高的,加班加点地处理。这种特权,固然体现执行力,令领导舒服,更值得警惕。调查一下:带团队的你,怎么看?
然后看到@纯银V的一条评论:
普通职员和高级职员最大的区别,不在于经验或者才能,而是普通职员靠上级安排的任务来驱动自己,高级职员靠责任感与成长目标来驱动自己。
觉得这个话题蛮有意思的,所以想写篇文章谈谈我的个人观点,一家之言,非常可能谬误,权当抛砖引玉。
腾讯微信的执行力是不是媚上?
@朱志这个段子需要一些上下文,前不久马化腾参加两会期间接受的采访谈到:
我们也是跟Line一样,在同一个月内,在美国也是设立办公室,在加紧去拓展欧美市场。但是大家都知道美国其实可能是最难的,所以现在还很难说,因为当地最强的就是Facebook。 可能竞争是要按天来计算的,都是生死时速 ,每天都在计算的这样一个竞争场景,我们也希望能够尽一把力,成和不成可能这辈子就这个机会了。
微信和Line的国际化竞争已经按天来计算了,必须要求按天来修复产品bug,这并不是媚上的需要,而是产品竞争客观上必须要求的执行速度。所以我对马化腾的勤奋,对微信团队自身的勤奋,抱着高度的敬佩,同时我也非常看好微信的前景。
阅读全文
听到一个真事,腾讯pony晚上一点在微信群里面提了一个小bug,下属立即组织行动小组,第二天6点解决了问题。360,新浪大都这样。以前总觉得大公司官僚,执行力低下,现在看看,能超越大公司执行力的创业公司寥寥无几。要在大公司夹缝中生存,只能模式创新。
然后看到@胡宁一条转发评论:
这段子表现出国内公司典型的敬畏上司,无原则讨领导欢心的倾向。回国这些年,感觉下属们普遍很"乖"。老板提出的意见,即使再微不足道甚至可能是错的,优先级自然是最高的,加班加点地处理。这种特权,固然体现执行力,令领导舒服,更值得警惕。调查一下:带团队的你,怎么看?
然后看到@纯银V的一条评论:
普通职员和高级职员最大的区别,不在于经验或者才能,而是普通职员靠上级安排的任务来驱动自己,高级职员靠责任感与成长目标来驱动自己。
觉得这个话题蛮有意思的,所以想写篇文章谈谈我的个人观点,一家之言,非常可能谬误,权当抛砖引玉。
腾讯微信的执行力是不是媚上?
@朱志这个段子需要一些上下文,前不久马化腾参加两会期间接受的采访谈到:
我们也是跟Line一样,在同一个月内,在美国也是设立办公室,在加紧去拓展欧美市场。但是大家都知道美国其实可能是最难的,所以现在还很难说,因为当地最强的就是Facebook。 可能竞争是要按天来计算的,都是生死时速 ,每天都在计算的这样一个竞争场景,我们也希望能够尽一把力,成和不成可能这辈子就这个机会了。
微信和Line的国际化竞争已经按天来计算了,必须要求按天来修复产品bug,这并不是媚上的需要,而是产品竞争客观上必须要求的执行速度。所以我对马化腾的勤奋,对微信团队自身的勤奋,抱着高度的敬佩,同时我也非常看好微信的前景。
阅读全文
http://www.faxiandao.com/archives/7680
http://www.faxiandao.com/archives/7662
http://www.faxiandao.com/archives/7160
关于腾讯的,感觉写得可以,Mark......
http://www.faxiandao.com/archives/7662
http://www.faxiandao.com/archives/7160
关于腾讯的,感觉写得可以,Mark......
截至目前:所有的行业都是娱乐业,因为娱乐业是最靠体验的,是大众的,没有抓到用户本质的东西需求,所有离开了用户需求的用户体验改进都是耍流氓。---提炼By Jack.
没有抓到用户本质的东西需求,所有离开了用户需求的用户体验改进都是耍流氓。所有的行业都是娱乐业,因为娱乐业是最靠体验的,我们在日常生活中,卖一瓶 水,你喝了你有体验,反正能解渴,不超出体验,好歹有一个东西,但是花70元看一场电影,在拉斯维加斯看一场秀,得到了什么,什么都没买到,买到的是一个 标准体验,所有电影、所有秀能不能成功,在于能不能给你一个巨大的情感冲击。
这个用户体验广义来说不仅仅是我刚才说的体检、开机加速、一键优化,最重要的体验是什么?给用户超出预期的体验是免费,商业模式颠覆不错,但是马后 炮,对用户来说不管什么商业模式,你怎么赚钱我不管,我知道我过去花一两百买一套杀毒,周鸿祎给我免费了,不仅免费,还是终身免费,永远免费,当时杀毒厂 商说我们降价一半,我们变得更便宜,这个不叫超出预期,只是说在不断的改善,只有彻底免费才叫超出预期。
如何在众多的功能中找到一 个点作为突破点,再大的一个市场也需要一个针尖一样点的做切入,所有成功的产品都要找到一个点,通过聚焦,把有限的资源聚焦到一个点上,才能形成压强...
当年百度超越谷歌的时候,百度在刚起步的时候,真的搜索技术比谷歌做得好?不是,是因为MP3搜索,会听到很多民工级用户在交流的时候,不会说我去 用一个搜索引擎,会说有一个网站上面可以免费听歌,可以免费下歌,如果能听到用户这样的声音,就恭喜你,说明你找到了一个值得聚焦的一个点,因为这是用户 关心的。
对微信的描述,特别是目前阶段用户的心理,那种空虚等,表述清楚明晰。
对搜索的抨击...
运用老毛的:伤其十指,不如断其一指...
什么叫超出预期,只有彻底免费才叫超出预期。那目前有没有什么东东自己能做到超出预期呢?这些都是作为一个技术人员的产品经理能,也有可能做到的,需要思考....
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
阅读全文
没有抓到用户本质的东西需求,所有离开了用户需求的用户体验改进都是耍流氓。所有的行业都是娱乐业,因为娱乐业是最靠体验的,我们在日常生活中,卖一瓶 水,你喝了你有体验,反正能解渴,不超出体验,好歹有一个东西,但是花70元看一场电影,在拉斯维加斯看一场秀,得到了什么,什么都没买到,买到的是一个 标准体验,所有电影、所有秀能不能成功,在于能不能给你一个巨大的情感冲击。
这个用户体验广义来说不仅仅是我刚才说的体检、开机加速、一键优化,最重要的体验是什么?给用户超出预期的体验是免费,商业模式颠覆不错,但是马后 炮,对用户来说不管什么商业模式,你怎么赚钱我不管,我知道我过去花一两百买一套杀毒,周鸿祎给我免费了,不仅免费,还是终身免费,永远免费,当时杀毒厂 商说我们降价一半,我们变得更便宜,这个不叫超出预期,只是说在不断的改善,只有彻底免费才叫超出预期。
如何在众多的功能中找到一 个点作为突破点,再大的一个市场也需要一个针尖一样点的做切入,所有成功的产品都要找到一个点,通过聚焦,把有限的资源聚焦到一个点上,才能形成压强...
当年百度超越谷歌的时候,百度在刚起步的时候,真的搜索技术比谷歌做得好?不是,是因为MP3搜索,会听到很多民工级用户在交流的时候,不会说我去 用一个搜索引擎,会说有一个网站上面可以免费听歌,可以免费下歌,如果能听到用户这样的声音,就恭喜你,说明你找到了一个值得聚焦的一个点,因为这是用户 关心的。
对微信的描述,特别是目前阶段用户的心理,那种空虚等,表述清楚明晰。
对搜索的抨击...
运用老毛的:伤其十指,不如断其一指...
什么叫超出预期,只有彻底免费才叫超出预期。那目前有没有什么东东自己能做到超出预期呢?这些都是作为一个技术人员的产品经理能,也有可能做到的,需要思考....
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
阅读全文