-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 257 KB
/
content.json
1
{"pages":[{"title":"","text":"google-site-verification: google8324cbe77e460d5e.html","link":"/google8324cbe77e460d5e.html"},{"title":"Message","text":"念两句诗 挑选中... jinrishici.load(function(result) { poem.innerHTML = result.data.content info.innerHTML = '【' + result.data.origin.dynasty + '】' + result.data.origin.author + '《' + result.data.origin.title + '》' document.getElementById(\"poem\").value(poem); document.getElementById(\"info\").value(info); });","link":"/Message/"},{"title":"Links","text":"KRUNK ZHOUhttps://krunk.cn/ 分享生活,技术,硬件组装等相关文章与知识分享 OkYes! 技术博客https://2890.ltd/ 念念不忘,必有回响 VANVANhttp://www.vanvan.org/ By Tom Jerryliang Homehttps://www.jerryliang.top/ 一个业余的电脑玩家 杨冬bloghttps://xn--z7qs34c.top/ 站在西伯利亚的最顶端 Shutter Moments | m0g1cianhttps://m0g1cian.piwigo.com/ Advemture awaits Zikin 的独立博客https://zikin.org/ 青春大概如你所說 我的信息网站名称:Hello Traveler网站地址:https://whrblog.online/网站描述:若我不再能奔跑,请让我在梦中飞翔。LOGO图片:https://s2.loli.net/2022/02/21/FMTIn8L1NlQpoS9.png","link":"/Friends/"},{"title":"404","text":"404 UH OH! 页面丢失 您所寻找的页面不存在。你可以点击下面的按钮,返回主页。 返回首页","link":"/404/"},{"title":"To Myself","text":"———致年少轻狂的自己 如果 惊涛骇浪是大海的勇气那么走遍世界的意义 便是寻找自己不畏遥远不惧风浪脚下之路终有尽头 万千美景 无边无际翻山越岭不知是否寻得另一个自己 波澜壮阔 与这般斑斓世界 似初相遇 或许最好的风景一直在前方所以最好的人生一定在路上留念永恒的瞬间敬步履不停的自己 敬广袤无垠的世界 ","link":"/To-Myself/"},{"title":"","text":"(function () { el = $(\"article.page-content\"); if (el !== undefined) { el.innerHTML = ''; fetch('data.json') .then(response => response.json()) .then(data => { galleryContent = document.createElement(\"div\"); galleryContent.id = \"gallery-content\"; galleryContent.class = \"justified-gallery\"; function renderGallery(node) { if (node.contents !== undefined && node.contents.length > 0) { node.contents.forEach(sd => { imgUrl = node.name + '/' + sd.name; imgThumbUrl = node.name + '/thumbnails/thumb_' + sd.name; galleryContent.innerHTML += ` `; }); } } data.forEach(d => renderGallery(d) ); el.append(galleryContent); $('#gallery-content').justifiedGallery({ rowHeight: 150, margins: 5 }); }); } })();","link":"/assets/gallery.js"},{"title":"","text":"/*! * justifiedGallery - v3.8.0 * http://miromannino.github.io/Justified-Gallery/ * Copyright (c) 2020 Miro Mannino * Licensed under the MIT license. */ !function(e){\"function\"==typeof define&&define.amd?define([\"jquery\"],e):\"object\"==typeof module&&module.exports?module.exports=function(t,i){return void 0===i&&(i=\"undefined\"!=typeof window?require(\"jquery\"):require(\"jquery\")(t)),e(i),i}:e(jQuery)}(function(l){var r=function(t,i){this.settings=i,this.checkSettings(),this.imgAnalyzerTimeout=null,this.entries=null,this.buildingRow={entriesBuff:[],width:0,height:0,aspectRatio:0},this.lastFetchedEntry=null,this.lastAnalyzedIndex=-1,this.yield={every:2,flushed:0},this.border=0<=i.border?i.border:i.margins,this.maxRowHeight=this.retrieveMaxRowHeight(),this.suffixRanges=this.retrieveSuffixRanges(),this.offY=this.border,this.rows=0,this.spinner={phase:0,timeSlot:150,$el:l(''),intervalId:null},this.scrollBarOn=!1,this.checkWidthIntervalId=null,this.galleryWidth=t.width(),this.$gallery=t};r.prototype.getSuffix=function(t,i){var e,s;for(e=i","link":"/assets/jquery.justifiedGallery.min.js"},{"title":"","text":"/*! * justifiedGallery - v3.8.0 * http://miromannino.github.io/Justified-Gallery/ * Copyright (c) 2020 Miro Mannino * Licensed under the MIT license. */ .justified-gallery { width: 100%; position: relative; overflow: hidden; } .justified-gallery > a, .justified-gallery > div, .justified-gallery > figure { position: absolute; display: inline-block; overflow: hidden; /* background: #888888; To have gray placeholders while the gallery is loading with waitThumbnailsLoad = false */ filter: \"alpha(opacity=10)\"; opacity: 0.1; margin: 0; padding: 0; } .justified-gallery > a > img, .justified-gallery > div > img, .justified-gallery > figure > img, .justified-gallery > a > a > img, .justified-gallery > div > a > img, .justified-gallery > figure > a > img, .justified-gallery > a > svg, .justified-gallery > div > svg, .justified-gallery > figure > svg, .justified-gallery > a > a > svg, .justified-gallery > div > a > svg, .justified-gallery > figure > a > svg { position: absolute; top: 50%; left: 50%; margin: 0; padding: 0; border: none; filter: \"alpha(opacity=0)\"; opacity: 0; } .justified-gallery > a > .jg-caption, .justified-gallery > div > .jg-caption, .justified-gallery > figure > .jg-caption { display: none; position: absolute; bottom: 0; padding: 5px; background-color: #000000; left: 0; right: 0; margin: 0; color: white; font-size: 12px; font-weight: 300; font-family: sans-serif; } .justified-gallery > a > .jg-caption.jg-caption-visible, .justified-gallery > div > .jg-caption.jg-caption-visible, .justified-gallery > figure > .jg-caption.jg-caption-visible { display: initial; filter: \"alpha(opacity=70)\"; opacity: 0.7; -webkit-transition: opacity 500ms ease-in; -moz-transition: opacity 500ms ease-in; -o-transition: opacity 500ms ease-in; transition: opacity 500ms ease-in; } .justified-gallery > .jg-entry-visible { filter: \"alpha(opacity=100)\"; opacity: 1; background: none; } .justified-gallery > .jg-entry-visible > img, .justified-gallery > .jg-entry-visible > a > img, .justified-gallery > .jg-entry-visible > svg, .justified-gallery > .jg-entry-visible > a > svg { filter: \"alpha(opacity=100)\"; opacity: 1; -webkit-transition: opacity 500ms ease-in; -moz-transition: opacity 500ms ease-in; -o-transition: opacity 500ms ease-in; transition: opacity 500ms ease-in; } .justified-gallery > .jg-filtered { display: none; } .justified-gallery > .jg-spinner { position: absolute; bottom: 0; margin-left: -24px; padding: 10px 0 10px 0; left: 50%; filter: \"alpha(opacity=100)\"; opacity: 1; overflow: initial; } .justified-gallery > .jg-spinner > span { display: inline-block; filter: \"alpha(opacity=0)\"; opacity: 0; width: 8px; height: 8px; margin: 0 4px 0 4px; background-color: #000; border-radius: 6px; }","link":"/assets/justifiedGallery.min.css"},{"title":"","text":"AV.initialize(\"atwHbFJu4O787cc0K5uyEQzw-gzGzoHsz\", \"GPjxAqd2KmMaKKFX2RA5SzDd\"); var time=0 var title=\"\" var url=\"\" var query = new AV.Query('Counter'); query.notEqualTo('id',0); query.descending('time'); query.limit(1000); query.find().then(function (todo) { for (var i=0;i","link":"/hot/"},{"title":"","text":"[{\"type\":\"directory\",\"name\":\"mortal-observation/\",\"contents\":[{\"type\":\"file\",\"name\":\"10.jpg\"},{\"type\":\"file\",\"name\":\"11.jpg\"},{\"type\":\"file\",\"name\":\"12.jpg\"},{\"type\":\"file\",\"name\":\"13.jpg\"},{\"type\":\"file\",\"name\":\"14.jpg\"},{\"type\":\"file\",\"name\":\"15.jpg\"},{\"type\":\"file\",\"name\":\"16.jpg\"},{\"type\":\"file\",\"name\":\"17.jpg\"},{\"type\":\"file\",\"name\":\"18.jpg\"},{\"type\":\"file\",\"name\":\"19.jpg\"},{\"type\":\"file\",\"name\":\"1.jpg\"},{\"type\":\"file\",\"name\":\"2.jpg\"},{\"type\":\"file\",\"name\":\"3.jpg\"},{\"type\":\"file\",\"name\":\"4.jpg\"},{\"type\":\"file\",\"name\":\"5.jpg\"},{\"type\":\"file\",\"name\":\"6.jpg\"},{\"type\":\"file\",\"name\":\"7.jpg\"},{\"type\":\"file\",\"name\":\"8.jpg\"},{\"type\":\"file\",\"name\":\"9.jpg\"}]},{\"type\":\"report\",\"directories\":0,\"files\":19}]","link":"/gallery/data.json"},{"title":"Gallery","text":"人间观察 我们生来就是世界的记录者,我们通过摄影来让时间停下,让瞬间变为永恒。 时间切片 每一张照片都能在一个特定的时刻,以纯粹的情感,激发我的联想。","link":"/gallery/"},{"title":"人间观察","text":"我们生来就是世界的记录者 我们通过摄影来让时间停下 让瞬间变为永恒","link":"/mortal-observation/"},{"title":"时间切片","text":"每一张照片都能在一个特定的时刻,以纯粹的情感,激发我的联想。 ——维利•罗尼 12345678910112023.5.5-5.25 5213 4000ED/PSed/0530 1-14.JPG2023.4.15-4.30 EXR 5298 诺日士/PSed/230503000045940007.jpg2023.5.5-5.25 5213 4000ED/PSed/0530 1-20.JPG2023.3.23-4.9 EURO100(repacked fuji c100) SP3000/PSed/000062.JPG2023.2.20-2.28 Cinestill 5219 800T 诺日士/PSed/000094900021.jpg2023.3.13-3.21 EXR 5298 SP3000/PSed/[email protected] 5213 4000ED/PSed/0530 1-11.JPG2023.3.13-3.21 EXR 5298 SP3000/PSed/[email protected] 5213 4000ED/PSed/0530 [email protected] Cinestill 5219 800T 诺日士/PSed/000094900023.jpg2023.6.6-6.13 Aerocolor2460 诺日士/PSed/000083140002.JPG","link":"/time-slices/"},{"title":"talking","text":"","link":"/talking/"},{"title":"Lenses Databases","text":"Canon RF EF 400mm F2.8L IS III USM 佳能 RF EF 400mm F2.8L IS III USM 比较接近的专利,比二代好了不少,中心分辨率比400gm的相关专利差一点点,但没有个100mp也看不出来,在apsc外一致性还更好一些。 Download Canon RF EF 400mm F2.8L IS III USM Hasselblad XCD 38mm F2.5 E3 g线会比较飞,但总体性能比e1好一些 Download Hasselblad XCD 38mm F2.5 E3 Hasselblad XCD 90V F2.5Hasselblad XCD 90V F2.5 Nikon AI-S AF Nikkor 85mm f/1.8 Nikon AI-S AF Nikkor 85mm f/1.8 和 Nikon 85mm f/1.8D AF Nikkor Lens 同样的结构,1988年的作品,有点先进,似乎比ef 85mm f1.8 usm高效 Download Nikon AI-S AF Nikkor 85mm f/1.8 Nikon PC-E Nikkor 24mm f/3.5D ED f3.5, f8Download 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152[descriptive data\\]title JP 2008-151949 Example 2 (Nikon PC-E Nikkor 24mm f/3.5D ED)\\[constants\\]\\[variable distances\\]Focal Length 24.64209 undefined undefinedAngle of View 101 undefined undefinedF-Number 3.6 undefined undefinedImage Height 58 58 58Magnification 0 -0.03333 -0.1d0 Infinity 725.94 233.20d18 11.681 10.857 9.213Bf 56.500 57.324 58.968\\[lens data\\]1 51.3085 2.3000 1.80400 51.08 46.582 23.3997 0.2000 1.55389 38.46 38.093 17.9290 5.7000 38.464 35.3343 1.9000 1.80100 42.58 34.965 19.4911 6.0000 32.156 45.0079 1.4000 1.58313 35.62 59.387 28.3075 0.1000 1.55389 33.34 38.098 26.4860 7.3000 33.34 9 50.5648 7.5000 1.58144 30.45 40.7510 -36.7513 0.9000 30.4511 -35.7288 1.5500 1.49700 26.92 81.6112 30.3482 0.7500 24.20 13 41.6778 9.0000 1.54814 25.71 45.7914 -25.7030 1.2000 1.80610 25.71 40.9415 -564.5828 0.2000 22.42 16 49.3653 1.5000 1.80400 21.51 46.5817 26.3180 10.0000 1.54814 21.51 45.7918 -31.7447 d18 21.5119 AS 6.5426 18.89620 34.7596 9.3000 1.49700 21.38 81.6121 -34.7596 0.2500 21.3822 -54.5882 1.2000 1.83400 22.82 37.1723 26.7220 5.4000 1.49700 23.78 81.6124 -70.0880 0.8000 23.78 25 -84.7454 3.3000 1.51633 24.58 64.1426 -40.1302 Bf 25.52 \\[aspherical data\\]3 17.9290 -1 -4.1351E-07 -6.5414E-09 4.3437E-11 -1.5271E-13 2.2759E-168 26.4860 -1 1.1134E-05 -1.4590E-08 1.2945E-11 2.4108E-14 -9.7211E-1626 -40.1302 0 9.3165E-06 1.9770E-08 -4.0934E-11 1.6059E-13 \\[figure\\]source Data/JP2008-151949_Figure03P.pngoriginX 5.38originY 76.16ppmm 1.606\\[notes\\]Bill: Measured d0 Nikon PC-E Nikkor 24mm f/3.5D ED f3.5, f8 Tamron 20-40mm f2.8 Di III VXD Prototype 加上了三个位置的0.3m近摄。无穷远到0.3m的呼吸效应分别是1.1%,2.4%,4.0%,40mm端应该已经是或者接近mfd,此时是0.2x,广角端明显还能更近,实物的官方标称是0.26x,0.17m Download Yongnuo YN 16mm f1.8 vs Sigma 16mm f1.8 永诺最近新发的只要1400的apsc镜头,这个永诺专利的镜片数据非常诡异,对数的话是万国牌,哪家的都有,而且都是一些很古老很奇怪的东西。但是经过搜索,我发现有一家国产厂商似乎提供这些东西,永诺用的都在它们的表格里,叫东莞赛诺镜片,看官网图的话,那是相当的小作坊。这个永诺的专利我也不知道它是就这么拉还是没调好。看结构图和实物的匹配还是不错的。直接放个白光mtf看看,被适马无情吊打。 via @Kevin SDownload Yongnuo YN 16mm f1.8 vs Sigma 16mm f1.8","link":"/lensesdb/"},{"title":"人间观察","text":"!相册描述【此行可删除】 自定义分隔符【此行可删除】 自定义分割线【此行可删除】","link":"/gallery/mortal-observation/"}],"posts":[{"title":"秋韵湘乡","text":"十一月,在机缘巧合下走进湘西十万大山,看看沈从文笔下的小镇。先来到的地方是芙蓉镇。从长沙出发,当天抵达已是下午。绿藤挂峭,苍翠叠宕。倾泻的瀑布与波光粼粼的水面,倒映着摇曳朦胧的万家灯火,在夜色的衬托下古镇十分惊艳,但吵闹的灯光与扑面而来的商业气息也让我怯步。 两个小时的车程,从芙蓉镇到保靖县再到龙凤村,路上很多乡间小道不太好走。但当我来到龙凤村的时候,还是觉得此行意义非凡。与世隔绝的山村里的生活在我眼里带着一层神秘面纱,他们传统、淳朴。山村悠然宁静,落叶飘零在小路上,犬吠、鸡鸣回荡在宁静的村庄中。村子里的人,身上沾满了泥土和阳光的味道。 夜幕降临,农家院落里的灯逐渐亮起,微风吹拂着,火光闪烁,烧热的火堆旁传来阵阵炊烟,院子里弥漫着炊烟与菜香的味道。村民们围坐在一起,火堆旁传来欢声笑语。 秋意渐浓,清晨的薄雾如梦如幻,在山间缭绕,一缕淡淡的晨雾从山间若隐若现地升腾而起,轻轻吻在田野上的露珠和枝叶间,将整个乡村笼罩在一层神秘而宁静的薄纱之中。初升的太阳在山梁后缓缓升起,洒下一缕温暖的晨曦,每一粒尘埃、每一片叶子都因此变得通透明亮。 村庄渐渐苏醒,晨起的村民们在门口迎接第一缕阳光,村舍间一阵炊烟袅袅升起,村舍里传来一阵阵炊具碰撞的声音,一切仿佛在这个清晨中沉静而生动。我静静地走过乡间的小路,感受着田野与露水的淡淡清香。 父亲回忆说,印象最深的一个早上,好像是秋天,婆和我早上走路10多里山里,路上翻过一个小山坳,眼前是一片绵延不断的薄纱样的晨雾,轻轻包绕着大小不一的山丘,山头浮在雾气中,宛如仙境。 这里是一个与世隔绝的角落,充满着质朴和生机,仿佛时光在这里流淌得慢了许多,静谧而美好。 我想我该走了。","link":"/2024/11/28/%E7%A7%8B%E9%9F%B5%E6%B9%98%E4%B9%A1/"},{"title":"那些我希望我能早点知道的摄影技术/技巧/经验(转载)","text":"摄影是非常私人的事情摄影的私人性是一把快乐且痛苦的双刃剑。我们每个人自然都是基于自身的审美去创作的,但往往不一定能受到其他人的认可。一定要记住:你自身和他人的审美都是有缺陷的。而你要做的就是去平衡“做得更好”和“做得更开心”这件事。去做能被他人接受并引领他人审美向上的作品。 糖水片是形式大于内容的艺术糖水片是一种泛指,在我这里它的意思是能让人 “非常直观且快速地获得美学愉悦” 的照片。无论是何题材,如果你的“形式”可以让观众不经理解内容而直接产生美学愉悦,那就是非常好的糖水片。以下图片均为引用,请注意观察一点:即使是小图看不清细节,这些图片依然很美: 明暗>色彩>内容我们对人的审美机制了解还不够透彻,但人眼提取信息的优先级是比较明确的:明暗>色彩>内容。以这个规律为中心,进而衍生出更高级的审美,以及摄影技巧。 明暗:明暗比例和构成决定构图基本人眼的视锥细胞只能分辨三种颜色,而其中有两种颜色(红、绿)在光谱上非常相近。这意味着人实际上色觉分辨能力是很弱的(当然现实中也普遍存在着色盲和色弱现象)。我在后期过程中为了避免色彩干扰我对明度的观察,时常会对照片首先进行去色,调整明度后再还原 顺带一提,HSL(色度,饱和度,明度)这个色彩空间模型就很好地利用了人眼明度与色度观察方式不同这个特点。当你把S也就是饱和度调为0时,此时图片就只剩下了明度——也就是明暗信息。明暗信息是最直接的构图元素,一些摄影师会用彩色相机拍黑白RAW+JPG,为的就是取景时忽略色彩干扰。色彩在后期可以恢复如果你的彩色相机能拍RAW并且有黑白的机内滤镜,你可以尝试使用这个滤镜进行构图练习。在后期时,只要在LR或者C1里面把颜色模式给改回彩色即可恢复彩色。(详细的原因这里就不解释了,总之彩色相机的RAW一定可以恢复出彩色信息。) 色彩:简化色彩成为色块如图所示,人眼更喜欢易与分辨的色块。例如这张色盲测试图,如果你的色觉正常,你会发现你很容易注意到12,然后是74,之后可能是6或者42,最后应该还会有张图不好分辨。而你注意力递减的原因并非内容(数字),而是因为其可分辨性在下降。色块化: 内容:图形,几何和眼摄影是一种平面艺术,这意味着所有的深度和尺度信息要靠观众通过他熟悉的元素来脑补。这些熟悉的元素包括但不限于——人的任意部分,特别是眼;“点线面、三角方形圆”之类的图中几何元素;透视消失点。内容可以讲的东西太多了,我自己也没那么高法力。 拍RAW+JPG为什么要拍RAW+JPG?因为对于一个合格的摄影师来说,他所拍摄时预览的画面应该已经接近非常接近最终效果。由于后期软件的技术限制,单凭RAW文件无法完全还原机内硬件ISP渲染的效果,因此保留JPG作为参考极为重要。此外保留JPG还有诸多益处:在Lightroom里使用RAW+JPG工作流需要做一个小设置:Treat JPEG Files Next To Raw Files As Separate Photos 如图中高亮部分所示。英文版也是类似的设置。 呈现比质量重要这也是我经历了很多次失望以后才终于承认的现实:内容的呈现形式,在如今的时代,又或许自古以来都是,比内容本身还要重要。创作者一定要思考自己的作品究竟是怎样被呈现的——比如说有没有被互联网平台压图压崩,自己的图片形式是否适合观看平台,比如,手机竖屏状态。 转自@coco_mizuho","link":"/2023/05/29/%E9%82%A3%E4%BA%9B%E6%88%91%E5%B8%8C%E6%9C%9B%E6%88%91%E8%83%BD%E6%97%A9%E7%82%B9%E7%9F%A5%E9%81%93%E7%9A%84%E6%91%84%E5%BD%B1%E6%8A%80%E6%9C%AF-%E6%8A%80%E5%B7%A7-%E7%BB%8F%E9%AA%8C/"},{"title":"听见阳光","text":"日色穿行在落叶与和风之间,渐变着天际,云卷淡影里,人间恰好能均匀地接受风与光的温柔。微蒙的光褪去蛰伏一夜的寂静,拨开了山海辽阔,穿梭于微隙,在晨露斑驳里折射出一抹黄色暖意,不经意的撩拨,云边也染上些许热烈。 放了假,日子也松弛下来。阳光把日子拉长,时间的脚步放缓,我看日色澄黄,撩动裙摆由窗棂浸染到室内,晶莹地流动。树叶被风吹得轻晃,阳光破碎一片,像远方的潮水将我从发怔的状态里拉出来。我望着太阳那湛明的体质,不经意间地抬起手想要去辨别它那绚烂交织的色泽,追随它的流动,那一刻,世界仿佛随着那不着痕迹的流动逐渐慢了下来,静了下来。 阳光迈着轻盈的步子缓缓映到书桌上,有意无意的跳跃在房间各处,让人不由得心绪紧张,如同期待花开,蓦然醉倒在光影流动里。晌午的日色带着些热烈,整整复斜斜地透过树叶间隙,变成了淡淡的圆圆的轻轻摇曳的光晕,给万物平添了一份暖色。地面上花影浮动,暗香吹拂左右,光霭花气漾开诗的故事,夹带日色温柔的和风轻吻黛山,恍若用梵高的画笔将橘黄色点缀其间,濒蒙一片,像油画般浓郁。 从白日行至黄昏,天际由橙黄逐渐染成少女的羞红,在透明如醇蜜的阳光下,人间仿佛浸在糖水罐头里。黄昏的雾气柔和了日色,落日弥漫的霞空像一杯醉人的酒,沿途散播日色温柔。明暗舒展,绚烂的色彩交错变换,橙黄与霞红纵横叠影,橘色的风漫过街角,日落的光晕弥散,川野俱晚,人间岁岁平安。 我坐在日落里,望着白鸟衔玫瑰远去,太阳温柔地沉没,微风踮起脚尖轻轻拂过发梢,那一刻,我听见了阳光的声音。","link":"/2022/12/11/%E5%90%AC%E8%A7%81%E9%98%B3%E5%85%89/"},{"title":"威廉·克莱因","text":"人物威廉·克莱因(1928~2022) 出生于美国纽约一个贫穷的犹太人家庭。克莱因少时极为聪颖,14岁便进入纽约城市学院学习。1945年在大三时就辍学加入美军赴欧洲作战。二战结束后,美军选拔会讲法语且是大学生的士兵到法国索邦大学进修,克莱因顺利入选,进入索邦大学学习超现实绘画与雕塑。复员后,留在巴黎学习绘画,师从法国著名画家费尔南德·莱热。 莱热的画作经常采用抽象的几何形状与色块,用以描绘城市生活与工业题材,他勇于突破常规的“革新”意识,以及对社会的激进看法,深深影响到克莱因。因其自我放逐的性格,他转身开始了摄影并很快取得了广泛的知名度。他执导过长篇小说电影、众多短片和长篇纪录片,并制作了250多个电视广告。以其对媒体的讽刺手法以及在新闻摄影和时尚摄影中广泛使用不寻常的摄影技术而著称。他是一位革命性的时尚摄影师。他的照片具有自然采光,高对比度以及标志性的场景和服装的高辨识性。 1952年,克莱因在意大利举办油画展览,结识了一位意大利建筑师,对方希望克莱因制作一批抽象的摄影作品。于是,克莱因回到美国,通过某些关系结识了《时尚》杂志艺术总监亚历山大·利伯曼。后来又提出: “我想用在欧洲生活了数年后回到祖国的眼睛,做一个有关自己出生城市的摄影记录” 因此,诞生了其代表作品《纽约》。 1962年,克莱因开始进入电影拍摄领域,后来因威廉·克莱因激进的政治倾向而导致了法国政府的高压,其1969年拍摄的影片《自由先生》被禁映,差点被法国驱逐出境。 20世纪70年代末,威廉·克莱因重新回归摄影,再度为摄影瞩目。1980年纽约现代艺术博物馆为他举办了大型个人回顾展。 代表作品 “好的,首先我已经厌倦了在印刷版上看到它,此外,还被误读了。这是假暴力,只是一个模仿。是我让那个男孩拿枪指着我的镜头的,我拍完照片后我们都笑了,那就像个双面自画像,我既是那个愤怒的男孩,也是那个胆怯的男孩”。 ——From the book《New York 1954-55》Marval,1995 克莱因一生中出版过多部摄影集,包括1958年《罗马》,1964年《莫斯科》、1965年《东京》,但最为著名的还是第一本画册——《纽约》(全名: Life is good & Good for you in New York, Trance Witness Revels), 借用了当时流行的一句广告词 “生活对你好上加好” 书名充满了反讽与反叛。 《纽约》首版由克莱因亲自编辑、设计,相比于同时代的摄影画册,显得极为前卫。该画册大量使用单张照片跨页、多个图像排列组合、椭圆画框等,大胆使用黑色版面,整本画册充满张力与挑衅性。 拿起相机的克莱因,被最有名的服装杂志——时尚 (VOGUE)的艺术指导亚历山大·林伯门(AlexhnderLiberman)所赏识, 将之聘为时尚的摄影家,林伯门回忆他看到克莱因作品的感受:“他的东西有我在任何其他人的作品所经验不到的暴力,这些照片刺目粗糙而不妥协,然而克莱因却将之捺入一种新的美学里,这些强烈的街头景象,使我感到兴趣,他是破除迷信的天才,攫取他所看到的。”克莱因拍摄时装的手法是前所未有的奇特,他把模特儿由摄影棚带到街头,实施交通管制,雇来作儒、演员,或运上一卡车的蜡像当配角,有时还重新粉刷街面。他将现实世界重新捏造成一个舞台,以便拍 一件新衣服。有人说他是服装摄影的费里尼,表现感知领域的怪诞与 您力。 克莱因有了《时尚》的丰厚饭票,就尽情的拍摄他的街头照片。他所用的镜头不是趋广角(21mm)就是超望远(500mm),彻头彻尾违反正常的视觉。他认为所谓客观的角度是不存在的,而摄影的工作并不需要客观地去看世界! “为什么摄影要背负替现实世界做证的重担,布列松下令用广角镜 头是歪曲事实,只有50mm的标准镜头才是正常视觉,而整个时代的 摄影家都将之奉为未来。在我看来广角镜头比标准镜头要来得正常。你甚至可以说50mm是一种局限观点下所受到的惩罚。我们是用两个眼睛在看世界,而相机却只有一个眼睛,无论用什么镜头,任何照片都是双眼所见的事物的扭曲。” 威廉·克莱因对社会事件的拍摄一改优雅的主流观念,他更注重时代感而不是个人。他拍摄的照片没有精准的画面,却有着宽广的构图和自然的拍摄瞬间,是对逝去时间精彩的记录。他的照片使观看者确信,生命的意义就在于这些短暂的时刻中,可能是转头的瞬间,也可是抬起的手臂。照片的定义丢失,却带来了生动的形式,令人更接近混乱和困惑。 个性很偏激的克莱因,看事情也有其极偏颇的一面,他的摄影风格也就是建立在极度偏差的视觉角度上,然而他不认为自己是在扭曲什 么。他只觉得他要把自己对世界的感觉,原原本本的表达出来而已。 大师语录 我来自摄影圈外,摄影的种种规范无法引起我的兴趣。有些事情,你可以有一台相机去做,却不能用任何其它的媒介。颗粒、反差、模糊,歪斜的取景、故意消减或夸张的色调等。我认为展示摄影的各种可能性是很棒的。 我一直在做跟以前被训练的完全相反的事情,我只有很少的技术背景,却成了一名摄影师。我选取了一台机器,却用最大的极限刻意使它失灵。对我来说,做一张照片,其实就是在做反摄影的照片。 有时我宁可拍照时不加瞄准,只想看看到底会发生什么。我会冲着人群”砰、砰“,它一定很像拳击手那样猛戳、绕圈、挨揍,突然有个机会,”砰“的一声正中目标,这是很棒的感觉。 要做你自己。我更喜欢去看东西,即使它是粗劣笨拙的,看起来不像其他人的作品那样。","link":"/2022/09/12/%E5%A8%81%E5%BB%89%C2%B7%E5%85%8B%E8%8E%B1%E5%9B%A0/"},{"title":"尤金·阿杰特——摄影界的“梵高”","text":"当20世纪20年代美国开始兴起“直接摄影”之时,在遥远的欧洲,尤金·阿杰特,又译为尤金·阿特热(_Eugene.Atget_)早已经在用“直接摄影”这一方式来进行摄影创作了(只是他在生前并不为人们所知)。纵观他的一生,笔者觉得用摄影界“梵高”来比喻是最为恰当不过的。而在梳理他摄影作品的过程中,我们也可以渐渐得出一个结论,那就是摄影从“画意”转变到“直接”是一种历史的必然。 挫折的生平有别于那些摄影史上的伟大摄影师,尤金·阿杰特的生平没有存在夸耀的地方,他只是生活在巴黎的一个普通人罢了。尤金.阿杰特(Eugene.Atget),1857年生于法国的里波恩,五岁的时候父母去世,被祖父母抚养长大,为了生存他从事过绘画、化妆师、海员等多种职业。1879年,他考取了法国国家戏剧艺术学院,后来成为了一名演员。这一职业他从事了十五年之久,但他的演艺生涯却一直没有大的发展。1896年,他因为疾病而声带失声,不得不放弃了戏剧舞台。在19世纪80年代,商业摄影在巴黎逐渐流行,从绘画事业中失败的尤金.阿杰特(Eugene.Atget)在1897年购买了一套老旧的二手大画幅相机,成立了一个小小的商业摄影工作室。1898年至1914年间,阿杰特接受了很多来自市政部门的委托拍摄,同时也将自己的作品销售给政府部门。1906年,巴黎市立历史图书馆委托尤金 阿杰特对巴黎的古老建筑进行系统拍摄。1925年,美国摄影家贝伦妮斯·阿博特(Berenice·Abbott)偶然看到了尤金·阿杰特的照片,并推荐给了曼·雷1927年,尤金·阿杰特在巴黎去世,贝伦妮斯·阿博特将他的遗留作品进行了整理并带到美国。1931年,他的第一部摄影集出版。1969年,美国纽约现代艺术博物馆为他举办了一次重要的回顾展。 籍籍无名的活在巴黎由于身体原因不得不放弃演艺生涯的阿杰特总是需要生存的,他选择了摄影,由于以前有一定的绘画基础,一开始考虑做一名画家,但是迫于生计且没有接受过系统的视觉艺术方面的教育和培训,他成了一名摄影师。 另一方面的原因,他希望摄影能够成为一份职业,通过摄影作品销售给他蒙帕纳斯地区的艺术家邻居们获得不错的收益。就如他康帕涅第一街17号门前的广告语:给艺术家的文献。其中包括了:曼雷、郁特里罗、杜诺亚·德·塞贡札克和弗拉芒克这样的画家,还有一些经营场所的店主。 落后的技术1871年,英国一名医生兼业余摄影爱好者R.L.马多克斯(Ric Hard.Lench.Maddox)发明感光“干板”。干板技术的出现为摄影艺术家的创作提供了极大的便利——他们可以随时拍摄。尤金.阿杰特(Eugene.Atget)在摄影过程中使用的就是干板,但在那个时代干板技术是一项比较落后的技术(在1889年,美国的G.伊斯曼发明了硝化纤维透明片基胶片,这种胶片明显更加轻便,形成的影像也更加清晰)。尤金.阿杰特(Eugene.Atget)用干板进行拍摄,用蛋白印相工艺来进行影像制作,这也是一种比较落后的摄影技术。笔者猜测这可能是和尤金.阿杰特(Eugene.Atget)本身的经济状况有着密切的关系——这一点我们可以从他工作室的简陋条件中观察到。 生存是第一重要的事情,因为以前从事过绘画,尤金.阿杰特(Eugene.Atget)知道那些画家、建筑师和设计师们需要用照片作为创作的素材和样本,所以他开始用这些相对落后的摄影器材和摄影技术来拍摄巴黎的风物人情。但那笨重的相机,脆弱的玻璃干板,繁琐的蛋白印相工艺,都让尤金.阿杰特(Eugene.Atget)的拍摄工作变得艰辛异常,所以他不得不早出晚归的长时间工作。 超现实主义因为穷困潦倒,阿杰特一直用着一台老旧的相机,且因为年久失修很多照片出现因为相场不对导致的暗角。用的工艺是蛋白工艺,玻璃干板的需要长时间曝光才能成像,这也就解释了为什么在阿杰特的照片里面,城市总是空无一人。可能阿杰特为了更好的实现这种效果,总是选择清晨薄雾散去之际,拍摄人烟稀少的巴黎街头,这便是“超现实”的由来。 在逐渐熟悉摄影这一媒介语言后,尤金.阿杰特(Eugene.Atget)开始展现出自己在摄影艺术上的才华。1906年,巴黎市立历史图书馆委托尤金.阿杰特(Eugene.Atget)对巴黎的古老建筑进行系统拍摄,于是他开始背着自己沉重的大画幅相机游走在巴黎的大街小巷,用平实朴质的视角来系统的记录巴黎的街道河流、建筑雕塑。这一拍,就是20多年。除了拍摄古老建筑,他也拍摄街头商贩、妓女、以及不同地区所流行的娱乐活动等题材。 阿杰特并不是漫无目的的拍摄这些景象,他致力于拍摄老巴黎,那个巴黎已经消失在时光里,那是中世纪的巴黎,他拍摄了即将拆除的建筑,记录石头、钢铁、植物等等。特写镜头、全景镜头、细节,以及不同角度、不同时间和光线环境下的景物,他镜头里的世界可以经历岁月和时光的考验。 1920年11月12日,他在给巴黎历史资料管理处的美术总监保罗莱昂的一封信中总结了自己的摄影生涯: 在过去的20年里,由于我的工作和主动,我收集了16到19世纪的旧巴黎所有古代街道的建筑艺术资料,其形式为摄影版开本18cm x 24cm:旧旅馆、有关历史的奇特房子、漂亮的建筑物正面以及门、镶板、门把手、古老的喷泉、楼梯(木质的和铁质的)、还有巴黎所有教堂的内部(全景和细节),包括巴黎圣母院、圣热尔韦、圣赛弗兰、圣于连、圣艾蒂安,夏尔多内的圣尼古拉教堂等等。这一庞大的艺术记录收集工作现已完成,我可以真实的说我拥有了整个巴黎。 “大师”却是偶然中的必然尤金.阿杰特(Eugene.Atget)一生都没有参加过一次摄影展览,也没有出版过一本画册,没有多少人认得这位身材瘦削的摄影老人。但是命运总是眷顾那些有准备的人,1925年美国摄影家贝伦妮斯.阿博特(Berenice.Abbott )偶然间看到了尤金.阿杰特(Eugene Atget)的照片(阿博特当时是艺术家曼.雷的助手,而曼.雷的工作室与阿杰特的住所同在一条街上),十分的喜欢,于是亲自了拜访了尤金.阿杰特(Eugene.Atget),观看并购买了他的一部分作品。多年以后她在谈到阿杰特的照片时,这样写道:“它们给我的影响是迅速的、巨大的,使我一下子认识到这就是毫无矫饰的现实主义。” 1927年,尤金.阿杰特(Eugene.Atget)在巴黎去世,贝伦妮斯.阿博特(Berenice.Abbott )将他遗留的作品进行了整理并带到了美国。1931年他的第一部摄影集出版。1969年美国纽约现代艺术博物馆为他举办了一次重要的回顾展从而确立了尤金.阿杰特(Eugene.Atget)在现代摄影史上的重要地位。 曼雷是阿杰特照片的购买者,当时他住在同一条街的31号。曼雷对阿杰的照片印象很深,并在当时超现实主义艺术家的圈子里宣传这些照片;其中三张被发表在1926年的杂志《超现实主义革命》上,另有11张于1929年在斯图加特举办的以现代主义为特征的“胶片与摄影”展上展出。(值得一提的是,阿杰特嘱咐曼雷刊登可以,但是不要附上自己的姓名) 1925年,美国摄影家贝伦妮斯·阿博特偶然间看到了尤金·阿杰特的照片(阿博特当时是艺术家曼·雷的助手,而曼·雷的工作室与阿杰特的住所同在一条街上),十分的喜欢,于是亲自了拜访了尤金·阿杰特,观看并购买了他的一部分作品。多年以后,她在谈到阿杰特的照片时,这样写道:“它们给我的影响是迅速的、巨大的,使我一下子认识到这就是毫无矫饰的现实主义。 1927年,尤金·阿杰特(Eugene·Atget)在巴黎去世,贝伦妮斯·阿博特(Berenice·Abbott )将他遗留的作品进行了整理并带到了美国。1931年,他的第一部摄影集出版。 约翰•萨考夫斯基基在担任纽约现代艺术博物馆摄影部主任期间,在1969年为尤金阿杰举办了一次重要的回顾展,这次展览确立了阿杰在现代摄影史上的地位。 约翰•萨考夫斯基在《尤金·阿杰》一书中写到: “阿杰特的作品之所以令人兴奋,并不在于他规避了空虚、浅薄,而在于他给我们展示了一个陌生的世界,里面充满了我们闻所未闻的节奏和共鸣,充满了对于我们几乎已经忘怀,或许我们从未了解的经历的暗指。” 尤金·阿杰特之所以有这样的地位和这些人的推崇是分不开的,但并不能说他配不上这份成就。 尤金·阿杰特的风格阿杰的风格到底是怎样的呢?他为何会被如此多的摄影家认同和推崇呢? 《世界摄影史》一书对尤金·阿杰的描述如下: “阿杰以电影导演拍摄的方式来进行摄影创作,拍摄特写镜头、长焦镜头、细节,以及从不同角度、不同时间和光线环境下进行拍摄,他镜头中的二维世界可以经历岁月和时光的考验。他创作了约1万余幅作品,包括商店橱窗、建筑物入口、拱廊、街景、公共场所和私人花园,还包括街头涌动的人群和从事日常劳动的工人,或者上流社会的生活,他作品中的巴黎亦梦亦幻,但都绝对真实。”而且,在阿杰这里,纪实摄影和艺术摄影并没有形成对立,而是完美地融合在一起,甚至不分彼此,这一点从新近出版的《尤金·阿杰》一书百幅作品中可见一斑,纪实的影像中不无优雅。 《摄影小史》 不管摄影者的技术如何灵巧,也无论拍摄对象如何正襟危坐,观者却感受到有股不可抗拒的想望,要在影像中寻求那极微小的火花,意外的,属于此时此地的;因为有了这火光,“真实”就像彻头彻尾灼透了相中人——观者渴望去寻觅那看不见的地方,那地方,那长久以来已成“过去”分秒的表象之下,如今栖荫着“未来”,如此动人,我们稍一回顾,就能发现。因为对相机说话的大自然,不同于对眼睛说话的大自然:两者会有不同,首先是因相片中的空间而不是人有意识的布局的,而是无意识所编织出来的。 《决斗写真论》 偶然通过相机记录下的世界,或许也听恰当的。亦即阿杰特之所以拍照,并不是因为他已有既定的影像,他只是将镜头对着巴黎的街道上所有的事物,凭借正确的光影原理,将事物烙印在干板上。我们当然无法忽视当时相机、底片的条件决定了他的摄影性格。需要长时间曝光的低感度底片,让街上的行人消失。还有当时无法进行夜间摄影,所以被认为”犯罪现场“的摄影,绝对不是他心中影像的具体化、外在化、而只是必然的结果吧。那个时代的摄影技术决定了阿特热影像的质感,只是难以否认的事实,同时也显示他的摄影并不是摄影家意识渗透的摄影,阿杰特不去意识的部分、没有意识的部分,决定了他摄影的本质。即使现在,我们依然因为观看他的照片而感动,因为通过相机无意识所支配的世界,已经动摇了我们的意识。 《摄影简史》 本雅明对阿杰的评价很高,认为他是“以为被他的职业所排斥的艺术家,他扯掉自己的面具然后去寻求剥去伪装的真实”。他认为,阿杰已经把物体从它的氛围中解放出来,由此他解释说阿杰的照片摆脱了传统摄影师所珍视的那种能让人产生共鸣的气氛:“它们并不孤独,只是缺乏气氛:这些照片中的城市空如平地,仿佛尚未找到一个新的占有者。它们是超现实主义摄影的成就,预示着人类与环境之间的一种有益的疏远,从而为受到政治训练的眼睛清理了场地,因为在这样的眼光下,所有亲近的事物都会对细节的阐明起作用。”换句话说,阿杰的主题是场景之外的,而不是有关他的情感,他让他的观众去观察,去分析,而不是去做梦。 阿杰特的影像既有纪实性也有艺术性,他既是超现实主义的先驱,也影响了后世的纪实摄影和直接摄影。在他的镜头了,我们找不到拍摄者的意图,并没有去刻意的去赋予拍摄主体特定的意义,它们都是绝对真实的、客观的。 这些都不是最重要的,这并不能说明阿杰特与超现实主义的关系,也没法使曼·雷产生了兴趣,更加不能让本雅明把他的作品看做超现实主义摄影的成就。一定程度都是因为阿杰特把他拍摄的很多东西做了改变。他使得没有生命的东西神奇的复活了,或者更确切地说,他们复活的时候阿杰特恰好注意到了。 时代的遗憾阿杰特对技术的掌握早已登峰造极。可这位大师终其一生活在阴影中。孜孜不倦地默默工作,却忘了在技术上的顶峰插上他的旗帜;因此不少后来者竟以为是他们发现了顶峰,却不知尤金·阿杰特老早之前就已经捷足先登。 为何如此坚持与专注的阿杰特没有在生前获得世人的认可,原因在于在当时的时代背景下,主流文化还没有将绘画和摄影的各自职能理清楚,这也是为何当时画意摄影风行的原因。这让我想到了稍早于他的印象派梵高,也是生前没有世人认可,被嘲笑为疯子。时代就是这样,伟大的人早于世人发现了美,但却需要世人花时间摆脱既定的理念。 尤金.阿杰特(Eugene.Atget)在长达30年的拍摄实践中形成了自己独特的观察方式,他将19世纪初巴黎完整的影印在自己的照片里,开创了一种崭新的摄影形式。他拍摄的影像是介于抒情和纪实之间,有一种独特的“超现实”的视觉感受,而这种视觉感受也应和了20世纪20、30年代人们对于现代摄影的一种探索,对后来的摄影艺术家们产生了深远的影响(沃克.埃文斯(Walker.Evans),李.弗莱德兰德((Lee.Friedlander)等人都受其深刻影响)。 虽然尤金.阿杰特(Eugene.Atget)已经离我们远去了,但他遗留的“巴黎影像”却一直在影响着我们,影响着摄影史,无论他是故意使然还是下意识所为,都对世界摄影发展做出了杰出的贡献,是值得后人学习与借鉴的。 这样的人有很多,多少伟大的人遭受着时代的遗弃,哥白尼、莫奈、梵高以及阿杰特。这是时代的遗憾,也是他们的遗憾。","link":"/2022/09/10/%E5%B0%A4%E9%87%91-%E9%98%BF%E6%9D%B0%E7%89%B9/"},{"title":"沃克·埃文斯的摄影美学","text":"维姬·戈德堡(Vicki Goldberg)是西方摄影评论领域的领军人物之一,以富有说服力和洞察力的文章著称。《光影的要义》(Light Matters)首版于2005年,该书收集了作家写作生涯以来的诸多优秀散文和评论。 戈德堡对摄影的观察深入浅出且包罗万象,她的写作主题跨越极广:从流行影像到战争新闻,从肖像摄影快照亭到可后期数字图像,从乏味无趣的窥视到充满悲剧的现场等等。她还从摄影领域的“大师”作品中提炼出新的启示,其中包括沃克·埃文斯、约瑟夫·寇德卡和黛安·阿勃斯等,并以同样敏锐地视角书写和剖析了比尔·维奥拉(Bill Viola)、森山大道和巴斯蒂安娜·施密特(Bastienne Schmidt)等当代影像先驱者的作品。 此外,维姬·戈德堡的著作还包括《摄影的力量:照片如何改变我们的生活》(The Power of Photography: How Photographs Changed Our Lives)、《作为印刷品的摄影:从1816年至今的影像写作》(Photography in Print:Writings from 1816 To the Present)等。1997年,戈德堡获得国际摄影中心(ICP)著名的“无限奖”,1999年,她荣获英国皇家摄影学会的约翰斯顿奖。 耶鲁大学艺术学院院长理查德·本森(Richard Benson)认为,沃克·埃文斯(Walker Evans,1903—1975年)是我们这个时代伟大的艺术家。本森曾经为埃文斯印制过底片,如果谈及毕加索,他或许会有些避重就轻,但若把语境仅仅限定在美国摄影或是美国艺术上,就很难不同意他的观点了。埃文斯将整个国家的生存状态从被低估和忽视中解救了出来。破败和遗弃的建筑、手绘招牌上的零星字母、有序的停车坪、杂乱的理发店、空荡的街道、垃圾回收站、废弃的汽车以及疲倦的面容,在埃文斯拍下它们之前,这些事物根本没有什么自命不凡的地位可言。恰恰在没有人关注到这一切时,埃文斯意识到并创造了无名之物的尊严和无名之辈的成就。 20世纪30年代,埃文斯将民间文化和普通人的生存环境推上了历史舞台的中央,将各种象征物、图形招牌、广告栏以及大量照片都变成了摄影的重要主题,并将纪实摄影提升到了一个新的复杂程度。如同法国大革命让朝臣们脱下蓝色缎子的膝上裤,换上黑色的西装一般,埃文斯把身披艺术外衣的摄影换上了日常工作服。** 这带来了摄影史上一次悄无声息的革命,它建立了一套全新的视觉模式和领域。埃文斯当然不是单枪匹马完成,他只是比别人做得更好。直到三四十年后,才陆续有很多人意识到,一场革命正在进行。但如果我们现在知道,除了上帝,一座没有任何恩典的小木教堂可以如此动人美丽,那是因为埃文斯用他的照片向一个曾对此不屑一顾的国度证明了这一点。 埃文斯的作品对大萧条时期农业安全管理局(Farm Security Administration)的照片产生了十分重要的影响,还包括本·沙恩(Ben Shahn,埃文斯教他摄影)、海伦·莱维特(Helen Levitt)、哈里·卡拉汉(Harry Callahan),以及20世纪五六十年代的主要摄影师,特别是罗伯特·弗兰克(Robert Frank)、李·弗里德兰德(Lee Friedlander,他说,不知道有多少比埃文斯年轻的摄影师们会不受他的影响)以及加里·温诺格兰德(Garry Winogrand,他曾经说,埃文斯的《美国影像》一书让他第一次意识到摄影可以与智慧相接)等人。 埃文斯还在不断影响后继的摄影师,从布鲁斯·戴维森(Bruce Davidson)、乔尔·梅耶罗维茨(Joel Meyerowitz)到罗伯特·劳森伯格(Robert Rauschenberg)、威廉·埃格尔斯顿(William Eggleston)等等,这些采用纪实摄影作为美国现代主义摄影载体的街头摄影师。 埃文斯有时也被认为影响了波普艺术,他笑称自己是波普艺术的先驱者,可能是由于60年代对商业文化的痴迷正蓄势待发,艺术家们把埃文斯的影像当成了一种时代的印证。吉姆·迪因(Jim Dine)和安迪·沃霍尔(Andy Warhol)都对埃文斯的作品着迷;沃霍尔甚至将他向劳森伯格致敬的摄影作品干脆命名为《现在让我们赞美伟大的人》(_Let Us Now Praise Famous Men_),这直接取材于埃文斯与詹姆斯·艾吉(James Agee)合作的那本里程碑式著作。 埃文斯对观念艺术也产生了重大影响,甚至对那些试图采用纪实风格的电影也产生了影响,并且很大程度上塑造了我们对大萧条这一历史时期的目光。埃文斯所敲响的音符几乎成了如今我们所处时代的背景音乐。 “沃克·埃文斯”(Walker Evans)是美国大都会艺术博物馆(Metropolitan Museum of Art)举办的第一场关于埃文斯的全面回顾展,它几乎涵盖了埃文斯每个时期的作品,包括他在《财富》杂志工作期间发表的作品以及晚年用宝丽来SX-70所拍摄的照片。时任博物馆摄影部助理馆长杰夫·罗森海姆(Jeff L. Rosenheim)收集了沃克·埃文斯的175张作品,以及该博物馆于1994年收购的各种以前从未展出过的物品,它们作为埃文斯档案的一部分,包括日记、信件、家庭相册、杂志、明信片、书籍等(还包括一份由普林斯顿大学出版社提供的作品目录,随该展览一起展出)。 埃文斯是一位身穿布克兄弟(Brooks Brothers,美国服装品牌)西装的叛逆者。他的父亲是一位广告主管,母亲则是一位社交攀附者。他们曾住在位于芝加哥郊区的肯尼尔沃斯(Kenilworth)和托莱多(Toledo)。沃克本意想成为一名作家,他在大学一年级结束便辍学了,但埃文斯还是通过自己的方式走近了当代文学。从1926年开始,他在巴黎度过了闷闷不乐的一年,回到纽约后发现自己的写作并不很理想,随后摆弄了一阵子相机,但直到1928、1929年才开始认真对待摄影。到了1930年,他对这种媒介的可能性感到非常兴奋,有时甚至认为自己对摄影已经到了疯狂的地步。 在摄影还普遍被认为是一个不上台面的行业时,做一名摄影师就已经足够叛逆了。 “我那没品位的父亲……觉得我想做的尽是些调皮捣蛋的事儿,以及想通过摄影把妹……”埃文斯说,“当然,这反而会让我对摄影更感兴趣,事实往往就是这么反常。” 人若是想叛逆总能找到理由。有人认为20世纪20年代的繁荣表象恰恰暴露了这个国家最糟糕的一面。“我当时真的很反感这个国家,”埃文斯说,“美国几乎成了一个买卖的国度,我想逃离,这一切让我感到恶心。我的摄影是对保守理念和乐观主义的半自觉反应,是一种对权威的反击。” 埃文斯决心成为艺术家,在大萧条时期过着勉强糊口的生活,甚至一度穷到不得不卖掉自己的书。他一生都渴望成为百万富翁,却又鄙视资本主义。但凡身上有一点钱,他就会把它们花在高级酒店或蜡制小腿皮鞋上,以此自娱自乐。他的一位朋友写道,埃文斯最初对他的兴趣 “源于一件特制的萨维尔街西装(Savile Row,英国伦敦的一条街道,聚集了售卖高档定制男装的店铺),他是如此觊觎这件西装以至于我答应在遗嘱中把它留给他。” 埃文斯不止一次被誉为大艺术家,幸好从来没人拿他的银行账户作为衡量标准。 受欧洲现代主义运动的影响,埃文斯最初拍摄了一些设计感强烈、角度奇特、城市几何以及带有蒙太奇效果的照片,其中三幅作品于1930年发表在哈特·克兰恩(Hart Crane)的《桥》(_The Bridge_)中。但埃文斯很快就开始了一些新的尝试,他到街头寻找拍摄题材,那些在城市的喧嚣中稍作休息的路人,他们看上去毫无防备,以及随意涂抹在墙上的标语,和微不足道的被摄对象等。他直接、朴素、甚至粗暴地观察着周围环境,没有任何华丽的修饰,也没有传统的艺术手法。他迅速地对当时的摄影风格进行了反叛,反对当时被认为摄影界的两位统治者爱德华·斯泰肯(Edward Steichen,太商业化)和阿尔弗雷德·斯蒂格利茨(Alfred Stieglitz,太艺术化)对相机不诚实地使用。 埃文斯对当时报纸上的新闻照片、新闻短片、以及他本人收集的明信片印象都十分深刻,他认为这些照片简洁而真实,据说连房地产经纪人办公室里的照片他都喜欢。 在他为1933年卡尔顿·比尔斯(Carleton Beals)的著作《古巴罪行》(_The Crime of Cuba_)所拍摄的摄影集中,就有几张关于揭露政府罪行的匿名照片。这很大程度上表明了埃文斯相信新闻照片所蕴含的力量,以及身为艺术家,埃文斯拥有使用任何素材的权利。在当时的美国,鲜有艺术家能够从新闻照片和新闻短片中获得灵感,但埃文斯做到了这一点。 时机已经趋于成熟。这是一个纪实的年代,而相机(摄影机)正是这个时代的明星,有些电影院甚至整天只放映新闻短片。约翰·多斯·帕索斯(John Dos Passos)的《美国》(U.S.A)三部曲中的部分章节就被命名为“照相机之眼”和“新闻短片”。在《现在,让我们赞美伟大的人》(_Let Us Now Praise Famous Men_)一书中,艾吉写道:“所有的感受都从原先对真实的想象转变成了如今人们与真实影像的残酷对视。这就是为何照相机在我看来,它更像是一种近似于与辅助设备无关的意识,它是记录我们这个时代最重要的工具。”而埃文斯则十分善于利用它来观察和捕获真实世界的残酷。 1931年,林肯·科尔斯坦(Lincoln Kirstein)还在哈佛大学读书时,就创办了一本先锋杂志和一个当代艺术协会,并影响了纽约现代艺术博物馆的建立,他邀请埃文斯去拍摄新英格兰地区的维多利亚式建筑,当时大多数人认为这些建筑并不值得保留。然而埃文斯说,这个还未毕业的学生在教我认真做事,我正在经历一个科尔斯坦式的转变,这其中充满了力量,闪烁着光芒,潇洒且技艺高超,涵盖了对“一切美学问题”真正透彻的领悟。(然而另一方面,科尔斯坦却发现埃文斯总是那么无聊,那么瘦,那么容易疲倦,他猜测或许是他吃得不够好。) 埃文斯很喜欢维多利亚时代的建筑,喜欢它们的风雅衰退,喜欢它们那古朴的典雅和装饰性的皱褶,它们的气质在浮华之下显得坚实而得体,仿佛是戴着蕾丝领的朝圣者。 1933年,科尔斯坦为埃文斯在MoMA举办了一场摄影展,这是美国大型博物馆有史以来的第一次个人摄影展。 1935年,MoMA聘请埃文斯拍摄非洲雕塑,约翰·契弗(John Cheever)担任他的助手。那一年,当埃文斯在新奥尔良及其周边地区拍摄建筑时,认识了保罗·尼纳斯(Paul Ninas)和他的妻子简·史密斯·尼纳斯(Jane Smith Ninas)(现为简·萨金特),他们都是画家。保罗·尼纳斯有一个情妇,她有时会和这对夫妇一起过夜;当埃文斯和简·尼纳斯相爱时,表面上吃饭跳舞的四人组事实上关系并不稳固。一天晚上,在尼纳斯家的客厅里,保罗用枪指着沃克,让他要么把简带走,要么立即滚出他们的生活。埃文斯因此离开,并随后给简写了一封长长的道歉信,事情便这样结束了。 埃文斯受雇于罗伊·斯特莱克(Roy Stryker),他是安置管理局(Resettlement Administration)摄影部负责人,该管理局成立于1935年,后来更名为农业安全管理局——一个旨在为陷入困境的农民提供帮助而成立的新政局。为了赢得公众对该计划的支持,13名FSA摄影师在8年的时间里拍摄了超过7.5万张照片和20万张底片——这是政府相信摄影力量的空前证明,也是对大萧条时期的重要记录。 埃文斯不参与政治,不愿接受政府的指导,也不愿相信通过摄影可以进行社会改革。 但不论如何,埃文斯对FSA的意义至关重要,斯特莱克后来说,埃文斯的照片大大拓展了他对于摄影的认知。埃文斯自己则觉得,其他几位自由摄影师包括多萝西娅·兰格(Dorothea Lange)、罗素·李(Russell Lee)和阿瑟·罗斯坦(Arthur Rothstein)只是偷学了他的风格,并将其应用到整个项目中。简·萨金特说,埃文斯始终对政治保持冷漠,甚至都不参加投票,直到40年代末他才开始投票,还会因此大闹情绪,其实他一生都在固执地抵抗权威。 政府的话埃文斯固然是不爱听的,于是斯特莱克很快发现,埃文斯很少向他报告拍摄进度,只要是在途中拍摄几乎找不到他的行踪,并且他也不完全按照要求去拍摄。由于当时他使用的主力相机是耗费时间的大画幅8×10相机,这种相机要比35毫米相机记录的细节多得多,所以他也没有像其他摄影师那样向管理局发送那么多的照片。于是,斯特莱克在两年多后就把他解雇了。 埃文斯强烈反对任何带有宣传意味的事物,不管它们背后的理由看似多么充分。由于拍摄了佃农的照片而使他多次被误读为社会改革摄影师,这个标签令他难以接受。“我不会把我的观念和工作政治化……使徒们是不会接纳我这么做的。我不认为一个艺术家能够直接缓解人类的状况,我能做的仅仅是去揭示它。”同时,埃文斯反对用摄影来做慈善事业,反对摄影背后的虚情假意,反对用影像去声援或利用,以及制造耸人听闻的效应,反对任何将艺术家的个性、情感和政治态度嵌入照片的行为。** 这种故意将艺术家自身的态度从作品中移除的做法是有先例的。马修·布雷迪(Mathew Brady)和他19世纪的美国同行们所拍摄的照片都是平铺直叙、直截了当的记录,而不是个人化的表达,但那是在摄影被公认为具有艺术气质之前的事;20世纪的前25年,尤金·阿杰(Eugène Atget)在巴黎朴实无华的门廊和商店门面前挖掘出了影像的诗意。埃文斯当然了解这两个人的作品,但他声称他的主要影响来自波德莱尔(Baudelaire)和福楼拜(Flaubert),他希望作者消失在作品中。埃文斯也读过现代主义中“非个人化”作家的作品,正如 T.S.艾略特(T. S. Eliot)所说的那样,“诗歌不是对情感的释放,而是对情感的回避,它不是个性的表达,而是个性的逃离。” 埃文斯开始将他的艺术理念与纪实摄影中平凡朴素、非个人化的修辞融为一体,并拍摄出如他所说的“直白、可信、超验的”影像。 当然,朴素也只是表面上的。在上世纪40年代,当未来的MoMA摄影部主任约翰·萨考夫斯基(John Szarkowski)(任期为1962—1991年)还是一名大学二年级学生时,他第一次看到埃文斯的《美国影像》(_American Photographs_)一书后十分困惑,甚至一度认为这可能是个恶作剧。如果要以上帝的名义发问,书中的艺术到底在哪里?他说,大部分都只是事实,任何一个有自尊心的大二学生都会认为,只有事实当然不能算艺术。但萨考夫斯基随即改变了自己的想法,在1971年的MoMA回顾展上,埃文斯终于一举成名。 1935—1936年,埃文斯的创造力势如破竹,他用影像记录下了一张又一张经典的美国历史,有的甚至是时间的历史,仿佛他目光所及的每一处都在诉说着某种深刻。 在宾夕法尼亚州的伯利恒(Bethlehem),埃文斯在取景时将墓地作为前景,工人的房子作为中景,工厂作为背景,他利用长焦镜头压缩空间,使三者相互挤压:他们的一生——出生、工作、死亡——都在工厂及其老板的奴役下。 一个女人来到FSA并索要这张照片的复本,当被问及为何需要它时,她回答道:“我想把它送给我的哥哥,他是钢铁公司的主管。我还想在上面写几行字:这里是你的墓场,你的街道,你的建筑,你的钢厂。但这里却有我们的灵魂。愿上帝诅咒你。” 他在一美分证件照相馆(Penny Picture Studio)的橱窗里纪念了无数陌生的肖像,普通公民在这里找到了他们身份的象征。事实上,他们只是通过照片为埃文斯排列出了新的组合,埃文斯则用镜头重新表现了他们,使照相馆摄影师的艺术被转换成了埃文斯自己的艺术,而这样的观念要比主流艺术家早许多年。 这张照片同时也是对于拍摄和时间的一种重复:相机将这些人保留成记忆,而埃文斯则再一次用相机地保留了他们先前的记忆,只不过是以一种再现的形式。 橱窗里的婴儿、青少年和穿吊带男人们现在或许都变了,或者消失不见了,他们的照片只是一种面带微笑的替代物。 埃文斯以清教徒式的严谨、夏克派(Shaker)式的朴素,以及新教徒式的节俭进行创作,同时在拍摄过程中融入适当的情感与机智,在各种场景、肖像和造型中传达着意义。这就是这个世界,这就是事物的本来面目,悄无声息地诉说着它们各自的历史,它们被建造出来、融入生活、最后被丢弃,如果你仔细观察,它们所经历的一切便会从记录的影像中显现出来。 一间店面就是一间店面,一条街道就是一条街道,同时它们又不只是这些:它们是人类生活与社会历史经过此地的场所与证明,它们受到传统、贸易和作为必需之物的影响,于是,过往的记忆和未来的期待得以进驻其间。 1936年夏天,埃文斯向FSA请假,与艾吉一起前往南方,为《财富》杂志撰写一篇关于佃农的文章。埃文斯的情感冷漠,无论是他本人还是在他的照片里都是如此;艾吉则从毛孔中渗透着他心中的内疚与忏悔,谈话时滔滔不绝,势不可挡,就像尼亚加拉河一般。在随后的几年里,每当埃文斯在半夜无精打采地自言自语和蹒跚踱步时,这位饶舌的朋友便会跟进他的卧室,追着他的话题聊天。埃文斯曾经说过:“我对主观表达感到尴尬,包括艾吉的散文,尽管我知道写得确实很棒。我永远也想象不出自己会成为那种有忏悔之心或者表现欲的人。” 他们两人与三个佃农家庭相处了几个星期。埃文斯拍摄人像,大多是让他的拍摄对象自己调整姿态,以及如何面对镜头。 一位女士害羞又优雅地轻弹了一下她的麻袋裙,这个细微的举动暴露了她的贫穷,而另一位则目光紧盯着镜头,眼神里没有一丝虚荣和自怜。一家人就这样聚在一间卧室里——光着脚,穿着脏衣服,露着擦破皮的小腿。 男孩半裸着身子,开心地笑着,其余的人则神情肃穆,像是在评价眼前的这位摄影师。他们的状态仿佛带着某种模糊而晦涩的尊严,就像是银版照片中的商人家庭一样。 埃文斯拒绝将摄影政治化,以及利用摄影进行宣讲和鼓吹,这样就使得职业摄影师与非职业摄影师、观看者与被观看者之间的差异变得平等起来。埃文斯坚持认为,人类作为自身本来就具有足够的价值,不应该遭到他人的反对,更不应该去反对自身,应根据他们自身的条件和状况进行拍摄,而不是去强加某种慈善的、带有偏见的目光,以及下意识地用阶级概念去打量他们。 有人说,埃文斯以剥削者的目光拍摄了这些家庭,让他们看起来比实际情况更糟糕,但威廉·克里森伯里(William Christenberry)在20世纪60年代第一次看到这些照片时,认出了其中的一个家庭就住在他祖父母家附近,于是他把这本书拿给照片中的一个孩子看,那个孩子说:“我们喜欢吉米先生和沃克先生,他们会给我们送圣诞礼物。” 埃文斯拍下了佃农们手工建造的简陋房屋,以及他们破旧的内部陈设。房间布局和采光都经过精心地设计,仿佛维米尔(Johannes Vermeer)在创作前准备一桌食物。他也拍摄南方的城镇,孤零零的商店和吟游艺人的海报,以及在长椅上久坐却连他们自己也不知在等待什么的人们。这些对建筑、街道和倦容的面无表情记录,是历史文本、文化记述、对国家的批判,甚至是对人类状况的严肃审视。埃文斯非常清楚相机与历史之间的紧密关系,他曾写道,他“感兴趣于任何一个当下成为过去的样子”。 艾吉的文章篇幅太长加上交稿很晚,于是《财富》杂志没有进行刊登。直到1941年,《现在,让我们赞美伟大的人》才以成书形式出版,埃文斯的照片(按照他所坚持的想法)被分组放在扉页前,没有文字说明,悄无声息地吐露着寻常百姓的秘密,也揭示着在他们被微薄收入与艰辛劳动所充斥的无序生活背后的普遍规律。 评论家莱昂内尔·特里林(Lionel Trilling)称此书是“我们这一代美国人无比真实和重要的道德坚守”,只不过随着欧洲进入战争状态以及大萧条开始好转,没有引起人们的兴趣,于是《现在,让我们赞美伟大的人》在当时只卖了六百多本。 1938年,现代艺术博物馆举办了“沃克·埃文斯:美国影像”(Walker Evans: American photos)主题摄影展,这是一场共有100张照片的回顾展,还附带了一份目录。这本书既是一首史诗,也是一首挽歌,其主题就是美国文化——这便是这个国家亲手创造出的一切;这便是美国梦所能够支撑的一切;在历史的回荡中,一切都在经历着无声的衰败,在时间的压榨下,一切都在悄然坍塌。 埃文斯把书中的照片分为两组,没有备注相关说明。开放式的照片和人物肖像不仅注解了眼前的所见,也注解了所有图像的传播。然后是各种汽车的照片,包括堆放在一起只剩下车骨架的报废车场,路上的行人,寂寞的街道,大萧条中的难民,一位矿工住房的墙上宣称美好生活的广告,所有的这一切都在悄无声息的摄影中被衬托出来,没有一丝脚步声,只剩下时间流逝时无人知晓的叹息。 在本书的第二部分,几乎没有人物在这里出现,空荡荡的街道和房屋排成行,似乎在沉睡中等待着被唤醒。这一部分以一张遗迹照片作为开始,这是一张被破碎的锡制残片,上面印着古典图案,这些残片依旧诉说着欧洲上层阶级对锡制品的渴望。接下来的照片里,是围绕着工厂和铁路而建的城镇,田地和工业厂房仿佛在吞噬着它们,随后是一些光板的教堂和房屋。随着书页的翻动,这些建筑的装饰也变得越来越精致,直到书的结尾处出现了另一件锡制遗物——又一份在艰难时期对华丽生活的憧憬——这便是美国文化,它们被无名的建设者和工匠们所创造,它们试图在一切困局被破除之前努力让此刻的平庸变得美好。埃文斯曾经说过:“我着迷于人类的作品和人类的文明。事实上,我认为这是世界上最有趣的事情,即人创造的一切。” 编辑顺序对埃文斯而言至关重要,他的照片在与其他照片的呼应和互动中改变着意义。在第一部分接近尾声时,几栋陈旧的房屋前,卡洛尔·隆巴德(Carole Lombard)的电影的海报暗示着好莱坞式的梦幻生活,然而,当我们继续向后翻两页就会发现,那些做梦的人,竟然是一群躺在路边、无处安睡的失业者,而在这一部分的的最后一张照片,则是一颗被连根拔起的大树倒在了一座荒废的种植园房屋面前,这喻示着一种无法实现且最终化为乌有的生活梦想。 隐匿在作品中的埃文斯希望读者们多花一些时间,在照片相互关涉的过程中去建立我们自己与生活的联系并得出结论。埃文斯问过许多观众一个问题,即生活的目标是否只是即刻的满足,他想说的是,虽然总有一些画刊能让人获得当下的愉悦,比如《生活》(_Life_)杂志(他讨厌的那种),但诗歌王国却不是那么容易建造的。 关于《美国影像》,威廉·卡洛斯·威廉姆斯(William Carlos Williams)曾写道, **“它使我们照见自己,让我们得以从狭隘的认知中抽离出来。我们看到了至今未曾意识到的真相,作为无名之辈,我们于此刻赋予自身以价值。” 另一部分人则认为这本书带有偏见,在这个国家需要正面鼓舞时却充满抱怨,以这样的方式批评自己的国家是不公正的。安塞尔·亚当斯(Ansel Adams)在写给爱德华·韦斯顿(Edward Weston)信中说:“我真他妈的对那些美国左派们的言论感到气愤。” 在新奥尔良,保罗·尼纳斯给他的妻子看了写有她名字缩写(J.S.N.)的献词页,这让她十分惊讶。这是简自从三年前埃文斯写给她的告别信以来,第一次收到他的消息。随后埃文斯开始了秘密通信,他在写给简朋友的信中塞进好运签大小的纸条。由于简同样拒绝再回到已经支离破碎的婚姻,于是找了个借口去了东部,并在1939年终于搬到了埃文斯那里。在MoMA展览之后,埃文斯无可争议地成为了大师,至少在当时少数关注摄影的人看来是这样,虽然他依旧找不到工作。有时艾吉会给他们10美元,好让他们熬过眼前一个礼拜。就这样,简和保罗离婚了,并在1941年一时兴起地和埃文斯结了婚。 埃文斯性格复杂,年轻时就容易陷入抑郁。据说他有身上一种聚光灯式的魅力,以致一进屋就仿佛照亮整个房间。二战期间,《时代》(_Time_)周刊的同事詹姆斯·斯特恩(James Stern)这样描述这位多重定义的男人:“沃克·埃文斯是个知识分子,一位教育家,一个忧郁症患者,一个讲究体面的人,一个花花公子——我想说情人来着。我知道有一些女性爱他、仰慕他,但觉得他有些古怪,还有些无赖。”德克萨斯大学(University of Texas)美国研究和英文教授比尔·斯托特(Bill Stott)在晚年认识了埃文斯,他说,埃文斯的谈话风格“总体上是精彩和浮夸的,充满了格言式的语句。” 埃文斯还有鬼才般聪明的一面。艺术家玛丽·弗兰克(Mary Frank)说,有一年,埃文斯没有收到预期去科德角的邀请,随后她便收到了埃文斯寄来的一封信,大意是这样说的:“亲爱的沃克,在这里真是太美妙了,唯一的问题是我非常想念你……请告诉我你什么时候能来,”并署名“玛丽”,最后他还是来了,并且一副满怀感激的样子。 有一次,当理查德·本森打印完埃文斯的代表作时,有人向埃文斯建议在三个空画框上签名,以防画框一旦损坏需要更换。艺术家的签名是很有价值的,但埃文斯却慷慨地同意了:他的签名一个是“亚伯拉罕·林肯”(Abraham Lincoln),一个是“沃尔特·惠特曼”(Walt Whitman),还有一个是“拉尔夫·沃尔多·爱默生”(Ralph Waldo Emerson)。(埃文斯在1971年回顾展的序言中引用了惠特曼的一句话:我不怀疑,在那些琐碎的事物、昆虫、粗人、奴隶、侏儒、芦苇、被摈弃的废物中,所包含的雄伟和美好远多于我的想象……) 1938年,埃文斯有了新的拍摄项目,在地铁里拍摄毫无防备的乘客。他像个游客一样把康泰时相机(Contax)挂在脖子上,但他既不用手去碰它,也不把它举起来取景,所以没有人意识到他是通过一根从袖子里穿到手上的快门线来拍摄的。他在地下抓拍那些毫不知情的陌生人,他们放下戒备,坦白着自己的表情。光线昏暗,列车摇晃,相机被他有效地固定住,他依靠运气把拍摄目标锁定在对面的长椅上。他故意放弃了对影像的控制,去拍摄那些无意中同样放弃对自己的影像控制的人们。没有人再去提醒他们“笑一个”,埃文斯把偶然性引入了摄影领域,而在这个领域,肖像摄影从未如此偶然过。 这些照片在很长一段时间内都没有发表,直到MoMA在1966年展出了它们,一本名为《众人受到召唤》(_Many Are Called_)的影集为它们带来了不少读者。埃文斯很清楚这些照片具有多大的侵略性,他曾称自己是一个“忏悔的间谍和歉意的偷窥者”。这些照片是通往个人隐私被普遍侵犯道路上的重要标志之一。埃文斯把它们看作是一种清单式的“民众”影像,其中包含了30年代的重要特征:“如同相机所拍下的那样,你在他们中间分辨不出哪些是法官、参议员或银行行长的面孔。你所看到的是即刻清醒的、惊愕的或者平淡无奇的表情:仿佛陪审团里坐着的女士们和先生们。” 从1943年到1945年,埃文斯为《时代》杂志撰写电影评论,有时也评论艺术和书籍。由于当时的汽油和胶卷都是稀缺物(译者注:二战时期美国政府对民众生活物资实行配给制),这给摄影带来了困难,而他即便有一份全职工作,却总是缺乏充沛的精力去胜任,似乎也没有足够的想法让他带着相机出门。同时,由于当时没有人委托他做专题拍摄,这种境况令他一度十分低迷,而且他很可能知道自己的状态已经非常糟糕。但不论如何他还在写作,正如他一直以来渴望的那样。他喜欢流行电影,就像他喜欢民间风格的建筑一样。在评论电影《康尼岛》(Coney Island)(1943年上映,沃尔特·朗执导)时,他说:“这部电影的彩色摄影会让许多观众羡慕不已。接下来,他们终于可以尽情地谈论漂亮的贝蒂·格拉布尔(Betty Grable)了。” 1945年,埃文斯作为唯一的职业摄影师加入了《财富》杂志,后来成为该杂志的特约摄影编辑。但他的内心一直对在资本主义的老巢里做艺术家感到十分矛盾,他设法保持自己的独立性,并在随后的20年里,努力做了一些他想做的事。他时不时地和上级领导见面,试图传达一些自己的想法,然后就带着相机出门了,有时几个月都不回来。埃文斯是个相当有说服力的人,他先成功说服了政府部门,随后又说服卢斯帝国(Luce empire)给他资金,好让他在自己的快乐时光里随心所欲。在20多年的时间里,他先后在《财富》杂志发表了大约40篇作品集和摄影随笔,其中包括几篇关于他的明信片收藏的随笔。 即便不会常有灵感出现,埃文斯仍在不停探索。他通过在街道上设置一个固定位置来拍摄路人,以此关注主体的不在场和影像失去人为控制的问题;他还透过行驶的列车窗户拍下路过的景象;他虽声称彩色摄影是粗俗的,却依旧发表了几篇关于彩色摄影的文章;并且,在芝加哥的街道上,新英格兰的旧旅馆里,陈旧的车站里,以及老旧的办公家具中,埃文斯一直在用影像探寻美国人的生活传统是如何被塑造和延续的。 埃文斯和简在一起的时间变得越来越少,在他的社交生活中渐渐失去了她的身影,以至于埃文斯的一些朋友和同事都不知道他已经结婚了。埃文斯一生都确信自己是艺术家,当他和简吵架时,他甚至会说,“你难道不知道我是谁吗!” 当简终于在画廊开办展览,并尝到了一点成功的滋味时,埃文斯竟认为这是在和他竞争。绘画对于简而言已经举步维艰,1955年,简终于离开了他,与另一个男人结了婚。 1959年,埃文斯结识了瑞士设计师伊莎贝尔·博舍斯坦·冯·斯泰格(Isabelle Boeschenstein von Steiger,现在是Storey),她漂亮、老练,比埃文斯年轻近30岁,一年半后,她与丈夫离婚并嫁给了埃文斯。埃文斯当时的朋友既包括莱昂内尔(Lionel)和戴安娜·特林(Diana Trilling)、玛丽·麦卡锡(Mary McCarthy)、埃德蒙·威尔逊(Edmund Wilson)等文艺界人士,也包括玛丽·弗兰克(Mary Frank)和罗伯特·弗兰克(Robert Frank)在内的波希米亚艺术家群体,但埃文斯习惯把他的熟人圈子分开交往。伊莎贝尔·斯托里(Isabelle Storey)说,她刚认识他时,他社交频繁,经常和乔克·惠特尼(Jock Whitney)等人在一起。作为一名艺术家和叛逆者,埃文斯的内心并不算封闭。“他是一个身穿礼服的艺术家,”斯托里说,“那时的我们被到处邀请。” 1964年,埃文斯先被邀请到耶鲁大学做演讲,随后开始在那儿授课。埃文斯会厚着脸皮让学生们为他提供各种帮助,包括借钱,但学生们认为埃文斯是名人,能够为他提供帮助是一种荣幸,当然埃文斯对他们也同样慷慨。他随后退出了《财富》杂志,因为当时他的身价已非杂志所能负担。他和伊莎贝尔在康涅狄格州的莱姆(Lyme)建了一栋房子,然而这时他们的婚姻已陷入困境。埃文斯开始酗酒,当他的妻子在瑞士教了一个学期的课后,埃文斯指控她抛弃了他。尽管埃文斯对女人有着巨大的吸引力,他对女人也很着迷,但他骨子里始终是一个爱德华时代的绅士,他无法想象一个女人在任何方面都与自己平起平坐,于是在1971年,伊莎贝尔·斯托里离开了他。 就在1973年,也就是埃文斯去世前两年,他给自己买了一台宝丽来SX-70相机。这时的他已是体弱多病,但由于这台相机使用起来十分方便,他对摄影又重新产生了兴趣。埃文斯的拍摄十分密集,在大约8个月的时间里拍摄了2400多张照片:人物特写、日常建筑、室内景物、各类标志等等。直到现在,见到这些作品的人依然不多。 晚年的埃文斯是一个痴迷的收藏家,他热衷于收集废旧物、票根和各类贝壳,有时还用它们来做拼贴画。 家中的后院固然被这些物品塞满,甚至连他的半张床都被盖住了,要想把埃文斯自己瘦弱的身体顺利躺平,就必须先把床上的东西推到一边。有一次,他买下了一整个院子的拍卖品,并借来了一辆卡车,把它们全部丢在了朋友处的草坪上。他还收集各类招牌,甚至唆使年轻朋友帮他在人流密集的路上偷窃招牌。有一次,威廉·克里森伯里突然意识到自己刚刚干了什么,他问埃文斯,如果警察拦住他们该怎么做。“哦,见鬼,”埃文斯说,“我会告诉他们,这是大学生联谊会搞的恶作剧。”那时的他已经快七十岁了。 埃文斯在这一时期的照片有着独特的民间气息,各类手绘招牌,广告牌,破旧的遗物,还包括一些生活中的边缘手工艺品等等,晚年的埃文斯只是单纯地把它们带回家。他将这些庸常的手工艺品提升为大众的普遍认知,并以此暗示,如果将它们按照一定的顺序排列组合,就会幻化成全新的音符弹奏出一个民族的曲调,它们也确实传递出了悲壮的旋律,同时保持着一个国家的历史特有的节拍。即使在今天,它们依然在这片土地上回响。 作者 维姬·戈德堡(Vicki Goldberg)是西方摄影评论领域的领军人物之一,以富有说服力和洞察力的文章著称。《光影的要义》(Light Matters)首版于2005年,该书收集了作家写作生涯以来的诸多优秀散文和评论。 译者 南艺翻译小组是由南京艺术学院传媒学院曹昆萍副教授率领摄影专业在读硕士生组成的翻译团队,致力于将国外优秀的摄影文论引入国内,以飱广大摄影专业人士及爱好者。 原文","link":"/2022/09/08/%E6%B2%83%E5%85%8B%C2%B7%E5%9F%83%E6%96%87%E6%96%AF%E7%9A%84%E6%91%84%E5%BD%B1%E7%BE%8E%E5%AD%A6/"},{"title":"旅行的意义是什么?","text":"喜欢独自旅行,“在路上”已成为一种生活姿态。 经常被问到“旅行的意义是什么”,想想在人生不同阶段,答案也有所不同。旅行,一开始是出于炫耀,当在每一个到过的地方贴上“到此一游”的标签后,也就有了不甘人后的底气,有了谈资,继而增添了履历,满足了虚荣心,这是一种眼睛的旅行。 后来是为了学习。“读万卷书,行万里路。”读书是一种纸上的旅行,旅行是一种路上的读书,谁都无法代替谁,当用开放心态去触摸未知世界时,生活会变得充实而灵动,这是一种头脑的旅行。再后来发现,旅行就是旅行,自有独特价值。于行者而言,星辰与大海既是初心,也是终点;既在路上,也在当下;既是远方,也是家园;这是一种心灵的旅行。 “旅人叩过每个陌生人的门/才找到自己的家/人只有在外面四处漂泊/才能到达内心最深的殿堂。” ——泰戈尔 一路走来,欣赏过那么多壮丽的景色,了解过那么多奇特的风情,接触过那么多陌生的脸孔,发生过那么多感人的故事,历经过那么多艰苦的磨练,不为炫耀,不为猎奇,更非走向虚无,而是更加认识自己。 路上是一个不断怀疑、否定、推翻、重建与求证的过程,一个忍受痛苦与挣扎的蜕变与重生的过程,一个不断告别过去、享受当下与寻找未来的过程。 如果风景与经历没有刻在心上,没有在远行中成长,那走得再远,也只是邮差。 “一个人的行走范围,就是他的世界。”当反思生活中的种种成败得失时,也许远行中曾经流连的一处风景、一个细节、一种心态就会涌上心头,让思考更宽广、更扎实,让人生选择时有丰富的可能性,而不会被眼前的世界所局限。 旅行的意义并不在于一个个具体的世俗目的,但事实上旅行的“名利”价值无处不在,而且是构建人生坐标的基石。 知乎上有个高赞的问答:“我读过很多书,但后来大部分都忘记了,你说这样的阅读究竟有什么意义?”“当我还是个孩子时,我吃过很多食物,现在已经记不起来吃过什么了。但可以肯定的是,它们中的一部分已经长成我的骨头和肉。”读书如此,旅行亦如此。旅行是一场感动,一场旅心,一场修行。走出去是为了走回来,只有清楚世界的方位,才能找到自身的定位。当跋涉过岁月与山河,挣扎过月亮与六便士,旅行成为身体和灵魂的一部分后,你会发现自己想要什么样的风景,什么样的生活,继而找到一条适合自己的路,找到自己最舒服的状态。那时,你已找到归途,找到自我,找到心安之家了;那时,你已懂得善待自己,成全自己,成为自己了。","link":"/2022/02/15/%E6%97%85%E8%A1%8C%E7%9A%84%E6%84%8F%E4%B9%89%E6%98%AF%E4%BB%80%E4%B9%88/"},{"title":"2021的尾声—My Lonely Moment","text":"在 2021 的最后,独自一人窗外弥漫的雾气一瞬,又一瞬“之后能做什么呢”转身,光芒涌现 var player = new DogePlayer({ container: document.getElementById('player'), userId: 1131, vcode: '4d215f84a8d12d66', autoPlay: false });","link":"/2022/01/31/2021%E7%9A%84%E5%B0%BE%E5%A3%B0%E2%80%94My-Lonely-Moment/"},{"title":"柯达克罗姆彩色反转片的冲洗(转)","text":"关于柯达克罗姆彩色反转片的概况柯达公司从1936年开始生产外式法柯达克罗姆色彩反转片,目前共生产三个品种,即:柯达克罗姆25、柯达克罗姆40和柯达克罗姆64。25型和64型是日光型,40型是灯光片。柯达克罗姆彩色反转片的感光度都比较低,25型为ASA25,40型为ASA40,64型为ASA64。它们的共同特点是颗粒细、清晰度高和色彩还原好,主要供作为幻灯片使用。柯达克罗姆胶片的冲洗工艺代号为K14,但原厂既不不公布配方,也不供应成药,只能寄回原厂或原厂指定的代理公司冲洗。 柯达克罗姆彩色胶片的构造柯达克罗姆彩色胶片的构造与一般多层彩色胶片没有根本的区别,其基本结构如下 结构 1 感蓝光乳剂层 2 黄滤色层 3 感绿光乳剂层 4 感红光乳剂层 5 片基 6 防光晕层 柯达克罗姆胶片也是在醋酸纤维片基上依次涂布着感蓝光乳剂层、黄滤色层、感绿光乳剂层和感红光乳剂层,片基的背面涂有碳黑的防光晕层。但是它在蓝、绿、红三层乳剂中含有丙烯酸乙酯和丙烯酸的共聚体,这样一方面可以取消明胶间的隔层,另一方面可以提高在显影过程中外式法彩色显影的上色率,同时也可以防止颜色穿层的现象。 外式法色彩显影的工艺过程:柯达克罗姆胶片,实际上是一种黑白分色多层乳剂的感光材料,在乳剂中并不含有成色剂。经过拍摄曝光在红、绿、蓝三个感光层产生潜影,在冲洗的时候,首先和一般反转片一样,要进行首次黑白显影,把三层感光层的潜影全部还原为金属银的负像。然后把各层残留着的未曝光的卤化银再进行分层曝光和分层彩色显影,这就和一般的反转片不同了。 先把胶片背面(即片基面)对着红光进行反转曝光,接着进行青色彩显,使感红层获得青色正像 再把胶片的乳剂面(即上层)对着蓝光进行反转曝光,接着进行黄色彩显,使感蓝层得到黄色正像 然后对中间感绿层用绿光进行反转曝光 接着进行品红色彩显 最后再经漂白、定影、水洗等过程即获得与被摄景物颜色相同的彩色正像。在进行外式法彩色显影时,可以根据成色剂的特性来调整显影液的配方,有时也可以更换彩色显影剂,用于调整色彩还原和提高胶片的上色率。 外式法彩色显影的成色剂:冲洗加工柯达克罗姆,由于胶片乳剂不含有成色剂,必须用外式法进行彩色显影,因此对成色剂的选择特别重要,它直接影响彩色还原质量和色彩平衡。通过试验我们进一步体会到,对黄、品红、青三种成色剂的要求是十分严格的,有以下一些特点: 彩色画面上所生成黄、品红、青三种染料的光谱特性应与胶片所具有的蓝、绿、红乳剂的感光特性相适应。 在彩色显影过程中,成色剂的上色率要高,但彩色灰雾要较低。 在彩色显影过程中,彩色影像应与银影像相符合,不能产生染料的扩散与渗透现象。 在冲洗加工过程中,应能经过得住酸、碱、醛等溶液的处理,而不致变色或褪色。 成色剂应能溶解于有机溶剂和氢氧化钠溶液中,也能溶解于彩色显影液中而不会产生沉淀。 冲洗工艺过程 工序 温度(℃) 时间(min) 1 预坚膜 24 3 2 水洗 20~24 0.5 3 首显 24 4 4 停显 22~24 3 5 水洗 20~24 10 6 红光曝光 7 青显影 24 10 8 黑白显影 22~24 2 9 停显 22~24 2 10 水洗 20~24 10 11 蓝光曝光 12 黄显影 24 14 13 黑白显影 22~24 2 14 停影 22~24 2 15 水洗 20~24 10 16 绿光曝光 17 品红显影 24 10 18 停影 22~24 2 19 水洗 20~24 10 20 漂白 22~24 5 21 水洗 20~24 10 22 定影 22~24 5 23 水洗 20~24 10 24 稳定 22~24 1 25 干燥 〖注〗红曝光:必须选用与胶片感色性相对应的红滤色镜(或滤色片)对红感光层进行反转曝光,红感光层是涂布在底层,即片基之上,所以,红曝光时,须将胶片片基面对着红光源。我们使用的红滤镜是柯达雷登70号,将红色滤色镜装在彩色放大机的滤色镜夹具中,插入光源前,把放大机镜头光圈全部打开,将红光投影在黑纸上以防反光,然后将柯达克罗姆胶片平放在投影台上,放大机镜头距胶片0.5米,打开光源后对胶片进行分段曝光,每段曝光5分钟,这些都是在暗室中进行。对于滤色镜的选择是十分重要的,这主要取决于他的波长和光谱透光特性,如果要改换滤色镜,需通过试验效果后确定。 青彩色显影:胶片红曝光后,装入显影罐中,然后将青成色剂溶解加入显影液中,调好温度,胶片进行青彩显,在温度24摄氏度下显影10分钟。为了全部地还原底层乳剂中的卤化银,在青色显影之后,须再用黑白显影液进行补充显影。同时为了控制、调整青色画面密度,还可以根据情况在青彩显液中加入适当的黑白显影剂,如米吐尔溶液,一般我们在1000毫升青显影液内加入1%的米吐尔溶液5-10毫升,这对青色密度的影响效果显著。 对青显影的要求是:应控制青色密度、灰雾和反差,因为青色显影效果,它也会影响后面黄显影与品红显影密度的上色率,如果青色灰雾大,会造成色彩不平衡。对于青显影液最好是配好就用,用多少配多少,用后即倒掉,以保证药液稳定。 黑白显影:这次黑白显影的作用主要是为了全部地还原底层乳剂中青显影后剩余的卤化银进行补充显影。 蓝曝光:柯达克罗姆胶片的蓝感光层是在胶片的上层,因此要把胶片乳剂面对着蓝光进行反转曝光,要注意蓝滤色镜的选择,对于它的波长和光谱透光特性应十分严格,以防止穿层现象。我们使用的滤色镜是柯达雷登47B。蓝曝光操作方法和红曝光一样,只是胶片乳剂面向上,对准蓝光源,也是采用分段曝光,在暗室中进行。 黄彩色显影:胶片蓝曝光后,装入显影罐中,然后将黄色成色剂按照配制黄显影液要求溶解后加入显影液中,调好温度后,胶片进入黄彩色显影,在温度24摄氏度下,显影14分钟。 对黄显影的要求是:黄上色率要高,灰雾要小。选用的黄色成色剂经显影后,画面里的黄色中不能有带有红色,黄色透明度要好。黄显影液也是随配好随用,用多少配多少,使用后即倒掉,以保证冲洗质量。 黑白显影:黄显影后,随即进行黑白补充显影,使黄乳剂层中已曝光而未显影的残余卤化银全部还原成金属银,以防止在品红灰雾显影时影响品红的上色率和增加灰雾。 品红灰雾显影:显影液中加入品红成色剂后再加入适当的灰雾剂,使乳剂中的银盐全部灰化,进行显影还原。同时为了控制品红画面密度,也可以根据情况在品红彩色显影液中加入适当的黑白显影液,如米吐尔溶液,一般我们在1000毫升品红显影液内加入1%的米吐尔溶液3-5毫升,即可控制品红密度。 配方预坚液 PH值9 水 800毫升 亚硫酸氢钠 1克 四硼酸钠 20克 甲醛 20毫升 无水硫酸钠 100克 溴化钾 1克 加水至1000毫升 首显液 PH值10.5 水 800毫升 米吐尔 4克 无水亚硫酸钠 50克 海得尔(对苯二酚) 4克 无水碳酸钠 30克 氢氧化钠 1克 硫氰酸钾 1克 溴化钾 3克 六硝基苯并咪唑1% 5毫升 加水至1000毫升 停显液 水 800毫升 98%醋酸 20毫升 加水至1000毫升 青彩色显影液 PH值11.3 水 600毫升 无水亚硫酸钠 10克 磷酸钠 25克 盐酸羟胺 1克 溴化钾 1克 六硝基苯并咪唑1% 10毫升 CD-2 2克 加水至800毫升 〖注〗在使用前取青成色剂1克,溶解于10%含有氢氧化钠溶液的20毫升中,成色剂完全溶解后加入上述显影液中,然后将显影液加水至1000毫升,胶片经红曝光后,即可进行青显影。其中CD-2化学成分名称为:2-氨基-5-二乙基氨基甲苯盐酸盐。 黄彩色显影液 PH值11.5 水 600毫升 无水亚硫酸钠 5克 磷酸钠 25克 氢氧化钠 2克 溴化钾 2克 盐酸羟胺 0.5克 六硝基苯并咪唑1% 10毫升 TSS 2.8克 加水至800毫升 〖注〗在使用前取黄色成色剂1.2克,用20毫升丙酮溶液溶解黄成色剂,完全溶解后再加入上述显影液中,然后将显影液加水至1000毫升。胶片经蓝曝光后,即可进行黄显影。其中TSS化学成分名称为:对氨基二乙基苯胺硫酸盐。 黑白显影液: 水 700毫升 米吐尔 3克 无水亚硫酸钠 45克 海得尔(对苯二酚) 12克 无水碳酸钠 60克 溴化钾 2克 加水至1000毫升 〖注〗使用时一份药液加一份水冲淡后显影,即1:1。 品红彩色显影液 PH值11.75 水 800毫升 无水亚硫酸钠 4克 TSS 4克 氢氧化钠 1克 一水合氨 8毫升 对硝基苯乙腈 1克 加水至1000毫升 〖注〗品红彩显液配方法:配方中除成色剂及灰雾剂(氢氧化胺),其他药品可先溶解配成储备液。在使用前将对硝基苯乙腈(品红成色剂)1克放入20毫升丙酮溶液和10毫升乙醇溶解中溶解,然后再加上上述显影液中,将水加至1000毫升,待其它准备工作完成后(如调好显影液温度等),胶片进入品红显影前再加入氢氧化胺8毫升(灰雾剂),此时,立即将胶片进行品红显影。其中TSS化学成分名称为:对氨基二乙基苯胺硫酸盐。 漂白液 PH值6.9 水 800毫升 铁氰化钾 50克 溴化钾 10克 加水至1000毫升 定影液 PH值8.5 水 700毫升 海波 200克 无水亚硫酸钠 10克 加水至1000毫升 稳定液 水 800毫升 皂角素(湿润剂) 1克 甲醛 10毫升 加水至1000毫升 样片Kelly-Shane FullerPaweł Pająk PDF展开/收起","link":"/2021/10/29/%E6%9F%AF%E8%BE%BE%E5%85%8B%E7%BD%97%E5%A7%86%E5%BD%A9%E8%89%B2%E5%8F%8D%E8%BD%AC%E7%89%87%E7%9A%84%E5%86%B2%E6%B4%97%EF%BC%88%E8%BD%AC%EF%BC%89/"},{"title":"提升Intel 4代处理器性能锁定全核倍频","text":"Z系列可以直接解锁全核倍频。对于B和H系列,如果你的主板BIOS选项中有 (CPU倍频 all core),也可以解锁全核倍频 工具 主板BIOS(2015年3月左右或者官方超频BIOS) UEFI Tool 替换BIOS中的微码运行UEFI.BIOS.Updater.1.66 文件夹中的ubu.bat。ubu.bat可以自己识别文件夹中的BIOS文件,如果没有自动识别,提示载入一个文件,选择bios文件即可。 更新CPU微码 更新HasWell架构微码输入7回车,更新CPU微码 输入1回车,更新HasWell架构微码 解锁HasWell限制输入7回车,解锁HasWell限制 输入0回车,完成BIOS编辑输入1回车,将新BIOS保存到当前目录输入任意键结束程序,程序目录下便有最新的BIOS了 刷写BIOS把它放入_FAT32_格式U盘根目录中详细刷写BIOS请参考主板官网的帮助 设置BIOS为all corecpu倍频必须必须选择所有内核(all core),否则解锁无效。在All core 填入你的CPU单核最大频率即可。如E3 1231V3 单核最大倍频为38 保存退出重启电脑即可 如果你打开电脑,打开CPUZ发现所有核心都运行在了最高倍频,那么恭喜,你锁住了。🎉 如果没有,请继续往下看。 Oops!我没锁住🤔 Make a screenshot of regedit with expanded key HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0 Your BIOS has microcode with 0x06 version, but Windows update it to 0x28 version.Delete or rename file C:\\Windows\\System32\\mcupdate_GenuineIntel.dll https://www.bios-mods.com/forum/Thread-Biostar-B85W-CPU-frequency-problem 大意就是我修改了BIOS中的微码为0x06,但是系统把微码更新成了0x28。 删除系统微码在PE中删除或重命名系统微码文件C:\\Windows\\System32\\mcupdate_GenuineIntel.dll 还是锁不住🤔 使用ThottleStop锁倍频 Show FIVR and TPL information in ThrottleStop. 设置ThottleStop中的FIVR的Turbo Ratio Limits为CPU单核最大倍频。修改即时生效。 最后把ThottleStop设置为开机启动就行了 🎉如果你锁住了,可以送我一条评论吗🎉 参考资料 https://www.bios-mods.com/forum/Thread-Biostar-B85W-CPU-frequency-problem https://zhuanlan.zhihu.com/p/54535319 https://www.techpowerup.com/forums/threads/how-can-i-get-throttlestop-to-auto-load-when-windows-starts-up.230371/","link":"/2021/09/20/enhance_haswell/"},{"title":"解读MTF曲线","text":"Modulation Transfer Function(调制传递函数)是分析镜头的解像比较科学的方法,这种测定光学频率的方式是以一个mm的范围内能呈现出多少条线来度量,其单位以line/mm来表示。所以当一支镜头能做到所入即所出的程度那就表示这支镜头是所谓的完美镜头,但是因为镜片镜头的设计往往还有很多因素影响所以不可能有这种理想化的镜头。 1.横坐标轴代表与画面中心的距离,从左到右代表从中心到边缘的成像 (全画幅镜头的横轴约22mm,残幅镜头的横轴约13mm) 2.纵坐标轴代表MTF值 3.黑色线条表示最大光圈,蓝色线条表示f/8光圈 4.粗线表示10线/mm,细线表示30线/mm 5.实线表示拍摄从中心呈放射状纹样的成像性能,用字母“S”表示 6.虚线表示拍摄线条呈同心圆向外扩展状纹样的成像性能,用字母“M”表示 [caption id=”” align=”aligncenter” width=”670”] https://www.canon.com.cn/product/ef/index/lensmtf.html\\[/caption\\] 1. MTF值越接近1越好,即MTF线越高越好 2.粗线约高,说明镜头的反差表现越好 3.细线越高,说明镜头的分辨率越好 4. MTF曲线越平坦,说明边缘和中心的成像差距越小 5.实线和虚线越接近,说明镜头的焦外成像越好 6.蓝线说明镜头f/8时的成像水平,近似于镜头的最佳成像水平 7.黑线说明镜头最大光圈时的成像水平,大光圈的价值所在","link":"/2021/07/01/%E8%A7%A3%E8%AF%BBmtf%E6%9B%B2%E7%BA%BF/"},{"title":"Digispark模拟HID键盘控制BIOS","text":"展开/收起 有一个穷鬼,十分喜欢折腾电脑硬件,可他的父母并不支持他的兴趣爱好,他们认为生为学生就应该心无杂念的一心想着读书。几年过去了,穷鬼的电脑开始渐渐的赶不上时代了,他看了看他的CPU,不由自主地叹了口气:“Pentium E5300… “ 在他的不懈努力之下,从K那里抢来了一块Q6600和一块9600GT 又过了几年,又从一个不知名的仓库里拆出了一块Q9300。 没过多久,他收到一个快递,拆开一看竟然是印着自己名字的GT1030,那天,是他的生日。 一年后,穷鬼上了高中,发现处理器还是差那么亿点点,他看了看自己空空荡荡的钱包,一咬牙,买了一块X5450,装CPU的那天,他心里想着,装上了这块CPU你就无敌了…… 欧耶,点亮了! 关机。 来BIOS里超个外频。欸,🌿🌿🌿,怎么点不亮了,#¥%……他发现了一个问题,每次开机前要断电, BIOS恢复后才能开机。 🌿那岂不是保存不了超频。 在默频用了一段时间后,他突发奇想,是否可以用arduino做badusb,在开机时模拟键盘,自动设置BIOS呢?他翻出来尘封已久的arduino……最后选择了digispark作为badusb Digispark?Digispark是一款类似于Arduino Uno基于Attiny85的微控制器开发板。可用于制作Badusb设备, BadUSB是一种通过重写U盘固件伪装成USB输入设备(键盘,网卡)用于恶意用途的usb设备。杀毒软件由于无法接触到usb固件,所以对它也无可奈何 点个灯尝试烧写一个示例程序。 1234567891011//_因为此开发板有两种类型,并且这两种的LED接的引脚不一样,所以下面的代码中,同时在操作两个引脚。_void setup() { pinMode(0, OUTPUT); //LED on Model B pinMode(1, OUTPUT); //LED on Model A } void loop() { digitalWrite(0, HIGH); // turn the LED on (HIGH is the voltage level) digitalWrite(1, HIGH); delay(300); // wait for a second digitalWrite(0, LOW); // turn the LED off by making the voltage LOW digitalWrite(1, LOW); delay(300); // wait for a second } 这款开发板比较特殊,先点击下载按钮,当出现如下提示时再插入开发板(而不是插好等下载) 1234项目使用了 718 字节,占用了 (11%) 程序存储空间。最大为 6012 字节。全局变量使用了9字节的动态内存。Running Digispark Uploader...Plug in device now... (will timeout in 60 seconds) 这段时间是用来烧写程序的,因为烧写时引导程序需要通过USB接口与计算机沟通,所以这时候计算机才能识别到开发板。5秒后,内部的boot loader会退出烧写模式,并加载用户程序,所以计算机就识别不到它了,并且此时led才能正常闪烁。展开/收起 123456789101112131415161718192021222324252627282930Running Digispark Uploader...Plug in device now... (will timeout in 60 seconds)> Please plug in the device ... > Press CTRL+C to terminate the program.> Device is found!connecting: 16% completeconnecting: 22% completeconnecting: 28% completeconnecting: 33% complete> Device has firmware version 2.2> Device signature: 0x1e930b > Available space for user applications: 6522 bytes> Suggested sleep time between sending pages: 7ms> Whole page count: 102 page size: 64> Erase function sleep duration: 714msparsing: 50% complete> Erasing the memory ...erasing: 55% completeerasing: 60% completeerasing: 65% complete>> Eep! Connection to device lost during erase! Not to worry>> This happens on some computers - reconnecting...>> Reconnected! Continuing upload sequence...> Starting to upload ...writing: 70% completewriting: 75% completewriting: 80% complete> Starting the user app ...running: 100% complete>> Micronucleus done. Thank you! var player = new DogePlayer({ container: document.getElementById('player_af937f3787ae1eb1'), userId: 1131, vcode: 'af937f3787ae1eb1', autoPlay: false }); 撸代码在GitHub上有一个为digispark一键生成代码的project > AutoMator 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859#include void loop() {}void setup() {DigiKeyboard.sendKeyStroke(0);DigiKeyboard.delay(1000);//STARTDigiKeyboard.delay(15000);//ENTER BIOSDigiKeyboard.sendKeyStroke(KEY\\_F1);DigiKeyboard.delay(1000);//TO ADVANCEDDigiKeyboard.sendKeyStroke(KEY\\_RIGHT\\_ARROW);DigiKeyboard.delay(600);//ENTER JUMPERFREE CONFIGURATIONDigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//SET OVERCLOCKING MODEDigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//MANUALDigiKeyboard.sendKeyStroke(KEY\\_UP\\_ARROW);DigiKeyboard.delay(600);DigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//TO CPU FREQUENCYDigiKeyboard.sendKeyStroke(KEY\\_DOWN\\_ARROW);DigiKeyboard.delay(600);//ENTER CPU FREQUENCYDigiKeyboard.print(\"380\");DigiKeyboard.delay(600);DigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//BACK TO ADVANCEDDigiKeyboard.sendKeyStroke(KEY\\_ESC);DigiKeyboard.delay(600);//TO CPU CONFIGURATIONDigiKeyboard.sendKeyStroke(KEY\\_DOWN\\_ARROW);DigiKeyboard.delay(600);//ENTER CPU CONFIGURATIONDigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//TO C1E SUPPORTDigiKeyboard.sendKeyStroke(KEY\\_DOWN\\_ARROW);DigiKeyboard.delay(600);//SET C1E SUPPORTDigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//DISABLE C1E SUPPORTDigiKeyboard.sendKeyStroke(KEY\\_UP\\_ARROW);DigiKeyboard.delay(600);DigiKeyboard.sendKeyStroke(KEY\\_ENTER);DigiKeyboard.delay(600);//SAVE && EXITDigiKeyboard.sendKeyStroke(KEY\\_F10);DigiKeyboard.delay(600);DigiKeyboard.sendKeyStroke(KEY\\_ENTER);} 编译失败了12const unsigned char ascii\\_to\\_scan\\_code\\_table \\[119\\]' previously defined hereconst unsigned char ascii\\_to\\_scan\\_code\\_table\\[\\] PROGMEM = { 这个错误由digispark.h中键位表不全所致。代码中如出现KEY_RIGHT_ARROW等未定义的键时会导致编译出错。 在digispark.h中补全键位表即可 12345#define KEY\\_UP\\_ARROW 0x52#define KEY\\_DOWN\\_ARROW 0x51#define KEY\\_LEFT\\_ARROW 0x50#define KEY\\_RIGHT\\_ARROW 0x4F#define KEY\\_ESC 0x29 怎么没反应🧐好欸,BIOS认digispark是个键盘了 等 再等 再等等 并没有反应 在digispark论坛中,很多人反应digispark模拟的hid键盘并不能在BIOS中使用 https://digistump.com/board/index.php?topic=1096.0 https://digistump.com/board/index.php?topic=2922.0 有大佬提出通过替换digispark.h和usbconfig.h文件可以解决这个问题https://github.com/bkgarry/DigikeyboardBIOS These two files (DigiKeyboard.h and usbconfig.h) replace the original digikeyboard files in the following windows directory.%localappdata%\\\\Arduino15\\\\packages\\\\digistump\\\\hardware\\\\avr\\\\1.6.7\\\\libraries\\\\DigisparkKeyboard(please note that the path may change for different versions of the digistump files and Arduino IDE) %localappdata% is the environmental variable to take you to your user’s local appdata so the path will work. Once these files have been replaced, recompile your existing code to your digispark and you will be able to use the same script to run your keyboard commands within a system BIOS) Working🤗 var player = new DogePlayer({ container: document.getElementById('player'), userId: 1131, vcode: '0314c74e2e4534b5', autoPlay: false });","link":"/2021/04/05/%E9%80%9A%E8%BF%87digispark%E6%A8%A1%E6%8B%9F%E9%94%AE%E7%9B%98%E6%8E%A7%E5%88%B6bios/"},{"title":"DIY适马佳能AF镜头兼容性修复(\\"rechip\\")","text":"原文:Github & Twitter 翻译/校对:Given 使用佳能EF卡口的旧的适马镜头不能在新的佳能机身上工作,因为适马不完全反向工程EF协议,没有实现所有需要的命令。这是一个DIY修复方法,使用ATtiny13单片机来修改协议,使镜头重新兼容数码EOS机身。 有些人喜欢称之为 “rechip”,”rechip”实际上是指官方的修复,包括更换镜头中的芯片。但这个修正是一个附加的修正,并没有替换镜头中现有的芯片,所以更应该称之为 “modchip”。 功能介绍**低功耗**:该修复在活动模式下(例如拍摄、自动对焦、实时视图模式或更改镜头设置时)消耗约500µA,在睡眠模式下(在标准模式下或相机关闭时,在几秒钟不活动后自动进入)消耗不到1µA。因此,它不会对电池寿命产生可衡量的影响。 **被动式**:本方案不像其他方案那样通过DCL线路由MCU处理,而是使用一个电阻,仅在必要时主动覆盖DCL。因此,在协议的正常运行中,它的影响为零,只改变需要改变的一个位。 **正确的EF协议**:与其他版本不同,这个版本正确解析EF协议,并跟踪命令长度。它还有一个超时功能,如果出了问题,可以与命令重新同步。 [dogevideo]57b05519765a9df3[/dogevideo] 编译输入make来编译工程(需要avra编译器),或者make flash来用avrdude flash (默认使用 usbtiny 编译器,但你可以使用 make PROGRAMMER=foo来改变编译器类型)。如果你使用其他的编程方法,不要忘了刷写保险丝 (LFUSE=0x72 HFUSE=0xfb)。 安装方法安装时,需要剪断相机到镜头的DCL线,并在线路上插入一个220Ω的电阻,然后将编程后的ATtiny13接上,如下图所示。 1234567891011121314151617 Camera side ========================================= DGND LCLK DLC DCL VDD PGND/DET VBAT | | | | | | | ATtiny13 ,------------------------+ | | __________ | | | | | | | | |o | | | | | \\ | | | 1|RESET VCC|8-' | | | 220/ | | | 2|PB3 PB2|7 | | | Ω \\ | | | 3|PB4 PB1|6----------+ | / | | |,-4|GND PB0|5---------------------+ | | || |__________| | | | | | | |`-------------------+ | | | | | | | | | | | | | DGND LCLK DLC DCL VDD PGND/DET VBAT ========================================= Lens side 问题佳能EF镜头同时接受12 YY和13 YY两个命令,以YY步数(符号为uint8)改变光圈。旧的胶片佳能机身使用12 YY,而新的数码机身使用13 YY。看来适马并没有通过尝试所有可能的命令来完全逆向工程协议,而只是实现了当时佳能机身使用的命令。因此,老的适马镜头只支持12 YY。如果这样的镜头用在新机身上,光圈永远不会移动。光圈有一个位子反馈给相机:是否在全开位置。相机会根据它所期望的光圈位置来检查这一点。因此,这些老镜头的行为如下:如果光圈是大开(常见情况),镜头只会在相机光圈设置为全开(匹配)的情况下拍摄,否则相机会抛出一个错误。如果光圈不是全开(比如被手动移动了,或者在关机时取下了镜头),那么相机会允许用其他光圈设置拍照,但光圈当然也不会移动。 解决方法把命令13补成命令12。他们之间只有一个比特的差异差。由于协议是MSB优先,所以只要前面7个位都收到后,即可完成,也就是说不需要延迟或缓冲协议,而是可以近乎实时完成。 原理代码的大部分时间都是处于在睡眠模式下的。当LCLK为低电平时(在命令开始时),它通过低电平INT0中断唤醒芯片。中断处理程序什么也不做,只是从掉电模式返回。然后,主程序禁用中断以防止其重新启动,并接收命令字节。唤醒延迟是这样的:当LCLK为高电平时,芯片正好可以对第一个命令位进行采样,这是预期的采样时间。 在接收到7个命令位后,代码会检查命令0x12/0x13。如果命令匹配,则等待下一个位周期,然后强制DCL为低。这将任何0x13命令改写成0x12,然后等待镜头通过LCLK脉冲确认命令。 由于命令可以有参数,而且没有明确的框架来区分参数和命令,因此代码中包含了所有256个可能的命令以及预期参数长度的表格(根据佳能镜头进行检查)。如果有任何参数字节,它就会读取这些字节,而不进行任何进一步的处理,然后回到睡眠模式,等待下一条命令。 为了在出现故障时实现超时,定时器0设置了0-700µs的超时,并在每个命令开始时启动,同时允许中断。只有当镜头应答一个命令时,它才会停止。如果定时器过期,它就会触发一个中断,该中断不会返回,而是从复位向量重新启动整个程序。这与佳能镜头的行为类似,如果一个命令字节的时间超过700µs,它将启动一个协议复位。 var player = new DogePlayer({ container: document.getElementById('player'), userId: 1131, vcode: '57b05519765a9df3', autoPlay: false });","link":"/2020/12/22/diy%E9%80%82%E9%A9%AC%E4%BD%B3%E8%83%BDaf%E9%95%9C%E5%A4%B4%E5%85%BC%E5%AE%B9%E6%80%A7%E4%BF%AE%E5%A4%8Drechip/"},{"title":"DIY Arduino 入射式测光表","text":"A Lightmeter/Flashmeter for photographers, based on Arduino. Components: Arduino NANO v.3 BH1750 light sensor SSD1306 128*96 OLED SPI Display Buttons Thanks @morozgrafix for creating schematic diagram for this device. The lightmeter based on Arduino as a main controller and BH1750 as a metering cell. Information is displayed on SSD1306 OLED display. The device is powered by 2 AAA batteries. Functions list: Ambient light metering Flash light metering ND filter correction Aperture priority Shutter speed priority ISO range 8 - 4 000 000 Aperture range 1.0 - 3251 Shutter speed range 1/10000 - 133 sec ND Filter range ND2 - ND8192 Displaying amount of light in Lux. Displaying exposure value, EV Recalculating exposure pair while one of the parameter changing Battery information Power 2xAAA LR03 batteries Detailed information on my site: https://www.pominchuk.com/lightmeter/ DIY测光表测光模式相当于相机内中央平均测光。在大多数拍摄情况下中央平均测光是一种非常实用的测光模式,在拍摄人像旅游照等对于中央亮度起到决定性作用的拍摄场景时,应用广泛。 所需元件1. Arduino nano 2. BH1750光强度模块 3. 0.96寸 7针SPI接口oled屏幕(SSD1306) 源码&&焊接123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178#include <SPI.h>#include <Wire.h>#include <Adafruit\\_GFX.h>#include <Adafruit\\_SSD1306.h>#include <BH1750.h>#include <EEPROM.h>#include <avr/sleep.h>#define SCREEN\\_WIDTH 128 // OLED display width, in pixels#define SCREEN\\_HEIGHT 64 // OLED display height, in pixels// Declaration for SSD1306 display connected using software SPI (default case):#define OLED\\_DC 11#define OLED\\_CS 12#define OLED\\_CLK 8 //10#define OLED\\_MOSI 9 //9#define OLED\\_RESET 10 //13Adafruit\\_SSD1306 display(SCREEN\\_WIDTH, SCREEN\\_HEIGHT, OLED\\_MOSI, OLED\\_CLK, OLED\\_DC, OLED\\_RESET, OLED\\_CS);BH1750 lightMeter;#define DomeMultiplier 2.17 // Multiplier when using a white translucid Dome covering the lightmeter#define MeteringButtonPin 2 // Metering button pin#define PlusButtonPin 3 // Plus button pin#define MinusButtonPin 4 // Minus button pin#define ModeButtonPin 5 // Mode button pin#define MenuButtonPin 6 // ISO button pin#define MeteringModeButtonPin 7 // Metering Mode (Ambient / Flash)//#define PowerButtonPin 2#define MaxISOIndex 57#define MaxApertureIndex 70#define MaxTimeIndex 80#define MaxNDIndex 13#define MaxFlashMeteringTime 5000 // msfloat lux;boolean Overflow = 0; // Sensor got Saturated and Display \"Overflow\"float ISOND;boolean ISOmode = 0;boolean NDmode = 0;boolean PlusButtonState; // \"+\" button stateboolean MinusButtonState; // \"-\" button stateboolean MeteringButtonState; // Metering button stateboolean ModeButtonState; // Mode button stateboolean MenuButtonState; // ISO button stateboolean MeteringModeButtonState; // Metering mode button state (Ambient / Flash)boolean ISOMenu = false;boolean NDMenu = false;boolean mainScreen = false;// EEPROM for memory recording#define ISOIndexAddr 1#define apertureIndexAddr 2#define modeIndexAddr 3#define T\\_expIndexAddr 4#define meteringModeAddr 5#define ndIndexAddr 6#define defaultApertureIndex 12#define defaultISOIndex 11#define defaultModeIndex 0#define defaultT\\_expIndex 19uint8\\_t ISOIndex = EEPROM.read(ISOIndexAddr);uint8\\_t apertureIndex = EEPROM.read(apertureIndexAddr);uint8\\_t T\\_expIndex = EEPROM.read(T\\_expIndexAddr);uint8\\_t modeIndex = EEPROM.read(modeIndexAddr);uint8\\_t meteringMode = EEPROM.read(meteringModeAddr);uint8\\_t ndIndex = EEPROM.read(ndIndexAddr);int battVolts;#define batteryInterval 10000double lastBatteryTime = 0;#include \"lightmeter.h\"void setup() { pinMode(PlusButtonPin, INPUT\\_PULLUP); pinMode(MinusButtonPin, INPUT\\_PULLUP); pinMode(MeteringButtonPin, INPUT\\_PULLUP); pinMode(ModeButtonPin, INPUT\\_PULLUP); pinMode(MenuButtonPin, INPUT\\_PULLUP); pinMode(MeteringModeButtonPin, INPUT\\_PULLUP); //Serial.begin(115200); battVolts = getBandgap(); //Determins what actual Vcc is, (X 100), based on known bandgap voltage Wire.begin(); lightMeter.begin(BH1750::ONE\\_TIME\\_HIGH\\_RES\\_MODE\\_2); //lightMeter.begin(BH1750::ONE\\_TIME\\_LOW\\_RES\\_MODE); // for low resolution but 16ms light measurement time. display.begin(SSD1306\\_SWITCHCAPVCC, 0x3D); display.setTextColor(WHITE); display.clearDisplay(); // IF NO MEMORY WAS RECORDED BEFORE, START WITH THIS VALUES otherwise it will read \"255\" if (apertureIndex > MaxApertureIndex) { apertureIndex = defaultApertureIndex; } if (ISOIndex > MaxISOIndex) { ISOIndex = defaultISOIndex; } if (T\\_expIndex > MaxTimeIndex) { T\\_expIndex = defaultT\\_expIndex; } if (modeIndex < 0 modeIndex > 1) { // Aperture priority. Calculating shutter speed. modeIndex = 0; } if (meteringMode > 1) { meteringMode = 0; } if (ndIndex > MaxNDIndex) { ndIndex = 0; } lux = getLux(); refresh();}void loop() { if (millis() >= lastBatteryTime + batteryInterval) { lastBatteryTime = millis(); battVolts = getBandgap(); } readButtons(); menu(); if (MeteringButtonState == 0) { // Save setting if Metering button pressed. SaveSettings(); lux = 0; refresh(); if (meteringMode == 0) { // Ambient light meter mode. lightMeter.configure(BH1750::ONE\\_TIME\\_HIGH\\_RES\\_MODE\\_2); lux = getLux(); if (Overflow == 1) { delay(10); getLux(); } refresh(); delay(200); } else if (meteringMode == 1) { // Flash light metering lightMeter.configure(BH1750::CONTINUOUS\\_LOW\\_RES\\_MODE); unsigned long startTime = millis(); uint16\\_t currentLux = 0; lux = 0; while (true) { // check max flash metering time if (startTime + MaxFlashMeteringTime < millis()) { break; } currentLux = getLux(); delay(16); if (currentLux > lux) { lux = currentLux; } } refresh(); } }} 运行库 Adafruit_Circuit_Playground Adafruit_Sensor Adafruit_SSD1306 Adafruit-GFX-Library BH1750 2020.11.23 立个flag 2022-02-03 重新设计PCB","link":"/2020/11/23/diy-arduino-%E5%85%A5%E5%B0%84%E5%BC%8F%E6%B5%8B%E5%85%89%E8%A1%A8/"},{"title":"用ESP8266扩展家中局域网","text":"via https://github.com/rubfi/esp_wifi_repeater ESP无线中继器这是一个在esp8266作为WiFi NAT路由器的概念和实现。它可以作为现有WiFi网络的无线AP扩展。esp以STA和soft-AP模式透明转发任何IP的流量。因为它使用NAT转发,所以在网络端和连接的站点上都不需要路由条目。站点在192.168.4.0/24网络中默认通过DHCP配置,并从现有的WiFi网络接收其DNS地址。 经过测试,ESP无线中继器可以在两个方向上实现约 5 Mbps,因此即使流媒体也是可能的。ESP无线中继器还允许远程监控(或数据包嗅探),例如使用 Wireshark。 烧录在 Windows 上,可以使用”ESP8266 下载工具”在 https://espressif.com/en/support/download/other-tools 从固件目录下载两个文件 0x000000.bin 和 0x10000.bin。(对于 ESP-01,将闪存大小更改为”8Mbit”) 使用 V2.0.0 SDK 编译的固件无法在某些 ESP-01 模块上启动。如果遇到这些问题,请使用目录firmware_sdk_1.5.4(地址 0x00000 和 0x40000)。 我用的D1 mini也只能用firmware_sdk_1.5.4编译的固件启动 使用固件烧录完成后可以使用putty连接ESP的com口,波特率115200以修改固件默认配置 固件从以下默认配置开始: ssid: ssid, pasword: password ap_ssid: MyAP, ap_password: none, ap_on: 1, ap_open: 1 network: 192.168.4.0/24 这意味着它通过AP sid,密码连接到互联网,并提供一个开放的AP与ap_ssid:MyAP。此默认值可以在文件user_config. h 中更改。可以使用控制台接口覆盖默认值并持续保存为闪存。此控制台可通过 115200 波特的串行端口或 tcp 端口 7777(例如,从连接的 STA 获得”telnet 192.168.4.1 7777”)。 控制台使用以下命令: help: prints a short help message show [configstats]: prints the current config or some statistics eg:show config set [ssidpasswordap_ssidap_password] value: changes the named config parameter set ssid TP-LINK_B9C0 set password !@#¥%……&*(( set ap_open [01]: selects, wheter the soft-AP uses WPA2 security (ap_open=0) or no password (ap_open=1) set ap_on [01]: selects, wheter the soft-AP is disabled (ap_on=0) or enabled (ap_on=1) set network ip-addr: sets the IP address of the internal network, network is always /24, router is always x.x.x.1 set speed [80160]: sets the CPU clock frequency set vmin voltage: sets the minimum battery voltage in mV. If Vdd drops below, the ESP goes into deep sleep. If 0, nothing happens set vmin_sleep time: sets the time interval in seconds the ESP sleeps on low voltage set config_port portno: sets the port number of the console login (default is 7777, 0 disables remote console config) portmap add [TCPUDP] external_port internal_ip internal_port: adds a port forwarding portmap remove [TCPUDP] external_port: deletes a port forwarding save [dhcp]: saves the current config parameters [+ the current DHCP leases] to flash quit: terminates a remote session reset [factory]: resets the esp, optionally resets WiFi params to default values lock: locks the current config, changes are not allowed unlock password: unlocks the config, requires password of the network AP scan: does a scan for APs monitor [onoff] port: starts and stops monitor server on a given port 状态指示灯在默认配置 GPIO2 配置驱动器状态 LED(连接到 GND)与以下指示: 常亮:已启动,但未成功连接到 AP 闪烁(1 秒):工作,连接到 AP 非正常闪烁:工作,内部网络中的流量 在user_config.h 中,可以配置备用 GPIO 端口。当配置为 GPIO1 时,它可与 ESP-01 板上的蓝色 LED 一起使用。但是,由于 GPIO1 ist 也是 UART-TX 引脚,这意味着串行控制台不工作。 MQTT 支持自版本 1.3 以来,路由器具有一个构建中的 MQTT 客户端(感谢 Tuan PM的库https://github.com/tuanpmt/esp_mqtt。这可以帮助将路由器/中继器集成到 IoT 中。家庭自动化系统可以例如,根据有关当前关联站的信息做出决策,它可以打开和中继器(例如,根据时间安排),或者简单地用于监视负载。路由器可以连接到本地 MQTT 代理或云中的公开代理。但是,当前它不支持 TLS 加密。 默认情况下,MQTT 客户端处于禁用状态。可以通过将配置参数”mqtt_host”设置为不同于”无”的主机名来启用它。要配置 MQTT,可以设置以下参数: set mqtt_host IP_or_hostname: IP or hostname of the MQTT broker (“none” disables the MQTT client) set mqtt_user username: Username for authentication (“none” if no authentication is required at the broker) set mqtt_user password: Password for authentication set mqtt_id clientId: Id of the client at the broker (default: “ESPRouter_xxxxxx” derived from the MAC address) set mqtt_prefix prefix_path: Prefix for all published topics (default: “/WiFi/ESPRouter_xxxxxx/system”, again derived from the MAC address) set mqtt_command_topic command_topic: Topic subscribed to receive commands, same as from the console. (default: “/WiFi/ESPRouter_xxxxxx/command”, “none” disables commands via MQTT) set mqtt_interval secs: Set the interval in which the router publishs status topics (default: 15s, 0 disables status publication) set mqtt_mask mask_in_hex: Selects which topics are published (default: “ffff” means all) MQTT 参数可以使用”显示 mqtt”命令显示。 prefix_path/Uptime: System uptime since last reset in s (mask: 0x0020) prefix_path/Vdd: Voltage of the power supply in mV (mask: 0x0040) prefix_path/Bpsin: Bytes/s from stations into the AP (mask: 0x0800) prefix_path/Bpsout: Bytes/s from the AP to stations (mask: 0x1000) prefix_path/Ppsin: Packets/s from stations into the AP (mask: 0x0200) prefix_path/Ppsout: Packets/s from the AP to stations (mask: 0x0400) prefix_path/Bin: Total bytes from stations into the AP (mask: 0x0080) prefix_path/Bout: Total bytes from the AP to stations (mask: 0x0100) prefix_path/NoStations: Number of stations currently connected to the AP (mask: 0x2000) prefix_path/join: MAC address of a station joining the AP (mask: 0x0008) prefix_path/leave: MAC address of a station leaving the AP (mask: 0x0010) prefix_path/IP: IP address of the router when received via DHCP (mask: 0x0002) prefix_path/ScanResult: Separate topic for the results of a “scan” command (one message per found AP) (mask: 0x0004) prefix_path/response: The router publishes on this topic the command line output (mask: 0x0001) 电源管理中继器监控其电流电源电压(显示在”show stats”命令中)。如果_vmin(_在 mV 中,默认 0)设置为值 > 0,并且电源电压低于此值,则它将进入_深度睡眠模式 vmin_sleep_秒。如果您已将 GPIO16 连接到 RST(很难在 ESP-01 上焊接),它将在此间隔后重新启动,尝试重新连接,并将继续测量。 运行截图","link":"/2020/08/07/%E7%94%A8esp8266%E6%89%A9%E5%B1%95%E5%AE%B6%E4%B8%AD%E5%B1%80%E5%9F%9F%E7%BD%91/"},{"title":"太阳神HELIOS 44M-4","text":"Helios 44 Helios 44型135镜头自1950年年初开始研制,基于卡尔-蔡司-耶拿的Biotar 2/58镜头的光学设计,最初被称为“BTK”,即BioTar Krasnogorskij,大意为克拉斯诺戈尔斯克的Biotar镜头。该镜头1958年开始在KMZ工厂正式生产,后来螺口的格里奥斯44镜头搬迁到白俄罗斯明斯克的BELOMO厂生产,卡口镜头依然在KMZ厂生产。1972年,格里奥斯44M问世,标志着该镜头开始向现代镜头演变;1981年格里奥斯44M -4定型,此后逐渐延伸出一个庞大的镜头家族。 Helios 44镜头有多重卡口,除了早期的插刀式之外,还有PK卡口、L39螺口和M42螺口。 Helios 44镜头均采用双高斯结构,使得该镜头可以轻松提供F2的大光圈,同时能够自动校正很多像差。但是由于早期双高斯结构设计上的问题,光圈全开时像场边缘部位的球形畸变校正不彻底,导致焦外光斑被压缩成椭圆形状,越靠近边缘变形越厉害,当焦外是明亮的杂乱光斑时能够形成所谓“漩涡散景”,即大家通常所说的漩焦。 Helios 44镜头版本繁多,如 Helios-44、Helios-44-2、Helios-44-7、Helios-44M、Helios-44M-4、以及后续的Helios-44M-5、Helios-44M-6和Helios-44M-7等。最早因为Helios-44-2有八片光圈,故有“八羽怪”的别称 Helios-44-2有两个用于控制光圈的光圈环,一个是无级调整光圈大小的光圈环,另一个环带有刻度,用于锁定最小光圈,以便在最大光圈下取景完毕后能迅速回到想用的光圈进行拍摄。 从Helios-44M开始,加入了自动顶针,光圈环减少为一个并带有刻度。镜头前面是对焦环,后面是光圈环,使用起来的感觉和如今的手动头一样。从Helios-44M-4开始,开始采用多层镀膜技术,分辨率大为提高 样片 Canon Kiss X3 f2 0.5‘ ISO 100 var player = new DogePlayer({ container: document.getElementById('player'), userId: 1131, vcode: 'abb6a1f3fefd5245', autoPlay: false });","link":"/2020/05/07/%E5%A4%AA%E9%98%B3%E7%A5%9Ehelios-44m-4/"},{"title":"4.7 玄风飞行基地","text":"[dogevideo]1e4b3e5ea84bd042[/dogevideo]","link":"/2020/04/08/4-7/"},{"title":"极致细节的无损视频","text":"var player = new DogePlayer({ container: document.getElementById('player'), userId: 1131, vcode: 'c7f76db19e56338b' }); 说出来可能不信,器材是09年的佳能500D加上外挂Magic lantern固件","link":"/2020/03/25/lossless_video_on_500D_with_magiclantern/"},{"title":"在单片机上运行Linux(转载)","text":"介绍在Linux论坛中,常见的问题是询问Linux的最低规格是多少。常见的答案是,它需要32位体系结构,一个MMU和至少一兆字节的RAM以适合内核。该项目旨在(并成功)的粉碎这些概念。您在右侧看到的开发板基于ATmega1284p。我也使用ATmega644a取得了同样的成功。该主板没有其他处理器,并且可以启动Linux 2.6.34。实际上,它甚至可以显示完整的Ubuntu堆栈,包括(如果有时间等的话)X和gnome。 内存完整的Linux安装需要兆字节或RAM和带有MMU的32位CPU。这个项目具有所有这些。首先让我们解决RAM。如您所见,板上有一个老式的30针SIMM内存模块。这些已用于基于80286的PC。它与ATmega接口,我编写了代码来访问它以及在规范内对其进行刷新(SDRAM需要不断刷新以避免丢失数据)。有多快?刷新中断每62ms发生一次,占用1.5ms,因此占用了不到3%的CPU。为了便于编程,一次访问一个字节访问RAM。这导致每秒大约300 KB的最大带宽。 存储随着对RAM要求的降低,我们有两个要处理。存储不是很难解决的问题。SD卡很容易与使用SPI对话,而我的项目做到了这一点。1GB SD卡可以正常工作,尽管512Mb对于该特定文件系统(Ubuntu Jaunty)而言已足够。ATmega确实有一个硬件SPI模块,但是由于某种原因,它并没有完全解决问题,因此我在接口上做一些改动。它仍然足够快-大约每秒200千字节。这也给项目增加了一个很好的感觉-可以在任何具有足够引脚的微控制器上完成-无需使用硬件模块。 中央处理器剩下的就是讨厌的32位CPU和MMU要求。那么,AVR没有MMU,而是8位的。为了克服这一障碍,我编写了一个ARM仿真器。ARM是我最熟悉的体系结构,它非常简单,可以轻松编写一个仿真器。为什么要写一个而不是移植一个?好吧,移植别人的代码是没有意思的,再加上我看到的所有仿真器都不是以易于移植到8位设备的方式编写的。原因之一:AVR编译器坚持将ints设置为16位,这样简单的事情如“(1 << 20)”会给您带来麻烦,并产生零。相反,您需要执行“(1UL << 20)”。不用说拖曳其他人的未知代码库,寻找所有假定为int且可能会失败的地方将是一场灾难。另外,我希望有机会编写一个不错的模块化ARM仿真器。所以我做了。 其它功能该板与现实世界的通信是通过串行端口进行的。目前,它连接到运行minicom的PC上的串行端口,但是可以替代地将键盘和字符LCD连接到板上,使其完全独立。板上也有两个LED。它们发出SD卡访问信号。一读,一写。板上也有一个按钮。按住一秒钟,它将在串行端口上吐出模拟CPU的当前有效速度。AVR的主频为24MHz(比其现有的20MHz略有超频) 速度有多快?uARM当然不是速度恶魔。引导到bash提示符(“ init = / bin / bash”内核命令行)大约需要2个小时。然后再花4个小时来启动整个Ubuntu(“ exec init”,然后登录)。启动X需要更长的时间。有效的仿真CPU速度约为6.5KHz,与您期望的在8位微控制器上仿真32位CPU和MMU相当。奇怪的是,系统一旦启动,就可以使用了。您可以输入命令并在一分钟内得到答复。也就是说,实际上您可以使用它。例如,我今天用它来格式化SD卡。这绝对不是最快的方法,但我认为它可能是_最便宜_,最慢_,_最容易组装的_,_最低的零件数量_和_最低端的 Linux PC。该板是用电线手工焊接的,甚至不需要印刷电路板。 有关仿真器的详细信息该仿真器是非常模块化的,可以随意扩展以仿真其他SoC和硬件配置。仿真的CPU是ARMv5TE。前一阵子,我开始支持ARMv6,但是由于不需要,它从未完成(如代码所示)。仿真的SoC是PXA255。由于设计的模块化,您可以替换SoC.c并使用相同的ARMv5TE内核制造一个全新的SoC,或者替换该内核,或者随意替换外围设备。这是有目的的,因为我的意思是该代码也可以作为ARM SoC工作原理的合理清晰演示。CPU模拟器本身的代码不太干净,因为它是一个CPU模拟器。它是几年前写的超过6个月的空闲时间,然后放在一边。最近专门针对该项目复活了它。仿真器实现了一个i-cache来加快处理速度。AVR上有很多功能,与我的外部RAM不同,AVR可以以每秒5兆字节的速度访问内部存储器。我从来没有实现过d-cache,但是它在待办事项列表中。对块设备的访问未模拟为SD设备。事实证明这太慢了。相反,我编写了一个半虚拟化的磁盘设备(pvdisk,请参阅pvDisk.tar.bz2,GPL许可证),该设备使用无效的操作码来调用仿真器并访问磁盘。我映像中的ramdisk加载了该pvdisk,然后将chroots加载到/ dev / pvd1。ramdisk作为“ rd.img”包含在内。我使用的“机器类型”是PalmTE2。为什么?因为我对硬件非常熟悉,所以它是我看到的第一个pxa255机器类型。 超级终端?您可以使用特殊的操作码向仿真器请求一些服务。在手臂上是0xF7BBBBBB,在拇指上是0xBBBB。选择它们是因为它们在ARM保证未定义的范围内。在R12中传递超级调用号,在R0..R3中传递参数,将返回值放置在R0中。来电: 0 =停止仿真 1 =打印十进制数 2 =打印字符 3 =获取滑枕尺寸 4 =块设备操作(R0 =操作R1 =扇区编号)。请注意,它们不写仿真RAM,而是填充仿真器内部缓冲区,仿真来宾使用另一个超级调用(每次一个字)访问该缓冲区。我本来打算实现DMA,但从未尝试过。操作: 0 = getInfo(如果扇区num为零,则返回num个扇区;如果扇区num为1,则返回以字节为单位的扇区大小) 1 =扇区读取 2 =扇区写入 5 =块设备缓冲区访问(R0 =值输入/值输出,R1 =字号,如果写则R2 = 1,否则为0) 支持Thumb?完全支持Thumb。不过,我作弊了一点,将每个thumb指令解码为等效的ARM指令,然后使用arm模拟器功能执行该指令。它没有其他方法快,但是它很简单并且代码很小。可以使用256KB的查询表,但是我觉得256KB对于微控制器的闪存来说太大了。有些thumb指令不能转换为ARM,而是可以正确处理。 自己建立出于非商业目的,您绝对可以这样做。接线如下。RAM DQ0..DQ7-> AVR C0..C7。RAM A0..A7-> AVR A0..A7。RAM A8..A11-> AVR B0..B3。RAM nRAS nCAS nWE-> AVR D7 B4 B5。SD DI SCK DO-> AVR B6 B7 D6。LED读写-> AVR D2 D3(LED的另一脚接地)。按钮-> AVR D4(另一条腿接地)。内存可以是任何30针16MB SIMM,并且可以每64ms进行4K周期的CAS-RAS刷新之前的CAS。我所用的(OWC)可以在线购买,价格为几美元。原理图如图所示。点击查看大图 源代码?有点混乱,但确实有效。趁热获取:LINK。许可证对于非商业用途,只要您将许可证文件与源保持在一起并发布所有更改,如果用于商业用途,请与我联系,我们会达成协议。要构建仿真器以在PC上进行尝试,请键入“ make” 使用“ ./uARM DISK_IMAGE”。要构建优化的PC版本, 使用“ make BUILD = opt”。为AVR构建, 使用“ make BUILD = avr”。它目前针对ATmega1284p。 要以ATmega644为目标,除了更改makefile之外,还要减少icache.h中的数字,以使icache足够小以适合644中的内部RAM。归档文件中还包括1284p的最终十六进制文件。 启动过程为了节省AVR中的代码空间,仿真器中几乎没有启动代码。实际上,“ ROM”总共有50个字节:8个字节可切换到拇指模式,还有一些拇指代码可读取SD卡的第一个扇区并以拇指模式跳至该扇区(请参见EmbeddedBoot.c)。SD卡的MBR具有另一个引导加载程序(以拇指模式编写)。这一节着眼于MBR,找到了活动分区并将其内容加载到RAM的末尾。然后,它跳转到目标ram地址+ 512(请参阅mbrBoot.c)。这里有第三大引导加载程序ELLE(请参阅ELLE.c)。这将重定位虚拟磁盘,设置ATAGS,然后调用内核。提供所有二进制文件和源文件,以便您可以随意制作自己的图像。引导过程应让人联想到PC引导。:)包含的mkbootimg。sh工具可用于制作启动分区的工作映像。完整的工作磁盘映像?链接。 via","link":"/2020/03/11/%E5%9C%A8avr%E5%8D%95%E7%89%87%E6%9C%BA%E4%B8%8A%E8%BF%90%E8%A1%8Clinux/"},{"title":"ESP8266+Blynk做一个根开机棒","text":"介绍这个应用程序是为启动服务器编写的,只支持启动一个设备。它需要在源码中配置WOL服务器以及配置服务器的静态IP。 Devices ESP8266 Arduino IDE(所需库文件ESP8266Ping,ESP8266 Plug-in,Blynk) Blynk Variable name Default value Comment auth Blynk_AuthToken Blynk Auth Token (You get after the project was created in Blynk) ssid WiFi_SSID Your WiFi network name pass WiFi_Password Your WiFi network password ip 192.168.0.123 Static IP for your WOL Server gateway 192.168.0.1 Your Gateway IP address bcastAddr 192.168.0.255 Your Broadcast IP address subnet 255.255.255.0 Your Subnet Mask IP address dns 1.1.1.1 IP address of your preferred DNS server device_ip 192.168.0.234 Static IP address of device to be turned on (used for ping) macAddr aa:bb:cc:dd:ee:ff Mac address of device to be turned on (important for the magic packet) email [email protected] Email address for notifications (when the device could not be turned on within the set time limit) device_name NAS The short name of your device that turns on boot_time 45 Maximum time to wait for the device to turn on (used for notification, read the known issues!) 需要更改的代码12345678910111213141516171819//WiFi configconst char auth\\[\\] = \"Blynk\\_AuthToken\"; //Blynk Auth Token (You get after the project was created in Blynk)const char ssid\\[\\] = \"WiFi\\_SSID\"; const char pass\\[\\] = \"WiFi\\_Password\";const IPAddress ip(192, 168, 0, 123); //Static IP for your WOL Serverconst IPAddress gateway(192, 168, 0, 1);const IPAddress bcastAddr(192, 168, 0, 255);const IPAddress subnet(255, 255, 255, 0);const IPAddress dns(1, 1, 1, 1); //IP address of your preferred DNS server//WOL device configconst IPAddress device\\_ip(192, 168, 0, 234); //Static IP address of device to be turned on (used for ping)byte macAddr\\[6\\] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}; //Mac address of device to be turned on (important for the magic packet)//Alert configconst char email\\[\\] = \"[email protected]\";const char device\\_name\\[\\] = \"NAS\";const uint16\\_t boot\\_time = 45;//number for countdown (It does not represent seconds, but it's close, read the known issues!) Code123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197//#define DEBUG#ifdef DEBUG#define BLYNK\\_PRINT Serial//#define BLYNK\\_DEBUG//#define ENABLE\\_DEBUG\\_PING#endif#define BLYNK\\_NO\\_BUILTIN//disable built-in analog and digital operations.//#define BLYNK\\_NO\\_INFO//disable providing info about device to the server. (saving time)#include <ESP8266WiFi.h>#include <BlynkSimpleEsp8266.h>#include <WiFiUdp.h>#include <ESP8266Ping.h> //blynk colors#define BLYNK\\_GREEN\"#23C48E\"#define BLYNK\\_BLUE\"#04C0F8\"#define BLYNK\\_YELLOW\"#ED9D00\"#define BLYNK\\_RED\"#D3435C\"#define BLYNK\\_DARK\\_BLUE\"#5F7CD8\"//WiFi configconst char auth\\[\\] = \"Blynk\\_AuthToken\";const char ssid\\[\\] = \"WiFi\\_SSID\";const char pass\\[\\] = \"WiFi\\_Password\";const IPAddress ip(192, 168, 0, 123);const IPAddress gateway(192, 168, 0, 1);const IPAddress bcastAddr(192, 168, 0, 255);const IPAddress subnet(255, 255, 255, 0);const IPAddress dns(1, 1, 1, 1);//WOL device configconst IPAddress device\\_ip(192, 168, 0, 234);byte macAddr\\[6\\] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};//Alert configconst char email\\[\\] = \"[email protected]\";const char device\\_name\\[\\] = \"NAS\";const uint16\\_t boot\\_time = 45;//number for countdown (It does not represent seconds, read the known issues!)//WOL#define MAGIC\\_PACKET\\_LENGTH 102#define PORT\\_WAKEONLAN 9byte magicPacket\\[MAGIC\\_PACKET\\_LENGTH\\];unsigned int localPort = 9;WiFiUDP udp;//pins#define STATE\\_PINV0#define BUTTON\\_PINV1#define PING\\_TIME\\_PINV2#define RSSI\\_PINV3//statestruct WOLServerState {bool IsOnline;uint16\\_t boot\\_time;bool boot\\_error;uint16\\_t ping;uint32\\_t previousMillis;uint32\\_t interval;};WOLServerState currentState = { false, 0, false, 0, 0, 5000UL };void setup() {#ifdef DEBUGSerial.begin(115200);#endifconnectWiFi();connectBlynk();//if (Blynk.connected()) {if (udp.begin(localPort) == 1) {BLYNK\\_LOG(\"udp begin OK\");buildMagicPacket();} else {delay(500);ESP.restart();}//}}void connectWiFi() {WiFi.mode(WIFI\\_STA);WiFi.hostname(\"WOL server\");WiFi.config(ip, dns, gateway, subnet);WiFi.begin(ssid, pass);int count = 0;while (WiFi.status() != WL\\_CONNECTED) {delay(250);digitalWrite(LED\\_BUILTIN, HIGH);delay(250);digitalWrite(LED\\_BUILTIN, LOW);count++;if (count > 20) {delay(500);ESP.restart();}}//BLYNK\\_LOG(\"WiFi connected, IP: %s\", WiFi.localIP().toString());}void connectBlynk() {Blynk.config(auth);Blynk.disconnect();int count = 0;while (Blynk.connect(10000) == false) {delay(250);digitalWrite(LED\\_BUILTIN, HIGH);delay(250);digitalWrite(LED\\_BUILTIN, LOW);count++;if (count > 20) {delay(500);ESP.restart();}}BLYNK\\_LOG(\"Blynk connected\");}void loop() {// Reconnect WiFiif (WiFi.status() != WL\\_CONNECTED) {connectWiFi();return;}// Reconnect to Blynk Cloudif (!Blynk.connected()) {connectBlynk();return;}uint32\\_t currentMillis = millis();if (currentMillis - currentState.previousMillis >= currentState.interval) {currentState.previousMillis = currentMillis;if (currentState.boot\\_time == 0) {currentState.interval = 5000UL;} else {currentState.boot\\_time--;if (currentState.boot\\_time == 0) {currentState.boot\\_error = true;Blynk.email(email, \"{DEVICE\\_NAME} : Alert\", String(device\\_name) + \" could not be turned on!\");}}if (Ping.ping(device\\_ip, 1)) {currentState.IsOnline = true;currentState.boot\\_error = false;currentState.boot\\_time = 0;currentState.ping = Ping.averageTime();} else {currentState.IsOnline = false;currentState.ping = 0;}}Blynk.run();}// Generate magic packetvoid buildMagicPacket() {memset(magicPacket, 0xFF, 6);for (int i = 0; i < 16; i++) { int ofs = i \\* sizeof(macAddr) + 6; memcpy(&magicPacket\\[ofs\\], macAddr, sizeof(macAddr)); } } //BLYNK\\_CONNECTED() { // Blynk.syncVirtual(BUTTON\\_PIN); //} // BOOT PC button handler of application BLYNK\\_WRITE(BUTTON\\_PIN) { if (!currentState.IsOnline && currentState.boot\\_time == 0) { BLYNK\\_LOG(\"AppButtonWakeOnLan: value=%d\", param.asInt()); udp.beginPacket(bcastAddr, PORT\\_WAKEONLAN); udp.write(magicPacket, MAGIC\\_PACKET\\_LENGTH); udp.endPacket(); currentState.boot\\_time = boot\\_time; currentState.interval = 1000UL; } } BLYNK\\_READ(STATE\\_PIN) { Blynk.virtualWrite(RSSI\\_PIN, WiFi.RSSI()); Blynk.virtualWrite(PING\\_TIME\\_PIN, currentState.ping); if (currentState.IsOnline) { Blynk.setProperty(STATE\\_PIN, \"color\", BLYNK\\_GREEN); Blynk.virtualWrite(STATE\\_PIN, String(device\\_name) + \" is Online\"); Blynk.setProperty(BUTTON\\_PIN, \"color\", BLYNK\\_DARK\\_BLUE); Blynk.setProperty(BUTTON\\_PIN, \"offLabel\", String(device\\_name) + \" running...\"); Blynk.setProperty(BUTTON\\_PIN, \"onLabel\", String(device\\_name) + \" running...\"); } else if (!currentState.IsOnline && currentState.boot\\_time > 0) {Blynk.setProperty(STATE\\_PIN, \"color\", BLYNK\\_BLUE);Blynk.virtualWrite(STATE\\_PIN, \"Waiting for ping...\");Blynk.setProperty(BUTTON\\_PIN, \"color\", BLYNK\\_YELLOW);Blynk.setProperty(BUTTON\\_PIN, \"offLabel\", currentState.boot\\_time);Blynk.setProperty(BUTTON\\_PIN, \"onLabel\", \"Waiting for ping...\");} else if (!currentState.IsOnline && currentState.boot\\_time == 0 && currentState.boot\\_error) {Blynk.setProperty(STATE\\_PIN, \"color\", BLYNK\\_RED);Blynk.virtualWrite(STATE\\_PIN, \"Oops! Something happened, Try It Again!\");Blynk.setProperty(BUTTON\\_PIN, \"color\", BLYNK\\_YELLOW);Blynk.setProperty(BUTTON\\_PIN, \"offLabel\", \"Try It Again\");Blynk.setProperty(BUTTON\\_PIN, \"onLabel\", \"Magic Packet has been sent\");} else {Blynk.setProperty(STATE\\_PIN, \"color\", BLYNK\\_RED);Blynk.virtualWrite(STATE\\_PIN, String(device\\_name) + \" is Offline\");Blynk.setProperty(BUTTON\\_PIN, \"color\", BLYNK\\_BLUE);Blynk.setProperty(BUTTON\\_PIN, \"offLabel\", \"Turn On\");Blynk.setProperty(BUTTON\\_PIN, \"onLabel\", \"Magic Packet has been sent\");}} Blynk via","link":"/2020/01/24/esp8266blynk%E5%81%9A%E4%B8%80%E4%B8%AA%E6%A0%B9%E5%BC%80%E6%9C%BA%E6%A3%92/"},{"title":"行摄北疆","text":"var player = new DogePlayer({ container: document.getElementById('player_a2cbd5de91db84e1'), userId: 1131, vcode: 'a2cbd5de91db84e1', autoPlay: false }); 2019.8.17飞机承载着我对遥远北疆的热忱,在滑行道上缓缓升腾,在气流的颠簸里,我知道我此时已在离北疆越来越近的路途上了,那是个令人心驰神往的名词——北疆。 从平原到戈壁,从绿洲到雪山。造物主的鬼斧神工恍若中国水墨的手笔一般,那奇妙的白茫茫的雾爬进了我们的视野,模糊了云层的日光,并把那高空底下的层峦叠嶂幻化成了迷一般的幢幢怪影。 终于来到了向往已久的天山北麓,大自然用五彩斑斓的画笔给黄土高坡添置了别样的色彩,新疆——触手可及。 雪山,雪岭无限延伸;雪峰,肃立威严。北国的冬雪尚未化尽,一座座山峦此起彼伏、银装素裹、延绵千里,那盘踞的身形恍若九天银河洒落人间阅尽千帆。那山脚下干的树枝虬劲疏落,在蓝天夏日的背景下仿佛国画,偏爱空白,也颇留意趣。有时有一群飞鸟循声觅食,在夕阳里,徒留几声凄清的脆鸣,袅袅于空谷山间。 2019.8.18行驶在独库公路上才能感到真正的孤独,裸露的岩壁,空无一人的公路,满是落石的路基。在这里,每一块岩石都在诉说这不同的故事。雪山半掩琵琶半遮面似得躲在云层后面,不由得增加了几分神秘感。 在这条一天可以体验四季的路上,每一个峰回路转都有别样的一番景致,正如移步换景一般,上一帧还是深不见底大峡谷,下一帧就变成了沟壑纵横的雪山。从针叶林到高山草甸再到雪线……甚是迷人。翻越雪山,一扫之前裸露的岩石滩,取而代之的是那郁郁葱葱的高山草甸,那是天公的神来之笔,满眼的苍翠从眼前开始延伸,直至渺远的他方,我想它可能是上苍对人世浮沉的些微怜悯。而那悠然的牛羊带着那偶尔露怯的眼神,惊慌地穿过公路,晃悠悠朝着远处走去,印着薄日的光,留下几个淡淡背影……极目远眺,那是修建独库公路的人在这片荒凉的土地挥着汗洒下泪,而我此时正踏在祖国的这方土地之上,闻着这方泥土淳朴的芬芳,我想那当是工人们灵魂的芬芳。 2019.8.19再次飞驰在独库公路上,太阳渐渐地从云层后露了出来,晨曦撒在远处巍峨的雪山上,犹如戴上了金顶。远山层峦叠起,草地色泽丰富,湖泊清如明镜,牛羊马儿悠闲自得。 平直的公路,向前飞驰的轿车,耳边呼呼的风声,再一次把我们带入雪山,驶向南疆,太阳又羞答答地躲在了云层之后。延绵的山路像绸带一般缠绕在延绵的雪上。 海拔一点点上升,车外气温一点点下降,我们距离雪线的距离也越来越近。越过雪线,翻过那重峦叠嶂,气势滂沱的天山山脉,又是延绵不断的下坡路,但是景致与北疆截然不同:这些“远看成岭侧成峰,远近高低各不同”的红色岩壁,静静的屹立在广袤的戈壁滩上,那是一种岑峦迭起的壮丽,是一种傲风凌雪的气度,更是一种气定山河的坦荡。库车大峡谷集雄、静、险、幽、神为一体,无不赞美叫绝。两侧红色峡谷陡峭险峻,谷内蜿蜒曲折、幽静深邃。 再折回,天气如同孩子似得,豆大的雨点从天上打下来。再向前,翻回之前的雪山。随着海拔的再次上升,豆大的雨点变成了鹅毛一般的大雪。穿出隧道,雪花如同幕布一样飘落。在这里我终于体验到了千里冰封万里雪飘的北国风光。 2019.8.20那拉提在准噶尔蒙古语中意为“最先见到太阳的地方” 挺拔的胡杨,环绕的山峦,哈萨克牧民的毡房,成群的牛羊,无不被它的美丽所震撼。 向前远眺,一望无际的草原,牛羊成群,骏马飞腾,哈萨克牧民那纯白的毡房点缀其间;路边各色的野花,风吹过沙沙作响,及腰的野草…… “天苍苍,野茫茫,风吹草低见牛羊”好像就是为那拉提所写。 2019.8.21雪白的云朵装着天空那无边的喜悦,如同棉花糖一般轻飘飘地浮游飘动着,恍若触手可及,在明净的天边演绎着斑斓的人生,千姿百态。 八卦城,相对称的结构,如同八卦一般放射状圆形的布局,街道如神奇迷宫般,街街相通,路路相连,极具有神秘色彩。相传乌孙王建城时,以太极坛为中心,八匹马朝着八个方向规划,形成一个八卦形态。 2019.8.22夏塔清丽开阔的雪山下,留有着小溪飞扬的身姿,潺潺的流水声在讲述着乌孙古道当年的辉煌。在峡谷中穿行,云卷云舒,光影似武,天山山脉木扎特峰在蓝天下呈现,雪山一面,不枉此行。雪山仿佛近在咫尺,又远在天边。抬头,漆黑的幕布上,偶尔璀璨的星辰在倾诉北疆之夜的寂寥。它闪屏一般地规律眨眼,像极了梵高笔下一帧又一帧变化流淌的罗纳河上的星夜,偌大的夜晚只有漫天的星辰懂得它的黑。而今,这样一望无际的夜空里,我猜测大概是藏着上帝对漫漫人世羞赧的怜悯与深沉的爱,让它在深刻的色调里走向永恒,正印证了那句话:每个人的心里都有一团火,路过的人只看到烟。 2019.8.23八月末的赛里木湖送走了酷暑难耐的夏天,迎来了凉风习习的秋天。寒风起草地黄,应了这句话,这正是一个青黄不接的的季节,白天的日照依旧如往常强烈,而下车时身上携带的热量,经不住湖畔的大风之来势,三两下的吹拂便随之消弭殆尽,只剩下了丝丝凉意不住地往袖口里钻。八月末的赛里木湖周边的景致也略显单薄。高原地区,气候出乎意料的多变,正如“东边日出西边雨”,穿越云雨区,阳光依旧。 夕阳慢慢移到了山的后方,光影随时间一分一秒地更迭,暗蓝的天空和旖旎的晚霞流光溢彩,这是夕阳跌落于地平线前给予世人最后的馈赠。","link":"/2019/08/18/%E6%96%B0%E7%96%86/"},{"title":"树莓派+SSD1306屏幕","text":"启用树莓派的I2C功能123sudo apt-get install -y python-smbussudo apt-get install -y i2c-toolssudo raspi-config 1Interfacing Options-->I2C-->enable 安装库文件1sudo python -m pip install --upgrade pip setuptools wheel PIL 库 1sudo apt-get install python-pil python3-pil Adafruit-SSD1306 库 1git clone https://github.com/adafruit/Adafruit\\_Python\\_SSD1306.git 连接屏幕 屏幕 GND 接树莓派 GND 屏幕 VCC 接树莓派 3V3 屏幕 SDA 接树莓派 SDA 屏幕 SCL 接树莓派 SCL 检测是否识别到 I2C 设备1sudo i2cdetect -y 1 运行在之前克隆的代码中包含了可以直接运行的示例源码 1sudo nano ~/Adafruit\\_Python\\_SSD1306/examples/stats.py 修改屏幕类型 12345678# 128x32 display with hardware I2C:# disp = Adafruit\\_SSD1306.SSD1306\\_128\\_32(rst=RST) # 128x64 display with hardware I2C:disp = Adafruit\\_SSD1306.SSD1306\\_128\\_64(rst=RST) # Note you can change the I2C address by passing an i2c\\_address parameter like:# disp = Adafruit\\_SSD1306.SSD1306\\_128\\_64(rst=RST, i2c\\_address=0x3C) 运行 1sudo python ~/Adafruit\\_Python\\_SSD1306/examples/stats.py 1sudo python ~/Adafruit\\_Python\\_SSD1306/examples/image.py","link":"/2019/08/07/%E6%A0%91%E8%8E%93%E6%B4%BEssd1306%E5%B1%8F%E5%B9%95/"},{"title":"树莓派lot=Node.js+Bylnk+DHT11/DHT22","text":"安装npm及Bylnk库 12345sudo apt install npm -ysudo apt-get install build-essentialsudo npm install -g npmsudo npm install -g onoffsudo npm install -g blynk-library 安装传感器库 bcm2835库 node-dht-sensor npm包 12345678wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.46.tar.gztar zxvf bcm2835-1.46.tar.gzcd bcm2835-1.46./configuremakesudo make checksudo make installsudo npm install -g node-dht-sensor 连接传感器 GND至GND DAT信号到GPIO7 VCC至3.3v 创建可执行文件12cd ~git clone https://github.com/wanghurui/Blynk-dht11-22.git 或者 123456789101112131415161718192021222324252627var blynkLib = require('blynk-library');var sensorLib = require('node-dht-sensor');var AUTH = 'YOUR\\_AUTH\\_TOKEN';// Setup Blynkvar blynk = new blynkLib.Blynk(AUTH);// Setup sensor, exit if failedvar sensorType = 11; // 11 for DHT11, 22 for DHT22 and AM2302var sensorPin = 4; // The GPIO pin number for sensor signalif (!sensorLib.initialize(sensorType, sensorPin)) { console.warn('Failed to initialize sensor'); process.exit(1);}// Automatically update sensor value every 2 secondssetInterval(function() { var readout = sensorLib.read(); blynk.virtualWrite(3, readout.temperature.toFixed(1)); blynk.virtualWrite(4, readout.humidity.toFixed(1)); console.log('Temperature:', readout.temperature.toFixed(1) + 'C'); console.log('Humidity: ', readout.humidity.toFixed(1) + '%');}, 2000);将**YOUR\\_AUTH\\_TOKEN**替换为App中的令牌。 1sudo NODE\\_PATH =/usr/local/lib/node\\_modules node ./blynk-sensor-test.js 输出应如下所示 1234567OnOff modeConnecting to TCP: cloud.blynk.cc 8442ConnectedTemperature: 18.0CHumidity: 26.0%Temperature: 18.0CHumidity: 26.0% 可以使用pm2将此程序放在后台守护进程并且开机自启动 1234npm install -g pm2sudo NODE\\_PATH=/usr/local/lib/node\\_modules pm2 start ./blynk-sensor-test.jssudo pm2 savesudo pm2 startup ","link":"/2019/07/30/%E6%A0%91%E8%8E%93%E6%B4%BEnode-jsbylnk-appdht11-dht22-am2302/"},{"title":"2019.7.19","text":"何谓友情?何谓缘分? 是离别时远隔重洋却心照不宣的默契,是多年来老旧相片里昔日光景的纪念,是与你聊的同一话题时一起旁若无人的开怀大笑,是茫茫人海行色匆匆里曾经彼此熟悉的身影…… 青春的颜色,是真情的颜色;相聚总是太少,真情总被无情错过。 希望多年以后,你仍然能在别人面前自豪的说出:“我是你的朋友”。 2019.7.20 Whr","link":"/2019/07/20/2019-7-19/"},{"title":"2019.6.29 大嵛山岛笔记","text":"大嵛山岛—-是闽东最大的列岛,是一个坐落在福鼎东南海域,距离三沙古镇港5海里,他由大嵛山、小嵛山、鸳鸯岛、银屿等十一个大小岛屿组成,大嵛山岛曾被中国国家地理”杂志社评为“中国最美的地方”中“最美的海岛”第八名。其山、湖、草、海在此浓缩。天湖四周山坡平缓,是有“南国天山”之誉的万亩草场。 嵛山岛地理位置特殊,扼闽浙海路之咽喉,是南来北往船只的必经之道,战略意义重大。明朝时期为抵御倭寇骚扰,1389年明政府在嵛山岛设置军事要塞,归北路福宁卫烽火寨管辖,1592年改守备为参将、节制水陆,改中军为嵛山游。清代中叶,嵛山列岛是蔡牵海上起义活动的重要根据地。辛亥革命先驱朱腾芬先生也在此组织义军抗清。 山势回环,路随山转,岛上的旅游巴士在这蜿蜒曲折的山路上飞驰着。随着海拔的增高,视线内的景物也随之变化,从灌木丛变成了高山草甸,从涓涓的小溪变成了气势滂沱的瀑布。旅游巴士一路颠簸,我们眼中摇摇晃晃的崎岖山路里承载的尽是一行人无尽的好奇与向往,我们驻足停留来到了山腰。 刚涉足这片陌生的土地,无比沉闷的湿气里一股沁人心脾草籽的清香扑面而来 我们沿着盘山步道一点一点向大嵛山山顶登去。我们行走在山脊上,缭绕的雾气被山顶的强风吹散,呼吸着雾气特有的味道,藏在雾霭中的两个天池逐渐拭去混沌,越发清冽。 天池周围群峰环拱,其状似盂,这可能就是嵛山岛名字的来源吧。在这里恍若置身于“天苍苍,野茫茫,风吹草低见牛羊”的大西北草原。如果不是我们来这里旅行,难以想象在碧波万顷的东海之上竟有如此风云奇诡的意境。 我极目远眺,它拼命掩面,半伏半隐,挣扎着躲进袅袅的雾霭中去。潮湿的季风将山间的云雾升腾出如海市蜃楼的形状;蓝天上,是上帝的一半明媚一半忧伤。山峦间,是悠悠的水,袅袅的烟,静静的谱写着属于大嵛山的歌…… 2019.6.29","link":"/2019/06/30/2019-6-29-%E5%A4%A7%E5%B5%9B%E5%B1%B1%E5%B2%9B%E7%AC%94%E8%AE%B0/"},{"title":"用WP-CLI给WordPress更换域名","text":"wp-cli 是一个命令行工具,可以让我们通过命令行安装、更新 WordPress,对 WordPress 执行一些批量操作,响应速度快,使用方便 安装 wp-cli 工具curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.pharchmod +x wp-cli.pharsudo mv wp-cli.phar /usr/local/bin/wp 搜索替换 WordPress 数据库中的域名wp-cli 工具为我们提供了一个搜索替换数据库中字符的命令,直接在 WordPress 的根目录执行以下命令即可完成更换 WordPress 域名的操作,该命令支持一些选项方便我们自定义操作,具体查看 wp search-replace 命令的官方说明。 wp search-replace ‘old.com’ ‘new.com’","link":"/2019/03/02/%E7%94%A8wp-cli%E7%BB%99wordpress%E6%9B%B4%E6%8D%A2%E5%9F%9F%E5%90%8D/"},{"title":"小米路由器mini/mini青春版 刷入Openwrt固件","text":"刷开发版 打开ssh 刷入breed 刷入固件 0.1小米路由器刷入开发版小米路由器mini在MiWiFi官网www.miwifi.com,下载 ROM Mini的开发版,下载完毕后放入fat32格式U盘下的根目录,并将包名改为miwifi.bin 断开路由器的电源,将U盘插入路由器的USB接口,用细长的工具按住reset后,接通电源,待路由器指示灯变为黄灯闪烁时,松开reset。 大约3-5分钟后,指示灯变成黄色常亮状态时可以拔掉U盘,此时刷机已经完成正在重启,稍等片刻路由器指示灯变蓝就可以正常使用了。 小米路由器mini青春版由于青春版没有usb的缺陷,只能使用后台的手动上传固件的方式进行刷入开发版 链接: https://pan.baidu.com/s/1rG3qNVrbPKnj0G3orQU5Mg 提取码: i422 下载旧版本的青春版开发版,在后台“常用设置” –>“系统状态”–>“手动上传更新包”完成刷机 0.2开启路由器ssh将小米路由器插上电源,这里不要让小米路由器联网(不需要小米路由器的Internet口连接另一台路由器的LAN口),连接小米路由器WiFi,打开后台页面192.168.31.1,配置小米路由器工作模式为“普通路由器工作模式”应该是默认,并且配置WiFi密码以及后台登录密码。 登录后台,在登录后可以在首页上看到小米路由器的sn,通过sn查询路由器ssh登录密码。 用一台可以联网的设备打开http://www.iptvfans.cn/miwifi/passwd复制sn到查询框中即可获取登录密码 打开终端: windows下推荐使用putty,在IP处填入小米路由器的ip,也就是192.168.31.1其他不动。然后会弹出一个关于密匙的窗口,点击yes即可。log as后填写root password是之前查询的密码。 Mac OS下的终端可以参考这个https://jingyan.baidu.com/article/f3e34a1289cda3f5eb6535c0.html在终端中输入 ssh [email protected] 并按下回车后同windows 1.0全盘备份插入U盘并新建文件夹(青春版请跳过) 12cd /extdisks/sda1mkdir xiaomi\\_rom\\_backup 备份 1cat /proc/mtd 1234567891011dd if=/dev/mtd0 of=/extdisks/sda1/xiaomi\\_rom\\_backup/all.bindd if=/dev/mtd1 of=/extdisks/sda1/xiaomi\\_rom\\_backup/bootloader.bindd if=/dev/mtd2 of=/extdisks/sda1/xiaomi\\_rom\\_backup/config.bindd if=/dev/mtd3 of=/extdisks/sda1/xiaomi\\_rom\\_backup/factory.bindd if=/dev/mtd4 of=/extdisks/sda1/xiaomi\\_rom\\_backup/os1.bindd if=/dev/mtd5 of=/extdisks/sda1/xiaomi\\_rom\\_backup/rootfs.bindd if=/dev/mtd6 of=/extdisks/sda1/xiaomi\\_rom\\_backup/os2.bindd if=/dev/mtd7 of=/extdisks/sda1/xiaomi\\_rom\\_backup/overlay.bindd if=/dev/mtd8 of=/extdisks/sda1/xiaomi\\_rom\\_backup/crash.bindd if=/dev/mtd9 of=/extdisks/sda1/xiaomi\\_rom\\_backup/reserved.bindd if=/dev/mtd10 of=/extdisks/sda1/xiaomi\\_rom\\_backup/bdata.bin 如果是青春版的话请执行 1234567891011dd if=/dev/mtd0 of=/tmp/all.bindd if=/dev/mtd1 of=/tmp/bootloader.bindd if=/dev/mtd2 of=/tmp/config.bindd if=/dev/mtd3 of=/tmp/factory.bindd if=/dev/mtd4 of=/tmp/os1.bindd if=/dev/mtd5 of=/tmp/rootfs.bindd if=/dev/mtd6 of=/tmp/os2.bindd if=/dev/mtd7 of=/tmp/overlay.bindd if=/dev/mtd8 of=/tmp/crash.bindd if=/dev/mtd9 of=/tmp/reserved.bindd if=/dev/mtd10 of=/tmp/bdata.bin 备份完成后请及时使用winscp把备份文件拷出,避免刷breed时内存不足导致路由器变砖。 输出应该是这样的 123456789101112131415161718192021222324252627282930313233root@XiaoQiang:~# dd if=/dev/mtd0 of=/extdisks/sda1/xiaomi\\_rom\\_backup/all.bin32768+0 records in32768+0 records outroot@XiaoQiang:~# dd if=/dev/mtd1 of=/extdisks/sda1/xiaomi\\_rom\\_backup/bootloader.bin384+0 records in384+0 records outroot@XiaoQiang:~# dd if=/dev/mtd2 of=/extdisks/sda1/xiaomi\\_rom\\_backup/config.bin128+0 records in128+0 records outroot@XiaoQiang:~# dd if=/dev/mtd3 of=/extdisks/sda1/xiaomi\\_rom\\_backup/factory.bin128+0 records in128+0 records outroot@XiaoQiang:~# dd if=/dev/mtd4 of=/extdisks/sda1/xiaomi\\_rom\\_backup/os1.bin25600+0 records in25600+0 records outroot@XiaoQiang:~# dd if=/dev/mtd5 of=/extdisks/sda1/xiaomi\\_rom\\_backup/rootfs.bin22716+1 records in22716+1 records outroot@XiaoQiang:~# dd if=/dev/mtd6 of=/extdisks/sda1/xiaomi\\_rom\\_backup/os2.bin4096+0 records in4096+0 records outroot@XiaoQiang:~# dd if=/dev/mtd7 of=/extdisks/sda1/xiaomi\\_rom\\_backup/overlay.bin2048+0 records in2048+0 records outroot@XiaoQiang:~# dd if=/dev/mtd8 of=/extdisks/sda1/xiaomi\\_rom\\_backup/crash.bin128+0 records in128+0 records outroot@XiaoQiang:~# dd if=/dev/mtd9 of=/extdisks/sda1/xiaomi\\_rom\\_backup/reserved.bin128+0 records in128+0 records outroot@XiaoQiang:~# dd if=/dev/mtd10 of=/extdisks/sda1/xiaomi\\_rom\\_backup/bdata.bin128+0 records in128+0 records out 1.1刷入Bootloader1cd /tmp 在电脑上下载好小米路由器mini专用的breedhttps://breed.hackpascal.net/breed-mt7620-xiaomi-mini.bin使用scp工具拷入路由器的/tmp目录中 青春版请使用https://breed.hackpascal.net/breed-mt7688-reset38.bin windows下使用winscp MacOS/unix/linux使用shell里的scp命令 密码还是之前sn查询的密码 Linux/Unix下详细命令 123cd /tmpwget https://breed.hackpascal.net/breed-mt7620-xiaomi-mini.binscp ./breed-mt7620-xiaomi-mini.bin [email protected]:/tmp 刷入Bootloader 1mtd -r write /tmp/breed-mt7620-xiaomi-mini.bin Bootloader 1.2刷入固件mini下载固件https://1jjklacnz-my.sharepoint.com/personal/alog_1_jjkl_ac_nz/_layouts/15/download.aspx?share=ETxwSwq7ms9JoISMXlZpPB8BtTJ8lBaX270VraNKh3ZBTA&ithint=.bin 青春版下载固件https://drive.google.com/file/d/1b-PJ9C1JQWO0\\_gmVWNgFckuEbS43eM97/view?usp=sharing 断电关闭路由器 更改电脑适配器设置,并设置IPv4:IP是192.168.1.2,子网掩码:255.255.255.0,默认网关:192.168.1.1 捅路由器上的reset键开机,过一会浏览器打开192.168.1.1,上传你下载的固件。 刷入方法可以借鉴一下我的TPlink842硬改篇 等待刷完之后手动重启路由器即可。","link":"/2019/02/19/%E5%B0%8F%E7%B1%B3%E8%B7%AF%E7%94%B1%E5%99%A8mini%E5%88%B7%E5%85%A5lean-r9-1-1%E5%9B%BA%E4%BB%B6/"},{"title":"TP link 842 v4.4硬改手记","text":"TPlink家族的路由器都有一个很大的问题,新路由器买回来十分好用,在用了几年之后各种卡网,各种宕机……早在一年前就萌生了硬改的想法,只是一直忙于学业😌😌😌 趁着刚考完试的闲暇时间,买来了flash,ddr和编程器。买的时候犯了一个大错误-_-,买flash没有查手册,看着w25q32v以为是32m的flash就下单了,在快递回来的几天左思右想找不到32m的固件,还去论坛询问,后来查手册才发现是4m的flash,可玩性大大降低了。(︶^︶) 0x01某宝上购买了两块winbond的W25Q32V的flash和HY64的DDR内存,还有一个CH341A的编程器。开始吐槽编程器,有一个晶振竟然是虚焊的,差评…… 0x02开始烧固件,系统是windows7 x64,没有出现不兼容的情况。刷入大H的breed,并在0001fc00写入在路由器背面的MAC地址,不然连网络都没有。店家给的转接板也不能用,无奈用手把flash摁在编程器上4分钟,刷了两次才成功,第一次手抖了一下卡在了83%,回想起论坛上各种spi flash坏道导致的问题,一阵阵冷汗不由自主地冒了出来。 还好没有什么大碍,又读了出来,摁的4分钟刷刷网页很快就过去了,手摁得有点僵,再一次差评…. 0x03把这个66脚的ddr焊到主板上去,我承认我是在外面找人焊的,这个对我来说太困难了,哪怕焊上去也是灯全部亮,系统没有反应,更可能的是焊盘掉了两三个,路由器废了。 后果.jpg 0x04在电脑段设置静态ip,ip地址为192.168.1.1,掩码为255.255.255.0,网关为192.168.1.1 在路由器上电开机前,捅住restart,接上电源,当看到LED灯全部亮起后闪了一下松开,打开浏览器访问192.168.1.1,不出意外的情况下就是之前刷好的breed了 在固件中心刷入openwrt固件和art无线修正固件,刷入速度极快。openwrt固件用了恩山AndyX大神的4m精简固件OpenWrt/LEDE 4M精简迷你固件-Luci界面-SFE加速-SQM分配-UPNP-IPv6-VLAN支持-WIFI计划 art无线修正的文件我上传到了git上https://github.com/wanghurui/Router-art-firmware SFE效果如下图,本地网速几乎增加了1m/s 0x05激动人心的时刻,刷完后的自动重启,在等了大概30s后跳出了下面这个页面 下图为Luci界面 在刷了机之后,无线性能只能用时间去测量它,掉线的情况应该少了,在家里的Xiaomi TV上测出来的峰值网速可以有5m/s,对于30m的有线通宽带已经心满意足了。 由于内存只有4m,而且刷完了之后只有150+k可以使用,一开始想在路由器上实现smartdns和koolproxy的都因为内存不足而放弃。不过我觉得在/tmp目录安装opkg和软件很ok😹😹😹 0x06 Bugs貌似Andy X的固件crontab有问题:我正确配置了crontab设置了每天6点自动重启,可是没有一次成功😐 Wed May 29 06:00:43 2019 daemon.info hostapd: wlan0: STA 68:db:ca:23:1f:71 WPA: group key handshake completed (RSN)Wed May 29 06:00:43 2019 daemon.info hostapd: wlan0: STA b0:65:bd:68:1a:9c WPA: group key handshake completed (RSN)","link":"/2019/01/21/tp-link-842-v4-4%E7%A1%AC%E6%94%B9%E6%89%8B%E8%AE%B0/"},{"title":"Monlor tools 2.0","text":"工具箱2.0已经比较完善了, 出于学习的目的, 想重新写新的工具箱, 尝试支持更多的固件. 现有工具箱处于维护状态, 有严重bug可能会更新解决一下. 如果Koolshare大佬们写的软件中心2.0有希望能移植到小米路由器, 也可以考虑移植而不开发新的工具箱. 工具箱正处于测试状态,安装需要有一定的动手能力。 支持以下的路由器,arm路由: R1D R2D R3D,mips路由: R3 R3P R3G R1CM 目前支持了以下几种插件: ZeroTier KoolProxy Aria2 VsFtpd kms Frpc Ngrok WebShell TinyProxy Entware KodExplorer EasyExplorer HttpFile VerySync FastDick FireWall JetBrains QianDao FileBrowser 安装方式插件的安装 离线安装插件,appmanage.sh add /tmp/kms.tar.gz安装插件 在线安装插件,默认下载源coding.net,安装命令appmanage.sh add kms monlor命令一键安装插件[推荐] 一键安装命令curl -kfsSl https://coding.net/u/monlor/p/Monlor-Tools/git/raw/master/install.sh 工具箱命令 卸载:uninstall.sh (不推荐) 更新:update.sh [-f] (不推荐) 初始化:init.sh 插件管理:appmanage.sh addupgradedel appname [-f] 工具箱配置:monlor (任意界面Ctrl + c可以退出配置) 在线更新:sh -c \"$(curl -kfsSl $(uci get monlor.tools.url)/scripts/update.sh)\" 在线卸载:sh -c \"$(curl -kfsSl $(uci get monlor.tools.url)/scripts/uninstall.sh)\" 目录结构1/ 注意事项 如果插件和工具箱都有更新,请务必先更新工具箱! 工具箱没有web界面,完全靠Shell开发,插件的安装、卸载、配置由配置文件完成。 安装完成后执行monlor命令配置工具箱,Ctrl + c或者输入exit可以退出。 关于迅雷快鸟FastDick,请按Xunlei-Fastdick这里的教程运行swjsq.py并找到运行成功后生成的swjsq_wget.sh文件,提取里面的uid,pwd,peerid即可。 插件列表显示异常运行rm -rf $(uci get monlor.tools.path)/config/applist.txt,运行monlor会自动获取插件列表 提问前请指出你的路由器型号,工具箱版本。如果是插件问题运行cat /var/log/appname*命令提交日志给我(appname为插件名,部分插件没有日志) Monlor tools已经不再更新,最新工具箱请移步到http://blog.whrblog.online/archives/1093","link":"/2018/11/09/1017/"},{"title":"SmartDNS","text":"SmartDNS是一个运行在本地的DNS服务器,SmartDNS接受本地客户端的DNS查询请求,从多个上游DNS服务器获取DNS查询结果,并将访问速度最快的结果返回个客户端,避免DNS污染,提高网络访问速度。 同时支持指定特定域名IP地址,并高性匹配,达到过滤广告的效果。 与dnsmasq的all-servers不同,smartdns返回的是访问速度最快的解析结果。 支持树莓派,openwrt,华硕路由器等设备。 软件效果展示阿里DNS 使用阿里DNS查询百度IP,并检测结果。 123456789101112131415161718192021222324252627pi@raspberrypi:~/code/smartdns_build $ nslookup www.baidu.com 223.5.5.5Server: 223.5.5.5Address: 223.5.5.5#53Non-authoritative answer:www.baidu.com canonical name = www.a.shifen.com.Name: www.a.shifen.comAddress: 180.97.33.108Name: www.a.shifen.comAddress: 180.97.33.107pi@raspberrypi:~/code/smartdns_build $ ping 180.97.33.107 -c 2PING 180.97.33.107 (180.97.33.107) 56(84) bytes of data.64 bytes from 180.97.33.107: icmp_seq=1 ttl=55 time=24.3 ms64 bytes from 180.97.33.107: icmp_seq=2 ttl=55 time=24.2 ms--- 180.97.33.107 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 24.275/24.327/24.380/0.164 mspi@raspberrypi:~/code/smartdns_build $ ping 180.97.33.108 -c 2PING 180.97.33.108 (180.97.33.108) 56(84) bytes of data.64 bytes from 180.97.33.108: icmp_seq=1 ttl=55 time=31.1 ms64 bytes from 180.97.33.108: icmp_seq=2 ttl=55 time=31.0 ms--- 180.97.33.108 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 31.014/31.094/31.175/0.193 ms smartdns 使用SmartDNS查询百度IP,并检测结果。 123456789101112131415161718pi@raspberrypi:~/code/smartdns_build $ nslookup www.baidu.comServer: 192.168.1.1Address: 192.168.1.1#53Non-authoritative answer:www.baidu.com canonical name = www.a.shifen.com.Name: www.a.shifen.comAddress: 14.215.177.39pi@raspberrypi:~/code/smartdns_build $ ping 14.215.177.39 -c 2PING 14.215.177.39 (14.215.177.39) 56(84) bytes of data.64 bytes from 14.215.177.39: icmp_seq=1 ttl=56 time=6.31 ms64 bytes from 14.215.177.39: icmp_seq=2 ttl=56 time=5.95 ms--- 14.215.177.39 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 5.954/6.133/6.313/0.195 ms 从对比看出,smartdns找到访问www.baidu.com最快的IP地址,这样访问百度比阿里DNS速度快5倍。 特性 多DNS上游服务器 支持配置多个上游DNS服务器,并同时进行查询,即使其中有DNS服务器异常,也不会影响查询。 返回最快IP地址 支持从域名所属IP地址列表中查找到访问速度最快的IP地址,并返回给客户端,避免DNS污染,提高网络访问速度。 支持非标准端口 支持非53端口查询,支持TCP查询,有效避免DNS污染。 特定域名IP地址指定 支持指定域名的IP地址,达到广告过滤效果,避免恶意网站的效果。 域名高性能后缀匹配 支持域名后缀匹配模式,简化过滤配置,过滤20万条记录时间<1ms Linux多平台支持 支持标准Linux系统(树莓派),openwrt系统各种固件,华硕路由器原生固件。 支持IPV4, IPV6双栈 支持IPV4,IPV6网络,支持查询A, AAAA记录。 高性能,占用资源少 多线程异步IO模式,cache缓存查询结果。 架构 SmartDNS接收本地网络设备的DNS查询请求,如PC,手机的查询请求。 SmartDNS将查询请求发送到多个上游DNS服务器,可采用标准UDP查询,非标准端口UDP查询,及TCP查询。 上游DNS服务器返回域名对应的Server IP地址列表。SmartDNS检测与本地网络访问速度最快的Server IP。 将访问速度最快的Server IP返回给本地客户端。 使用下载配套安装包 下载配套版本的SmartDNS安装包,对应安装包配套关系如下。 系统 安装包 说明 标准Linux系统(树莓派) smartdns.xxxxxxxx.armhf.deb 支持树莓派Raspbian stretch,Debian 9系统。 标准Linux系统(x86_64) smartdns.xxxxxxxx.x86_64..tar.gz 支持x86_64系统。 华硕原生固件(optware) smartdns.xxxxxxx.mipsbig.ipk 支持MIPS大端架构的系统,如RT-AC55U, RT-AC66U. 华硕原生固件(optware) smartdns.xxxxxxx.mipsel.ipk 支持MIPS小端架构的系统,如RT-AC68U。 华硕原生固件(optware) smartdns.xxxxxxx.arm.ipk 支持arm小端架构的系统,如RT-AC88U。 openwrt 15.01 smartdns.xxxxxxxx.ar71xx.ipk 支持AR71XX MIPS系统。 openwrt 15.01 smartdns.xxxxxxxx.ramips_24kec.ipk 支持MT762X等小端路由器 openwrt 15.01(潘多拉) smartdns.xxxxxxxx.mipsel_24kec_dsp.ipk 支持MT7620系列的潘多拉固件 openwrt LEDE smartdns.xxxxxxxx.mips_24kc.ipk 支持AR71XX MIPS系统。 openwrt LEDE smartdns.xxxxxxxx.mipsel_24kc.ipk 支持MT726X等小端路由器 openwrt LEDE smartdns.xxxxxxxx.x86_64.ipk 支持x86_64路由器 openwrt LEDE smartdns.xxxxxxxxxxx.arm_cortex-a9.ipk 支持arm A9核心CPU的路由器 openwrt LEDE smartdns.xxxxxxxxx.arm_cortex-a7_neon-vfpv4.ipk 支持arm A7核心CPU的路由器 openwrt LUCI luci-app-smartdns.xxxxxxxxx.xxxx.all.ipk openwrt管理统一界面 openwrt系统CPU架构比较多,上述表格未列出所有支持系统,请查看CPU架构后下载。 merlin梅林固件理论和华硕固件一致,所以根据硬件类型安装相应的ipk包即可。(梅林暂时未验证,有问题提交issue) CPU架构可在路由器管理界面找到,查看方法: 登录路由器,点击System->Software,点击Configuration Tab页面,在opkg安装源中可找到对应软件架构,下载路径中可找到,如下,架构为ar71xx 1src/gz chaos_calmer_base http://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/generic/packages/base 请在Release页面下载:此处下载 标准Linux系统安装(树莓派, X86_64系统) 安装 下载配套安装包smartdns.xxxxxxxx.armhf.deb,并上传到Linux系统中。 执行如下命令安装 1dpkg -i smartdns.xxxxxxxx.armhf.deb 修改配置 安装完成后,可配置smartdns的上游服务器信息。具体配置参数参考配置参数说明。 一般情况下,只需要增加server [IP]:port, server-tcp [IP]:port配置项, 尽可能配置多个上游DNS服务器,包括国内外的服务器。配置参数请查看配置参数章节。 1vi /etc/smartdns/smartdns.conf 启动服务 12systemctl enable smartdnssystemctl start smartdns 将DNS请求转发的SmartDNS解析。 修改本地路由器的DNS服务器,将DNS服务器配置为SmartDNS。 登录到本地网络的路由器中,配置树莓派分配静态IP地址。 修改WAN口或者DHCP DNS为树莓派IP地址。 注意: I. 每款路由器配置方法不尽相同,请百度搜索相关的配置方法。 II.华为等路由器可能不支持配置DNS为本地IP,请修改PC端,手机端DNS服务器为树莓派IP。 检测服务是否配置成功。 使用nslookup -querytype=ptr 127.0.0.1查询域名 看命令结果中的name项目是否显示为smartdns或主机名,如smartdns则表示生效 123456pi@raspberrypi:~/code/smartdns_build $ nslookup -querytype=ptr 127.0.0.1Server: 192.168.1.1Address: 192.168.1.1#53 Non-authoritative answer:1.0.0.127.in-addr.arpa name = smartdns. openwrt/LEDE 安装 将软件使用winscp上传到路由器的/root目录,执行如下命令安装 12opkg install smartdns.xxxxxxxx.xxxx.ipkopkg install luci-app-smartdns.xxxxxxxx.xxxx.all.ipk 修改配置 登录openwrt管理页面,打开Services->SmartDNS进行配置。 在Upstream Servers增加上游DNS服务器配置,建议配置多个国内外DNS服务器。 在Domain Address指定特定域名的IP地址,可用于广告屏蔽。 启用服务 SmartDNS服务生效方法有两种,一种是直接作为主DNS服务;另一种是作为dnsmasq的上游。 默认情况下,SmartDNS采用第一种方式。如下两种方式根据需求选择即可。 启用方法一:作为主DNS(默认方案) 启用smartdns的53端口重定向 登录路由器,点击Services->SmartDNS,勾选Redirect选项,启用53端口转发。 检测转发服务是否配置成功 使用nslookup -querytype=ptr 127.0.0.1查询域名 看命令结果中的name项目是否显示为smartdns或主机名,如smartdns则表示生效 123456pi@raspberrypi:~/code/smartdns_build $ nslookup -querytype=ptr 127.0.0.1Server: 192.168.1.1Address: 192.168.1.1#53 Non-authoritative answer:1.0.0.127.in-addr.arpa name = smartdns. 界面提示重定向失败 检查iptable,ip6table命令是否正确安装。 openwrt 15.01系统不支持IPV6重定向,如网络需要支持IPV6,请将DNSMASQ上游改为smartdns,或者将smartdns的端口改为53,并停用dnsmasq。 LEDE之后系统,请安装IPV6的nat转发驱动。点击system->Software,点击update lists更新软件列表后,安装ip6tables-mod-nat 使用如下命令检查路由规则是否生效。 1iptables -t nat -L PREROUTING grep REDIRECT 如转发功能不正常,请使用方法二:作为DNSMASQ的上游。 方法二:作为DNSMASQ的上游 停用smartdns的53端口重定向 登录路由器,点击Services->SmartDNS,去勾选Redirect选项,停用53端口转发。 将dnsmasq的请求发送到smartdns 登录路由器,点击Network->DHCP and DNS,修改DNS forwardings(DNS转发)为: 1/#/127.0.0.1#5353 其中#5353为smartdns的服务端口号,未修改的情况下,默认为5353。 检测上游服务是否配置成功 使用nslookup查询www.baidu.com域名,查看结果中百度的IP地址是否只有一个,如有多个IP地址返回,则表示未生效,请多尝试几个域名检查。 12345678pi@raspberrypi:~ $ nslookup www.baidu.com 192.168.1.1Server: 192.168.1.1Address: 192.168.1.1#53 Non-authoritative answer:www.baidu.com canonical name = www.a.shifen.com.Name: www.a.shifen.comAddress: 14.215.177.38 启动服务 勾选配置页面中的Enable(启用)来启动SmartDNS 注意: 如已经安装chinaDNS,建议将chinaDNS的上游配置为SmartDNS。 SmartDNS默认情况,将53端口的请求转发到SmartDNS的本地端口,由Redirect配置选项控制。 华硕路由器原生固件/梅林固件 说明:梅林固件派生自华硕固件,理论上可以直接使用华硕配套的安装包使用。但目前未经验证,如有问题,请提交issue。 准备 在使用此软件时,需要确认路由器是否支持U盘,并准备好U盘一个。 启用SSH登录 登录管理界面,点击系统管理->点击系统设置,配置Enable SSH为Lan Only。 SSH登录用户名密码与管理界面相同。 下载Download Master 在管理界面点击USB相关应用->点击Download Master下载。 下载完成后,启用Download Master,如果不需要下载功能,此处可以卸载Download Master,但要保证卸载前Download Master是启用的。 安装SmartDNS 将软件使用winscp上传到路由器的/tmp/mnt/sda1目录。(或网上邻居复制到sda1共享目录) 1ipkg install smartdns.xxxxxxx.mipsbig.ipk 重启路由器生效服务 待路由器启动后,使用nslookup -querytype=ptr 127.0.0.1查询域名 看命令结果中的name项目是否显示为smartdns或主机名,如smartdns则表示生效 123456pi@raspberrypi:~/code/smartdns_build $ nslookup -querytype=ptr 127.0.0.1Server: 192.168.1.1Address: 192.168.1.1#53 Non-authoritative answer:1.0.0.127.in-addr.arpa name = smartdns. 额外说明 上述过程,smartdns将安装到U盘根目录,采用optware的模式运行。 其目录结构如下: (此处仅列出smartdns相关文件) 1234567891011121314U盘└── asusware.mipsbig ├── bin ├── etc ├── smartdns └── smartdns.conf └── init.d └── S50smartdns ├── lib ├── sbin ├── usr └── sbin └── smartdns .... 如要修改配置,可以ssh登录路由器,使用vi命令修改 1vi /opt/etc/smartdns/smartdns.conf 也可以通过网上邻居修改,网上邻居共享目录sda1看不到asusware.mipsbig目录,但可以直接在文件管理器中输入asusware.mipsbig\\etc\\init.d访问 1\\\\192.168.1.1\\sda1\\asusware.mipsbig\\etc\\init.d 配置参数参数 功能 默认值 配置值 例子 server-name DNS服务器名称 操作系统主机名/smartdns 符合主机名规格的字符串 server-name smartdns bind DNS监听端口号 [::]:53 IP:PORT bind 192.168.1.1:53 cache-size 域名结果缓存个数 512 数字 cache-size 512 rr-ttl 域名结果TTL 远程查询结果 大于0的数字 rr-ttl 600 rr-ttl-min 允许的最小TTL值 远程查询结果 大于0的数字 rr-ttl-min 60 rr-ttl-max 允许的最大TTL值 远程查询结果 大于0的数字 rr-ttl-max 600 log-level 设置日志级别 error error,warn,info,debug log-level error log-file 日志文件路径 /var/log/smartdns.log 路径 log-file /var/log/smartdns.log log-size 日志大小 128K 数字+K,M,G log-size 128K log-num 日志归档个数 2 数字 log-num 2 conf-file 附加配置文件 无 文件路径 conf-file /etc/smartdns/smartdns.more.conf server 上游UDP DNS 无 [ip][:port],可重复 server 8.8.8.8:53 server-tcp 上游TCP DNS 无 [IP][:port],可重复 server-tcp 8.8.8.8:53 address 指定域名IP地址 无 address /domain/ip address /www.example.com/1.2.3.4 bogus-nxdomain 假冒IP地址过滤 无 [ip],可重复 bogus-nxdomain 1.2.3.4 force-AAAA-SOA 强制AAAA地址返回SOA no [yesno] force-AAAA-SOA yes 转自github 原文链接https://pymumu.github.io/smartdns/","link":"/2018/11/03/smartdns/"},{"title":"Pi上传CPU温度到oneNet","text":"参考代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748\\# -\\*- coding:utf-8 -\\*-# File: cputemp.py#向平台已经创建的数据流发送数据点import urllib2import jsonimport timeimport datetimeAPIKEY = 'xxxxxxxxxxx' #改成你的APIKEYdef get\\_temp(): # 打开文件 file = open(\"/sys/class/thermal/thermal\\_zone0/temp\") # 读取结果,并转换为浮点数 temp = float(file.read()) / 1000 # 关闭文件 file.close() # 向控制台打印结果 print \"CPU的温度值为: %.3f\" %temp # 返回温度值 return temp def http\\_put(): temperature = get\\_temp() #获取CPU温度并上传 CurTime = datetime.datetime.now() url='http://api.heclouds.com/devices/xxxxx/datapoints' #改成你自己的① values={'datastreams':\\[{\"id\":\"temp\",\"datapoints\":\\[{\"at\":CurTime.isoformat(),\"value\":temperature}\\]}\\]} print \"当前的ISO时间为: %s\" %CurTime.isoformat() print \"上传的温度值为: %.3f\" %temperature jdata = json.dumps(values) # 对数据进行JSON格式化编码 #打印json内容 print jdata request = urllib2.Request(url, jdata) request.add\\_header('api-key', APIKEY) request.get\\_method = lambda:'POST' # 设置HTTP的访问方式 request = urllib2.urlopen(request) return request.read()while True: time.sleep(60) resp = http\\_put() print \"OneNET请求结果:\\\\n %s\" %resp time.sleep(60) 注:①为设备API地址 执行效果 转自https://open.iot.10086.cn/bbs/thread-2533-1-1.html 有改动","link":"/2018/07/22/pi%E4%B8%8A%E4%BC%A0cpu%E6%B8%A9%E5%BA%A6%E5%88%B0onenet/"},{"title":"自己动手建造WordPress全站Ajax","text":"全站 ajax 加载网站的用户体验是很奇妙的,全程浏览网站期间看不到任何浏览器刷新的迹象,点击网站上的链接,如果网站的速度可以的话,会给人一种瞬间加载的顺滑感觉,同时不失有高大上的感觉。 现在我看到很多 WordPress 网站已经部署上了全站 ajax 加载代码,效果也不错,所以我也在主题中设置了全站局部刷新的 ajax 代码。 全站 ajax 看似技术复杂,但是实际上操作起来非常简易,原因是已经有大神写好了相关的函数,任何开发者只要稍微修改一下参数,就可以轻松改造自己的网站。 全 站 ajax 代码的来源是从 WordPress 插件中提取出来的,作者是英国的卢克和威廉姆斯。这款代码适用范围非常广,不仅 WordPress 网站可以使用,只要结构统一完整的网站都可以使用,只需要简单的几部就可以改造完成。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162var ajaxhome='';var ajaxcontent = 'content';var ajaxsearch\\_class = 'searchform';var ajaxignore\\_string = new String('#, /wp-, .pdf, .zip, .rar, /goto');var ajaxignore = ajaxignore\\_string.split(', ');var ajaxloading\\_code = 'loading';var ajaxloading\\_error\\_code = 'error';var ajaxreloadDocumentReady = false;var ajaxtrack\\_analytics = falsevar ajaxscroll\\_top = truevar ajaxisLoad = false;var ajaxstarted = false;var ajaxsearchPath = null;var ajaxua = jQuery.browser;jQuery(document).ready(function() { ajaxloadPageInit(\"\");});window.onpopstate = function(event) { if (ajaxstarted === true && ajaxcheck\\_ignore(document.location.toString()) == true) { ajaxloadPage(document.location.toString(),1); }};function ajaxloadPageInit(scope){ jQuery(scope + \"a\").click(function(event){ if (this.href.indexOf(ajaxhome) >= 0 && ajaxcheck\\_ignore(this.href) == true){ event.preventDefault(); this.blur(); var caption = this.title this.name \"\"; var group = this.rel false; try { ajaxclick\\_code(this); } catch(err) { } ajaxloadPage(this.href); } }); jQuery('.' + ajaxsearch\\_class).each(function(index) { if (jQuery(this).attr(\"action\")) { ajaxsearchPath = jQuery(this).attr(\"action\");; jQuery(this).submit(function() { submitSearch(jQuery(this).serialize()); return false; }); } }); if (jQuery('.' + ajaxsearch\\_class).attr(\"action\")) {} else { }}function ajaxloadPage(url, push, getData){ if (!ajaxisLoad){ if (ajaxscroll\\_top == true) { jQuery('html,body').animate({scrollTop: 0}, 1500); } ajaxisLoad = true; ajaxstarted = true; nohttp = url.replace(\"http://\",\"\").replace(\"https://\",\"\"); firstsla = nohttp.indexOf(\"/\"); pathpos = url.indexOf(nohttp); path = url.substring(pathpos + firstsla); if (push != 1) { if (typeof window.history.pushState == \"function\") { var stateObj = { foo: 1000 + Math.random()\\*1001 }; history.pushState(stateObj, \"ajax page loaded...\", path); } else { } } if (!jQuery('#' + ajaxcontent)) { } jQuery('#' + ajaxcontent).append(ajaxloading\\_code); jQuery('#' + ajaxcontent).fadeTo(\"slow\", 0.4,function() { jQuery('#' + ajaxcontent).fadeIn(\"slow\", function() { jQuery.ajax({ type: \"GET\", url: url, data: getData, cache: false, dataType: \"html\", success: function(data) { ajaxisLoad = false; datax = data.split('<title>'); titlesx = data.split('</title>'); if (datax.length == 2 titlesx.length == 2) { data = data.split('<title>')\\[1\\]; titles = data.split('</title>')\\[0\\]; jQuery(document).attr('title', (jQuery(\"<div/>\").html(titles).text())); } else { } if (ajaxtrack\\_analytics == true) { if(typeof \\_gaq != \"undefined\") { if (typeof getData == \"undefined\") { getData = \"\"; } else { getData = \"?\" + getData; } \\_gaq.push(\\['\\_trackPageview', path + getData\\]); } } data = data.split('id=\"' + ajaxcontent + '\"')\\[1\\]; data = data.substring(data.indexOf('>') + 1); var depth = 1; var output = ''; while(depth > 0) { temp = data.split('</div>')\\[0\\]; i = 0; pos = temp.indexOf(\"<div\"); while (pos != -1) { i++; pos = temp.indexOf(\"<div\", pos + 1); } depth=depth+i-1; output=output+data.split('</div>')\\[0\\] + '</div>'; data = data.substring(data.indexOf('</div>') + 6); } document.getElementById(ajaxcontent).innerHTML = output; jQuery('#' + ajaxcontent).css(\"position\", \"absolute\"); jQuery('#' + ajaxcontent).css(\"left\", \"20000px\"); jQuery('#' + ajaxcontent).show(); ajaxloadPageInit(\"#\" + ajaxcontent + \" \"); if (ajaxreloadDocumentReady == true) { jQuery(document).trigger(\"ready\"); } try { ajaxreload\\_code(); } catch(err) { } jQuery('#' + ajaxcontent).hide(); jQuery('#' + ajaxcontent).css(\"position\", \"\"); jQuery('#' + ajaxcontent).css(\"left\", \"\"); jQuery('#' + ajaxcontent).fadeTo(\"slow\", 1, function() {}); }, error: function(jqXHR, textStatus, errorThrown) { ajaxisLoad = false; document.title = \"Error loading requested page!\"; document.getElementById(ajaxcontent).innerHTML = ajaxloading\\_error\\_code; } }); }); }); }}function submitSearch(param){ if (!ajaxisLoad){ ajaxloadPage(ajaxsearchPath, 0, param); }}function ajaxcheck\\_ignore(url) { for (var i in ajaxignore) { if (url.indexOf(ajaxignore\\[i\\]) >= 0) { return false; } } return true;}function ajaxreload\\_code() { //add code here }function ajaxclick\\_code(thiss) { jQuery('ul.nav li').each(function() { jQuery(this).removeClass('current-menu-item'); }); jQuery(thiss).parents('li').addClass('current-menu-item');} 代码部分需要根据自己的实际修改一小部分: 第一行 ajaxhome 填写网站的访问网址; 第二行 ajaxcontent 填写网站文章的容器id名称,即异步加载的部分; 第三行 ajaxsearch_class 填写网站搜索框的容器名称,一般都是“searchform”; 第四行 ajaxignore_string 是忽略使用ajax加载的链接,比如说feed源等等; 第六行 ajaxloading_code 加载时显示的内容,可以设定动画; 第七行 ajaxloading_error_code 加载失败时显示的内容,可以设定动画。 只要按照上述要求修改好代码,单独存放为 JS 文件并且引入网页之中,效果立竿见影。有木有很神奇的感觉。 ajax异步加载影响其他jQuery特效: 部署上 ajax 异步加载代码后,会出现一个问题,首次打开网站后,jQuery 动画都会正常运行,但是点击网页执行了 ajax 异步加载之后,所有的动画都会失效。 这是因为进行异步加载后 jQuery 代码无法获取元素,特效自然消失,为解决这个问题,还需要对 jQuery 代码进行改造。 解决方式是使用 live() 事件,live()事件的用法如下 1$(selector).live(event,data,function) event 用来替换 click()、hover() 等动作;data 可选,是参数;function 是需要执行的动作。 举个例子,一个 click() 事件改写为 live() 事件,原本代码是这样: 1$(\".menu-item\").click(function(){$(\".topmenu\").fadeOut(500)}); 修改之后 1(\".menu-item\").live(\"click\",function(){$(\".topmenu\").fadeOut(500)}); 原文出自KRUNK ZHOU 原文链接:https://krunk.cn/kblog325/","link":"/2018/07/06/%E8%87%AA%E5%B7%B1%E5%8A%A8%E6%89%8B%E5%BB%BA%E9%80%A0wordpress%E5%85%A8%E7%AB%99ajax/"},{"title":"GitHub文件加速","text":"","link":"/2018/06/23/whr-uptime/"},{"title":"pm2让hexo博客在后台运行","text":"估计有好多人和我一样,在linux上部署成功hexo这个开源博客的时候,很高兴的用$ hexo server在服务上跑了起来。都遇到了 hexo 进程无法一直常驻后台。 ssh 一关,博客进程就死掉了。这可就扎心了,因为我们不可能一直本地开着ssh吧。 我也尝试过很多办法,比如screen,windows X system …… 于是经过一番大肆搜索,官方说用$ hexo s & 但是我在用的时候还是进程莫名奇妙的死掉了 安装pm21npm install -g pm2 写一个执行脚本在博客根目录下面创建一个hexo_run.js 12345678910//runconst { exec } = require('child\\_process')exec('hexo server',(error, stdout, stderr) => { if(error){ console.log('exec error: ${error}') return } console.log('stdout: ${stdout}'); console.log('stderr: ${stderr}');}) 运行脚本在博客根目录下 1pm2 start hexo_run.js","link":"/2018/06/23/pm2%E8%AE%A9hexo%E5%8D%9A%E5%AE%A2%E5%9C%A8%E5%90%8E%E5%8F%B0%E8%BF%90%E8%A1%8C/"},{"title":"树莓派打开powersave","text":"powersave顾名思义,减少功耗,这个功能在有些供电不足的情况下十分好用,可以减少树莓派宕机的次数。 举个栗子我的一台供电不足树莓派上搭了个web server,再叫几个好伙伴访问一下,写两篇文章或者评论什么的,第一个访客还没有什么问题,第二个一来,503了。。。 通过powersave功能可以将Pi的CPU主频降到最低 sudo -i echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 然后 sudo cat/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 我的Orangepi的主频已经降到了480mhz了,毕竟windowsX system玩的少,在shell里面这点主频足够了 编辑/etc/rc.local把降频功能加入到自启动项目中 echo powersave > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor 完美节能","link":"/2018/06/06/%E6%A0%91%E8%8E%93%E6%B4%BE%E6%89%93%E5%BC%80powersave/"},{"title":"我为什么写博客","text":"一个选择 我知道现在可能说这话有点不合时宜,毕竟博客时代都已经过去了,再号召大家用过就好像时的东西是不是有点逆流而上? 我曾经也问过自己这个问题,但是我觉得,博客时代过去跟我们要开博客是没有多大关系的,就好像你的读书时代已经过去你就不再读书一样。 判断一件事情值不值得去做有一个方法:在一张白纸的左边写不值得做的原因,然后在右边写值得做的原因,写完一比较,一权衡,自然能够得出结果。 大家都成年人了,你会觉得这样思考分析总结的过程才是正确的思考的方法吧? 所以,我在这里列出要写(独立)博客的原因,供大家去选择,然后填在你白纸的右边。 注意,我不是给你一个建议,而是提供一个选择,这个选择蕴藏着我也不知道的可能。 博客内容 写博客不难,你可以当作是生活的记录,但是这样的记录没有任何的意义。写要对得住写本身,写出来的东西应该是思考的结果。我认为,如果你要开一个博客,博客的内容应该是这样的: 1. 不是生活杂记、不是流水账、不是牢骚、不是抱怨、不是心情琐记……;2. 有目的地写,要务实,追求质量;3. 承认真实的自己,不要吹嘘,不要装逼,无需讨好读者;4. 记录自己学习、思考、总结的过程;5. 分享你的故事、所得、感想、经验; 值得写的原因 以下是一个清单,可以根据自己的情况匹配,然后选择。 重新认识自己 是不是很久没有跟自己对话了? 你可以尝试从回答一些问题开始,将你过去要回避的问题写下来,例如就可以从这个九个问题开始: 1、请你介绍一下你自己,你是个什么样的人? 2、你有什么理想吗?这个理想是怎么形成的? 3、你理想的伴侣关系是什么样的?你自己在这个伴侣关系中扮演什么样的角色?要承担什么样的责任? 4、你理想的事业是什么,你正在做的工作符合你的事业理想吗?这份工作对你的意义是什么? 5、你对亲子关系怎么看?对你来说,什么是一个理想的父亲(母亲),你期望自己成为这样一个理想父亲(母亲)吗? 6、你对钱怎么看,你认为赚到多少钱是足够的?如果你明天一早醒来,已经有足够的钱,你将会如何继续安排自己的生活? 7、对你来说,什么是理想的性生活?什么是理想的性道德,在你的性道德观中,什么样的性生活是禁忌的,需要避免的,什么样的性生活是美好的,需要得到鼓励和发展的? 8、你的择友标准是什么?什么样的人你会愿意交往,什么样的人你会拒绝和他交往? 9、你对死亡怎么看?你希望自己活到多少岁,你准备怎么度过从现在到死亡的这段时间?如果你要立遗嘱,这份遗嘱会怎么写? 以上的这九个问题摘自《很少人能顺畅回答这9个问题——心理治疗刚开始医生常常会先问你的 》by 李孟潮。 这些问题的答案你可以选择不发,但是我强烈地建议写下来,只有在写的时候你才可以慎重地思考这些问题,而不会回避跳过或者留下空白,这是接受自己的第一步。 提供持续学习的动力 例如,我为自己设限每天写一千字,信息的不断输出给我带来恐惧,我害怕有一天我写无可写,于是我不停地阅读,通过个人的知识管理促使自己不断学习,提高核心竞争力。 详细的知识管理可以看我的这篇文章:《个人知识管理的方法》,回复「知识」可见 积累更多的知识 写并不是单纯的写。 例如你写着写着,你突然忘记了一个概念,于是上网找,找回来这个概念的时候,你重温这个概念,可能还会顺便看了一下这个概念的其他东西。 例如你需要获取第一手的资料,寻找信息来源本身就是一个知识积累的过程,同时,你慢慢就学会了鉴别知识:什么是没有用的心灵鸡汤,什么是不值得关注的吐槽名人,还有,在这个过程中,你还养成你的心智。 提高将事情讲清楚的能力 很多东西你以为懂了,但当你在写下来的时候,你就觉得无从下手了。 如果一件事情你不能讲清楚,十有八九你还没有完全理解。 将事情写下来,慢慢就可以提高你的逻辑思维能力,分析能力,写会迫使你在你脑中搭建一个有条理的框架。例如我写这篇文章一样,我就将值得写博客的原因一点一点地罗列出来,事情就更加清晰,你也可以更好的思考问题。 分享带来的连锁反应 “通过分享,你获得了直接而快速的回报,你最终或许会发现你已将版权和“保留所有权利”抛诸脑后。新的经济学准则是:参与你作品的人越多,回报越高。在分享主义里,如果你愿意你可以保留所有权,但是我乐于分享。” by 毛向辉 《分享主义:一场思维革命》 互联网精神其中最重要的就是分享主义,基于分享主义,你可以享受到社会化及互联网给你带来的种种便利和好处,你分享了一个知识,你就成为了互联网中的一个点,这个点的大小由你自己来决定,互联网的大潮会将你的这个点推送到它所能触及的每个角落,让需要的人得到,同时,你的这个点也会继续扩大,连接到整个网络,这个点有可能连接成一张网,而你就是这张网的中心。 帮你找到志同道合的人 在微博,在朋友圈,你可能找不到跟你志同道合的人,而在博客,你可以通过看他的几篇文章就迅速地理解认同这个人,即使你没有见过这个人,但你也可以通过这种关联来相互学习。 如果你在一个领域有相当的了解,你将这些内容发在网络上,网络上跟你志趣相投的人也会被你吸引过来,根据吸引力法则,你是怎样的人你就被怎么样的人吸引,这就是博客所能赋予你的魅力。 即使博客没有被他人关注,我们依然可以找到同好,你可以自己将博文转载到其他站点,人们会通过搜索引擎找到你,有邮件、微博等工具,我们不乏与他人交流的途径。by Gabriel Weinberg《Why I blog》 记录成长 隔一段时间,你再回头看你写的博客,你会发现自己正在通过这样的方式在不断的成长,这种成长在自己眼里是一种财富,在别人眼里是一张地图,你得到了收获,不断修正自己的错误,别人得到了指引,避免走弯路。 更多的情况是当你回望自己的时候你会发现自己是一个傻逼,so what,that is what I am! 培养持续做一件事情的能力 开始是坚持,后来是习惯,接着喜欢。以后当有人对你说,「你写那么多有用的东西,你真的很厉害啊!」你可以笑而不语,也可以大声说道:「你妹,你不知道我开始的时候多么痛苦!」 让你长久地去跑步,你可能做不到;让你每个月看一本书,你也可能做不到;但让你持续地写一个博客,你可以做得到。 你不相信?你不试试你怎么知道? 默默地持续做一件事是一种难得的能力,也是一种难得的品质。 讨论反思 每人都会有思维的盲点,就好像这篇文章一样,可能你觉得我可能说得不对,你可以反驳我,我欢迎这种讨论,因为讨论的过程中会产生各种的思维的碰撞,这种碰撞会让你反思,也会激发出你新的灵感,这种讨论反思给自己的带来巨大的受益。 互联网给你的反馈就是让你承受更多,接受更多,成为一个更好的人。 搜寻到你意想不到东西 世界不止是你的家,你的公司,你的朋友圈,你应该去发现一个更大的世界,通过写博客,你会知道世界上还有很多人像你一样在写博客,这些人和知识正在世界的某个角落在等着你。 例如,在写这篇文章的过程中,我才知道了Gabriel Weinberg,我才要将阳志平的博客重读一遍。写的过程会让你有很多新的发现,这些新的发现都值得你去再写下来,总结分享出去。 一个人在做一件属于自己的事 很多你认为自己很牛逼的事情都是自己一个人做出来。 别人在刷微博,你在看书,别人在看穿越剧,你在学英文,别人在去唱K,你在写个人总结。吃饭也要找同伴,出游要找同伴,看电影要找同伴,你上一次一个人在做一件属于自己的事是在什么时候? 如果你想要清晰地思考,就必须远离人群。但是走得越远,你的处境就会越困难,收到的阻力也会越大。因为你没有迎合社会习俗,而是一步步地与它背道而驰。如果自己就是潮水的一部分 ,怎么能看见潮流的方向呢?你只能永远保持质疑,问自己,什么话是我不能说的?为什么?——Paul Graham《不能说的话》 互联网的身份识别: 一个长期的价值博客是一份很好的简历。这里的“简历”并非是狭义上的求职简历,毕竟现在还没有到价值博客的时代,很多人写博客都是到处转载或者干脆碎碎念,正因此面试官未必拿个人博客当成了解一个人的更可靠窗口。 这里的“简历”是指一个让别人了解自己的窗口,虽然我们未必做得到像罗永浩、Keso这样的博客,个人的影响力已经足以支撑出一份事业(牛博和5gme),但至少你会因此而结识更多的人,你的博客价值越高,你结识的人就越牛,跟牛人交流又会让你的眼界得到极大的开阔,打开一扇又一扇你原本不知道的门,于是你就变得更牛… 这是一个良性循环。by 刘未鹏 最后 你可能想不到在白纸的左边(不值得写博客的原因)写什么了,想不到写个「博客时代已经过去」或者「我没有时间」也可以,但与此同时,你也可以用那些时间去思考一下「怎么做到长期写一个价值博客」。 如果你不想思考,也可以回复「价值」看看别人的建议。 转自知乎 你为什么写博客","link":"/2018/05/20/%E6%88%91%E4%B8%BA%E4%BB%80%E4%B9%88%E5%86%99%E5%8D%9A%E5%AE%A2/"},{"title":"树莓派WIFI自动重连","text":"python代码autowifi.py,放在/home/pi目录下 #!/usr/bin/pythonimport os, time while True: if ‘192’ not in os.popen(‘ifconfig grep 192’).read(): print ‘\\n****** wifi is down, restart… ******\\n’ os.system(‘sudo /etc/init.d/networking restart’) time.sleep(5*60) #5 minutes shell脚本autowifi.sh,也放在/home/pi目录下 #!/bin/shpython /home/pi/autowifi.py & 开机自动启动以上脚本:在终端窗口执行以下命令即可 sudo cp -f /home/pi/autowifi.sh /etc/init.d/sudo chmod +x /etc/init.d/autowifi.shsudo chown root:root /etc/init.d/autowifi.shsudo update-rc.d autowifi.sh defaults 脚本会每5分钟检测一次,若wifi断线,则自动重新连接 如果出现 “insserv: warning: script ‘xxxx’ missing LSB tags and overrides” 移除wolfram-engine sudo apt-get remove wolfram-engine 转自创客社区 原文链接http://bbs.nxez.com/thread-99-1-1.html","link":"/2018/05/09/%E6%A0%91%E8%8E%93%E6%B4%BEwifi%E8%87%AA%E5%8A%A8%E9%87%8D%E8%BF%9E/"},{"title":"论破解大疆限高","text":"作为一个过来人讲,DJI这种机器破限高没啥意义。 但是有人会说,站得高望得远啊。 因为大疆的机载图传天线是向四周发射的。你要飞的高且有图传,必须飞的远。 但是飞到一千三四百高的时候电量就报警了,要求返航了,受到天气温度,电池寿命的影响,有时候飞到破千 飞机就嚷嚷着要返航回来了。 如果你光头顶的话,一没有图传,二直升的效率低于斜线上升。一上去连片刻停留的没有就下来了有啥意义。 所以DJI的机机破高没意义,向往挑战的心理解,但是损人不利己的事情咱千万别干。 整理来自Arkbird fpv群","link":"/2018/05/08/%E8%AE%BA%E7%A0%B4%E8%A7%A3%E5%A4%A7%E7%96%86%E9%99%90%E9%AB%98/"},{"title":"JS实现仿饿了么在浏览器标签页失去焦点时网页标题改变","text":"S实现浏览器标签页失去焦点时网页Title的改变 这个 API 本身非常简单,由以下三部分组成。 document.hidden:表示页面是否隐藏的布尔值。页面隐藏包括 页面在后台标签页中 或者 浏览器最小化 document.visibilityState:表示下面 4 个可能状态的值 hidden:页面在后台标签页中或者浏览器最小化 visible:页面在前台标签页中 prerender:页面在屏幕外执行预渲染处理 document.hidden 的值为 true unloaded:页面正在从内存中卸载 Visibilitychange事件:当文档从可见变为不可见或者从不可见变为可见时,会触发该事件。 这样,我们可以监听 Visibilitychange 事件,当该事件触发时,获取 document.hidden 的值,根据该值进行页面一些事件的处理。 记住:必须是基于支持H5的浏览器才可以 1234567891011121314var OriginTitile = document.title;var titleTime; document.addEventListener('visibilitychange', function() { if (document.hidden) { document.title = '(つェ⊂)我藏好了哦~ ' + OriginTitile; clearTimeout(titleTime); } else { document.title = '(\\*´∇`\\*) 被你发现啦~ ' + OriginTitile; titleTime = setTimeout(function() { document.title = OriginTitile; }, 2000); } }); 最后在Wordpress中使用Custom Javascript插件启用 本文来源于KRUNK BLOG( https://krunk.cn),","link":"/2018/04/17/js%E5%AE%9E%E7%8E%B0%E4%BB%BF%E9%A5%BF%E4%BA%86%E4%B9%88%E5%9C%A8%E6%B5%8F%E8%A7%88%E5%99%A8%E6%A0%87%E7%AD%BE%E9%A1%B5%E5%A4%B1%E5%8E%BB%E7%84%A6%E7%82%B9%E6%97%B6%E7%BD%91%E9%A1%B5%E6%A0%87%E9%A2%98/"},{"title":"树莓派创建自定义HDMI模式","text":"我们经常使用HDMI连接树莓派,但是有时候树莓派HDMI导致屏幕不能显现,让人很烦 在config.txt中使用以下配置字符串指定新模式 hdmi_cvt= width width in pixelsheight height in pixelsframerate framerate in Hz aspect aspect ratio 1=4:3, 2=14:9, 3=16:9, 4=5:4, 5=16:10, 6=15:9margins 0=margins disabled, 1=margins enabledinterlace 0=progressive, 1=interlacedrb 0=normal, 1=reduced blanking 前三个参数是必需的。其余的是可选的。如果未指定,则方面默认为16:9 使自定义模式成为默认模式。 请注意。不能保证您的显示器将支持由此产生的分辨率/帧速率。 但是,如果您目前正在以非原生分辨率运行显示器,那么这可能值得一试。","link":"/2018/02/22/%E6%A0%91%E8%8E%93%E6%B4%BE%E5%88%9B%E5%BB%BA%E8%87%AA%E5%AE%9A%E4%B9%89hdmi%E6%A8%A1%E5%BC%8F/"},{"title":"树莓派用自带的网卡搭建热点","text":"主要用到的软件有hostapd、dnsmasq sudo apt-get install hostapd dnsmasq 然后在/etc/dnsmasq.conf末加入(自己修改IP和网段,这个文件是已存在的,很详细的配置文件,但是所有行都加入了#号注释掉) interface=wlan0 dhcp-range=10.0.0.2,10.0.0.5,12h 然后新建/etc/hostapd/hostapd.conf,加入 interface=wlan0 hw_mode=g channel=10 auth_algs=1 wpa=2 wpa_key_mgmt=WPA-PSK wpa_pairwise=CCMP rsn_pairwise=CCMP wpa_passphrase=wifi密码 ssid=wifi名字 接着修改/etc/sysctl.conf,更改(如果有这一行,把#号去掉就行) net.ipv4.ip_forward=1 最后,将下面脚本加入到/etc/rc.local的exit 0前 ifconfig wlan0 down ifconfig wlan0 10.0.0.1 netmask 255.255.255.0 up iwconfig wlan0 power off service dnsmasq restart hostapd -B /etc/hostapd/hostapd.conf & > /dev/null 2>&1 sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT 重启,就可以看到热点了。 转自周半仙的博客","link":"/2018/02/17/%E6%A0%91%E8%8E%93%E6%B4%BE%E7%94%A8%E8%87%AA%E5%B8%A6%E7%9A%84%E7%BD%91%E5%8D%A1%E6%90%AD%E5%BB%BA%E7%83%AD%E7%82%B9/"},{"title":"小米路由器monlor tools插件","text":"小米路由器Shell工具箱,monlor大神制作,主要参考了小米的Misstar Tools制作,仅学习之用!博主参与调试 工具箱正处于测试状态,更新比较频繁,安装要有一定的动手能力,出问题会用U盘刷固件。 arm路由: R1D R2D R3D , mips路由: R3 R3P R3G R1CM 目前支持了以下几种插件: 1. ShadowSocks 影梭 #成功 2. KoolProxy 去广告 3. Aria2 下载神器 4. VsFtpd ftp服务器 5. kms Windows激活工具 6. Frpc 内网穿透(占用资源较多,建议arm路由使用) 7. Ngrok 内网穿透(比较轻量级) 8. WebShell 网页ssh 9. TinyProxy http代理 10. Entware opkg软件包工具(仅支持arm路由) 11. KodExplorer 可道云,在线文档管理器(依赖于Entware,仅支持arm路由) 12. EasyExplorer 文件传输同步工具(仅支持arm路由) 13. HttpFile http文件查看工具(依赖于Entware,仅支持arm路由) 工具箱已经开发到了web界面,但是web界面插件不完全,插件的安装、卸载、配置由shell完成。 安装完成后执行monlor命令配置工具箱,Ctrl + c或者输入exit可以退出。 才疏学浅,但有一颗学习和折腾的心! 安装方式curl命令 1sh -c \"$(curl -kfsSl https://coding.net/u/monlor/p/Monlor-Tools/git/raw/master/install.sh)\" && source /etc/profile &> /dev/null 工具箱命令1. 卸载:uninstall.sh 2. 更新:update.sh [-f] 3. 初始化:init.sh 4. 插件管理:appmanage.sh addupgradedel appname [-f] 5. 工具箱配置:monlor (任意界面Ctrl + c可以退出配置) Web界面预览 注意事项1. 如果插件和工具箱都有更新,请务必先更新工具箱! 2. 工具箱没有web界面,完全靠Shell开发,插件的安装、卸载、配置由配置文件完成。 3. 安装完成后执行monlor命令配置工具箱,Ctrl + c或者输入exit可以退出。 4. ss插件推荐使用aes-256-cfb或rc4-md5加密方式,较新的加密方式可能不支持 目录结构/ — /etc — /monlor — /apps/ — 插件安装位置 — /config/ — 工具箱配置文件 — /scripts/ — 工具箱脚本 — /tmp — /messages — 系统日志,工具箱日志 — /userdisk — /data/ — 硬盘目录 — /extdisks/ — /sd*/ — 外接盘目录 这篇文章已经没有实效性,最新版monlor tools请移步到__http://blog.whrblog.online/archives/1017","link":"/2018/02/02/%E5%B0%8F%E7%B1%B3%E8%B7%AF%E7%94%B1%E5%99%A8monlor-tools%E6%8F%92%E4%BB%B6/"},{"title":"用Ardunio和ESP8266模块做一个云温度传感器","text":"前言前段时间用ESP8266模块+温度、湿度、气压传感器做了个云传感器。炫了几天装B后,就被群友索要教程。 写这个教程,我其实是非常犹豫的,因为涉及到的知识点比较多,要写一大堆东西,极其占用时间。 如果你是个高中生,或者是个大学新生,或者没接触过类似的东西,你会发现要独立完成全套的软硬件编程和设计,要学的东西有点多…… 这样也导致了我这个教程,我也不知道该怎么写,能显得通俗易懂…… 两年前,我刚接触单片机的时候,就做过类似的东西,一个STC的51单片机STC15W408AS,一个ESP8266-12E模块,加一个DS18B20温度传感器。 单片机获取传感器的实时温度,然后用AT命令和ESP8266模块通信,ESP模块负责把数据通过GET方式传给一台阿里云服务器。云服务器有一个Eclipes做的HttpServer的页面,数据存入MySql数据库,最后再做一个小网页展示最新1000条数据记录。 ESP模块连WIFI需要的SSID和密码,通过一个安卓手机APP实现,APP当时是用了APICloud这个APP快速开发工具做的。不得不说,做一些简单的APP,这种快速开发工具真的很赞,一个代码,能同时在线打包Android和IOS两种安装包。不过当时APICloud很恶心的一点,就是各种收费插件,显示全部无线路由器名字列表的插件都要收费。好了,不吐槽这个了。当时我还用过另外一个APP快速开发工具:APPCan。这个倒是没有那么多的收费插件,但是这个工具的Tcp协议有问题,官方暂时也没有修改的打算,所以只好放弃,转用APICloud。 以上这种方式,开发速度非常快捷。我在拿到ESP8266模块后不到一个星期就完成了。 当然,这个项目也没任何核心技术和难度,我当时接触单片机和硬件还不到两个月呢。 两年后,无意间看到了有人用Arduino配合Esp8266的开发库在完成类似的事情,网上也有很多类似的教程。 Arduino我一直没有买过任何开发板,因为我51单片机都不算太精通,我还打算重点学习STM32的使用方法,所以根本没关注过Arduino,尽管它非常火。 但是ESP8266模块我这里有一大堆啊,自己买了好多块,去年还在乐鑫免费申请了好多块,于是我根据别人的教程帖子,下载了ArduinoIDE和ESP8266最新版本2.3.0的开发板,接上串口线随便烧录了几个例程,居然很顺利的就完成了。 顺便说一句,ArduinoIDE的文本编辑功能做的真的很差劲,连编译器最简单的文字自动补完功能都没有,全部的代码都要一个一个字符敲进去,反正是弱爆了。 而且ESP8266的开发板还不能自动更新,据说被墙了,只有去下载压缩包,手工更新。 不过很多小的开发库,自动更新都没问题的。 当然我还是喜欢自己到GIT上手工搜索开发库,手工安装。哈哈。 反正不管怎么说,这些都是小坑,一个晚上都趟过去了。Arduino用的应该是C++语言。反正C就这个样子,根据例子写就是了,没啥好说的。 Arduino烧录ESP8266模块的固件真是非常方便,成功率基本是100%,还是全自动的。程序写好后,按住按键,让GPIO0接地,烧录器插到USB口,松开按键,选择“上传”,然后等一会就烧录成功了。 如果遇到烧录失败,把USB转TTL模块拔了重新插上就可以了,当然GPIO0要接地。 我这里用的是烧录STC单片机用的那种带3.3 V输出的USB转TTL的烧录器,烧录速度还可以,关键是这种烧录器我家里有好几个,根本不用重新购买。 总之一句话,硬件都是现成的,我只要安心编程就好。 我们要做的东西先展示一下硬件,我用洞洞板搭建和焊接的。正面还凑合看。 反面很难看,飞线的,想好看不去打板子是没戏的。 然后还有一个小网站来配合它。当然这个网站我们要自己做。 后面我再介绍怎么完成它。 为了酷一点,我们还要做一个图表来展示。图表里面能显示24小时的数据折线图。 上面看看很简单吧,可是这一套东西,如果要自己独立实现,嘿嘿,你要软件和硬件都懂一点才行。 硬件准备先说一下我们需要准备哪些硬件。当然,我做这个的时候,纯粹是一时兴起,所以我只会用我手头上现有的模块和元件,不会去额外购买的。 1、ESP8266模块。这里我用的是2年前购买的安信可公司的ESP8266-12E。 你也可以用ESP8266-12F,或者用乐鑫公司的ESP-WROOM-02模块。 下图就是ESP-WROOM-02模块,这个模块我手上很多,乐鑫搞活动的时候我去申请的。但是没用过,因为没转接板,飞线太难看。 两个模块的引脚顺序是不一样的,我这里就不再介绍ESP-WROOM-02模块了,百度上很多资料,程序肯定能通用。 2、ESP8266的转接板。 这里说一句,转接板不是必需的,但是有了它,明显搭建ESP8266最小系统的时候省事多了。 顺便说一句,安信可的GPIO5和GPIO4引脚顺序搞不清楚,他们给的原理图和实物居然是相反的,害我浪费了好多时间才发现。后来干脆重画了他的最小系统的原理图。 3、AMS1117 3.3V模块 因为ESP8266的供电是3.3V的,所以必须要有一个降压芯片。 其实这个芯片很费电,静态电流就有8mA,如果你打算用电池供电,一定不要选它。 实在是便宜,淘宝育松店的价格还要低个2毛钱,所以我也懒得自己焊了。 4、DS18B20温度传感器 这种传感器温度实在不准确,DS18B20的温度精度是正负0.5°,马马虎虎了。 而且离发热元件距离比较近的时候,温度有明显上升。 如果你追求精度,我建议你买下面这种封装在不锈钢管里面的。 5、湿度计传感器DHT12 你也可以买DHT11 ,代码通用的。 但是11和12价格基本一样的情况下,我为啥不买个精度稍微高点的DHT12呢? 这里多说一句,DHT12也带温度的,精度也是正负0.5°,干嘛还要上DS18B20呢? 我只想说,第一,这个温度误差绝对不止是0.5°,第二,多学一种硬件用法。 6、气压传感器BMP280 你也可以用BMP180,精度稍差点而已,价格基本一样。 BMP280,可以测量温度和气压。温度也不是那么精确,主要还是测量气压的。 气压的误差大概是正负1hPa。我们知道,大气压强大概是100000Pa左右,有时候会用hPa做单位,1hPa=100Pa。 还有一种型号BME280,这个传感器温度、湿度、气压全带了。可惜价格比较贵,温度和湿度它精度也不高,就算了。 7、IIC接口的0.96英寸,OLED 12864显示屏。 个人感觉白色字体的比较好看。 为啥用IIC接口的呢,因为占用的IO引脚少,SPI接口的要4~5个IO引脚呢。 8、一块5*7cm的洞洞板,一个微动开关,一个单刀小开关,一个microUsb插座,一个蓝色发光LED,4根杜邦针,几个圆孔插座和4口杜邦插座啥的,还有若干个1K和10K电阻用来做上拉和限流啥的,其实个人测试,不接也行……当然最好接上…… 9、一个USB转TTL的烧录器 这个烧录器,其实是烧录51单片机用的……我想大家手头应该有好几个吧,因为我手头就有4、5个……用的时候还老是找不到……越买越多…… 记得把电源线,插到3.3V的位置,5V会烧了ESP8266模块。 还有那种3、4块钱的简易版本烧录器,我不建议使用,因为它的3.3V电流很小,容易烧录失败。反正用这种8块钱的烧录器,烧录的波特率如果不高于115200的话,我基本没失败过。记得安装驱动程序, 要不没法用。 搭建软件环境光有硬件还不行啊,还要有软件,要不我怎么写代码,怎么烧录固件呢? 这次我们不用额外单片机,直接用ESP8266模块内置那个牛逼32位单片机。根据官方文档,这个单片机只用了大概几分之一的资源用来控制WIFI,所以我们还有大量的内存和存储空间,用来做我们自己的事情。 这里感谢万能的Arduino,兼容超级多的32位单片机,也感谢为ESP8266写Arduino开发库的哥们,你真是太闲了,还有空写这个,有工资吗? 首先我们要下载一个最新版本的Arduino,版本号1.8.3。你可以到Arduino的官方网站去下载,也可以下载我的打包文件。 这个兼容Win7和Win10系统,我这里是Win7 64位版本的。Win10也肯定没问题。 反正就是一直Next,不要更改路径,安装在C盘就可以了。最后在桌面会生成一个图标,这个就表示你安装成功了。 你可以打开看看,这个时候你还不能直接对ESP8266模块进行编程,因为我们还要安装ESP8266的开发板的库。 本来可以直接在开发板管理器里面直接下载更新的,不过它好像被限制了,禁止进入境,所以你得下载安装包,手工更新。 上面的图是我安装好的时候,显示的版本号2.3.0的ESP8266开发板。这个我也帮大家打包好了。 随便解压到任何一个目录,里面只有一个目录 。 把这个目录拷贝到下面的目录下面: C:\\Users\\Administrator\\AppData\\Local\\ 某个同学说,哎呀,我C盘没有Users目录啊, 这个就是Users目录。 用户目录下面,再打开 目录。 某个同学又说了,哎呀,我的 目录下面,没有 目录啊。 是啊,这个目录是隐藏的,所以呢,打开文件夹选项,把它改成不隐藏的。 某个同学说,文件夹选项我也找不到啊,所以啊,看下图啊,实在不行百度啊。 写教程就这点麻烦,很多常识你不写,很多人都看不懂,所以大家要学会百度。。。。 最后打开AppData目录下面的 目录,把刚才的 文件夹整个拷贝进去。 最后 文件下面是这些东西就可以了。 事情还没完,再打开Arduino IDE,在文件菜单下面的首选项里面, 把里面的内容,弄成和我下面的图一样就可以了。 具体的配置,可以参考下面这个网址,我也是从里面学的。 http://www.geek-workshop.com/thread-26170-1-1.html 附加开发板管理器网址: 填入下面的地址,然后点“好”保存。 http://arduino.esp8266.com/stable/package\\_esp8266com\\_index.json 下面的还有一个参数配置,应该和下面的保存一致。 C:\\Users\\Administrator\\AppData\\Local\\Arduino15\\preferences.txt 如果不一样,就再检查一下你刚才拷贝的 文件夹,里面应该有个 文件的。 反正搞了半天,重启一下Arduino,看看“工具”“开发板”“开发板管理器” 如果开发板安装好了,应该有2.3.0 INSTALLED 之类的显示。 或者干脆把开发板往下拉,看看有没有ESP8266的,类似于下图: 如果你用的是ESP8266-12E,你可以选 作为你的默认开发板。 如果你用的是老款的ESP8266-01啥的,你就老老实实选通用的开发板 当然12E的模块,也可以选通用的。 总算把软件环境搭好了,妈的,写了半天,真心累啊。 搭建ESP8266的最小环境首先你要把ESP8266的最小系统搭建起来,否则没法烧录和测试。 看看下面的ESP8266最小系统原理图。有转接板的,你可以焊上杜邦针,用杜邦线搭个最小环境。然后把烧录器接到电脑上,写个小程序测试一下。 我还是用安信可的模块做说明,乐鑫的模块请对照引脚,自己搭建。 乐鑫模块的EN脚,等同于安信可模块的CH_PD引脚,也就是使能脚。其他名字基本一样,请一一对照。 这里再啰嗦几句吧。 首先,CH_PD和REST要上拉,也就是通过1K~10K电阻接到3.3V。 其次,GPIO15要下拉,也就是通过电阻接到GND上。 烧录器的TX接到ESP8266的RXD引脚。 烧录器的RX接到ESP8266的TXD引脚。 (注意了,Tx要接Rx,Rx要接Tx,这个是常识,别Tx接Tx,Rx接Rx,还在QQ上反复追问我为什么?我又不是百度!!) 烧录器的电源也接到ESP8266上,注意要3.3V电,别5V电接过来。 GPIO0是烧录脚,也就是上电的时候,如果这个引脚悬空或者上拉,那么正常进入程序空间运行程序。如果这个引脚接地了,那么进入烧录模式,烧录器通过串口可以重新烧录里面的固件。 烧录ESP8266测试打开Arduino,选择一个自带的ESP8266的例子。 把代码往下拉,找到下面红框的代码,改成你家里的wifi的SSID和密码。 不改代码也行,反正我们就是看看能不能烧录固件而已。 打开“工具”,把开发板选得和我一样的。 当然,如果你不是12E的模块,你选 也行。 ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― 把你的ESP8266最小系统,接到烧录器上。4根线(3.3V,GND,Tx,Rx)别接错了。 按住GPIO0引脚上的微动开关,让GPIO0引脚接地,然后把烧录器插到电脑的USB接口上,松手就可以了,没必要一直按着。 最后点一下这个红框里的箭头,也就是上传按键。 大概会先花个半分钟编译固件, 只要代码没语法错误,基本就不会失败。 然后再花个半分钟烧录啥的。烧录时会有进度条显示。 到了100%就表示烧录好了。 如果显示错误信息,尝试把烧录器拔下来,按住烧录开关,重新插一次USB插口,再点上传按键。 要是你卡在这一步,呵呵,我也是爱莫能助了。 我写了这么多东西,任何一点错误都有可能导致你烧录失败,根本没法判断哪里出错了。也许你接线错了,也许你连烧录器的驱动都没安装,反正种种可能,你自己查吧。 做这种东西,掉各种坑里才是正常,一帆风顺非常罕见。细心很重要,耐心更重要。 在我写这篇教程前,我已经帮大家填平了很多坑了…… 我本人也掉过无数次的坑,常常有半夜忽然恍然大悟,然后爬起来填坑的经历。 正式焊接硬件上面的步骤都通过了,你可以进行下一步的工作了。否则焊了个硬件,没法烧录固件,岂不是浪费? 本来打算把我的焊接图拍下的,后来想想看算了,除非打板,否则洞洞板拍焊接图毫无意义,还容易误导大家。所以大家还是看原理图吧。另外,我建议大家全部的模块都用插座,这样以后拆起来也方便。你看我全部的模块都是用的插座,都不是直接焊死的。图上好像都被挡住了,反正我基本都用的插座…… 原理图 在文档里面,原理图不是很清晰,所以大家可以去看PDF版本的。 原理图看不明白,不知道怎么焊接实物的,我觉得你还是先打打基础比较好…… 我也是先画出原理图,才焊接的实物。 原理图的硬件很简单,一个ESP8266模块,一个DS18B20温度传感器,一个4.7K或者10K的上拉电阻,一个IIC接口的0.9英寸的OLED(这个可有可无,实时显示的,不影响数据上传云服务器),一个5V转3.3V的稳压芯片ASM1117 3.3。 如果考虑用18650锂电池供电,而非外接5V电源供电,还要考虑加上锂电池保护芯片和锂电池充电芯片,外加一个小开关。 为了简单,其实是偷懒,这里就不做电池供电的设计了。而且ESP模块,耗电量蛮大的,一块2200mAh的电池,我估计最多24小时就要没电……所以用电池,除了特殊场合的应用,真心不是啥好想法。 实测电流,居然只有80mA左右,还是在上传数据的时候,其它时间电流只有20mA左右。看来哪怕用充电宝供电,都可以坚持非常长的时间。 实测:用使用了好几年的5000mAh的充电宝供电,大概工作了56个小时。 看来以前用官方的AT命令固件,运算量蛮大的,造成非常耗电。 自己写的Arduino代码,没那么多功能,所以耗电量大大下降,真是意外之喜。 不过我建议用5V 手机充电器供电就可以了。 以前老式的塞班手机充电器,500~800mA的,家里还好几个,废物利用了。 下载传感器和OLED屏的库文件这里的内容实际应该放到软件环境搭建里面的,可是我忘了。 所以就放在这里吧。 Arduino的官方库里面,是没有常用传感器的库的,需要你去Git上下载。 当然,我帮你下载好了。你拷贝一下就OK了。 Arduino的库文件可以放到两个地方。 官方常用库的存放目录是:C:\\Program Files (x86)\\Arduino\\libraries 你可以把库文件的目录拷贝到这个文件夹下面。 实际上,第三方库文件的存放目录,一般是下面这个: 也就是操作系统“文档”目录下的“Arduino”目录下的” libraries”目录。 因为我安装的是克隆版的盗版Win7,所以文档被放到D盘了。 如果你是正版操作系统,这个文档应该在C盘下面。 反正不管怎么样,你随便选一个目录,把我们用到的传感器和OLED的库,拷贝进去,然后重启Arduino就可以了。 其实你也可以在Arduino的库管理器里面在线更新:(这个功能没有被屏蔽掉) 搜一下模块或者芯片的名字,基本都能找到现成的库,而且还不止一个,让你不知道用哪个好。 不过毕竟乱,我还是建议去Git里面搜,然后手工下载安装。 在GIT里面,有个adafruit的元件库,里面有3400多个元件库,我想你很难找不到你要的库了…… https://github.com/search?utf8=%E2%9C%93&q=adafruit&type= 而且这个adafruit的库,里面的底层代码写的都比较规范,我喜欢手工下载它的库,不想用其它人的库了。 有人可能不会在GIT里面下载东西,其实很简单。 看到绿色的按钮了吗?点开,点Download ZIP 就可以下载库的压缩包了。 下载的压缩包,你可以用Arduino的项目—加载库—添加一个.ZIP库,添加到库里面。 也可以把压缩包解压后,拷贝到上面说的两个库文件的目录之一下面,重启Arduino即可。 说句题外话: 比如我用温度传感器的库来读取温度,先包含一下库的头文件,定义一下引脚,然后新建一个传感器的类,最后几句代码就非常简单的实现了温度的读取。 DS18B20的底层代码,都封装成库了,用户根本不用关心底层怎么实现的,只要看看示例,复制一下代码就可以搞定。 我以前用51单片机,换个型号,底层代码的延时基本都要重新改过,并且一一测试,真是折腾死了。Arduino这种方式,简直太方便了,难怪会这么火。 如何看示例Arduino全部库里面基本都有示例代码。 示例代码可以非常快的帮助我们学会该种库的使用。 我以前常说,你不会写,你还不会抄吗? 示例代码就是让我们来抄的,其实我做的这个东西,全部的代码,有一大半都是我拼凑的各种示例代码修改来的。 要学Arduino,你必须知道怎么看示例。 其他的我不多说了。 如果你有心,可以把我们这个东西用到的各种模块的示例都测试一遍。 Arduino的代码,基本都带串口数据同步输出功能,右上角就是。 一直串口定义和数据打印非常方便,二是单片机资源丰富,不在乎串口哪点资源消耗。 不像51单片机那样,数据基本不会同步到串口输出,因为很占单片机的资源(增加固件大小,占用计算时间,占用定时器,破坏时序啥的)。 所以你可以通过串口,很轻松的看到输出的数据。当然注意程序定义的串口的波特率和你选择的波特率要一样。 注意程序里面定义的波特率和串口监视器的波特率要一样。 常用的波特率是9600和115200。 波特率的概念请自己去百度。不同波特率之间不能通信,或者通信数据会全部错误。 软件设计流程用Arduino自带的例子烧录过几次后,确认Esp8266的开发板可用后,我就打算修改我以前的项目,做个不用外置单片机的云传感器出来。 但是我这里还有几个问题需要解决,否则还是没法完成我这个项目。 1、用ESP8266模块读取DS18B20、DHT12、BMP280等传感器的数据。 通过下载各种传感器的开发库,用库自带的例子逐一读取数据 ,全部成功。我要做的就是把代码拼凑起来,同时要合理分配ESP8266少的可怜的几个IO口。 还要查阅ESP8266的官方文档,确定每个引脚的功能。 比如IIC用的SDA和SCL引脚,ESP8266是默认GPIO4和GPIO5引脚,别的引脚不能用。 2、温度、湿度、气压、PM25等数据,通过OLED显示出来。 主要是美观大方,不能简单的堆叠显示数据。 OLED的显示界面,我修改了好几次才满意。还加上了信号强度显示和数据上传成功次数显示。 PM25的数据,想通过EPS8266的ADC引脚读取,但是PM25模块比较大,接上去不美观,放弃了,以后有需要再接。而且ADC我测试,感觉精度不高,大概有0.1V的差距,不知道问题出在哪里,以后再研究。 3、简单的WIFI设置页面。 我需要一个简单web页面来设置ESP8266连接WIFI的SSID和密码。 还要设置上传数据的公网服务器的网址或者IP,还有它的端口。 我可不想再做2个APP(一个Android的,一个IOS的)来搞定这种事情。虽然我以前做过这种APP,但是我觉得这次要让ESP8266当Web服务器来搞定它。 网上和实例代码,都是在程序里面写死的,这个不符合我的要求。 百度了一个日本人的例子,里面用了Flash文件读写库来保存参数,非常有抄袭的价值。 本来打算用JSON代码来传递数据,他用的是Flash内存里面文件保存和读取方式来传输SSID和密码,也是没问题的,而且代码更简单。 当ESP8266上电时,3秒内按一下按键,则进入了WIFI设置模式。 ESP会变成AP,我们可以通过手机WIFI或者笔记本的WIFI看到它。 连上ESP的WIFI,密码是11111111,然后打开浏览器,输入192.168.4.1,则进入设置页面。 输入WIFI的SSID,密码,还有你服务器的网址,端口,点提交就Ok了。 当然,在执行这些操作的时候,我们的云传感器的OLED也要同步显示相同的信息。 照片我就不拍了。 4、数据上传服务器 既然是云传感器,那么数据肯定要上传到云服务器上的。 以前我是用AT命令连接云服务器的,现在AT命令没法用了,要自己写代码了。 这个好像更简单,Arduino自带的例子里面有实例,网上 的代码也很多,测试过以后没有问题,也搞定了。 当然,对我来说简单。 我们知道,HTTP协议里面,常见的两种方法:GET和POST。 GET常用来发送请求(Request)。当然它也可以带参数。 网页的地址常见到:http://xxxx.com?a1=10&a2=20&a3=30 这里就是一个GET,它还带了a1,a2,a3 三个参数。 Web服务器可以解析网址,从而把a1,a2,a3 的值保存到数据库里。 这种也是最简单的HTTP的数据上传方式。 但是也不保险,因为很容易就可以在网页里,通过构造网址,手工传一些错误数据进来。 如果你用AT命令或者代码上传数据的话, 你还要构造一个简单GET包,类似于下面: “GET “ + url + “ HTTP/1.1\\r\\n” + “Host: “ + host + “\\r\\n” + “User-Agent: BuildFailureDetectorESP8266\\r\\n” + “Connection: close\\r\\n\\r\\n” 具体的去百度吧,东西太多,没法讲。 这里User-Agent可以省略掉,不加也不影响服务器端的数据解析。 除了GET外,我们还可以构造POST包。 POST和GET的区别在于POST可以传输大量的数据,GET的传输的数据大小是有限制滴。 POST的网址后面也可以跟参数,还要跟一个data包。 然后Web服务器是数据解析方式也略有区别。 总体而言,GET简单,POST复杂点,GET不安全,POST安全点。 后面我会专门为GET和POST做个章节。这种东西,玩WIFI不能不掌握啊。 5、建立一个云网址 我需要一个云服务器来保存我的数据。还需要一个小网址来展示我的数据。 实际上这些内容很多,我放到后面来说。 当然,你也可以使用网上那些免费的云数据库,不过需要注册一个用户名,还要输入一个复杂的IDKey啥的,还要研究人家的数据上传协议。 我最讨厌约束,我想要有自己的云服务器,自己的协议,最简单的那种。 首先我要做一个小网站,这个网站的功能很简单,要解析云传感器发来的数据,并且保存到数据库里面。还能根据时间查询数据,数据要能下载为Excel文档,最好还要带一张酷炫点的曲线图表。 两种方案:1、Linux系统,MySQL5.7数据库,Java或者PHP编程或者Python啥的, Nginx或者Apache代理。 2、Windows2008系统,SqlServer2008数据库,.Net V4.0环境,IIS7.5代理啥的。 随便选一种吧,小网站,几个页面而已。我不想开虚拟机,所以果断方案2。 先下载安装一个VS2012,再安装一个SQLServer2008数据库,建一张简单的表。 你说你不会用数据库,也不建表?也看不懂表结构? 这里我不想多讲欸,跳过吧,后面我们用脚本建库就好了。哎,写到这里,我明显开始偷懒了。 VS2012做一个简单查询,图表之类的,用百度的开源图表Echarts。 http://echarts.baidu.com/ 不知道的可以去看看,做的不错,现在国内网站的图表,基本都是这个,很赞。 我们只要折线图,所以下载一个最小版本就可以了。 然后找个有类似图表的网站,查看网页源代码后,公然进行抄袭。 数据大家都是用Ajax进行传输,前台的代码基本一样,改改文字就行了。 它好像用的是Java,我用的.Net,不过没关系,后台代码我比它还简单。 建立一个 ,专门负责从数据库里面查询数据,然后发给前台的脚本,让前台的jQuery代码填充图表。 再建立一个 ,负责解析云传感器发来的数据,保存到SQLServer数据库里面。 具体的代码就不讲了,太多太多,没法讲……后面有时间我单开教程讲吧。最后你们自己去百度,看看怎么写小网站,怎么搭建网站,怎么玩数据库,怎么写SQL…… 可是大部分人都不想学这些,都只是想做个传感器而已…… 拥有自己的云其实我不缺公网服务器的,公司有几台闲置的公网服务器,我都可以拿来私用,但是没法给大家共享。所以,我要抛弃公司的服务器,和大家一起拥有自己的私有云。 先看看国内有哪家公司比较厚道,会给我们一个自己的云呢? 有钱鹅公司的理念一直是:不充钱,你怎么能变强呢? 有意思公司的理念一直是:充了钱,你也不一定能变强。 找不到公司的理念一直是:花了钱,你也不一定能治好病。 招财猫公司的理念一直是:花了钱,你也不一定能买到真的。 综合来说,只有去招财猫公司的网站找一下了。 首先,我们要购买一个自己的域名。域名最好也是免费的。 其次,我们要找一个免费的或者非常便宜的云服务器。 1、申请自己云服务器的域名。 先来到招财猫公司的网站: https://www.aliyun.com/ 随便注册一个用户名和密码,或者用你的招财猫账号和密码登录。 然后来到域名注册的地方 https://wanwang.aliyun.com/domain/searchresult/?keyword=fsdfds&suffix=.top 找一下 这种域名。 当然,com域名你是别想了,top和xin之类的还凑合。 .win是最便宜的,因为工信部到现在没法备案这种域名,所以还是换个别的吧。 我选择了 mysensor.top 也就是我的传感器,没人注册,1元拿下,哈哈。 可惜还要备案。经过漫长的审核和等待,20天的样子,终于备案成功了。。。。。 最坑爹的是,拍照片要购买招财猫公司的幕布,这个价格是15元,还不能退货。 到手后,我发现根本不是布,只是一张有招财猫字样的海报纸。 好吧,这是我买过最贵的海报了,果然你花了钱也不一定能买到真的…… 所谓的1元域名,最后要花16元…… 其他的基本就没花钱了,就是从申请到域名备案完成,等了大半个月。 在浙江,你的网站不仅要工信部备案,公安机关也要备案。具体方式看阿里的说明吧。 大家别忘了在自己的网站下面加备案的备案号啥的。 2、购买一个自己的云 经过仔细的查找,最便宜,性能最差劲的云服务器,1年的价格也要近300块钱 我有300块钱干嘛不好呢?云不能吃也不能喝,装B效果也非常有限。 好吧,云服务器方案取消,去买一个最便宜的网站空间吧。 最后6块钱买了个假云!! 申请云空间的时候,请选择 Windows2008系统,SqlServer2008数据库,IIS7.5,.net V4.0之类的环境。 不要选择Linux,MySQL之类的。不过后面也能随时更换好像。 https://cp.aliyun.com/login 看到6块钱了吧。 1年6块钱的云,你还想怎么样??想要真正的云服务器? 招财猫公司的理念再跟着我念一遍…… https://wanwang.aliyun.com/hosting/free?spm=0.0.0.0.xkJ5oL 200M网页空间+20M的数据库空间+10G的月流量。 我们只是存个云传感器数据而已,20M数据库空间大概够我们存20万条数据了,马马虎虎吧。 200M的网页空间根本用不了,能和数据库空间互换一下就好了…… 在线支付6元大洋后,我们就可以拥有了自己空间。 貌似还不错,各种环境都搭配好了,直接通过FTP把网页和数据库备份文件拷贝过去就可以了。 打开我的电脑,随便打开一个文件夹。然后在上面的地址栏里面输入 ftp://你的FTP地址/ 鼠标右键,选择 登录,输入用户名和密码,保存密码,省的每次都输入。 你说你不知道你的FTP地址?? 进https://cp.aliyun.com/login登录后,进入控制台页面,就可以看到你的FTP地址了。 密码啥的,你自己记牢了。 域名解析1、赶紧去备案你的域名。 当然你也可以不备案,一直用临时域名。比如,我的临时域名: 这个域名每隔4个小时,就要重新登录一下。不过通过GET方式上传数据不受影响。 2、域名解析。 在https://cp.aliyun.com的控制台,找到域名绑定。 其实这里不绑定也没啥关系应该,主要是找到你的云空间的站点地址。 比如,我的站点地址是:60.205.47.232 这里添加域名,把你刚才申请的域名给添加进去。 要添加2个,一个带”www.”,一个不带”www.”。 复制一下这个地址,然后去阿里云的域名解析那里,新建A记录。 先进https://www.aliyun.com/ 然后登录你注册域名的账户。 登录后,点一下上面的控制台。选择左边的“域名与网站(万网)”,进入“域名” 找到你的域名,然后点“解析”,进入域名解析。哎,我都不想写了。 这里对于新手来说,可以点一下新手引导设置啥的,或者直接加A记录。 所谓的A就是Adress,也就是地址的意思。 把刚才我们6块钱云空间的IP地址,复制进去。类似于我下面的图。 说个常识,域名是不带“www.”这个4个字符的。 比如我申请的域名是mysensor.top 而不是www.mysensor.top。 当然,你用上面2个都能访问我的网站。 因为我A记录里面,www和@我都添加过。否则你只能访问其中一个。 你要填加2个A记录,主机记录分边是@和www 好了,绑定好以后,你应该在几分钟后就能通过域名访问你的云了。 但是几个小时后,这个就会失效,因为你得备案。给你几个小时,只是让你验证一下域名解析是否好用而已。 备案请自己完成,比较繁琐。当然你也可以不备案,只用临时域名。 配置自己的云域名都配置好了,我们的云空间也要把网站搭建起来。 1、配置数据库 网站需要接入SQLServer2008数据库。 为了简单易用,数据库里面只有1张表,tbl_Data 进入我们的云主机控制台,https://cp.aliyun.com 选择“数据库信息” 最右边有个“管理”,进入数据库管理网页,著名的DMS。 数据库名字,后面有个:1433,表示端口号。 1433是SQLServer的默认端口,这里应该不用你做任何更改。 你输入用户名和密码就可以了。 先打开建表的SQL脚本文件, 先把USE [xxxxxx] 里面的xxxxx改成你的数据库的名字 也就是你的数据库的用户名后面加_db 然后点一下 把脚本复制到下面的空白处, 执行完成后,左边的数据库下面,就应该有1张表了,名字是tbl_Data 我截图里面有4张,是其他的测试库,这些都不用管。 表名字前的dbo表示的是表的拥有者是数据库的普通用户。 表tbl_Data就是我们的云传感器的数据表。 里面有7个字段,Id是流水号,也是主键。类型是int,也就是整数的意思。 这个Id的数值是自动增长的,是标志种子。 EspId是Esp8266模块的Mac地址,类型是可变字符,最多16个字符。 Temp是存放温度数据的字段,依然用可变字符类型存储,最多10个字符。 Humi是湿度,Pressure是气压,PM25就是PM2.5的数据,UpTime是上传时间,这个字段是依靠默认值getdate(),直接从数据库获取的,不需要自己填写。 数据库的种类非常多,常见的就是10几种吧。所以你有兴趣可以全部掌握。而且很多知识都是相通的。 最后要做的事情,就是修改网站配置文件里面数据库的信息。打开网页的目录,里面有个 ,用记事本打开。 里面有一段配置,你需要自己修改。 你要改4个地方: 数据库的地址: 把=后面的地址,改成你自己的。你的地址,在云空间的控制台哪里可以找到。 记得后面有个;,不要给删掉了。 数据库的名字: =后面就是数据库的名字,刚才我们说了半天了。 数据库的用户名: 数据库的密码: 把这些都修改好后,保存文本文件。 2、拷贝网站到云空间 把网页目录里面的东西,全部通过FTP,拷贝到你云空间下面。 我的FTP下面的文件非常多,很多其他的网页,我就不截全图了。 其他的一些设置,可以看看.net版本啥的,是不是4.0。 最后浏览器里面输入你的临时域名,看看能不能打开网站。 如果遇到上面的页面,输入FTP的用户名和FTP密码,4个小时内有效。 如果能看到下面的页面,就表示OK了。 当然,你如果没有备案啥的,下面的备案号之类的,你可以打开文件删掉。 也就是DataList.aspx文件里面,最下面的地方。 对了,别忘了你的云传感器,重新上电启动,启动的时候,按一下按键进入WIFI配置。 Host里面请填入你的临时域名。Port是80。 最后提交后,重启你的云传感器。 然后打开你的云网站,点一下开始查询。 如果有数据,那么恭喜你,你终于成功了。。。。。。 万里长征基本完成了。 因为我们的云只有20M的数据库空间,所以我只会保留最后20万条数据。其他的记录,都会自动删除。 可以用数据库的触发器删除,也可以加在网站的源代码里面。 为了方便大家,我还是加到源代码里面。基本的思路,就是每上传10000条记录,则调用SQL删除多余的数据。 这个教程是我2年多来,写的最累,也是最长的教程。 其实是个很简单的东西,ESP8266连WIFI,往云上传东西嘛。 教程写了这么多,还有很多的知识,都是一笔带过。可是我已经没法再详细了…… 大家能学到的知识依然很少,走马观花的看看而已。 浅雪 2017年8月5日星期六 GET和POST简介这里我简单说一下GET和POST的包结构。详细的说明你们自己去百度。 一个标准的GET包,基本就是下面这个样子的。 必须以GET开头,你不要写成Get、get之类的,大小写需要统一,不要自找麻烦。 因为根据相关规定,HTTP的方法,也就是GET、POST之类的是区分大小写。 剩下的那些Header,比如Accept、HOST、Connection之类的包括网站的地址啥的,都是不区分大小写的。 GET后面跟着的是相对地址和参数。 相对地址不说了,应该能看明白,就是网址的子目录或者其它文档。 参数这里详细说一下。 GET的作用,就是从服务器获取某些东西的意思。 你要获取哪些东西,是可以自己通过参数来制定的。 举个例子:GET /xxxx.html?stuid=abc&name=张三&class=一年级 HTTP/1.1 这里有3个参数,stuid,name,class,他们之间通过&符号分隔开。 第一个参数和相对地址之间,通过?分隔。 参数名称和参数值之间,通过=分隔。 HTTP/1.1和前面的参数,通过空格 来分割。 另外,GET后面的那堆东西,不是全部必须的,但是有些是不能省略的。比如我红线标出来的这些。 GET肯定是不能省略的,GET后面的参数也可以不要,但是 /必须要一个,这个是你要GET的路径。比如GET / HTTP/1.1,表示你要GET根目录下的默认文档。 HTTP/1.1是绝对不能省略的,它告诉服务器你们之间打算用HTTP/1.1通信协议。 Host也是绝对不能省略的,它是GET的对象的网址。这个也可以是一个IP地址。 Connection加不加都行,它的状态常用的有Close和Keep-Alive,也就是每次通信后,是否关闭连接或者保持连接。如果你不加,就让服务器自己看着办。 这里说个题外话,GET包的每行后面其实都有2个看不见的符号:/r/n ,也就是回车+换行。服务器也是根据/r/n来分隔每行的。 POST包的结构和GET基本相似 只不过把GET换成了POST,还多了2个东西:一个是Content-Length,这个是要发送的数据的字节长度。还一个就是要发送的数据,当然数据也可以不要。 你要发送的数据,可以是文本,也可以是文件、图片、视频啥的。 对于POST包来说,安全性比GET包更高一点。 你可以在网页上用手工构造一个GET包,但是你很难构造一个POST包。 我喜欢用GET,后面带一些参数,来上传数据。因为GET包比较简单。 当然,你也可以用POST,后面带一些参数来上传数据,基本和GET一样简单。 但是,最后还是把数据放到POST的数据包里。 数据包里面,你可以把你的数据,自由的组合。你可以用数据1,数据2,数据3…… 之类的方式,通过逗号来做分割符,服务器收到包后,把包转为字符串,然后在分割字符串。也可以通过JSON来处理,或者XML来处理。 JSON和XML不知道的,都自己去百度。服务器端要处理JSON或者XML数据,都要安装对应的插件,简单的数据,你也可以挑战自己的通过文本处理来解析,哈哈。 如果你以后用ESP8266模块做服务器处理JSON数据,那么尽量要使用ESP8266JSON之类的第三方库才行。 GET和POST实例说了那么多,不给例子的都是耍流氓。 我平常看学习文档,最恨那种没例子的,新手根本不知道怎么入门。 鉴于我们是使用ESP8266模块进行开发的,我这里用ESP8266模块自带的AT命令来给出例子。 如果你的ESP8266模块自己烧录了Arduino代码,那么里面的AT命令固件就被你覆盖掉了,所以你最好使用原装的模块,里面默认的固件都是AT命令固件。 这里最好使用转接板,要不USB转TTL烧录器,不太好接到ESP8266上去。 或者你花钱买那种转接板上自带ch340芯片的转接板,这样连烧录器都省掉了。 https://item.taobao.com/item.htm?spm=a1z0d.6639537.1997196601.33.7be0196r5S7P0&id=531515702108 这个玩意的正面带一个esp8266模块,反面就是ch340芯片和稳压芯片,还带一个烧录开关,反正做的挺全面的。 比那种5毛钱一个的单独转接板,要方便一点。不过我手头上很多esp8266模块了,还有好多烧录器,我也懒的买这种,不花冤枉钱。我用的是下面这种,就接4根线:3.3V,GND,RX,TX。 如果你打算买这种模块,最好买两个。一个用来做Arduino开发,一个用来测试AT命令。要不你烧录了Arduino的固件,里面有AT命令的固件就没了。当然你也可以重新从官方下载带AT的固件烧回去,不过就很麻烦了。 可能有人不懂啥叫AT命令,其实很简单,你也可以去百度一下: AT命令就是用标准串口来收发的指令集。它以”AT”开头,+命令,/r/n(回车换行符)结束。 这样,对设备的控制就大大简化了,转换成简单的串口数据通信了。 还很多设备都支持AT命令,不单单是ESP8266。比如常见的蓝牙串口模块。 当然,它们的指令都是AT开头,回车换行符结尾而已,中间的命令基本都不一样。 为了配合GET和POST的测试,我还要往我的云里面加一个测试页面,让大家更方便的测试。 首先呢,我先在VS2012里面新建一个没有显示页面的文档: test.ashx 然后里面判断一下请求的类型,再读取2个简单参数:id和name 如果请求是POST,那么再读取一下POST的data数据,把它转成字符串显示。 先用浏览器测试一下GET方式。 打开浏览器,在地址栏输入:mysensor.top/test.ashx 再输入2个参数: 为啥不加GET、HTTP/1.1和HOST之类的东西了呢,因为浏览器发送GET包的时候,会自动帮你补全的,你加了反而不对了。我们自己发包的时候,就要加这些东西了。 如果是POST怎么测试呢?找个在线测试工具 http://www.sojson.com/httpRequest/ 再看看返回值 这可以看到,在线POST测试工具,把参数也给当data发出来了。其实,data里面的东西和参数是互不干扰的。 下面我们用ESP8266模块+烧录器,通过AT命令和串口,来测试GET和POST。 首先你要准备一个USB转TTL的烧录器,推荐8块钱的那款,输出电流较大。 然后准备一个ESP8266模块,最好带转接板,杜邦针焊好。 接线方式很简单,不会的可以翻到上面“搭建ESP8266的最小环境”那里去看看。 这里我们要用到一个工具,串口助手。其实这个玩意并不好,只不过人都懒,能用就可以。不过这个小工具,虽然有各种小bug,也算是超值了,全国都在用。后来作者也更新了新版本,对应的功能和广告也更多了,我下载了但是也懒得去用新版本的。 把烧录器插到电脑上,驱动程序安装好,就可以打开串口助手了。 选择一下串口,ESP8266-12E模块的波特率默认是115200。 发送新行一定要打勾。 我前面说了,AT命令是以换行符来判断命令的结束的。 ESP8266的AT命令手册里面,有详细和全面的AT命令,这里我就不多说了。 我只说我们用到的几个。 首先看看你的ESP8266模块是否能正常工作。 输入:AT 然后点发送。 注意,命令后面不要有空格,否则会返回Error。 如果你能收到ESP8266的回应,说明你们模块正常工作,可以进行下一步的操作。 依次输入以下AT命令: AT+CWMODE=1 这个命令是把ESP模块设置为Station模式,也就是客户端模式。 AT+CWJAP=”SSID”,”password” 输入你家的WiFi的SSID和密码,让ESP8266模块能连上WIFI。 上面这2条命令,输一遍就可以了,它能够自动保存。 当连上WIFI后,你可以发送AT+CIFSR 来看看是否真的连上WIFI了。 当基本的设置完成后,我们就可以创建一个TCP的客户端,去发送GET命令了。 有人问,为啥要创建一个TCP的客户端啊 原因很简单,GET和POST只是网络封包的类型,你只有在客户端里面才能把它们发送到服务器端。 我们上面可以通过网页直接写GET,但是ESP8266模块里面,可放不下浏览器,只能自己构造包来发送。 依次输入 AT+CIPSTART=”TCP”,”mysensor.top”,80 和服务器建立TCP连接,服务器地址:mysensor.top,端口:80。 AT+CIPMODE=1 设置透传模式 AT+CIPSEND 开始发送数据 当你看到>符号的时候,就表示可以往服务器发送GET或者POST包啦。 先发一个GET包 GET /test.ashx?id=123456&name=xiaowang HTTP/1.1 点了发送,可是没收到返回数据。 没收到数据就是对的,应为你的包还没发完呢,继续发。 Host:mysensor.top 好了,一个最简单的GET包已经发好了。 可是告诉服务器我不发了,结束了,你可以给我返回数据了呢? 很简单,再发一个换行符就可以啦。 下面不要放任何东西,直接发送一个换行符。 看看我们收到的数据。 比用浏览器发GET,多了一大堆东西。浏览器会帮你过滤掉这些没用的东西,而直接给你显示数据。 发一个GET封包是不是很简单呢? 难者不会,会者不难。 我们再继续测试发POST包。 把刚才的GET包,稍微改一下。 我们先不发data,只发id和name两个参数看看。 POST /test.ashx?id=123456&name=xiaowang HTTP/1.1 Host:mysensor.top 因为对于POST包,数据长度必须要有,也就是data,因为我们这次不发data,所以长度为0。 Content-Length:0 再发一条空指令,表示发包结束。 再看看我们收到的数据。和GET基本一样。 现在我们把data加上,再看看结果。注意我的发送顺序。 POST /test.ashx?id=123456&name=xiaowang HTTP/1.1 Host:mysensor.top Content-Length:10 发送一条空语句 发送我们的data 1234567890 发送完data后,会立刻收到服务器发来的数据: 在这里,我们可以看到,data数据和参数id、name,并没有混到一起。 如果我不想让别人看到我的id和name,我完全可以把id和name放到data里面发送。 比如下面这样: POST /test.ashx HTTP/1.1 Host:mysensor.top Content-Length:15 发送新行 123456,xiaowang 这样,id和name就被塞到data里面发送了。别人看不到你的数据,也不知道你的数据格式,安全性就提高了。 而且data里面不仅可以放字符串,还能放图片,放文件,放很多东西…… 在我的Arduino代码里,我是用GET来传输数据给服务器的,因为这样做简单。 我也可以改成POST的,毕竟网上POST的例子不多。在Arduino里,需要自己建一个client,去连服务器。然后往client里面丢封包,和AT命令其实也差不多。 我看到一些免费的物联网,他们的POST协议,最后的data,是要组合成JSON的格式来存放数据的,都是一样的道理。","link":"/2017/08/11/217/"}],"tags":[{"name":"IT","slug":"IT","link":"/tags/IT/"},{"name":"Linux","slug":"Linux","link":"/tags/Linux/"},{"name":"miwifi","slug":"miwifi","link":"/tags/miwifi/"},{"name":"Date","slug":"Date","link":"/tags/Date/"},{"name":"折腾","slug":"折腾","link":"/tags/%E6%8A%98%E8%85%BE/"},{"name":"摄影","slug":"摄影","link":"/tags/%E6%91%84%E5%BD%B1/"},{"name":"行者笔记","slug":"行者笔记","link":"/tags/%E8%A1%8C%E8%80%85%E7%AC%94%E8%AE%B0/"},{"name":"Hexo","slug":"Hexo","link":"/tags/Hexo/"},{"name":"Friends","slug":"Friends","link":"/tags/Friends/"},{"name":"R.C","slug":"R-C","link":"/tags/R-C/"},{"name":"浅雪的DIY","slug":"浅雪的DIY","link":"/tags/%E6%B5%85%E9%9B%AA%E7%9A%84DIY/"},{"name":"Raspi/Orapi","slug":"Raspi-Orapi","link":"/tags/Raspi-Orapi/"},{"name":"Wordpress","slug":"Wordpress","link":"/tags/Wordpress/"}],"categories":[{"name":"uncategorized","slug":"uncategorized","link":"/categories/uncategorized/"}]}