Tag Archives: Arduino

Hello World

Arduino软串口的使用

Arduino Uno自带一个串口,也就是管脚1、2,“硬串口”,IDE upload代码、使用串口监视器调试程序,用到的都是这个串口,那么,如果你还需要用串口连接其他设备时,应该怎么办呢?
为了不应现调试程序,这里需要用到“软串口”,也就是将其他数字管脚当成串口使用~~の,难道要按TTL串口协议解析串口数据不成?
到是没有这么复杂,Arduino已经自带SoftwareSerial库,完成了对串口逻辑的封装。以下代码是串口读取VAMLED电压模块的逻辑,咱们以此为例来看看软串口是怎么用的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <SoftwareSerial.h>
 
SoftwareSerial EVSerial(2, 3); //定义软串口管脚,分别是rx tx 
 
void setup (){
  EVSerial.begin(9600); //波特率
  Serial.begin(9600);
}
 
void loop() {
  if(EVSerial.available() > 0){
    Serial.print(">> ");
    Serial.println(EVSerial.readString());//在串口监视器,打印电压模块传递的电压值
    delay(1000); //每读取一次,延时
    EVSerial.print(0); //向VAMLED模块发送“上报电压”指令
  }
}

以上逻辑,即包含了SoftwareSerial读取和写入的操作,不过实际使用有两个问题:
1. 每模拟一个软串口都要消耗单片机的资源,内存和flash、堆栈等。软串口和硬串口对于发送数据是一样的,但在接收数据时,性能就有差别了,硬串口是支持中断接收数据的,不会影响程序运行的实时性,但是软串口不支持中断,接收串口数据你得去不断轮询,收到的数据还有可能会丢掉
2. 具体到上面这个例子,实际收到的电压值包含乱码,不好解析,具体原因正在研究,等有结果了再更新o(* ̄︶ ̄*)o
———-
转载请注明出处:http://www.jiangkl.com/2022/10/arduino_serial/

Hello World 软硬兼施

Arduino如何多任务

小搜了一下,Arduino没有简单的多线程/多任务的解决方案
换个方向想想,也对,Arduino本身那点存储空间,就是个微控制器,专心能控制好一个东西就行了,还搞神马多任务
不过,考虑到代码的整齐度,简单的模块划分还是需要的,比如,需要同时分别控制指示灯和舵机时,你不能把所有的代码都放在Loop函数里吧
借鉴以前用js做动画里的实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <Servo.h>
Servo duoji1servo;
 
const int pinLed1   = 12;   //连接红色led
const int pinLed2   = 13;   //连接蓝色led
const int pinDuoji  = 9;    //连接舵机控制端口
 
void setup() {
  pinMode(pinLed1, OUTPUT);
  pinMode(pinLed2, OUTPUT);
  duoji1servo.attach(pinDuoji);
}
 
long _ti = 0;  //控制参数累加
void loop() {
  _ti++;
  ledTest(_ti);
  duojiTest(_ti);
  delay(1);    //1毫秒
}
 
//led闪动测试
int ledi = 0;
void ledTest(long ti){
  ledi++;
  if(ledi == 512){
      ledi = 0;
  }
  int n = ledi;
  if(ledi > 255){
    n = 512 - ledi;
  }
  analogWrite(pinLed1, n);   //分别控制LED亮度
  analogWrite(pinLed2, (255 - n));
}
 
//舵机测试
int duojii = 0;
void duojiTest(long ti){
  if(ti % 10 == 0){//调用间隔,10毫秒计算一次
    duojii++;
    if(duojii > 360){
      duojii = 1;
    }
    if(duojii <= 180){  //正传
      duoji1servo.write(duojii);
    }else{              //反转
      duoji1servo.write(360 - duojii);
    }
  }
}
Hello World 软硬兼施

Arduino的指令时间研究

习惯了服务器端编程的思路,玩硬件也想把时间搞得清楚一些
简单研究Arduino一个指令所需的时钟周期,板子是某宝上最常见的Arduino UNO R3,先上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const int LED1  = 13;               //红色LED
const int LED2  = 12;               //蓝色LED
int loopin      = 0;
 
void setup() {
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}
 
void loop() {
  loopin++;
  if(loopin % 2 == 1){              //点亮红色LED
    digitalWrite(LED1, HIGH);
    digitalWrite(LED2, LOW);
    delay(1000);                    //持续1秒
  }else{                            //点亮红色LED
    digitalWrite(LED2, HIGH);
    digitalWrite(LED1, LOW);
    delay(1000);                    //持续1秒
    //******************************关键看这里,这个for循环的时间,约等于delay(1000),此时双色同时亮起
    for(long i = 0; i < 160000; i++){
      digitalWrite(LED1, i % 2 == 0 ? LOW : HIGH);
      digitalWrite(LED2, i % 2 == 1 ? LOW : HIGH);
    }
  }
}

就这么多~~
整体上,用一个超长的for循环模拟出一个1秒的delay,然后观察同时亮起的时间,是否等于单独亮起的时间
实际测算,到16万时,同时亮起的时间,基本等于另外两个亮起的时间
(这里只是估算,有时间的话,也可以算的更精确一点:对着计数器数秒,看闪动的次数是否和秒数一直,不一致的话,就调整这个i得最大值)
也就是说,这里的一个for循环,Arduino的大约需要 1/160 毫秒,或者说0.16M,简答分析这个for循环做了哪些事情
1. i+1,= i, i与最大值比较,大约3次
2. i%2,== 0 ?, 高电平或低电平输出,大约3次
3. 与上一步基本一致
加起来大约10个指令?
Arduino UNO R3的晶振频率是16M,也就是说,大约,晶振的10个周期,可以执行一个程序指令
另一个方面,UNO的处理器核心是ATmega328,8位处理器,i是long型32位,上面的每次运算,cpu至少要算四次(具体8位处理器怎么捣腾相加两个32位的数,记不清了),按这种方式算的话,其实也差不多
—-over
转载请注明出处: 昆仑的山头