玩了下SproutCore

照着文档做了个hello world,运行起来后发现这货完全是浏览器本地运行,压根儿没有服务器的请求。嗯,这下是标准的HTML5了吧。

一个静态的本地应用有什么用呢?有人也有这种疑惑:没有服务器段那如何和数据库打交道呢?如果还是要调用Rails,那表明这个框架只能算上半个。

所以把这东西当作一个C-S的框架比如Swing来看就容易明白了。或者更直接点:它就是为手机上的移动web应用准备的,这个应用可以是http的web应用,也可以是本地的js+css应用。

作为一个C-S框架,比web应用要更关注界面中组件之间的交互,事件绑定和数据绑定是要优先考虑的,而这也是SproutCore的强处。

如果用它通过REST直接连CouchDB之类的文档数据库,倒是一个好的组合。

另外由于HTML5已经足够强大,比如图形和拖放,所以完全可以用javascript来写些“本地”应用。你可能说Swing和Gtk之流已经很成熟了呀?但答案是:HTML5是标准。

所以我关心的一点是SproutCore的模版语言仿佛走上了java JSTL的老路子:

{{#collection SC.TemplateCollectionView contentBinding="Todos.todoListController"}}}
   {{view Todos.MarkDoneView}}
{{/collection}}

又是XML,极端难看啊。如果页面要微调,肿么半呢?

准备用Arduino了

这些天做测速器,卡住了,很郁闷。

具体情况是Attiny45的external interrupt有些妖,我明明设置了只有pin4可以响应pin change,结果pin3,pin4都可以响应。在中断程序中我要读取计时器来确定pin change响应间隔,结果值一直为0,设为violate也无用。另外USB也时不时的断线,有时候断后要过一会才能连接上(电容的缘故么?)。看来系统不稳定,最怕这种事情。唯一确认的是pin change可以捕捉到,调试的LED也是有频率的闪动。想调试吧,软件USB不可靠,UART接口attiny45没有,手头有个atmega8l,阵脚多,有uart口,兴匆匆在taobao上买了个uart-usb转接口,焊好后发现这芯居然没有pin change中断,悲剧啊。

中断在这里用的很合适,attiny45也有很多用在工业马达控制上的,就是新手难以驾驭啊。

一直在关注Arduion,用的也是avr方案,而且封装的不是很厉害,有点avr经验的就会发现好多东西是一样的。比如这里测速的话直接用pulseIn方法,返回就是时间,也不用操作寄存器,多简单,去tmd的中断。

Arduion用的语言跟C极为相似,我怀疑是不是就是几个宏而已。当然,操作也简化了很多,函数库有具体含义的方法名,比操作神马DDRB更明了。如果这种语言能翻译成C代码就好了,这样菜鸟可以学习,也好用到成品中去。

taobao上买了个国产的,88¥,比意大利产200¥便宜,当然YY度也少了。玩单片机后发现这东西折腾起来花不了多少钱,不像电脑硬件,一个普通的显卡就得1000¥。富玩表,穷玩车,宅男玩电脑,我看这些都是穷人玩不起的。我单片机100个电阻2¥,谁比我便宜啊?搞错了、搞坏了也不纠结不后悔,扔掉再买,哥不差钱。

其实最好折腾的是软件……好吧,再说。

新的点灯程序

昨天看了下《嵌入式C编程与atmel avr》后,立刻照着上面做了个程序,没想到一次成功,哈哈。(这本书还是不错,老外写的,可惜现在已经买不到了,我看的是扫描版。)

这个程序主要是演示中断和计数器,目的让LED灯每隔大概半秒闪一次。

#define LED_PORT_DDR        DDRB
#define LED_PORT_OUTPUT     PORTB
#define LED_BIT             0
unsigned int timecount = 0;

ISR(TIM0_OVF_vect) {
	TCNT0 =0;
	if(++timecount == 31){
		LED_PORT_OUTPUT ^= _BV(LED_BIT);//toggle
		timecount = 0; //reset
	}
}

int __attribute__((noreturn)) main(void)
{
uchar   i;

    wdt_enable(WDTO_1S);
    odDebugInit();
    DBG1(0x00, 0, 0);       /* debug output: main starts */
    usbInit();
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
    i = 0;
    while(--i){             /* fake USB disconnect for > 250 ms */
        wdt_reset();
        _delay_ms(1);
    }
    usbDeviceConnect();
    LED_PORT_DDR |= _BV(LED_BIT);   /* make the LED bit an output */
    // 1:1024 presc.
    TCCR0B = 0x05;
    TCNT0 =0;
    TIMSK= 1 << TOIE0; //unmark Timer 0 overflow interrup

    sei();
    DBG1(0x01, 0, 0);       /* debug output: main loop starts */
    for(;;){                 /* main event loop */
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
        wdt_reset();
        usbPoll();
    }
}

解释如下:

  1. AVR-GCC里面中断用推荐用宏ISR,老的代码用SIGNAL。
  2. attiny45的频率为16.5MHZ,这个频率对于半秒来说太快,所以要用prescaler来降低计数的节拍频率,最小的是原来的频率的1/1024,16.5Mhz / 1024 = 15.625KHZ。上面的设置TCCR0B就是这个用途。这样系统每滴答一次需要1/15.625khz = 64 微秒,计数器为8位,所以滴答256次后就异常了,而这个异常代码是能捕获的,所以能捕获到的最小的计时单位为:64 * 256微秒 = 16 毫秒, 这个离500毫秒还有段距离,所以要用一个全局变量timeout,当timeout递增到31次时,大概就是500毫秒了。这个时候就可以点灯了。
  3. 接下来就要打开中断了,TIMSK这句就是enable Time0的溢出中断。
  4. TCCR0A是用来设置PWM的,要设置prescaler需要用TCCR0B。

数据达到最大值而产生的异常在单片机里面成了一个有实际用途的中断,这种思路真是很奇特。如果一个单片机的中断越多,那么功能也越强大,因为代码能相应更多的事件,而且代码也更清晰。有点类似观察者模式。

接下来做的事情就是测风扇的转速(RPM),思路应该差不多。外行搞单片机还是循序渐进好,首先要有个能够work的东东,不管这个东东有多么小。然后开始滚。 

DIY苹果蓝牙

介绍下:这个是参考网上例子做的一个PC机上的苹果蓝牙无线一体的适配器。这个蓝牙本来笔记本上用的,放到PC上来就要做些调整。主要调整就是把USB的5V电压转成其需要的3.3V电压,上面的三脚贴片就是转换电压的。但是最难的还是布线上面,一则蓝牙的数据线是扁平的接口,比较难弄,二则板上的USB口不好固定。感觉如果不重新印刷电路板要做最后的成品干净利落是很难的。

为搞这个东西前后损失了4个蓝牙适配器。掩面。东西太小,手太糙。

 

 

 

Tagged