用树莓派制作gif动画

1. 安装树莓派摄像头,得是官方的。

2.更新系统安装imagemagick软件包:

sudo apt-get -y install imagemagick

 

然后;

raspistill -w 800 -h 600 -t 10000 -tl 2000 -o image%02d.jpg
convert -delay 10 -loop 0 image*.jpg animateMe.gif

默认情况下,相机拍摄的分辨率为3280×2464像素,分辨率为72 ppi(p ixels p er inch )。这非常大,因此图像处理时间会更长。在Raspistill中,可以通过说明宽度和高度来调整图像的大小。

  • -w -h 用于将图像大小调整为800 x 600像素
  • -t 表示整个过程花费的总时间(以毫秒为单位)
  • -tl  拍照的频率
  • -o 输出文件名
  • image%02d.jpg自动为带有图像的照片命名,并在右侧为生成的计数器添加两个空格例如:

    • image00.jpg
    • image01.jpg
    • image02.jpg

如果您觉得可拍摄超过99张照片,则可以创建3个甚至4个空格,这样您就可以使用图像%03d.jpg图像%04d.jpg保存数千张图像

convert 是来自ImageMagick的命令。此行将所有已保存的jpeg带有图像前缀,并将它们转换为动画GIF,延迟(-delay)为10/100秒。

-loop 0 表示GIF将永远循环。

【DonkeyCar】学习笔记一

DonkeyCar,简称驴车,是无意中通过一个兄弟昊男得知的,是一款基于树莓派控制的人工智能小车,是一个开源项目,网上也有Donkeycar的相关说明,我们自发组织了一个驴车管委会,驴车的项目也在我和昊男的努力推进下base在github上,起名donkeydrift, 漂移驴车。

Donkey 是一个用Python编写的高级自驾车库。 官方这么说。

建立自己的Donkey2
Donkey2是大多数人首先建造的标准车型。零件价格约为250至300美元,需要2小时才能组装完成。以下是制造自己汽车的主要步骤:

  1. 组装硬件。
  2. 安装软件。
  3. 校准你的车。
  4. 开始驾驶。
  5. 训练自动驾驶仪。
  6. 试用模拟器。

我们就按照这个步骤来慢慢学习一下驴车的制作和调试的方法。

首先看看硬件方面:

概观

这些是2017年文章Make Magazine文章中的更新说明 。最新版本的软件安装说明在软件说明部分中进行了维护在制造汽车后务必遵循这些说明。

选择一辆车

共有4个完全支持的机箱全部采用“Exceed”品牌制造:

这些汽车电气特性相同,但有不同的轮胎,安装和其他细节。值得注意的是,Desert Monster,Short Course Truck和Blaze都需要可以轻松打印或从驴店购买的适配器。这些是标准的制造汽车,因为它们大多是即插即用,都有一个无刷电机,使训练更容易,他们外观比较粗糙,并且价格低廉。

“Donkey Pro”名称还支持3辆车。这些是1/10比例的汽车,这意味着它们更大,性能更好,而且稍贵。他们可以在这里找到: HobbyKing Trooper(非专业版)在这里找到 HobbyKing Mission-D 在这里找到 * Tamaya TT01或克隆 – 在全球范围内找到但通常必须作为工具包建造。另外两辆车已经准备好被批准了,但是这一辆车更难装配。

这是一个覆盖不同模型视频Donkey Pro模型还没有很好的文档记录,只有一个警告。

有关更多详细信息和其他选项,请点击以下链接:支持的汽车

驴

 

开动你自己的车

其实我们最想做的是自己的小车,通过自己DIY硬件和重构软件实现一个小产品,直接做成成品。

需要的零件:

选项1:通过官方驴商店购买

有两个官方商店:

如果您在美国,可以使用Donkey商店。Donkey Store的目的是让构建Donkey Car变得更容易,更便宜。驴店由驴车的原始创始人经营,利润用于资助驴车的开发。另外值得注意的是,Donkey商店的零件设计比标准版本略有改进,因为它使用的是最好的零件,这些零件只能大批量生产或者更难获得。Donkey Store构建与所有其他构建一样是开源的。

如果您在亚洲,香港的DIYRobocars社区也会在Robocar Store销售汽车用品他们是长期的驴社区成员,并使用收益来支持该项目的研发工作。值得注意的是,它们也可以出售给欧洲和美国,但成本效益可能较低。

部分说明 链接 近似成本
超过磁铁,沙漠怪物,火焰或短程卡车 见上面的链接 〜$ 90
带microUSB电缆的USB电池(任何能够提供2A 5V输出的电池都足够) Anker 6700毫安 $ 17
覆盆子3 amazon.com/gp/product/B01CD5VC92 $ 38
MicroSD卡(很多都可以使用,我喜欢这个,因为它很快启动) amazon.com/gp/product/B01HU3Q6F2 $ 18.99
驴部分工具包 [磁铁]](https://squareup.com/store/donkeycar/item/magnet-partial-kit)或Desert Monster,SCT,Blaze 89美元或99美元

选项2:自下而上构建

如果你想自己购买这些零件,想要定制你的驴子或住在美国,你可能想要选择底部装配。

部分说明 链接 近似成本
磁铁车或替代品 蓝色红色 $ 92
M2x6螺丝(4) 3.50美元*
M3x10螺丝(8) 黑色氧化物 7.89美元*
带microUSB电缆的USB电池(任何能够提供2A 5V输出的电池都足够) Anker 6700毫安 $ 17
覆盆子3 amazon.com/gp/product/B01CD5VC92 $ 38
MicroSD卡(很多都可以使用,我喜欢这个,因为它很快启动) amazon.com/gp/product/B01HU3Q6F2 $ 18.99
广角树莓Pi相机 amazon.com/gp/product/B00N1YJKFS $ 25
母头对母头跳线 amazon.com/gp/product/B010L30SE8 7美元*
伺服驱动器PCA 9685 amazon.com/gp/product/B014KTSMLA 12美元**
3D印刷防滚架和顶板。 购买:Donkey商店档案:thingiverse.com/thing : 2260575 $ 45

*如果很难找到这些组件,那就有一些摆动空间。您可以使用M2.2,m2.3或#4 SAE螺丝代替M2。可以使用#6 SAE螺钉代替M3。机械螺钉可用于夹紧。

**如果您可以等待15-45天的运输,可以从阿里快递购买此组件~2。

 

可选升级

  • 草帽帽子草帽帽子代替了伺服驱动器和USB电池,并可以在Donkeycar商店购买这里和视频的说明,可以发现在这里实施Sombrero帽子需要使用LiPo电池(见下文)。

宽边帽

  • LiPo电池和配件: LiPo电池具有明显更好的能量密度并具有更好的下降曲线。见下文(由Traxxas提供)。

驴

部分说明 链接 近似成本
LiPo电池 hobbyking.com/en_us/turnigy-1800mah-2s-20c-lipo-pack.htmlamazon.com/gp/product/B0072AERBE/ $ 8.94至$ 17
Lipo充电器(需要1小时为上述电池充电) amazon.com/gp/product/B00XU4ZR06 $ 13
Lipo电池盒(防止爆炸时造成损坏) amazon.com/gp/product/B00T01LLP8 $ 8

 

硬件

如果您从Donkey Car Store购买零件,请跳至步骤3。

第1步:打印部件

如果您没有3D打印机,可以从Donkey StoreShapeways3dHubs订购零件我用黑色PLA打印部件,层高2毫米,没有支撑。顶部翻车保护杆设计为颠倒印刷。请记住,除非你有“磁铁”,否则你需要打印适配器

我用黑色PLA印刷部件,层厚度为0.3毫米,喷嘴为0.5毫米,没有支撑。顶部翻车保护杆设计为颠倒印刷。

 

第2步:清理零件

几乎所有3D打印部件都需要清理。重新钻孔,清理多余的塑料。

驴

特别是,清理滚动条侧面的插槽,如下图所示:

驴

 

步骤3:组装顶板和滚动保持架

如果你有一个Exceed Short Course Truck,Blaze或Desert Monster观看此视频

将螺母滑入防滚架侧面的槽中。这不是特别容易。您可能需要再次清理孔并使用小螺丝刀将螺钉推入,使其与防滚架底部的孔对齐。

驴

将螺母滑入后,可以安装底板。再次,这可能是棘手的。我用小螺丝刀推动螺母,防止其在槽中旋转。好消息:你永远不应该再这样做了。

驴

 

第4步:将Servo Shield连接到Raspberry Pi。

注意:如果你有一个宽边帽,这是没有必要的,宽边帽只是插入Pi

将Raspberry Pi连接到底板后你可以做到这一点,我认为当它们放在工作台上时更容易看到它们。如下所示连接部件:

驴

作为参考,下面是Raspberry Pi Pinout供参考。您会注意到我们连接到3.3v,两个I2C引脚(SDA和SCL)和地:

驴

 

步骤5:将Raspberry Pi连接到3D打印底板。

在您开始之前,现在是插入已经闪存的SD卡并对电子设备进行台架测试的好时机。完成后,连接Raspberry Pi和Servo就像将螺钉穿过电路板进入顶板上的螺丝凸台一样简单。M2.5x12mm螺钉应该是通过电路板的完美长度,塑料和仍然有洗衣机的空间。螺钉的“帽”部分应朝上,螺母应位于顶板的底部。以太网和USB端口应朝前。这很重要,因为它可以让您访问SD卡并使相机带状电缆正常排列。

使用电缆扎带或尼龙搭扣将USB电池连接到印刷底板的下面。

驴

 

第6步:连接相机

有两个版本的驴机箱,较新的没有螺丝,较旧的一个。这包括两者的说明:

无螺丝设计 较新的设计非常简单,只需先将相机滑入插槽,电缆端即可。但是,请小心不要推动相机镜头,而是按下主板。![驴](../ assets / build_hardware / assemble camera.jpg)

如果您需要取下相机,则试图按下镜头,而不是按照这些图片所示推动连接器。
驴 驴

用螺丝设计

安装相机有点棘手,M2螺丝可以拧入塑料,但有点硬。我建议用1.5mm钻头(在英制刃中1/16位)钻出孔,然后用螺钉预先拧紧它们,然后再打开相机。只需要拧入两个螺钉即可。

有时使用两个顶部螺孔会导致短路。将螺钉放在底部的两个孔中。

在使用汽车之前,请从相机镜头上取下塑料薄膜。

驴

很容易以错误的方式放置相机电缆,因此请查看这些照片并确保电缆正确放入。如果您不熟悉youtube上有很多教程。

驴

 

第7步:把它们放在一起

请注意,如果您有沙漠怪物底盘,请参阅下面 的 7B部分。最后的步骤非常简单。首先将滚动条组件连接到汽车上。这是使用车辆附带的相同引脚完成的。

驴

第二次将伺服电缆连接到汽车上。油门电缆在伺服控制器上运行到通道0,转向是通道1。

驴

现在你已经完成了硬件!

步骤7b:连接适配器(仅限沙漠怪物)

沙漠怪物没有相同的设置将车身固定在车上,需要上面提到的两个适配器。要连接适配器,必须首先从机箱中卸下现有适配器,然后使用与此照片中所示相同的螺钉拧紧自定义适配器:

适配器

完成后。 等下一篇,软件介绍。

 

树莓派结合ADC做个光敏感应的灯

其实没有什么想法,就是想把ADC用熟练了,这些小案例都是自己杜撰的,实际上没有那么多场景需要用,但是最近真的用在了智能浇花设备上,土壤湿度采样的传感器是模拟的,所以,可以用ADC秀一波操作。

步骤1:从https://www.raspberrypi.org/downloads/下载最新镜像,然后选择Raspbian。

步骤2:烧录镜像然后启动树莓派。 

步骤3:通过在终端中键入以下命令连接到Internet并更新系统:

sudo apt-get update 

sudo apt-get upgrade

Step4:将所有东西连接在一起然后打开你的树莓派,不知道为啥网上给树莓派起名字叫覆盆子,太tm难听了。raspberry就改成树莓不行么?

手绘电路图,看懂了就过,看不懂就自己学习一下再过。

接驳示意图,ADC的AIN1 通道采样。 

中间抽头给树莓派,采集信号信息。

下面的内容就是开始编程了,如果你喜欢用C,那么就这样,写个源码:

#include <stdio.h>      //include  system standard io header file

#include <stdlib.h>     // include system standard libraries header file

#include <linux/i2c-dev.h>   //include  i2c-dev header file

#include <sys/ioctl.h>          // include ioctl  header file 

#include <fcntl.h>                // include fcntl header file

#include <wiringPi.h>  // It's very important when you control GPIO, wiringPi header file

void main()

{

         wiringPiSetup();   // initializing the wiringPi's function

         // Define the pin's mode ,pinMode(PIN, DIRECTION); PIN refer to the GPIO name in wPi when you typing "gpio readall" you can find out the pin's name, usring the wPi column's data, direction can be INPUT and OUTPUT and so on, more information please read the /usr/include/wiringPi.h file.

         pinMode(29, OUTPUT);  // Physical Pin = 40, name is GPIO.29 and wPi name is 29, BCM 21.

       // Create I2C bus
        int file;
        char *bus = "/dev/i2c-1";
        if ((file = open(bus, O_RDWR)) < 0)
            {
                  printf("Failed to open the bus. n");
                  exit(1);
             }
       // Get I2C device, ADS1115 I2C address is 0x48(72)
       ioctl(file, I2C_SLAVE, 0x48);

      // Select configuration register(0x01)
      // AINP = AIN0 and AINN = AIN1, +/- 2.048V
      // Continuous conversion mode, 128 SPS(0x84, 0x83)
       char config[3] = {0};
       config[0] = 0x01;
       config[1] = 0xD4;
       config[2] = 0x83;
       write(file, config, 3);
       sleep(1);

       // Read 2 bytes of data from register(0x00)
       // raw_adc msb, raw_adc lsb
       char reg[1] = {0x00};
       write(file, reg, 1);
       char data[2]={0};
       if(read(file, data, 2) != 2)
          {
                printf("Error : Input/Output Error n");
           }
       else
           {
        // Convert the data
               int raw_adc = (data[0] * 256 + data[1]);
               if (raw_adc > 32767) 

                 {
                       raw_adc -= 65535;
                  }

          // Output data to screen
                 printf("Analog Data is: %d n", raw_adc);
                 if ( raw_adc > 3200 )
                    {
                         printf("Turn on LEDn");
                         digitalWrite(29, LOW);  // turn on the LED 
                     }
                 else
                     {
                         printf("Turn off LEDn");
                         digitalWrite(29, HIGH);  //turn off the LED
                      }
             }

}

然后编译和测试:

gcc -o sensor   -lwiringPi  sensor.c 

注意:gcc是编译工具,-o表示定义输出文件名,-lwiringPi表示需要使用wiringPi的库来完成编译代码。

编译后,您将在工作目录中获得名为sensor的二进制文件。 

只需使用此命令执行它:

 

while true

do

     ./sensor 

done

如果你喜欢用python好吧,那么就更简单了。

直接用adafruit的ads1x15的代码改改就能用。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Jacky.Li
# License: Public Domain

# Import the time module.
import time

# Import the ADS1x15 module.
import Adafruit_ADS1x15

# import the OS module
import os


# Create an ADS1115 ADC (16-bit) instance.
adc = Adafruit_ADS1x15.ADS1115()

# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
# – 2/3 = +/-6.144V
# – 1 = +/-4.096V
# – 2 = +/-2.048V
# – 4 = +/-1.024V
# – 8 = +/-0.512V
# – 16 = +/-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
GAIN = 1

print('Reading ADS1115 values, press Ctrl-C to quit…')
# Main loop.
while True:
# Read all the ADC channel values in a list.
    values = [0]*4
    for i in range(4):
# Read the specified ADC channel using the previously set gain value.
        values[i] = adc.read_adc(i, gain=GAIN)
# Note you can also pass in an optional data_rate parameter that controls
# the ADC conversion time (in samples/second). Each chip has a different
# set of allowed data rate values, see datasheet Table 9 config register
# DR bit values.
#values[i] = adc.read_adc(i, gain=GAIN, data_rate=128)
# Each value will be a 12 or 16 bit signed integer value depending on the
# ADC (ADS1015 = 12-bit, ADS1115 = 16-bit).
# Print the ADC values.
    print(values[1]) # print analog data which detected via ADC's AIN1 port.

    if values[1] < 3000:
        os.system("gpio mode 29 out") # Change pin's direction as output.
        os.system("gpio write 29 1") # make pin 29 high level
    else:
        os.system("gpio mode 29 in") # Change pin's direction as input.
        os.system("gpio write 29 0") # make pin 29 low level
# Pause for half a second.

    time.sleep(0.25)

注意缩进。

运行看看效果;

python sensor.py 

嗯,就这样吧,开开脑洞就可以玩儿得更愉快。。哈哈, 白了个白~

 

 

树莓派ADC采样光敏电阻来做智能家居控制雏形

又是ADC,还是ADS1115的模块,16bit采样率,很适合做模拟采样。接驳方式:

原理图:

然后,刻录最新的raspbian镜像,可以从官方下载:https://www.raspberrypi.org/downloads/ 并将TF卡插回Raspberry Pi并打开电源。

请记住打开ssh服务并将你的Pi连接到互联网,以便我们可以下载并安装必要的软件包。

打开终端编辑一个文件:

sudo  vim.tiny   adc.c 

然后用下面的代码:

#include <stdio.h>                      // some header file, offer the function libs.

#include <stdlib.h>

#include <linux/i2c-dev.h>

#include <sys/ioctl.h>

#include <fcntl.h>

#include <unistd.h>        // very important, offer "read() and "write()" function

 

void main()               

{

    // Create I2C bus

    int file;

    char *bus = "/dev/i2c-1";   

    if ((file = open(bus, O_RDWR)) < 0)

    {

        printf("Failed to open the bus. n");

        exit(1);

    }

    // Get I2C device, ADS1115 I2C address is 0x48(72)

    ioctl(file, I2C_SLAVE, 0x48);

 

    // Select configuration register(0x01)

    // AINP = AIN1 and AINN = GND, +/- 2.048V

    // Continuous conversion mode, 128 SPS(0x84, 0x83)

    char config[3] = {0};

    config[0] = 0x01;

    config[1] = 0xD4;

    config[2] = 0x83;

    write(file, config, 3);

    sleep(1);

 

    // Read 2 bytes of data from register(0x00)

    // raw_adc msb, raw_adc lsb

    char reg[1] = {0x00};

    write(file, reg, 1);

    char data[2]={0};

    if(read(file, data, 2) != 2)

    {

        printf("Error : Input/Output Error n");

    }

    else

    {

        // Convert the data

        int raw_adc = (data[0] * 256 + data[1]);

        if (raw_adc > 32767)

        {

            raw_adc -= 65535;

        }

 

        // Output data to screen

        printf("Data: %d n", raw_adc);

       }


保存退出后编译:

gcc  -o adc  adc.c  -O3   &&  ./adc

执行后可以读取一次,用shell脚本简单调用一下,间隔0.2秒刷新,看看数据状态。

然后简单写个脚本检测抓拍并上传到我的博客后台的服务器,当然了,现在已经关闭了,怕不法分子看到乱上传东西,就这么个意思吧,你们理解了操作步骤就好。

然后把光敏电阻放在门夹缝的位置上,如果你没有回家,你家人没有回家,但是光敏电阻值发生了变化, 你就会收到一份邮件,拍到一个尝试盗窃的贼? 或者是一个不明飞行物?

有兴趣就试试看吧,白了个白~

 

 

树莓派通过ADC采样音量大小触发告警提示

有一个问题困扰我,当我制作视频时,如果被噪音干扰会导致失败,失败就得重新录,非常痛苦。

我想,如果有一个设备可以帮助我避免这个问题就好了,手里一堆很早以前买的树莓派,一堆。真的是一堆。

所以突然想到用ADC模块用语音传感器模块进行语音采样,然后通过调整阈值来显示文字或语音提示,让大家保持安静。 


首先,您需要这些组件来构建它。

1. Raspberry Pi 3B 或者3B+

2. 8GB Class 10 TF卡 

3. 5v / 2.5A电源 

4. 4CH 16位ADC For RPi (52pi.taobao.com有售)

5.面包板 没有就焊接~

6.语音传感器(模拟) 淘宝上几块钱可以买一堆。

7.大屏幕(电视机) 

8.跳线

步骤1:

下载最新Raspbian的镜像并将其刻录在TF卡上,建议用etcher这个工具,各种平台上都有它的安装包。

步骤2: 接线,语音采样的模块很便宜,所以基本上没有什么芯片在上面帮我做转换,但是我看到了比较器芯片,我这里不要数字信号,因为只有0和1的信号我无法判断音量的大小。

所以我选择了模块的模拟引脚,A0。 

然后因为AIN0 上面接了NTC,所以避开了AIN0 ,直接接在了AIN1 通道上面,就是黄色的线缆,然后供电用的是树莓派的3.3v, GND接树莓派。一切都很自然就搞定了。

当然为了方便展示我开专门插了一个0.91英寸的OLED,虽然这个项目里面没有用到。但是真的很好用,芯片就是ssd1306. 简单粗暴的很~

就像这样连接起来,上面有两个跳线帽,记得要接,一个是I2C地址的跳线帽,就是0x48的哪个, 还有一个是NTC接到AIN0通道的跳线帽,如果接通就可以通过NTC读取模拟的温度值了,实际上并不是温度,而是电压,要通过电压来进行换算的,后面再说这问题。

第3步:

将Raspberry Pi连接到互联网并更新软件,并安装名为“figlet”的软件, 当噪音等级的数量达到一个值的时候,它将被调出并显示“请TM安静!”,当然是显示在你的屏幕上,我觉得可以扩展的东西很多,可以加个超级功放, 然后搞个大功率的喇叭,提前录好声音,猛猛的一嗓子,直接让闹腾的家伙瞬间安静下来。

 

然后编写一个代码来采用adc:

编译一下:  

gcc -o adc adc.c

sudo cp adc  /bin/adc   为了方便使用,我就没有去修改PATH变量的内容,直接将编译出来的工具放在/bin下面了,方便我调用。

然后写个shell脚本,开机自动加载也比较方便。

vim.tiny  notify.sh

保存退出后,给文件执行权,然后测试一下。

chmod +x notify.sh

./notify.sh

对着麦克风来一嗓子,屏幕上应该是这样:

你还可以搞点儿别的什么,反正能够采集声音了,就达到了让树莓派采集ADC的消息的功能,非常方便弄别的项目,你可以自己看看,开开脑洞。

白了个白~

 

 

树莓派串口设置

最近总有人遇到树莓派串口通信的问题, 这里我简单说明一下。

Raspberry Pi和串口

默认情况下,Raspberry Pi的串行端口配置为用于控制台输入/输出。虽然如果您想使用串行端口登录,这虽然在调试时候很有用,但这意味着您无法在程序中使用串行端口。为了能够使用串行端口连接并与其他设备(例如Arduino)通信,需要禁用串行端口控制台登录。

不用说,您需要一些其他方式来登录Raspberry Pi,我们建议使用SSH链接通过网络上执行此操作

禁用串行端口登录

要启用自己使用的串行端口,需要禁用端口上的登录。有两个文件需要编辑

第一个和主要的是 /etc/inittab

此文件具有启用登录提示的命令,需要禁用此命令。编辑文件并移至文件末尾。你会看到类似的一行

T0:23:respawn:/ sbin / getty -L ttyAMA0 115200 vt100

通过在开头添加#字符来禁用它。保存文件。

#T0:23:respawn:/ sbin / getty -L ttyAMA0 115200 vt100

禁用启动信息

当Raspberry Pi启动时,所有启动信息都将发送到串行端口。禁用此启动信息是可选的,您可能希望保持启用状态,因为有时查看启动时发生的情况很有用。如果您在启动时连接了设备(即Arduino),它将通过串行端口接收此信息,因此由您决定是否存在此问题。

您可以通过编辑文件/boot /cmdline.txt 来禁用它。

该文件的内容如下所示

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

删除对ttyAMA0的所有引用(这是串行端口的名称)。该文件现在看起来像这样

dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

重启

为了启用您所做的更改,您需要重新启动Raspberry Pi

sudo shutdown -r now 或者sudo init 6

测试串口

测试串口的一个好方法是使用minicom程序。如果您没有安装此运行

sudo apt-get install minicom

使用适当的串行端口适配器和接线将PC连接到Raspberry Pi串口,然后在PC端打开Putty或类似的串行终端程序。使用9600波特的串行端口设置连接。

现在使用Raspberry Pi运行minicom

minicom -b 9600 -o -D /dev/ttyAMA0

输入minicom终端屏幕的内容应出现在串行PC终端上,反之亦然。

下面想接串口GPS就接上去使用好啦~

如果想用python去读取GPS信号,通过:

pip install pyserial 

然后编写文档:

import serial 

import time

 

ser = serial.Serial('/dev/ttyAMA0',  115200, timeout=2)

try:

    while True:

        if ser.is_open:

            data = ser.read(100)

            print(data)

except Exception as e:

    print(e)

当看到数据了再分析一下就好,时间不多了,我就简单说到这里。

白了个白~

记一次怼SB的感慨!

今天我是出来怼某些蠢货的~ 我个人博客我怎么写我乐意~

每次我谈论树莓派都会遇到几个啥也不是的东西跳出来瞎逼逼, 我个人从总体使用过程中来看我更倾向于使用3B+, 我很在乎那一点点儿性能的提升,虽然我遇到很多工程师都会跳出来反驳说NanoPi性能超越树莓派,orangePi超越树莓派,说各种Pi的能力都很强大,但是我就是喜欢树莓派,大概是树莓派是我使用的第一个pi的版本吧,交点儿情怀税哈~

但是我很快就发现我喜欢树莓派的原因了,是互联网上铺天盖地的树莓派资料应接不暇,Maker创建自己的DIY项目,学生用树莓派做毕业设计, 工程师用树莓派做自动化管理设备,网络工程师用树莓派做流量监控设备,黑客用树莓派hack无线网络,航模爱好者用树莓派做数传+图传,艺术家用树莓派打造自己的Magic Mirror, 音乐爱好者用树莓派制作自己的打击垫儿和效果器, 油头宅男用树莓派打造自己的家庭媒体中心,仓鼠党用树莓派打造自己的家用NAS, 还有科技大牛用树莓派建立自己的科学运算集群和超牛逼的机器人, 我的小伙伴还用树莓派结合tensorflow制作自动学习避障小车DonkeyCar, 游戏爱好者不断用树莓派制作游戏机,不管是手持的还是街机,都有它小众的市场,树莓派基金会最想看到的还是我们用它来学习编程, 教育孩子接触和学习,但是我们已经玩儿得停不下来了,哎,还有太多的好玩儿的项目数也数不过来,这么多资源,就算是我按照他们的想法全部玩儿一遍,也够玩儿数月时间了,总结下来,就是海量的资料漫天飞舞。

也许,这就是吸引我的原因之一吧,但谁又知道是不是一种情结呢?

身边的很多小伙伴都有树莓派,遇到我给我说的第一句话就是:我到底能拿树莓派做什么?

每次我都无法回答, 因为可能因为他不懂linux,不懂硬件,更不了解GPIO能做什么。难道大家的创意都被扼杀了吗?

身边的大牛们一次次过来PK我:“你这个东西为什么不用STM32做?”“ 你这个项目我用arduino就实现了!” “我觉得lattepanda做起来会更高性能!”“ 你这个树莓派弱爆了,我都用nanoPi 实现了!”“ 我觉得你这个项目用香蕉派会更好!” “我用ESP32也能实现和你一样的功能!” “你觉得树莓派到底比arduino好在哪里?” 

这时候他们的表情都是:

每次遇到这个问题,我都只好笑笑:"因为我不会其他的板子”,“因为我没有其他的开发板” “因为我不懂STM32”,“因为我懒”,最后直接统一回复:因为我愿意~” 从此整个世界安静了, 都不用手起刀落。

当时我的内心活动可能是这样的:

刚开始:yyi.jpg

我深知1万小时定律,东一榔头西一棒子我真的搞不定,来不及学精那么多东西,只能笨鸟慢点儿飞,移山慢点儿挖, 看不惯的都给我闭上你们的嘴,别让我出来给你一顿怼, 二营长,你他娘的意大利炮呢!?!

!!!!!!!

也就这样吧,心里默念:仁慈的主啊,快来收了这群SB吧~

利用shell脚本批量转换DTS文件到Stereo AC3

有些人可能会遇到一些带有DTS音轨的AVI电影。

有时我们不想将其保留为DTS。

不幸的是,为了提取和转换DTS音频,必须要烧一下大脑,因为LINUX中的A/V工具对这种格式不兼容,很不爽是不是?

这是我创建的一个脚本,用于翻录一堆AVI文件,DTS跟踪并自动将它们转换为Stereo AC3音轨。

将其复制/粘贴到文本文件并将其另存为“avidts2ac3”:

#!/bin/bash

#avidts2ac3 (extracts DTS tracks from video file and converts it to ac3)

#requirements: mplayer / ffmpeg

#variables
current_directory=$( pwd )
OUTPUT_AVI="output_avi.av" #'av' extension used to prevent filename conflict
OUTPUT_WAV="output_wav.wav"
OUTPUT_AC3="output_ac3.ac3"

#remove spaces
for i in *.avi; do mv "$i" `echo $i | tr ' ' '_'`; done > /dev/null 2>&1 &

#remove uppercase
for i in *.[Aa][Vv][Ii]; do mv "$i" `echo $i | tr '[A-Z]' '[a-z]'`; done > /dev/null 2>&1 &

#rip with Mencoder / encode with ffmpeg
for i in *.avi ; do nice -n 10 mencoder $i -oac pcm -ovc copy -o $OUTPUT_AVI && nice -n 10 ffmpeg -i $OUTPUT_AVI -acodec copy $OUTPUT_WAV && nice -n 10 ffmpeg -i $OUTPUT_WAV -ac 2 -ab 192 -ar 48000 $OUTPUT_AC3 && mv $OUTPUT_AC3 "`basename "$i"`.ac3" && rm $OUTPUT_WAV ;done

#Cleanup
rm $OUTPUT_AVI

exit;

您可能希望将其作为root复制到自己的环境变量PATH中去,这样使用命令就不用给绝对路径了。(/usr/bin或/urs/local/bin)

别忘了给它权限:chmod + rx avidts2ac3

然后将要转换的所有AVI影片放在一个目录中,并使用该目录中的脚本。

对于那些想要或需要了解它的机制的人来说,它是按照分步指南为您分解的:

DTS到AC3

1)在WAV PCM中转换电影中的音频:

nice -n 10 mencoder input_video.avi -oac pcm -ovc copy -o output_movie.avi

2)从新的AVI中提取WAV文件:

nice -n 10 ffmpeg -i output_movie.avi -acodec copy movie_audio.wav

3)将WAV转换为AC3立体声

nice-n 10 ffmpeg -i movie_audio.wav -ac 2 -ab 192 -ar 48000 audio.ac3

之后,您可以将mpeg2电影与新的AC3音轨复用

*请注意,一旦提取了WAV,你就可以将其转换为你喜欢的任何内容。

据说阿里云昨晚上又大面积故障了

早上起来发现朋友圈哀鸣遍野,仔细一看原来是阿里云大面积宕机了,吓得我赶紧起来看了看我的博客,好像还没有影响到…暗自庆幸!

看来阿里运维开年就知道年终奖已消失殆尽,今年的干劲儿也会受到影响吧?话说苦逼的运维一直是给开发背锅的….

凉凉….

 

 

 

 

 

 

树莓派Nintendo专用退出游戏按钮

小时候玩儿任天堂的游戏的时候,如果想退出游戏,直接按reset键就出来了,可以重新选择,可是我现在用的是retropie模拟任天堂,那么问题来了,如果要映射热键去跳出游戏,默认官方已经设置了select+start的热键是针对LR系列的模拟器,如果是LR系列的模拟器,这样一起按就可以退出游戏回到es界面,但是对于其他的模拟器:如DOSBox、Mupen64plus、DGen、PPSSPP、MAME4ALL、AdvanceMAME等其他非LR系列的模拟器,就不适用于RetroArch的的热键了,这时候要回到ES系統首页,就非常麻烦,所以就可以做一款通过硬件的reset回到ES首页的功能。

硬件需求:

——————-

1 x  非自锁开关1个

杜邦线若干

树莓派 2B/3B/3B+/3A+/zero /zero w 均可

1x 16GB class 10 SD卡

1x HDMI 线

1x 5v/2.5A电源

———————

然后,烧录好retropie系统,并且联网更新,打开ssh, 基本配置搞定了再来接下来的操作。

利用了GPIO的37 pin和39pin ,分别代表 GPIO26和GND

然后软件配置更简单:

1. ssh远程连接到树莓派。

2. 建立一个目录

sudo mkdir  scripts

cd scripts/

sudo touch ExitEmu.py

3. 编辑这个文件然后填写:

from time import sleep 

import os

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM) # 使用BCM的命名方式

GPIO.setup(26, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

 

def  exitEmulator(channel):

    print('exitEmulator')

   os.system('killall retroarch')

    pids = [pid for pid in os.listdir(‘/proc’) if  pid.isdigit() ]

    for pid in pids:

        try:

            commandpath = open(os.path.join('/proc', pid, 'cmdline'), 'rb').read()

             if commandpath[0:24] == '/opt/retropie/emulators/':

                 os.system('kill -QUIT %s'  %  pid)

                 print('kill -QUIT  %s'  %  pid) 

        except  IOError:

            continue

GPIO.add_event_detect(26, GPIO.RISING, callback=exitEmulator, bouncetime=500)

while True:

    sleep(10)

保存退出后直接执行测试一下:

sudo python ExitEmu.py

然后按下按钮,如果看到屏幕上出现: exitEmulator 及 retroarch两行字符串代表指令成功了。

接下来让它能够开机自动启动就好了。

直接编辑:/etc/rc.local,添加刚才的脚本。

sudo vim.tiny /etc/rc.local 

在exit 0之前填写:

sudo python  /home/pi/scripts/ExitEmu.py &   

然后保存退出后重启你的树莓派,就可以尝试使用你的按键了。是不是感觉非常方便呢?

 

参考:

*  https://forum.recalbox.com/topic/3504/emulator-exit-button-gpio/10

* https://www.element14.com/community/docs/DOC-78055/l/adding-a-shutdown-button-to-the-raspberry-pi-b

* https://learn.adafruit.com/retro-gaming-with-raspberry-pi/adding-controls-software?view=all

* https://www.reddit.com/r/raspberry_pi/comments/2yw4fn/finally_set_up_retropie_complete_with_a_gpio/

* http://raspberrypi.stackexchange.com/questions/40311/how-can-i-add-an-on-off-switch-to-my-raspberry-pi-2

 

 

 

Retropie汉化的方法

很多时候,新安装的retropie系统没有中文,很多玩家很郁闷,就各种吐槽,各种不爽,毕竟游戏还是要简单易懂的话看起来才舒服,所以打开了retropie的源码看了看,是因为内置的字体库不兼容导致的,所以安装字体,调整一下就可以显示中文了。

继续阅读Retropie汉化的方法

记一次坑爹的grub修复

公司的路由盘存放着共享的数据,年前老板最后离开公司的时候来了把硬关机,直接拔电源的那种硬, 过完年回来就发现路由盘死了,上面的seafile系统瘫痪了。

Tater不在,只好自己硬上,修呗,检查发现每次开机map device table都找不到,起初以为硬盘坏了,烧录了一个USB启动盘,用了个软件叫: https://rufus.ie/

自己下载,然后各种安装添加ppa仓库,安装boot-repair工具,完全不好用。后来同事找到一篇帖子,需要修复EFI。。。

步骤如下:

尝试 EFI shell环境启动

开机总是停留在这里:


一般情况下进入 efi shell 后会显示 Device mapping table, 有时候会出现磁盘的信息,就是fs0,当出现的时候说明识别出了硬盘,但是无法引导。

在shell下面键入:

reconnect -r 

重新连接控制器,出现成功后再执行map看看是否有磁盘列出来。

如果这样列出,就可以确认磁盘没有问题了,问题出现在grub上,由于设备是X86_64架构,而且又是用了EFI的启动模式,初步估计问题出在了grub-efi上。

Ubuntu U盘PE,大白菜修复盘~

利用烧录工具烧录Ubuntu16.04 镜像到U盘,软件已经上面提到,简单粗暴,还很小巧。

选择设备镜像文件然后选择U盘设备信息。

一路默认即可。

 

速度很快,也就几分钟就可以完成了,插到PPC上,按下F7, 这个很坑爹的操作尝试了好几次,才找到相应的启动选项:

   

通过USB启动后尝试检查设备是否有问题,能够挂载和读取设备内容说明没有问题。

检查了/boot分区的启动信息,看不出哪里出问题了,有点儿犹豫问题所在,决定还是重新构建grub信息。

这是检查了/etc/fstab文件系统挂载配置文件,没有啥问题,确认是grub的问题了。


再次重启,进入live CD,选择 Try Ubuntu without installing 进入Live OS。
进入系统后打开终端(快捷键Ctrl+Alt+T)这个是最常用的开终端的方式。

先来查看系统分区情况:

sudo fdisk -l  
sudo blkid  
df -Th  
这个系统2块硬盘 /dev/sda ,两个分区,/dev/sda1 为 EFI 分区,/dev/sda2 为系统分区, /dev/sdb1 是存储数据的分区。

为chroot做准备:

1. 挂载分区

sudo mount /dev/sda2 /mnt  
sudo mount /dev/sda1 /mnt/boot/efi

2. 挂载虚拟文件系统

系统上的/dev   /proc  /sys /run  /dev/pts 这些是常见的虚拟文件系统,可以通过循环直接挂载到目标位置。

for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt$i; done

3. chroot 切换系统根目录

sudo chroot /mnt

4. 最关键的部分-修复引导信息

apt-get update
apt-get -y install grub-efi
grub-install --target=x86_64-efi --efi-directory=/boot/efi
update-grub

--target 指定系统结构
--efi-directory 指定 EFI 分区挂载点

update-grub 更新grub信息

Grub重新安装后,重启:

成功登陆,心里就想骂,这个EFI好鸡肋。

帮助参考文献

https://help.ubuntu.com/community/Grub2/Installing#via_ChRoot

转载记得标明出处,你妹的,打字很累的。白了个白。

STM32学习笔记1-操作GPIO

0x01 初始化GPIO

使用HAL库的优点在于不用手动添加初始化的代码了,CubeMX会根据软件设置自动生成。

自动生成的HAL库GPIO初始化代码:


/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  ** This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * COPYRIGHT(c) 2019 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ——————————————————————*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ———————————————————*/
IWDG_HandleTypeDef hiwdg;

/* USER CODE BEGIN PV */
/* Private variables ———————————————————*/

/* USER CODE END PV */

/* Private function prototypes ———————————————–*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_IWDG_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes ———————————————–*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  *
  * @retval None
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration———————————————————-*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_IWDG_Init();
  /* USER CODE BEGIN 2 */
    
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); 
    HAL_Delay(500);
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* IWDG init function */
static void MX_IWDG_Init(void)
{

  hiwdg.Instance = IWDG;
  hiwdg.Init.Prescaler = IWDG_PRESCALER_4;
  hiwdg.Init.Window = 4095;
  hiwdg.Init.Reload = 4095;
  if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : LED1_Pin */
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void _Error_Handler(char *file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)

  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
 

其中在while(1)中的这段:

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
    HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); 
    HAL_Delay(500);

就是类似digitalWrite函数的操作。

这里操作的模块是stm32f051c8t6的小模块,先点个灯测试一下,烧录上传后就看到效果了。

这里使用的是HAL库,其实还有更底层的LL库,更加清晰直观。 后面再尝试。

新西兰之行

先来一张我在huka falls 拍的大头照吧!哈哈!适逢当地圣诞节来临之际的大狂欢,蹭了一点儿热度.

这个就是新西兰靠近奥克兰的huka falls,湖卡瀑布.我也不知道是不是这个湖卡,原名给你们了自己查.

出了湖卡瀑布,我们就去了汉密尔顿国家公园,这里终于有机会飞无人机了,但是还是因为我们停留时间太短而放弃飞行…因为新到手的无人机还真tm不太会飞.

路边的随意拍摄的小房子,呸,是小别墅!据说便宜的地方50万纽币就可以买下来了!

一路的蓝天白云让我突然觉得这个资本主义国家的天空也不尽然是全阴霾密布的,乌云过去还是有蓝天的,至少水是纯净的,天空是蓝色的,空气是清新的,通透的感觉,深呼吸都觉得是放纵自己,猛吸一口觉得要醉氧。我突然觉得我爱上了这个世界上偏远的南半球小国,至少爱上了这里的草原,如果未来爱上一匹野马,在这里是真的不怕没有草原,听导游说如果买了房子可以拥有这里999年的居住权,就觉得自己费尽心思在上海买的这套40年商住简直是鸡肋中的鸡肋!

虽然已经旅途过半,而且这次还没看到毛利战舞,没有喝到当地鲜醇爽口的啤酒,但是已经被这里的人文环境深深影响了..

还有美美的老婆陪着我,还是很开心哒!

l路边吃点儿汉堡

也许应该去这家

大家还是去了一家看上去人气稍微旺点儿的地方.随后就是一路颠簸来到霍比屯..

老婆很幸福的拿起了我的单反

被她姐姐抢了先,手机拍出了大片的效果…

这也是..

.

她自己这张是老姨夫的华为荣耀拍摄的…是不是活捉一个精灵?

转眼就踏上飞往皇后镇的飞机了…

说实话,我手机拍摄的照片太少,单反里面的照片还有43Gb,等我整理出来再展示出来吧!

今天又到周末了

讲真的,我有点儿感觉吃力了,太多的开发板要尝试,太多的文档要写,太多的想法要去实现,我还要赚钱,养家, 要为了孩子做准备。。妈蛋,鸭梨山大思密达!
时间如流水,钱财如粪土!
我要继续赚更多的粪土才能养育我播种的这片土地。。。
我的瓦利机器人要继续做起来了,我的烂尾项目都要好好的开始收尾了,不能再拖了~