ESP8266原生代码写闪灯Blink
参考:
ESP8266-blink
初始化的时候需要调用gpio_init()
然后,上述Github代码中欠缺一个非常重要的步骤:需要选择gpio的功能,使用PIN_FUNC_SELECT
然后使用GPIO_OUTPUT_SET设置电平。
GPIO2是模块上的LED,GPIO14是接口板的LED
参考:
ESP8266-blink
初始化的时候需要调用gpio_init()
然后,上述Github代码中欠缺一个非常重要的步骤:需要选择gpio的功能,使用PIN_FUNC_SELECT
然后使用GPIO_OUTPUT_SET设置电平。
GPIO2是模块上的LED,GPIO14是接口板的LED
二级域名设置为grav.idarc.cn,通过隐性Url转向到idarc.cn/grav ,这个时候,发现在手机浏览器上显示的仍然是PC端的布局方式。在chrome中调试,发现grav的页面是响应式布局,缩小chrome边框会逐渐改为手机布局方式。chrome调试打开手机模拟(Nexus 6P),发现仍然是PC布局,查看window.innerWidth,居然=950。直接打开idarc.cn/grav ,查看window.innerWidth,布局正确,是手机样式,并且window.width=412,也是没错的。
同事在使用官方的EspFlashDownloadTool的时候,虽然能一次同时烧录8个,然而烧录完毕后该工具不会自动重启ESP固件,每次还需要为每个设备手动去选择串口,以及为不同产品选择不同的bin文件。
为什么用Python开发:本来对node.js比较熟悉,然而考虑到要给同事安装,装完node又装python 显得很麻烦,而且node的serialport模块需要安装node-gyp,node-gyp需要vs studio本地编译,并且项目依赖还需要npm install。最坑爹的是serialport没有promise化,自动化和串口交互就会掉入回调地狱(虽然本项目不涉及)。而python的所有模块统一装在一起,pyserial也不需要二次编译,而且似乎pyserial也比serialport的功能强大一些,就还是选择python开发,虽然一两年每碰python手生得很了——得抱着本书在旁边当字典。
最终源码只需要单个文件,如起个名字叫autoflash.py,关联python可以直接运行。
安装过程:
1. 装python2.7.14,装的时候添加python路径的选项要勾上;
2. 更换pip源为豆瓣,(国内开发python靠豆瓣,开发node靠淘宝啊),在用户目录(如C:\users\xxx)下新建pip\pip.ini ,输入:
[global]
index-url = https://pypi.douban.com/simple
pip install esptool
解释一下subprocess,Popen默认是开新的子进程的。等待进程结束使用wait或者communicate,不过建议用communicate,因为后者机制上更好一些,不容易出问题。
serial_port方法的源码来自于Seg
源码如下:
#!/usr/bin/env python
from __future__ import division, print_function
import sys
import glob
import subprocess
import multiprocessing as mp
import shlex
import serial
def serial_ports():
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(256)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def main():
sps = serial_ports()
print(sps)
processes = {}
for sp in sps:
cmd = shlex.split('esptool.py --port ' + sp +
' --baud 1152000 --after hard_reset write_flash 0x00000 \
eagle.flash.bin 0x10000 eagle.irom0text.bin 0x3fc000 esp_init_data_default.bin')
print(cmd)
processes[sp] = subprocess.Popen(cmd)
for sp in sps:
processes[sp].communicate()
print('[Finished]')
if __name__ == '__main__':
main()
BLE事实上是完全不同的技术,与经典蓝牙完全不兼容。最早由诺基亚与2006提出,名字开始也不叫蓝牙,叫Wibree。并且在蓝牙4.0版本中被纳入。
BLE传输距离100米,空中速率125k/1M/2Mbps,应用速率270kbps,延时仅6ms,发送数据耗时仅3ms,发射功率10mW,功耗10mW~500mW。峰值电流15mA。
BLE使用3个独立信道发送广播包来发现彼此。设备每隔一个广播间隔发送一次广播包,为防止冲突,发送间隔会加上一个<10ms的随机值。扫描者在每个扫描间隔后的扫描窗口上监听。
客户端Client,一般是手机、电脑,发送GATT( Generic Attribute Profile)命令和请求,接收回应。
服务端Server,例如温度传感器,接收GATT请求并回应。
特性Characteristic,客户端、服务端之间传输的数据,如电池电压。
服务Service,一组相关特性,组合提供特定功能。如体温服务包括温度测量值、测温间隔等特性。
描述符Descriptor,为特性提供额外信息。例如温度特性可能有单位、最大最小可测量值。特性可有0个或多个描述符。
有的特性和描述符是用于系统管理的,如通用访问(Generic Access)服务可读取模块名、序列号等特性。服务也可以包括其他子服务。设备主要功能称为主服务、辅助功能称为次服务。
标识Identifiers,特性、服务、描述符统称为属性attributes,以UUID标识。任何实现都可以为特定用法选择随机或者伪随机的UUID,但蓝牙标准保留了一些UUID(形式是 xxxxxxxx-0000-1000-8000-00805F9B34FB )做标准属性。
128位的UUID常常在标准服务中被省略为16位或32位。例如,设备信息服务简称是0x180A,而不是0000180A-0000-1000-... 完整列表在这儿
GATT操作,GATT有一系列的命令,用于客户端发现服务端。
命令还能读(C<-S)写(C->S)特性值。
可以通过特性的UUID、或者句柄值读取值。
写入操作一般以句柄标识特性,还可选择是否从服务端返回。
当特性数据超过MTU,可以使用“长读”和“长写”操作。
GATT提供通知和指示。客户端可以从服务端请求特定特性的一个通知。服务端可以在特性值可用的时候再发给客户端(有点像订阅)。例如,温度传感器可以在每次测出温度后通知客户端。这可以防止客户端轮询服务端。
指示和通知类似,不同点是,指示需要客户端回应他收到了消息。
中心设备和外围设备的耗电不同。距离信标(proximity beacons)设备可以使用1000mA的纽扣电池工作1~2年。另一方面,持续扫描这些信标的设备可以在几小时内耗光1000mA电量。
2016年6月sig发布蓝牙5,新增如下特性
参考文章
截取解释部分:
帧控制(2 bytes):
用于指示数据帧的类型,是否分片等等信息,说白了,这个字段就是记录了mac 802.11的属性。
*Protocol version:表明版本类型,现在所有帧里面这个字段都是0x00
*Type:指明数据帧类型,是管理帧,数据帧还是控制帧
*Subtype:指明数据帧的子类型,因为就算是控制帧,控制帧还分RTS帧,CTS帧,ACK帧等等,通过这个域判断出该数据帧的具体类型
*To DS/From DS:这两个数据帧表明数据包的发送方向,分四种可能情况讨论
**若数据包To DS为0,From DS为0,表明该数据包在网络主机间传输
**若数据包To DS为0,From DS为1,表明该数据帧来自AP
**若数据包To DS为1,From DS为0,表明该数据帧发送往AP
**若数据包To DS为1,From DS为1,表明该数据帧是从AP发送自AP的,也就是说这个是个WDS(Wireless Distribution System)数据帧,至于什么是WDS,可以参考下这里的介绍 #传送门
*Moreflag:分片标志,若数据帧被分片了,那么这个标志为1,否则为0
*Retry:表明是否是重发的帧,若是为1,不是为0
*PowerManage:当网络主机处于省电模式时,该标志为1,否则为0.
*Moredata:当AP缓存了处于省电模式下的网络主机的数据包时,AP给该省电模式下的网络主机的数据帧中该位为1,否则为0
*Wep:加密标志,若为1表示数据内容加密,否则为0
*Order 这个表示用于PCF模式下,这里不予讨论
生存周期/Associate ID (2 bytes):
先前不是讲过虚拟载波监听的一个机制么,他的Network Allocation Vector(NAV)就存在这里,这里叫duration,即生存周期。当然不是所有时候这个字段存放的NAV值。在特定类型数据帧中,它也可能表示Associate ID。一旦有主机关联到AP了,AP都会为主机分配一个Associate ID。比如在网络主机通知AP自己要进入省电模式(power saving)的时候,网络主机发给AP的通知数据帧里面,这个域就表示的是Associate ID而不是NAV了。当然还可以通过最高位来判断这个域的含义:
*在15bit为0的时候,该域表示duration
*在15bit为1,14bit为1的时候,表示Associate ID。
序列控制(2 bytes:4 bits/12 bits):这个域分2部分,一个是分片序列号和标识帧列号。分片序列号就是记录分片序号的。比如一个帧A被分片成a1,a2,a3,那么a1,a2,a3这三个分片帧的分片序列分别是0,1,2。这个和IP分段原理一样的,该域占4个比特位。剩下的12个比特位就用于标识帧的序号,这个跟IP头里面的序列号一样。
MAC地址 1-4
这四个地址在不同帧中有不同含义。这些以后会讨论。
以后我们可能会碰到以下类型的mac地址
RA(receiver address):无线网络中,该数据帧的接收者
TA(transmitter address):无线网络中,该数据帧的发送者
BSSID(Basic Service Set ID):在infrastructure BBS中,BSSID就是AP的mac地址。但是在IBBS中,它是一个随机即生成的46位二进制序列,还有最高两位分别是Universal/Local标志位和Individual/Group标志位。IBBS的BSSID中,Universal/Local标志位为1,表示本地MAC,Individual/Group标志位为0,表示是个人MAC。也就是说在IBBS中,BSSID地址应该类如 10xxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx(x表示随机数要么0要么1, 2进制表示)
DA(destine address):该帧的目的mac地址
SA(source address):该帧的源mac地址
这里的DA和SA含义和普通以太网中的含义一样,在无线网络中可能我们需要通过AP把数据发送到其它网络内的某台主机中。但是有的人会奇怪,直接在RA中填这台主机的mac地址不就久好了么。但是请注意RA的含义,说的是无线网络中的接收者,不是网络中的接收者,也就是说这台目的主机不再无线网络范围内。在这种情况下我们的RA只是一个中转,所以需要多出一个DA字段来指明该帧的最终目的地,当然,如果有了DA那必须有SA,因为若目的主机要回应的话,SA字段是必不可少的。(假设没有SA字段,那么目的主机回应的数据包就只能发送到源主机所属的AP上了~)
URI编码有%20等这样的字符,以%来转义不适合在URI中传输的字符.
在JS中有两对编解码函数, encodeURI/decodeURI和encodeURIComponent/decodeURIComponent, 有什么区别? 参考这篇文章
举例:
//保留字符
encodeURI('?')
"?"
encodeURIComponent('?')
"%3F"
decodeURI('%3F')
"%3F"
decodeURIComponent('%3F')
"?"
//非打印字符
encodeURI(' ')
"%20"
encodeURIComponent(' ')
"%20"
decodeURI('%20')
" "
decodeURIComponent('%20')
" "
//mark字符
encodeURI('_')
"_"
encodeURIComponent('_')
"_"
"?"属于URI中特殊的字符,而空格不是,这两对编解码函数的区别就是这一类特殊字符(保留字符)要不要被编解码.
Mark字符与基本字符一样,不需要被编解码.
保留字符(reserved characters):这类字符是URI中的保留关键字符,它们用于分割URI中的各个部分。这些字符是:";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
Mark字符(mark characters):这类字符在RFC-2396中特别定义,但是没有特别说明用途,可能是和别的RFC标准相关。 这些字符是:"-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
基本字符(alphanum characters):这类字符是URI中的主体部分,它包括所有的大写字母、小写字母和数字
其他非打印字符都需要被编解码
蓝牙分为两个互不兼容的版本:经典蓝牙和低功耗蓝牙。前者又称为BR/EDR,后者又称为BLE,BLE又分为Smart和Smart Ready,前者是单向,后者是双向。
蓝牙使用2.4G~2.483.5G之间的频段,其中2.400~2.402G(2M)、2.480~2.483.5G(3.5M)为保护频段,2.402~2.480为实际使用的频段。
在经典蓝牙中,2.402~2.480这79M频段依次划分为79个信道,编号0~78(这与WIFI 2.4G的1~13编号方式不同),BLE中,则是每2M划分一个频段,共40个信道(实际上用了2.402~2.481G),编号0~39.
经典蓝牙中,BR是基本速率,为1Mbps,使用GFSK调制,EDR为2或3Mbps,分别采用π/4-DPSK和8DPSK调制。
通信上采用主从制,基本网络称为piconet,最多1主7从,扩展网络称为scatternet,实际为一个设备的双重身份,在一个网络里为从在另一个里面为主。一个piconet中,主设备定义时钟,1个tick(滴答)为312.5us,2个tick为一个slot(槽),2个slot为一个slot pair(槽对),一个包长为1,3,5个槽,主设备双号槽发送、单号槽接收(双发单收),从设备相反。
除了极少用到的广播外,主从同一时间为一对一通讯,主设备对多通讯为按RR(Round-robin)规则时分复用快速切换。从设备需要时时监听所有接收槽,所以从设备负担要比主设备重一些。一个从设备也可以同时监听多个主设备。
2.4G信号虽然没有可见的线缆,然而传输需要电磁波衍射路径的通畅。辐射功率1~4级,从100mW到0.5mW,增益从20DBm到-3DBm,典型距离从100米到0.5米。
由于class 1级一般用于工业,而一般消费蓝牙设备都是电池供电,采用的是class 2标准。
然而在蓝牙3、4、5这几个版本中,最大速度增加到25、50Mbps,最大距离增加到10~240米。
最终覆盖受到传播条件、覆盖物、产品样品多样性、天线配置、电池电量等的影响。实际空旷环境中,两个class 1设备可以通讯超过1km。
参考文章
常用的创建硬链接和软连接方式。
软连接相当于windows的快捷方式。
而硬链接则相当于指针,而源文件名也是指针,只有在指针都删除的时候,源文件才会被删除。
ln /path/to/file /path/to/hardlink
ln -s /path/to/file /path/to/link
ubuntu on windows里面的蓝色几乎看不清楚,windows项目组出了个新theme,然而只针对新购windows,升级并不能覆盖。自己如何修改?
打开cmd,右上角邮件,选择默认值->颜色,依次点选各个颜色并修改右面的三个数字即可。
参考微软的新旧theme:
微软原文链接
Color Name | Console Legacy RGB Values | New Default RGB Values |
---|---|---|
BLACK | 0,0,0 | 12,12,12 |
DARK_BLUE | 0,0,128 | 0,55,218 |
DARK_GREEN | 0,128,0 | 19,161,14 |
DARK_CYAN | 0,128,128 | 58,150,221 |
DARK_RED | 128,0,0 | 197,15,31 |
DARK_MAGENTA | 128,0,128 | 136,23,152 |
DARK_YELLOW | 128,128,0 | 193,156,0 |
DARK_WHITE | 192,192,192 | 204,204,204 |
BRIGHT_BLACK | 128,128,128 | 118,118,118 |
BRIGHT_BLUE | 0,0,255 | 59,120,255 |
BRIGHT_GREEN | 0,255,0 | 22,198,12 |
BRIGHT_CYAN | 0,255,255 | 97,214,214 |
BRIGHT_RED | 255,0,0 | 231,72,86 |
BRIGHT_MAGENTA | 255,0,255 | 180,0,158 |
BRIGHT_YELLOW | 255,255,0 | 249,241,165 |
WHITE | 255,255,255 | 242,242,242 |
打开windows cmd(admin权限)
lxrun /setdefaultuser root
bash
passwd your_username
exit
lxrun /setdefaultuser your_username
9 to 5 is for the weak. NYTimes在一篇讲硅谷工作狂们的文章中这样说到。这也是中国IT业者的同样问题。
然而结果是,虽然你这么努力,但是那并没有什么用
NYTimes的这篇文章说的和我的看法一样,全文转载至此。
在硅谷,朝九晚五属于失败者
DANIEL SAVAGE
DAN LYONS
2017年9月1日
硅谷为“不同凡想(thinking different)”而自豪。因此,在许多行业开始更加注重工作和生活的平衡时,硅谷反其道而行之,把工作狂标榜为理想的生活方式之选可能看上去也说得通。那里已经出现了一个完全是作坊式的产业,贩卖以互联网为中心的成功学,称没有比创业更崇高的使命,还说要取得成功,必须愿意放弃一切。
科技行业从业者用“奋斗”(Hustle)这个词来描述这种极客突击队的生活方式。到处都能听到这个词,还能买到以它为主题的T恤和咖啡杯,上面印着“梦想、奋斗、利润、重复”和“比所有人都更辛苦、更忙碌、更努力”口号。你可以去为期八周的“创业奋斗”训练营(训练营!),也可以参加只有一天时间的奋斗大会(Hustle Con),听成功的“奋斗者”分享他们的诀窍。票价300美元左右(约合2000元人民币),或者你也可以花2000美元(约合13000人民币),成为“VIP奋斗者”。今年的大会已于6月举行,吸引了2800人,其中20多人花钱买了VIP票。
但对一些人来说,“奋斗”只是极端工作狂的一种委婉说法。加里·沃伊内楚克(Gary Vaynerchuk),又名加里·维伊(Gary Vee),是一位企业家,也是一名天使投资人。他在Twitter上有150万粉丝,还出版了一系列以《碾压它》(Crush It!)等为名的畅销书。他告诉自己的粉丝,他们应该一天工作18个小时。每天都这样。不能休假,不能约会,不能看电视。“想闪亮全场吗?想买飞机吗?”他在一场励志演讲中问道。“那就工作吧。工作才能让你得到这一切。”
沃伊内楚克还是苹果《应用星球》(Planet of the Apps)的评委。这是一档应用开发者争夺一家风险投资公司资金的真人秀节目。在最近的广告中,一名参赛者旁边的引语是:“我几乎见不到我的孩子。这是必须承担的风险。”节目的宣传推文接着说:“为了最终的奖励,他将投入一切。”
天哪。这名参赛者正在开发一款应用,它能让你直观地看到商品目录上的一款咖啡桌放在你家客厅里是什么样子。我想,这款应用很酷,但它真的比见到自己的孩子更重要吗?筹集到一些风险投资的机会,真的是“最终的奖励”吗?(在Twitter上引发批评浪潮后,苹果撤下了这篇宣传推文。)
这对创业者来说够惨了,但普通员工也相信这种疯狂。去年,Lyft发表了一篇博客,称赞一名在开始阵痛后仍坚持载客并自己驾车去医院分娩的司机。批评人士从中看到了反乌托邦的意涵——Gizmodo网站的评价是“骇人听闻”——Lyft删除了博客。但该公司的员工,包括那名司机自己,似乎真的对文章引起的负面反馈感到不解。
一百年前,工厂工人成立工会并举行罢工,要求改善工作条件和限制工作时间。如今,硅谷的员工却颂扬自己遭受的剥削。一款流行T恤上写着“朝九晚五属于无能者”(9 to 5 is for the weak)。一个名叫基思·拉布瓦(Keith Rabois)的风险投资人最近在Twitter上炫耀自己工作18年,休假时间不超过一周。渴望成为扎克伯格的人被告知,创业就像加入海豹突击队(Navy SEALs)一样。对某一类人——通常是年轻、男性——来说,磨难也是诱惑的一部分。
真相是,这些创业者和他们的员工付出的额外努力中,很多是没有意义的。根据斯坦福大学的经济学家约翰·彭卡韦尔(John Pencavel)在2014年发布的一份报告,一周工作超过56个小时几乎不会带来生产率的增加。但重要的可能不是生产率,而是表现出责任感和团队精神。
“人人都想当模范员工,”目睹很多科技行业员工压力过大的湾区临床社工阿尼姆·阿韦(Anim Aweh)说。“一个女人告诉我:‘对员工的期望不是聪明地工作,而是努力地工作。就是工作、工作、工作,直到再也动不了。’”
广告
这已经造成了悲剧。去年,优步(Uber)的工程师约瑟夫·托马斯(Joseph Thomas)自杀。他的遗孀将其归咎于公司工作时间长、心理压力大的拼命文化。
现在,一些人开始反击。软件开发人员戴维·海涅迈尔·汉森(David Heinemeier Hansson)正试图说服创业者,让他们相信不用累得要死也能成功。(遗憾的是,这一点居然还需要说。)
在最近的一篇文章中,汉森指责风险投资人用“根深蒂固的创业神话”给创业者洗脑,“不仅颂扬掏空自己,还把这作为基本要求。”他说,风险投资人在剥削创业者。他们的态度是,“要么让我富起来,要么就死在尝试的过程中,”他写道。
到目前为止,“死在尝试的过程中”的可能性更大。绝大部分创业公司都会以失败告终。取得Facebook那种级别的巨大成功的几率微乎其微。没人比风险投资人更清楚这一点了。他们通过把赌注分散在几十家公司上,并鼓动它们都变得狂热来增加自己成功的几率。
汉森的文章把工作了18年却几乎没有休假的风险投资人拉布瓦单独挑了出来。这在Twitter上引发了一场争论。拉布瓦抨击说,汉森轻松对待的创业方式堪称完美,但只是“对希望一事无成的懒人而言”。
汉森和商业伙伴贾森·弗里德(Jason Fried)经营着一家名为Basecamp的芝加哥软件公司,雇佣了56名员工,公司已经在盈利。每周的工作时间上限为40小时,夏季削减到32小时。汉森先生拥有足够多的空闲时间,可以作为业余车手参加耐力赛车比赛。
2010年,两人出版了一本谴责工作狂的书《重来》(Rework),明年他们还要出版一本《平静的公司》(The Calm Company)。汉森对我说,“看到人们在创业的祭坛上被要求放弃假期、睡眠、青春、家庭和伦理”,他们有一种触目惊心的感觉。
他们举办研讨会,发表了很多公开演讲。弗里德说,他们的发言通常都被很好地接纳——尽管在旧金山,他们经常听到“不可思议的吸气声”。汉森则说:“有人对我们说,我们的雄心壮志不够。我们并不试图改变世界。这种扭曲的毒害太深了。”
成为下一位高科技界身家上亿的20出头名人,这种机会的吸引力依然很大。每年有数以千计的新人涌入旧金山,希望能够接受这种奋斗的宗教的洗礼。如今的情况已经很糟糕,但以后还可能更加糟糕。
Dan Lyons是《混乱:我在创业泡沫里的不幸遭遇》(Disrupted: My Misadventure in the Start-Up Bubble)的作者,他正在撰写一本关于职场文化的书。
翻译:陈亦亭、土土
用了这么多年的vim,居然只会用i, :wq, /三板斧,哈哈哈
最近用cmder开bash发现无法使用上下左右键,才又增加了一些学vim的动力。
用hjkl替代上下左右以前就知道,但用的不大顺手,
移动到行尾并编辑:Shift+A
翻页:Ctrl+F/B
文件开头:gg
文件末尾:shift+G
句首句尾:()
段首段尾:{}
~/.vimrc改造
syntax enable
syntax on
set ai
如果代码中使用了一些es2015的特性,最典型的就是用import替代require,就需要以es2015的方式运行node
npm install -g babel-cli
babel-node xxx.js --presets es2015,stage-3
腾讯电脑管家里面freecommander版本太老,是2014版的,网上好多2017 x64都是假x64,这儿是一个真实的下载地址:freecommander x64 2017 760 beta
2017 760中,支持dos box改为第三方软件从当前目录启动,我喜欢用cmder。修改方式是:
工具>设置>dos命令行>dos命令说明,改为:
C:\your_app_path\Cmder.exe %ActivDir%