工程学导论Tech Tutorial

本博客为 ENGR1000J-S2-24SU Tech-TA 讲义的中文版本

希望帮助大部分更加熟悉中文的同学更好理解这些内容

也希望能够帮助非本课程的同学们上手单片机的基础使用

注: 中文版的内容和英文讲义完全一样

Arduino + 超声波传感器

模块原理

  1. 触发位引脚(Trig)获得约10微秒的高电平,发射超声波,同时接收位引脚(Echo)也变为高电平
  2. 当超声波模块接收到回声,接收位引脚重新变回低电平
  3. 计算接收位引脚高电平的持续时间,结合声速,计算出距离

接线

Arduino_Ultrasonic_Sensor-2024-05-21-16-10-13

(使用tinkercad绘制)

  • vcc接5V供电
  • Gnd接Arduino板上的GND接地
  • Trig和Echo分别接两个通用输入输出引脚即可,这里选择9和10

Arduino_Ultrasonic_Sensor-2024-05-21-16-16-49

代码编写

完整代码

// 定义引脚
const int trigPin = 9;
const int echoPin = 10;

// 定义时间变量
long duration;
int distance;

// 初始化函数
void setup() {
  // 初始化串口通信
  Serial.begin(9600);

  // 设置引脚模式
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

// 主循环函数
void loop() {
  // 调用测距函数
  distance = measureDistance();

  // 输出测得的距离
  Serial.println("Distance: " + String(distance) + " cm");

  // 延迟1秒
  delay(1000);
}

// 测距函数
int measureDistance() {
  // 清空trigPin
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);

  // 发送10微秒的脉冲到trigPin
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // 读取echoPin,返回脉冲宽度(微秒)
  duration = pulseIn(echoPin, HIGH);

  // 计算距离(单位:厘米)
  int distance = duration * 0.034 / 2;

  return distance;
}

函数理解

  1. pinMode(pin, mode)

    • 功能: 设置指定引脚的工作模式。
    • 参数:
      • pin: 要设置模式的引脚编号。
      • mode: 引脚模式,可以是INPUT(输入模式)或OUTPUT(输出模式)。
    • 示例:
      pinMode(13, OUTPUT); // 设置13号引脚为输出模式
  2. Serial.println(data)

    • 功能: 向串行监视器发送数据,并在发送的数据末尾添加换行符。
    • 参数:
      • data: 要发送的字符串或数值数据。
    • 示例:
      Serial.begin(9600); // 初始化串行通信,波特率为9600
      Serial.println("Hello, Arduino!"); // 向串行监视器发送字符串
  3. digitalWrite(pin, value)

    • 功能: 向指定引脚输出高电平(HIGH)或低电平(LOW)。
    • 参数:
      • pin: 要输出信号的引脚编号。
      • value: 输出值,可以是HIGH(高电平)或LOW(低电平)。
    • 示例:
      digitalWrite(13, HIGH); // 将13号引脚设置为高电平
  4. delay(ms)

    • 功能: 暂停程序执行指定的毫秒数。
    • 参数:
      • ms: 暂停的时间,单位为毫秒。
    • 示例:
      delay(1000); // 暂停程序执行1秒(1000毫秒)
  5. pulseIn(pin, value)

    • 功能: 测量指定引脚上一个脉冲的持续时间。
    • 参数:
      • pin: 要测量脉冲的引脚编号。
      • value: 脉冲的类型,可以是HIGH(高电平脉冲)或LOW(低电平脉冲)。
    • 返回值: 脉冲的持续时间,单位为微秒。
    • 示例:
      unsigned long duration;
      duration = pulseIn(7, HIGH); // 测量7号引脚上高电平脉冲的持续时间

代码说明

  1. 定义引脚:

    const int trigPin = 9;
    const int echoPin = 10;

    trigPin连接到HC-SR04传感器的触发引脚(Trig),echoPin连接到回声引脚(Echo)

    这里的 9 和 10 是和实际的接线对应起来的

    就是给引脚数字起名字,这两行代码也可以用宏定义实现,即:

    #define TRIG_PIN 9
    #define ECHO_PIN 10
  2. 初始化函数:

    void setup() {
      Serial.begin(9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }

    设置串口通信速率为9600波特,并设置引脚模式

    这里波特率只要和串口监视器的波特率一致就可以,建议9600

  3. 主循环函数:

    void loop() {
      distance = measureDistance();
      Serial.println("Distance: " + String(distance) + " cm");
      delay(1000);
    }

    在主循环中调用measureDistance函数测量距离,并将结果通过串口输出,每次测量后延迟1秒

  4. 测距函数:

    int measureDistance() {
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      int distance = duration * 0.034 / 2;
      return distance;
    }

    该函数首先清空trigPin,然后发送10微秒的脉冲信号,读取从echoPin接收到的回声信号的持续时间,并计算出距离

    pulseIn函数用于测量某个引脚上的脉冲宽度(高电平或低电平的持续时间)

运行

点击上传按钮

Arduino_Ultrasonic_Sensor_en-2024-05-21-16-37-20

打开串行监视器

Arduino_Ultrasonic_Sensor_en-2024-05-21-16-38-15

传感器读取到的数据实时显示在窗口中

Arduino_Ultrasonic_Sensor_en-2024-05-21-16-36-17

Arduino + L298N + DC Motor

直流电机简介

基本参数

额定电压:额定电压(Rated Voltage)是指直流电机在最佳性能下运行时所需的电压。

转速:转速(Speed),通常用转每分钟(RPM, Revolutions Per Minute)表示。转速与扭矩之间存在反比关系,在电机的应用中需要平衡两者以满足具体的使用需求。

对于VG100-S2第一阶段的项目,电机额定电压的选择要求小于等于12V,转速可以选择较低转速以提高扭矩。

使用原理

在直流电机的两个电极分别接高电压和低电压,不同的电压差形成不同的转速。

L298N电机驱动板

接口介绍

DC_Motor_and_L298N-2024-05-26-19-46-07

  • OUT1, OUT2, OUT3, OUT4: 电流输出,连接直流电机
  • 12V(VS),和 GND: 用于电流输入(不一定要12V的电源。5V~35V都OK)
  • 5V(VSS),可用于输出5V电压
  • IN1, IN2, IN3, IN4: 信号输入,连接Arduino
  • EN1,EN2: A侧输入和B侧输出的使能,可用于控制电机转速

可以提供最大约2A的电流

使用方法1

IN1, IN2 控制电机方向和电机速度

需要两个模拟输出引脚

实现思路简单一些

接线

DC_Motor_and_L298N-2024-05-28-17-28-31

DC_Motor_and_L298N-2024-05-28-17-29-01

DC_Motor_and_L298N-2024-05-28-17-30-09

  1. Arduino与L298N驱动模块的连接

    • IN1: Arduino的D5引脚连接到L298N的IN1引脚。
    • IN2: Arduino的D3引脚连接到L298N的IN2引脚。
    • 不要拔掉ENA的跳线帽
  2. 电源连接

    • 驱动模块电源输入:
      • 将L298N的VCC引脚连接到电池
      • 将L298N的GND引脚连接到电源的负极(地)。
    • Arduino电源:
      • 可以通过USB供电,或使用外部电源供电。
  3. 电机连接

    • 将直流电机的两根线连接到L298N的OUT1OUT2引脚。确保电机连接正确,以便IN1和IN2控制电机的正反转。

代码编写

int IN1 = 5; // D5引脚连接到驱动模块的IN1
int IN2 = 3; // D3引脚连接到驱动模块的IN2

void motor(int speed1) { // speed1 驱动电机的速度,值范围-255到255,正值正转,负值反转
  int s1, s2; // 定义s1和s2变量,用于表示电机正反转状态
  if(speed1 > 0) { 
    s1 = IN1; // 正转时,s1表示IN1
    s2 = IN2; // 正转时,s2表示IN2
  } else {
    s1 = IN2; // 反转时,s1表示IN2
    s2 = IN1; // 反转时,s2表示IN1
    speed1 = -speed1; // 将speed1取绝对值,使其成为正数
  } 
  digitalWrite(s1, LOW); // 给s1所代表的引脚写入低电平,确定电机的负极
  analogWrite(s2, speed1); // 给s2所代表的引脚写入模拟信号,根据speed1的绝对值控制电机速度
}

void setup() {
  pinMode(IN1, OUTPUT); // 设置D5为输出引脚
  pinMode(IN2, OUTPUT); // 设置D3为输出引脚
  Serial.begin(9600); 
}

void loop() {
  motor(50); // 调用motor函数,设置电机速度为50,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(100); // 调用motor函数,设置电机速度为100,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(255); // 调用motor函数,设置电机速度为255(最大速度),电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(-100); // 调用motor函数,设置电机速度为-100,电机反转
  delay(1000); // 等待1秒钟,使电机保持当前速度
}

函数介绍

digitalWrite

  • 功能: digitalWrite 用于将数字引脚设置为高电平(HIGH)或低电平(LOW)。
  • 使用方法: digitalWrite(pin, value);
    • pin: 要操作的引脚编号(如 D5)。
    • value: HIGHLOW,分别表示高电平和低电平。
  • 引脚要求: 可以用于任何所有引脚。

示例:

digitalWrite(5, HIGH); // 将D5引脚设置为高电平
digitalWrite(3, LOW);  // 将D3引脚设置为低电平

analogWrite

  • 功能: analogWrite 用于向PWM引脚输出模拟信号,范围是0到255,通过PWM技术模拟模拟信号。
  • 使用方法: analogWrite(pin, value);
    • pin: 要操作的PWM引脚编号(如 D6)。
    • value: 0到255之间的值,0表示0%占空比(低电平),255表示100%占空比(高电平)。
  • 引脚要求: 只能用于支持PWM的引脚。

示例:

analogWrite(6, 128); // 在D6引脚输出50%占空比的PWM信号

使用方法2

IN1, IN2 控制电机方向

ENA 控制电机速度

需要两个数字输出引脚+一个模拟输出引脚

节约模拟引脚,代码优雅一点,接线稍麻烦一点

分别控制正反转和速度

接线

DC_Motor_and_L298N-2024-05-28-17-24-27

DC_Motor_and_L298N-2024-05-28-17-24-54

DC_Motor_and_L298N-2024-05-28-17-25-22

  1. Arduino与L298N驱动模块的连接

    • IN1: Arduino的D5引脚连接到L298N的IN1引脚。
    • IN2: Arduino的D3引脚连接到L298N的IN2引脚。
    • EN1: Arduino的D6引脚连接到L298N的EN1引脚。
  2. 电源连接

    • 驱动模块电源输入:
      • 将L298N的VCC引脚连接到电池
      • 将L298N的GND引脚连接到电源的负极(地)。
    • Arduino电源:
      • 可以通过USB供电,或使用外部电源供电。
  3. 电机连接

    • 将直流电机的两根线连接到L298N的OUT1OUT2引脚。确保电机连接正确,以便IN1和IN2控制电机的正反转。

代码编写

C style
int IN1 = 8; // D8引脚连接到驱动模块的IN1
int IN2 = 7; // D7引脚连接到驱动模块的IN2
int EN1 = 6; // D6引脚连接到驱动模块的EN1,用于控制电机速度

void motor(int speed1) { // speed1 驱动电机的速度,值范围-255到255,正值正转,负值反转
  if(speed1 > 0) {
    digitalWrite(IN1, HIGH); // IN1高电平,电机正转
    digitalWrite(IN2, LOW);  // IN2低电平
  } else {
    digitalWrite(IN1, LOW);  // IN1低电平
    digitalWrite(IN2, HIGH); // IN2高电平,电机反转
    speed1 = -speed1; // 将speed1取绝对值,使其成为正数
  }
  analogWrite(EN1, speed1); // 使用PWM信号控制电机速度
}

void setup() {
  pinMode(IN1, OUTPUT); // 设置D8为输出引脚
  pinMode(IN2, OUTPUT); // 设置D7为输出引脚
  pinMode(EN1, OUTPUT); // 设置D6为输出引脚
  Serial.begin(9600); // 初始化串口通信,设置波特率为9600
}

void loop() {
  motor(50); // 调用motor函数,设置电机速度为50,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(100); // 调用motor函数,设置电机速度为100,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(255); // 调用motor函数,设置电机速度为255,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor(-100); // 调用motor函数,设置电机速度为-100,电机反转
  delay(1000); // 等待1秒钟,使电机保持当前速度
}
C++ style
class Motor {
  private:
    int IN1;  // 电机驱动模块的IN1引脚
    int IN2;  // 电机驱动模块的IN2引脚
    int EN1;  // 电机驱动模块的EN1引脚,用于控制电机速度

  public:
    Motor(int in1, int in2, int en1) {  // 构造函数,用于初始化引脚
      IN1 = in1;
      IN2 = in2;
      EN1 = en1;

      pinMode(IN1, OUTPUT); // 设置IN1为输出引脚
      pinMode(IN2, OUTPUT); // 设置IN2为输出引脚
      pinMode(EN1, OUTPUT); // 设置EN1为输出引脚
    }

    void setSpeed(int speed) {  // 设置电机速度的方法,speed值范围为-255到255
      if (speed > 0) {
        digitalWrite(IN1, HIGH); // IN1高电平,电机正转
        digitalWrite(IN2, LOW);  // IN2低电平
      } else {
        digitalWrite(IN1, LOW);  // IN1低电平
        digitalWrite(IN2, HIGH); // IN2高电平,电机反转
        speed = -speed; // 将speed取绝对值,使其成为正数
      }
      analogWrite(EN1, speed); // 使用PWM信号控制电机速度
    }
};

Motor motor1(8, 7, 6);  // 创建Motor类的实例,指定IN1, IN2, EN1引脚

void setup() {
  Serial.begin(9600); // 初始化串口通信,设置波特率为9600
}

void loop() {
  motor1.setSpeed(50); // 设置电机速度为50,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor1.setSpeed(100); // 设置电机速度为100,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor1.setSpeed(255); // 设置电机速度为255,电机正转
  delay(1000); // 等待1秒钟,使电机保持当前速度
  motor1.setSpeed(-100); // 设置电机速度为-100,电机反转
  delay(1000); // 等待1秒钟,使电机保持当前速度
}

参考资料

材料购买建议

lab上发放的材料仅以教学为目的,搭建项目的材料是大家自由购买的

硬件的选型也是项目制作的重要部分,适用性、易用性、价格成本都是大家需要考虑的因素

以下是我们给大家的一些建议

结构材料

已在5.25的announcement里提及

电子模块

发放材料中推荐使用的

  • Arduino UNO
    • 作为主控单片机
    • 对于第一阶段的项目来说足够且适合
  • L298N
    • 不错的电机驱动板选项
    • 还有其它品种的电机驱动板,可以按需选择
  • 格式 2S 800mah 电池
    • 这是一块品质很不错的电池
    • 但参数不一定是最合适的
  • 超声波传感器
    • 距离信息也是不错的判断标准

需购买或建议购买的

  • 电池
    • 电压建议 3S
    • 容量自行选择。越大->续航时间越长、充放电周期长、重量较大、价格较高
    • 放电倍率(c数)不需要追求太高
  • 传感器
    • 市面上有很多品种的传感器,分别用来检测不同的环境信息
    • 请根据Phase 1的项目任务选择合适的传感器
    • 可以考虑多传感器的融合检测
  • 直流电机
    • 也许你需要新的专门用于小车的电机
    • 注意电机和支架、联轴器、车轮的搭配
    • 电机还有其它种类,可自行选择
  • 其它机电模块
    • 多了解,多参考其它方案。有很多好用的模块

关于报销

  • 有平均每人200RMB的报销额度。(即每队报销额度1000~1200)
  • 一定要开好发票,发票信息见 上海交通大学开票信息.docx。其中纳税人名称和纳税人识别号是最重要的。单位注意选择“企业”而非“个人”
  • 商家不应以任何理由拒绝开票。请大家维护自己的消费者权益
Author

Shi Hantian

Posted on

2024-05-28

Updated on

2024-05-28

Licensed under