12月 29

手工打造自己的备份服务器

  习惯经常备份,但是总用移动硬盘也不是很方便,有些问题要在线同步会比较方便,放到公共云觉得安全不靠谱,几百G当下来网速也是问题。决定自己用pcduino打造一下。东西配齐。
image
  L型贴片的孔太小,要改成M3的。出师不利,电钻打到手上,指纹都没有了,如果不是带着防割手套估计一下就废了,只能缠上创可贴接着干。以后一定要用台钳,带护目镜,真是太危险了。
image
  安装pcduino的底座制作完毕。
image
  两侧板子搞定,缺角的为右边的。
image
  安装pcduino和两侧板子
image
  安装好硬盘,系统安装完成。
image
  侧片来一张,还留了一个硬盘的位置,将来在买一个硬盘。用rsync打造成双盘镜像(从arm的性能考虑就不使用软raid了)。
image
  在路由器上配个固定IP,对外共享一下。开机远程SSH登陆,在media下已经可以看到有硬盘加载了。以后HDIM连在电视上配个红外接收,自己开发机顶盒了。搞定收工、制手。

12月 04

python和C统计jpeg图片RGB值的效率

  测试硬件pcduino(arm),操作系统ubuntu 3.4.29+ armv7l GNU/Linux。测试文件,图片jpeg,大约1.3M。测试内容统计图片的RGB里的值,存在数据库里将来看看能不能做搜索用。
  先是用python,开发速度非常快,但是效率有点问题,所以有用C做了一下。以下是代码和两次的测试结果。C使用的jpeglib库8.0版本。

python代码

#!/bin/python
#-*- coding:utf-8 -*-
# Filename:   
# Revision:    1.0
# Date:        2013-12-04
# Author:      simonzhang
# web:         www.simonzhang.net
# Email:       simon-zzm@163.com
### END INIT INFO
from PIL import Image
# 对RGB简历字典
R = {}
G = {}
B = {}
# 初始化值
for i in xrange(256):
    R[i] = 0
    G[i] = 0
    B[i] = 0
# 大图片需要处理很长时间,所以要用python可以按比例将图缩小
a = Image.open('123.jpg')
#a = a.resize((int(a.size[0] * 0.1), int(a.size[1] * 0.1)), Image.ANTIALIAS)
x = a.size[0]
y = a.size[1]

# 循环处理每个像素点的RGB值
for lx in xrange(x):
    for ly in xrange(y):
        rgb = a.getpixel((lx, ly))
        R[rgb[0]] += 1
        G[rgb[1]] += 1
        B[rgb[2]] += 1
# 打印最终结果
print sorted(R.items(), key=lambda R:R[1],reverse=True)[0]
print sorted(G.items(), key=lambda G:G[1],reverse=True)[0]
print sorted(B.items(), key=lambda B:B[1],reverse=True)[0] 

C代码

/*
*Filename:   
* Revision:    1.0
* Date:        2013-12-04
* Author:      simonzhang
* web:         www.simonzhang.net
* Email:       simon-zzm@163.com
*/
#include 
#include 
#include 

/* we will be using this uninitialized pointer later to store raw, uncompressd image */
//unsigned char *raw_image = NULL;
/* */
int max_num;

/* find max values*/
int sort_values(int arr[255])
{
    int largest1, largest2, temp;
    max_num = 0;
    largest1 = arr[0];
    largest2 = arr[1];
    if (largest1 < largest2)
    {
        temp = largest1;
        largest1 = largest2;
        largest2 = temp;
    }
    int i;
    for (i = 2; i < 255; i++)
    {
        if (arr[i] >= largest1)
        {
            largest2 = largest1;
            largest1 = arr[i];
            max_num = i;
        }
        else if (arr[i] > largest2)
        {
            largest2 = arr[i];
        }
    }
    return largest1;
}


read_jpeg_file(char *filename)
{
    /* these are standard libjpeg structures for reading(decompression) */
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    /* libjpeg data structure for storing one row, that is, scanline of an image */
    JSAMPROW row_pointer[1];
    FILE *infile = fopen( filename, "rb" );
    unsigned long location = 0;
    int i = 0;
    if ( !infile )
    {
        printf("Error opening jpeg file %s\n!", filename );
        return -1;
    }
    /* here we set up the standard libjpeg error handler */
    cinfo.err = jpeg_std_error( &jerr );
    /* setup decompression process and source, then read JPEG header */
    jpeg_create_decompress( &cinfo );
    /* this makes the library read from infile */
    jpeg_stdio_src( &cinfo, infile );
    /* reading the image header which contains image information */
    jpeg_read_header( &cinfo, TRUE );
    /* Uncomment the following to output image information, if needed. */
    /* Start decompression jpeg here */
    jpeg_start_decompress( &cinfo );
    /* allocate memory to hold the uncompressed image */
    //raw_image = (unsigned char*)malloc( cinfo.output_width*cinfo.output_height*cinfo.num_components );
    /* now actually read the jpeg into the raw buffer */
    row_pointer[0] = (unsigned char *)malloc( cinfo.output_width*cinfo.num_components );
    /* read one scan line at a time */
    int r[255], g[255], b[255];
    for(i=0;i<255;i++)
    {
        r[i] = 0;
        g[i] = 0;
        b[i] = 0;
    }
    while( cinfo.output_scanline < cinfo.image_height )
    {
        jpeg_read_scanlines( &cinfo, row_pointer, 1 );
        for( i=0; i

先是测试python部分
#time python countrgb.py

(12, 510858)
(17, 429677)
(9, 662996)

real 11m4.009s
user 10m42.200s
sys 0m1.090s

开始测试C的部分
首先优化编译一下
#gcc countrgb.c -l jpeg -O3 -o countrgb
#time ./countrgb 123.jpg
12,510858
17,429677
9,662996

real 0m0.750s
user 0m0.730s
sys 0m0.010s

  两次统计结果相同,说明统计方法没有问题。python用了11分钟,C用了0.75秒,看来真的不是一般的快了。C代码编译后的文件8K,静态编译500多K。不过我是喜欢用python,开发速度快,结构清晰。

7月 28

51单片机 超声波测距测试

我使用51单片机,超声波模块是hc-sr04。以前在raspberry上用python测的,这次因为需要转到51单片机上,所以用C语言重写,原理上基本一致。

#include 
#include 
typedef unsigned char uchar;
typedef unsigned int  uint;	
  

// 测试距离
uint S;
// 非中断用计时计数器
uint hcsr_count;
sbit Led = P1^5;
sbit Trig = P1^1;
sbit ECHO =P1^2;
sbit Led4 = P1^4;


// 超声波给20us的高电平
void delay_20us()
{
	uchar bt ;
	for(bt=0;bt<4;bt++);
}

main()
{
	uint count;
	uchar us50;
	Led = 0;
	Led4 = 0;
	Trig = 0;
	ECHO = 0;
	while(1)
	{
		hcsr_count = 0;
		// 开始20us的搞电平
		Trig = 1;
		delay_20us();
		Trig = 0;
		count = 0;
		//等待Echo回波引脚变高电平
		while(ECHO ==0 )  
		{
			_nop_();
		}
		// 开始接收
		while(ECHO == 1 )
		{
			for(us50=0;us50<10;us50++);
			hcsr_count++;
			// 如果获得范围大于两米
			// 则强制返回值
			if (hcsr_count >= 2357)
				ECHO = 1;
		}
		//算出来是CM。1.7 出处。 
		// 在空气中传播速度34000cm/s。
		// hcsr_count每次计数时间约为0.00005秒,既1/20000秒
		// 34000cm/s * (1/20000)s = 1.7cm/s
		// 统计出的为往返路程,除2后为单程
		S = (hcsr_count*1.7)/2;     //算出来是CM
		if(S < 20)
		{
			Led = 1;
		}																												   
		else if(S > 21)
		{
			Led = 0;
		}
	}
}

超声波测距源码

5月 17

iptables 允许苹果推送服务

  业务上要给苹果设备做推送,所以服务器要连接苹果的推送服务器。因为服务器启动了iptables防火墙所以请求被拦截了,需要开通。

苹果服务器使用2195端口,我的防火墙对于出的流量是没有限制的。所以iptables添加
#apple push message
iptables -A INPUT -p tcp –sport 2195 -j ACCEPT

  用telnet测试连接成功,然后程序测试成功。
# telnet gateway.sandbox.push.apple.com 2195

  有的是说2196也是,最好也加上。