骷髅峡谷拆机

前言

闲着没事拆拆骷髅峡谷看看,没想到出奇的简单。螺丝位置我都用红圈圈出来了。

先拆上盖

上盖

再拆下盖

上盖

拆上盖内部螺丝

上盖内部

拆下盖内部螺丝

下盖内部

把内部推出来,要把接口那地方稍微按一下,内壳部分就能拿出来了。

内部

把电路板拿出来,小心两根天线。

电路板

完工

看上去做工真的不错,顺便清理下风扇的灰尘。装回去声音小多了。

K2P B1版本刷梅林固件

前言

由于K2拿回家里用了,于是又撸了一台K2P放在办公室用,也是为了它的千兆有线网口,毕竟办公室是千兆网,通过K2P访问共享存储会方便快速很多。

早上下的单,第二天中午才到,一到手还是熟悉的开箱,长相颜值确实比K2高了很多,网上很多图片我也就不放了,银色版本,全身金属质感,炫酷。

简介

到手第一件事依旧是刷机,毕竟原生固件有众所周知的问题,但是一看我这版本是B1,哎毕竟非洲人。

K2P出了两个不同版本(或者严谨的说是三个,但是A2和A1只是在电容和屏蔽罩上有差别,CPU都是一样的,就不细分了),分别是A1和B1。其中A1采用的MTK MT7621A的处理器,而B1采用的是博通BCM47189,性能上面的差别网上众说纷纭,但是我试用下来反正千兆能跑满,也就不纠结那么多了。毕竟不花钱又能要求啥呢。

如果你是A1版本,那么恭喜你,网上有很多傻瓜方案都可以搞定,非常简单方便,大致流程无非是刷入Breed->刷入固件->开心使用吧。甚至Bootloader都有很多种,除了Breed还有其他可选。固件更是有非常多的选择,这里推荐荒野无灯的padavan,毕竟我K2也用的padavan还不错,当然如果喜欢LEDE之类的爱折腾的玩家也可以刷入LEDE等其他固件。

而我这B1版本就比较惨了(连官方都没出适配B1的固件),因为博通方案的缘故,Breed是没希望了,看了下至少还有一个梅林固件可用,并且CFE的一个小漏洞也让我们能开启telnet进行一些命令行操作,勉强够用了,期待以后有更多大神推出更多固件和BL。

刷机(仅限B1)

准备(开Telnet)

  1. 首先要进入官方的CFE恢复界面,开启一下telnet功能来备份官方固件(毕竟万一梅林不好用或者哪天用到了官方固件)。方法还是老套路,长按reset开机,10s后可以用192.168.2.1进入CFE界面。(这里吐槽一下斐讯的路由器默认IP居然是192.168.2.X段的)

  2. http://pan.baidu.com/s/1boIHBXH下载修改版的固件。

  3. 在计算机上启动tftp服务器,将固件解压后放入tftp服务器根目录,然后在CFE网页输入

    http://192.168.2.1/do.htm?cmd=flash+-noheader+你电脑IP:固件名

固件名默认是k2p_bcm_v10d.bin+flash0.trx,而电脑IP我设置的192.168.2.2

  1. 等个几分钟就刷好了。可以ping 192.168.2.1来看,刷的时候是不通的,刷完又通了。然后重启。

备份官方固件

  1. telnet进去路由器

  2. cat /dev/mtd0 /dev/mtd1 /dev/mtd3 /dev/mtd4 /dev/mtd5 /dev/mtd6 /dev/mtd7 > /tmp/all.bin

  3. mount --bind /tmp/all.bin /www/web-static/fonts/icofont.eot

  4. http://192.168.2.1/web-static/fonts/icofont.eot下载固件
    下载后将icofont.eot改名为all.bin,并确认固件大小为16777216字节

刷机

  1. http://pan.baidu.com/s/1boIHBXH 下载固件
  2. 同样在tftp服务器根目录下放上固件。使用
    http://192.168.2.1/do.htm?cmd=flash+-noheader+你电脑IP:固件名 刷入
    (这里固件名是K2P_Merlin_V10d.trx+flash0.trx)
  3. ping一下看刷完了用http://192.168.2.1/do.htm?cmd=nvram+erase清除下内存,然后重启。
  4. 享受梅林固件

恢复MAC地址

因为梅林和官方的内存结构不一样,所以mac地址没了,需要手动设置一下。刷完以后在web的“系统管理”-“系统设置”页面打开telnet或ssh,telnet或ssh登录名和密码是你的web登录名及密码。

ssh上去使用

设置WAN口地址
nvram set wan0_hwaddr=路由器MAC地址
设置LAN口地址
nvram set lan_hwaddr=路由器MAC地址 
nvram set et0macaddr=路由器MAC地址 
设置2.4G地址
nvram set w1_hwaddr=路由器MAC地址
nvram set wl0_hwaddr=路由器MAC地址
nvram set 0:macaddr=路由器MAC地址
设置5G地址
nvram set wl1_hwaddr=路由器MAC地址+1
nvram set sb/1/macaddr=路由器MAC地址+1
保存上述设置
nvram commit

即可

后记

刷完以后用了一段时间,表示一切正常,需要的功能(你懂得)都有,还可以开双WAN,千兆也可以跑满,不错的说。

折腾斐讯K2刷LEDE

昨天又看到有人上车,于是没有经受住诱惑,撸了一台蓝色的斐讯K2,不知道能不能安全下车。颜值嘛还可以。做功嘛略显粗糙。打开看了一下配置。MT7620,64M的RAM和8M的ROM。。。这也能标399的价格,也是呵呵了。

首先刷一个优秀的Bootloader,这里我选择Breed,毕竟当年的U-Boot已经不行了。
这里有一个神奇的方法可以刷入Breed,不禁让我对作者的脑洞感到由衷的佩服。只有一句“这TM也行”可以表达我的内心想法了。

http://www.right.com.cn/forum/thread-204435-1-1.html

刷完Breed以后重启长按reset就可以进入刷机模式,就可以刷入系统固件了。
多年经验告诉我Openwrt是个好固件,然而去年openwrt内部出现了一些问题。导致有一部分核心人员独立出来成立了LEDE-Project。全称Linux Embedded Development Environment(名字起的好霸气啊),想想以前那么多的openwrt版本,那么混乱的Issue管理和补丁发布。这次还是试试LEDE吧。毕竟是新项目,又是openwrt的核心团队搞的,应该会不错的。

LEDE官网在此

在官网一搜,居然有K2的专门版本。这下好了,不用自己编译了。交叉编译搞死人。搜索PHICOMM K2 PSG1218就可以找到了。这里也贴一下下载地址
刷完之后重启。看到一个丑丑的Luci界面。

配置好密码和网络等基本配置。还剩90%的剩余空间。爽啊。果断准备安装全套[不可描述]、[不可描述]和[不可描述]的软件。
安装过程中就不写了。水表已拆。说一句现在安装和编译东西比几年前我搞hg255d的时候简单方便多了。又不用考虑剩余内存。简直是一帆风顺啊。
嗯再放一个获取中国国内IP列表的脚本吧。

wget -O- 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | awk -F\| '/CN\|ipv4/ { printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /etc/不可描述.txt

最后装一个luci-i18n汉化包和theme包美化一下。结束战斗。

测试一下2.4G+5G(虽然我只开了5G)信号都还是不错的。速度也还算稳定。[不可描述]的速度也能跑满带宽。十分满意。最后贴个界面图,这个 luci-theme-material还是挺好看的。
图

采用Arduino IDE对ESP8266进行编程

话说ESP8266真是个神奇的芯片,不仅可以使用NodeMCU和micropython等固件,还可以直接支持采用Arduino IDE环境进行编程和烧写。本身又有wifi和gpio,又便宜。简直是折腾神器。

采用Arduino编程的最大好处是,很多库可以直接引用。不用再写一些很底层的代码去驱动外设。这大大提高的开发效率,并且像上篇文章里写的,采用lua语言的NodeMCU还是有一些局限性的。比如不支持微秒级的延时。

要采用Arduino对ESP8266进行编程,首先要有一个1.6.4版本以上的Arduino IDE

其次在设置里需要把additional board manager URLs 设置为http://arduino.esp8266.com/stable/package_esp8266com_index.json

这样在工具里的开发板选择里就有了NodeMCU1.0选项。

下载完工具链就可以直接编写了。

下面是用Arduino写的gp2y1010au0f粉尘检测来测AQI的代码。测试通过

/*
   NodeMCU连接夏普GP2Y1010AU0F空气质量传感器检测PM2.5
*/
/* 定义引脚 */
#define PIN_DATA_OUT A0 //连接空气质量传感器模拟量输出的IO口, NodeMCU只有A0可以作为ADC
#define PIN_LED_VCC 5 //空气质量传感器中为内部Led供电的引脚
/* 定义时间 */
const int DELAY_BEFORE_SAMPLING = 280; //采样前等待时间
const int DELAY_AFTER_SAMPLING = 40; //采样后等待时间
const int DELAY_LED_OFF = 9680; //间隔时间
/**
   读取输出电压
*/
double getOutputV() {
  digitalWrite(PIN_LED_VCC, LOW);
  delayMicroseconds(DELAY_BEFORE_SAMPLING);
  double analogOutput = analogRead(PIN_DATA_OUT);
  delayMicroseconds(DELAY_AFTER_SAMPLING);
  digitalWrite(PIN_LED_VCC, HIGH);
  delayMicroseconds(DELAY_LED_OFF);
  //Arduino模拟量读取值的范围为0~1023,以下换算为0~5v
  double outputV = analogOutput / 1024 * 5;
  return outputV;
}
/**
   根据输出电压计算灰尘密度
*/
double getDustDensity(double outputV) {
  //输出电压和灰尘密度换算公式: ug/m3 = (V - 0.9) / 5 * 1000
  double ugm3 = (outputV - 0.9) / 5 * 1000;
  //去除检测不到的范围
  if (ugm3 < 0) {
    ugm3 = 0;
  }
  return ugm3;
}
/**
   根据灰尘密度计算AQI
   环境空气质量指数(AQI)技术规定(试行)](http://kjs.mep.gov.cn/hjbhbz/bzwb/dqhjbh/jcgfffbz/201203/t20120302_224166.htm
*/
double getAQI(double ugm3) {
  double aqiL = 0;
  double aqiH = 0;
  double bpL = 0;
  double bpH = 0;
  double aqi = 0;
  //根据pm2.5和aqi对应关系分别计算aqi
  if (ugm3 >= 0 && ugm3 <= 35) {
    aqiL = 0;
    aqiH = 50;
    bpL = 0;
    bpH = 35;
  } else if (ugm3 > 35 && ugm3 <= 75) {
    aqiL = 50;
    aqiH = 100;
    bpL = 35;
    bpH = 75;
  } else if (ugm3 > 75 && ugm3 <= 115) {
    aqiL = 100;
    aqiH = 150;
    bpL = 75;
    bpH = 115;
  } else if (ugm3 > 115 && ugm3 <= 150) {
    aqiL = 150;
    aqiH = 200;
    bpL = 115;
    bpH = 150;
  } else if (ugm3 > 150 && ugm3 <= 250) {
    aqiL = 200;
    aqiH = 300;
    bpL = 150;
    bpH = 250;
  } else if (ugm3 > 250 && ugm3 <= 350) {
    aqiL = 300;
    aqiH = 400;
    bpL = 250;
    bpH = 350;
  } else if (ugm3 > 350) {
    aqiL = 400;
    aqiH = 500;
    bpL = 350;
    bpH = 500;
  }
  //公式aqi = (aqiH - aqiL) / (bpH - bpL) * (desity - bpL) + aqiL;
  aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL;
  return aqi;
}
/**
   根据aqi获取级别描述
*/
String getGradeInfo(double aqi) {
  String gradeInfo;
  if (aqi >= 0 && aqi <= 50) {
    gradeInfo = String("Perfect");
  } else if (aqi > 50 && aqi <= 100) {
    gradeInfo = String("Good");
  } else if (aqi > 100 && aqi <= 150) {
    gradeInfo = String("Mild polluted");
  } else if (aqi > 150 && aqi <= 200) {
    gradeInfo = String("Medium polluted");
  } else if (aqi > 200 && aqi <= 300) {
    gradeInfo = String("Heavily polluted");
  } else if (aqi > 300 && aqi <= 500) {
    gradeInfo = String("Severely polluted");
  } else {
    gradeInfo = String("Broken roof!!!");
  }
  return gradeInfo;
}
void setup() {
  Serial.begin(115200);
  pinMode(PIN_DATA_OUT, INPUT); //定义为输入(ADC读取模拟量)
  pinMode(PIN_LED_VCC, OUTPUT); //定义为输出
}
void loop() {
  double outputV = getOutputV(); //采样获取输出电压
  double ugm3 = getDustDensity(outputV); //计算灰尘浓度
  double aqi = getAQI(ugm3); //计算aqi
  String gradeInfo = getGradeInfo(aqi); //计算级别
  //打印到串口
  Serial.println(String("outputV=") + outputV + "\tug/m3=" + ugm3 + "\tAQI=" + aqi + "\tgradeInfo=" + gradeInfo);
  //间隔1秒执行下次检测
  delay(1000);
}

采用NodeMCU和GP2Y1010AU0F检测空气质量

夏普GP2Y1010AU0F传感器用于检测空气中的灰尘浓度。可以检测非常细小的灰尘,例如香烟烟雾(粒径0.1~2um)。
该传感器中心有一个孔洞,可使空气自由穿过。内部有一个LED向孔洞进行照射。当空气中的灰尘穿过孔洞时,光线反射到接收端,通过放大电路将反射光强放大并转化为输出电压。通过测量输出电压并进行响应的换算,即可得知空气中灰尘的浓度。

GP2Y1010AU0F引脚连接

(1)V-LED + 150ohm电阻 + 220uF电容->VCC
(2)LED-GND->GND
(3)LED->D1(GPIO 5)
(4)S-GND->GND
(5)VO->A0
(6)VCC->VCC

其中需要加150ohm电阻和220uF电容,连接方式如下图中红框所示:

connect

可以直接使用NodeMCU的adc即A0接口进行采样。先对GPIO 5拉低产生一个采样脉冲,读取A0的adc数据,即为输出电压。转换后可得粉尘浓度。代码如下

pin1 = 1
gpio.mode(pin1, gpio.OUTPUT) 
tmr.alarm(1, 2000, 1, function()
    gpio.write(pin1,gpio.LOW)
    adcv = adc.read(0)
    gpio.write(pin1,gpio.HIGH)
    outv = adcv/ 1024 * 5
    ugm3 = (outv - 0.9) / 5 * 1000
    if (ugm3 >= 0 and ugm3 <= 35) then
	    aqiL = 0
	    aqiH = 50
	    bpL = 0
	    bpH = 35
		aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 35 and ugm3 <= 75) then
	    aqiL = 50
	    aqiH = 100
	    bpL = 35
	    bpH = 75
		aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 75 and ugm3 <= 115) then
	    aqiL = 100
	    aqiH = 150
	    bpL = 75
	    bpH = 115
	    aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 115 and ugm3 <= 150) then
	    aqiL = 150
	    aqiH = 200
	    bpL = 115
	    bpH = 150
	    aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 150 and ugm3 <= 250) then
	    aqiL = 200
	    aqiH = 300
	    bpL = 150
	    bpH = 250
	    aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 250 and ugm3 <= 350) then
	    aqiL = 300
	    aqiH = 400
	    bpL = 250
	    bpH = 350
	    aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	elseif (ugm3 > 350) then
	    aqiL = 400
	    aqiH = 500
	    bpL = 350
	    bpH = 500
	    aqi = (aqiH - aqiL) / (bpH - bpL) * (ugm3 - bpL) + aqiL
	else
		aqi = 0
	end
	print(aqi)
end)

其中adcv/ 1024 * 5和(outv - 0.9) / 5 * 1000为1024级采样精度转换为电压和相应电压下的粉尘浓度换算,具体可以查阅datasheet得到。如果换算后为负数,即可认为浓度太低检测不到。

下方的aqi换算公式为国家标准环境空气质量指数(AQI)技术规定(试行)( HJ 633—2012 2016-01-01实施)。

实际运行时发现数据不稳定,时有时无。查阅资料发现LED开启过程中有一个上升期。当LED开启持续0.28ms时,对输出电压进行采样最为准确。而NodeMCU的elua脚本并不支持微秒级别的延时。于是考虑其他方法。

查阅资料发现在不更换其他芯片单片机的情况下,ESP8266这块芯片可以采用Arduino的IDE进行C语言程序的编写。下一篇文章会具体写一下如何采用Arduino IDE环境对ESP8266进行编程。