最近刚刚参加完校招并成功签约,在公司的签约会午餐上和人正吹着逼呢,老前辈们说让我们自我介绍一下。这一下可不得了,一桌6个应届生,除了我以外的5个人都是全国电子大赛获奖者,还有拿了一等奖马上要去人民大会堂领奖的,我的内心:???怎么办???!!!要怎么才能不被人发现我是个FW???
所以我很急,马上要上班了,同志们都这么恐怖,我能咋办?为了参加工作之后尽可能地被少几个人发现我是FW的这个事实,我觉得有必要自我加强一下,随便学点东西,所以想到了玩下硬件。上学的时候接触过不少开发板,想了一下自己学的话,为了基础能扎实一点,经济压力能小一点,想了想还是从Arduino入手吧,于是果断淘宝买了一组开发板和器件,从零开始学习硬件开发。
首先先了解一下Arduino的功能和硬件实现:
Arduino Uno引脚分配和定义
Arduino硬件设计解析
了解得差不多了之后,板子也刚好到了,直接上手做做实验,Arduino的开发可以使用官方的Arduino IDE或者是图形编程软件mBLOCK或Mixly(米思奇),第一回上手,先试试Arduino IDE。以前在学校用Arduino设计过婴幼儿用智能腰带,所以上手还是比较快的,先试着Hello Arduino一下:
void setup() {
// put your setup code here, to run once:
Serial.begin(19200);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("Hello Arduino");
delay(1000);
}
结果:
在这里我发现delay出来的1000ms并不是严格的1000ms,粗略估计误差在2%以内,上网找了一下资料,最详细的可能是这一条(这是对microbit的误差解释,我想对于arduino应该原理上是大同小异的):
单片机电子时钟利用内部定时,计数器溢出产生中断(12MHz晶振一般为50ms)再乘以相应的倍率,来实现秒、分、时的转换。从定时,计数器产生中断请求到响应中断,需要3_8个机器周期。定时中断子程序中的数据人栈和重装定时,计数器的初值还需要占用数个机器周期。此外。从中断人口转到中断子程序也要占用一定的机器周期。在编程时的库一般会把平均值6个机器周期加入定时/计数器的初值中。但是,从定时,计数器溢出中断请求到执行中断需要几个机器周期(3~8个机器周期)。就很难确定准确值,正是这一原因导致了电子时钟计时的不准。解决方案比较难,需要修改固件,同时每块板子都不一样,首先换高精度晶振,然后从程序人手,采用动态同步修正方法给定时,计数器赋初值。动态同步修正方法如下:由于定时,计数器溢出后,又会从O开始自动加数,故在给定时/计数器再次赋值前,先将定时,计数器低位(TLO)中的值和初始值相加,然后送人定时,计数器中,此时定时,计数器中的值即为动态同步修正后的准确值。采用同步修正方案后,电子时钟的精度虽然提高了很多,但是由于晶振频率的偏差和一些其他未知因素的影响(同一块电路板、同样的程序换了一片单片机后,走时误差不一样,不知是何原因),时间长了仍然会有积累误差。为此,可采用自动调整方案。实际上是一种容错技术。其自动调整原理为:实测出误差Is所需的时间,然后每隔这样一段时间后就对秒进行加“1”或减“1”调整。
总结下来因为成本限制,每块microbit的计时器精度都没有你想象中的高,同样受限于成本每块板子出厂矫正的可能性也不大。
这么便宜的板子,编程教育入门用的,你还要什么自行车。
行吧,现在先不要自行车了,之后有需求再仔细研究一下这个容错技术。
根据模拟电路的知识,发光二极管通常用元素周期表Ⅲ、Ⅴ族元素的化合物,如砷化镓、磷化镓等制成。这种管子通过电流时将发出光来,这是由于电子与空穴直接复合而放出能量的结果。光谱范围是比较窄的,其波长由所使用的基本材料而定。
发光二极管的反向击穿电压为 5v。 其正伏安特性曲线太陡,必须与限流电阻串联,以便在使用时控制流过管道的电流。 限流电阻 R可通过以下公式获得:
R = ( E − V F ) / I R = (E - V_{F})/I R=(E−VF)/I
公式中,E为电源电压,VF 是LED的正向压降,I为LED的工作电流。一般来说,LED的正向压降为1.5V至2.0V,工作电流通常为10mA到20mA,因此在5V逻辑电路中,我们可以使用220Ω电阻作为限流电阻。
电路图如下:
在封装中,LED长脚为正,短脚为负,我在第一次连电路时出现错误,8个LED灯没有一个亮的,尝试了换线、换电阻(有点色弱怕色环看错了)、换LED,最后发现实际上是LED接反了,此时右边的Vcc 改为GND可正常运行。因此我认为正确的思路应该将检查电路放在第一步。
流水灯代码如下:
int led_array[8] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int flash_speed = 500 ;
/* flash led form left to right one by one */
void led_flash(void)
{
int i ;
for( i = 0 ; i < 8 ; i++ )
{
digitalWrite(led_array[i],LOW);
delay(flash_speed);
digitalWrite(led_array[i],HIGH);
}
}
/* turn on all led form left to right */
void led_turn_on(void)
{
int i ;
for( i = 0 ; i < 8 ; i++ )
{
digitalWrite(led_array[i],LOW);
delay(flash_speed);
}
}
/* turn off all led */
void led_turn_off(void)
{
int i ;
for( i = 0 ; i < 8 ; i++ )
{
digitalWrite(led_array[i],HIGH);
delay(flash_speed);
}
}
void setup() {
// put your setup code here, to run once:
int i ;
Serial.begin(115200);
for( i = 0 ; i < 8 ; i++ )
{
pinMode(led_array[i],OUTPUT);
digitalWrite(led_array[i],HIGH); // set led control pin defalut HIGH turn off all LED
}
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("start flash led !");
led_flash();
led_turn_off();
led_turn_on();
}
运行结果:
既然都已经连好了,来试试不同的点亮方式,先来个简单的依此闪烁:
int led_array[8] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int flash_speed = 500 ;
void led_flash(void) { /* flash led form left to right one by one */
int i ;
for ( i = 0 ; i < 8 ; i++ ) {
digitalWrite(led_array[i], LOW);
delay(flash_speed);
digitalWrite(led_array[i], HIGH);
}
} /* turn on all led form left to right */
void setup() { // put your setup code here, to run once:
int i ;
Serial.begin(9600);
for( i = 0 ; i < 8 ; i++ ) {
pinMode(led_array[i],OUTPUT);
digitalWrite(led_array[i],HIGH); //set led control pin defalut HIGH turn //off all LED } }
}
}
void loop()
{ // put your main code here, to run repeatedly:
Serial.println("start flash led !");
led_flash();
}
运行结果:
然后试试花里胡哨的:
int led_array[8] = { 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 } ;
int flash_speed = 500 ;
void led_flash_mode(void) { /* flash led form left to right one by one */
int i,j ;
for ( i = 3, j = 4 ; i>=0 ; i--, j++ ) {
digitalWrite(led_array[i], LOW);
digitalWrite(led_array[j], LOW);
delay(flash_speed);
digitalWrite(led_array[i], HIGH);
digitalWrite(led_array[j], HIGH);
}
} /* turn on all led form left to right */
void setup() { // put your setup code here, to run once:
int i ;
Serial.begin(9600);
for( i = 0 ; i < 8 ; i++ ) {
pinMode(led_array[i],OUTPUT);
digitalWrite(led_array[i],HIGH); //set led control pin defalut HIGH turn //off all LED } }
}
}
void loop()
{ // put your main code here, to run repeatedly:
Serial.println("start flash led !");
led_flash_mode();
}
运行结果:
重新开始玩板子,希望能一直坚持下去,我目前想到了一些好点子,不仅仅是玩板子,而是把板子结合到其他创作中,再接再励吧。
目前算是重新温习一下Arduino,色环电阻,LED,C语言等相关知识,以后再深入学习。
生命不息,学习不已。——沃·兹基·硕德