【雕爷学编程】Arduino 手册之数学运算 map()

在这里插入图片描述
在这里插入图片描述
什么是Arduino?
Arduino 是一款开源的电子原型平台,它可以让你用简单的硬件和软件来创建各种创意的项目。无论你是初学者还是专家,Arduino 都能为你提供无限的可能性。你可以用 Arduino 来控制传感器、灯光、马达、机器人、物联网设备等等,只要你能想到的,Arduino 都能帮你实现。

如果你想了解更多关于 Arduino 的信息,你可以访问 Arduino 的官方网站,那里有丰富的资源和教程供你参考。你也可以加入 Arduino 的社区,和来自世界各地的爱好者、学生、设计师和工程师交流心得和经验。此外,你还可以使用 Arduino 的在线编程工具,在云端编写代码并上传到你的开发板上。

Arduino 是一个不断发展和创新的平台,它有着广泛的应用领域和潜力。这里希望本手册能激发你对 Arduino 的兴趣和热情,让你享受 Arduino 带来的创造力和乐趣

在这里插入图片描述

维基百科的定义
Arduino 是一个开源嵌入式硬件平台,用来供用户制作可交互式的嵌入式项目。此外 Arduino 作为一个开源硬件和开源软件的公司,同时兼有项目和用户社群。该公司负责设计和制造Arduino电路板及相关附件。这些产品按照GNU宽通用公共许可证(LGPL)或GNU通用公共许可证(GPL)许可的开源硬件和软件分发的,Arduino 允许任何人制造 Arduino 板和软件分发。 Arduino 板可以以预装的形式商业销售,也可以作为 DIY 套件购买。

Arduino 2005 年时面世,作为意大利伊夫雷亚地区伊夫雷亚互动设计研究所的学生设计,目的是为新手和专业人员提供一种低成本且简单的方法,以建立使用传感器与环境相互作用的装置。初学者和爱好者可用Arduino制造传感器、简单机器人、恒温器和运动检测器等装置。

Arduino 这个名字来自意大利伊夫雷亚的一家酒吧,该项目的一些创始人过去常常会去这家酒吧。 酒吧以伊夫雷亚的 Arduin(Arduin of Ivrea)命名,他是伊夫雷亚边疆伯爵,也是 1002 年至 1014 年期间的意大利国王。

在这里插入图片描述

十七、Arduino数学运算 map()
map()是Arduino中的数学运算函数,用于将一个数值从一个数值范围映射到另一个数值范围。它接受五个参数:待映射的数值、原始范围的下限、原始范围的上限、目标范围的下限和目标范围的上限,并返回映射后的数值。它的适用范围:
1)将模拟输入的范围(0-1023)映射到模拟输出的范围(0-255),实现PWM信号的控制。
2)将传感器的读数映射到实际的物理量,例如温度、距离、角度等。
3)将数值映射到不同的颜色或音调,实现可视化或声音效果。

应用场景:
1)传感器数据转换:map()函数常用于将传感器读数从原始范围映射到更有意义的数值范围。例如,将光敏电阻的读数从0到1023的范围映射到0到100的亮度值范围,以便更直观地表示光照强度。
2)输出信号映射:在控制系统中,输出信号的范围可能与输入信号的范围不一致。使用map()函数可以将输入信号映射到所需的输出信号范围,以满足特定的控制需求。
3)数据调整与归一化:在数据处理与分析中,可能需要对数据进行调整或归一化,以便进行比较、统计或其他操作。map()函数可以将数据映射到所需的范围,使其符合分析或处理的要求。

使用map()函数时,需要注意以下事项:
1)map()函数可以接受整数或浮点数作为参数,但是返回的结果类型与参数类型相同。如果要将结果赋值给不同类型的变量,需要进行类型转换。
2)map()函数只能接受五个参数,分别是被映射的数值,原区间的下限和上限,目标区间的下限和上限。如果要映射多个数值,需要分别调用map()函数。
3)map()函数使用整数运算,所以可能会丢失小数部分或产生四舍五入的误差。如果需要更精确的映射,可以使用浮点数运算或自定义公式。

以下是Arduino数学运算map()的三个实际运用程序案例:
案例一:使用电位器和RGB LED灯实现颜色变化效果。当电位器旋转时,RGB LED灯的颜色随之变化。使用map()函数将电位器的读数映射到RGB LED灯的三个通道上。

// 定义电位器和RGB LED灯的引脚
#define POT_PIN A0
#define RED_PIN 9
#define GREEN_PIN 10
#define BLUE_PIN 11

void setup() {
    
    
  // 设置RGB LED灯为输出模式
  pinMode(RED_PIN, OUTPUT);
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
}

void loop() {
    
    
  // 读取电位器的模拟值,并使用map()函数将其映射到0-255范围内
  int pot_value = analogRead(POT_PIN);
  pot_value = map(pot_value, 0, 1023, 0, 255);
  // 使用map()函数将电位器的读数映射到RGB LED灯的三个通道上
  // 当电位器读数为0时,RGB LED灯显示红色
  // 当电位器读数为255时,RGB LED灯显示绿色
  // 当电位器读数为511时,RGB LED灯显示蓝色
  // 当电位器读数在其他值时,RGB LED灯显示混合色
  int red_value = map(pot_value, 0, 511, 255, 0);
  int green_value = map(abs(pot_value - 255), 0, 255, 0, 255);
  int blue_value = map(pot_value - 511, 0, 511, 0, 255);
  
   // 控制RGB LED灯的颜色
   analogWrite(RED_PIN, red_value);
   analogWrite(GREEN_PIN, green_value);
   analogWrite(BLUE_PIN, blue_value);
}

案例二:使用温湿度传感器和蜂鸣器实现温度报警功能。当温度高于设定的阈值时,蜂鸣器发出提示音。提示音的频率随着温度的升高而升高。使用map()函数将温度映射到蜂鸣器的频率上。

// 引入DHT库
#include <DHT.h>
// 定义DHT传感器的类型和引脚
#define DHT_TYPE DHT11
#define DHT_PIN A0
// 创建DHT对象
DHT dht(DHT_PIN, DHT_TYPE);
// 定义蜂鸣器的引脚
#define BUZZ_PIN 2
// 定义温度的阈值和范围,单位为摄氏度
#define TEMP_THRESHOLD 30.0
#define TEMP_MIN 30.0
#define TEMP_MAX 50.0
// 定义蜂鸣器的频率范围,单位为赫兹
#define FREQ_MIN 1000
#define FREQ_MAX 2000

void setup() {
    
    
  // 初始化DHT传感器
  dht.begin();
  // 设置蜂鸣器为输出模式
  pinMode(BUZZ_PIN, OUTPUT);
}

void loop() {
    
    
  // 获取当前的温度,单位为摄氏度
  float temp = dht.readTemperature();
  // 如果温度高于阈值
  if (temp > TEMP_THRESHOLD) {
    
    
    // 使用map()函数将温度映射到蜂鸣器的频率范围内
    int freq = map(temp, TEMP_MIN, TEMP_MAX, FREQ_MIN, FREQ_MAX);
    // 让蜂鸣器发出提示音
    tone(BUZZ_PIN, freq);
    delay(100);
    noTone(BUZZ_PIN);
    delay(100);
  }
}

案例三:使用陀螺仪和LCD显示屏显示当前的倾斜角度。陀螺仪可以检测X轴和Y轴方向上的倾斜角度,范围为-90度到90度。使用map()函数将倾斜角度映射到LCD显示屏的字符位置上,实现可视化效果。

// 引入Wire库和LiquidCrystal库
#include <Wire.h>
#include <LiquidCrystal.h>
// 定义陀螺仪的地址
#define GYRO_ADDR 0x68
// 定义LCD显示屏的引脚
#define RS_PIN 7
#define EN_PIN 8
#define D4_PIN 9
#define D5_PIN 10
#define D6_PIN 11
#define D7_PIN 12
// 创建LiquidCrystal对象,指定引脚顺序
LiquidCrystal lcd(RS_PIN, EN_PIN, D4_PIN, D5_PIN, D6_PIN, D7_PIN);

void setup() {
    
    
  // 初始化串口通信,设置波特率为9600
  Serial.begin(9600);
  // 初始化I2C通信,加入I2C总线
  Wire.begin();
  // 向陀螺仪发送指令,激活陀螺仪
  Wire.beginTransmission(GYRO_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  // 初始化LCD显示屏,设置列数为16,行数为2,并清屏
  lcd.begin(16,2);
  lcd.clear();
}

void loop() {
    
    
   // 向陀螺仪发送指令,请求读取数据
   Wire.beginTransmission(GYRO_ADDR);
   Wire.write(0x3B);
   Wire.endTransmission(false);
   // 接收陀螺仪返回的数据,共14个字节
   Wire.requestFrom(GYRO_ADDR,14,true); 
   int acc_x = Wire.read()<<8|Wire.read(); 
   int acc_y = Wire.read()<<8|Wire.read(); 
   int acc_z = Wire.read()<<8|Wire.read(); 
   int temp = Wire.read()<<8|Wire.read(); 
   int gyro_x = Wire.read()<<8|Wire.read(); 
   int gyro_y = Wire.read()<<8|Wire.read(); 
   int gyro_z = Wire.read()<<8|Wire.read(); 
  
   // 计算X轴和Y轴方向上的倾斜角度,单位为度,范围为-90到90
   float angle_x = atan2(acc_x, sqrt(acc_y * acc_y + acc_z * acc_z)) * RAD_TO_DEG;
   float angle_y = atan2(acc_y, sqrt(acc_x * acc_x + acc_z * acc_z)) * RAD_TO_DEG;
   
   // 使用map()函数将倾斜角度映射到LCD显示屏的字符位置上,范围为0到15
   int x_pos = map(angle_x, -90, 90, 0, 15);
   int y_pos = map(angle_y, -90, 90, 0, 15);
   
   // 在LCD显示屏上显示当前的倾斜角度,保留一位小数,并在对应的位置上显示一个点表示倾斜方向
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Angle X: ");
   lcd.print(angle_x,1);
   
   lcd.setCursor(0,1);
   lcd.print("Angle Y: ");
   lcd.print(angle_y,1);
   
   lcd.setCursor(x_pos,y_pos);
   lcd.print(".");
}

案例四:传感器数据转换:

int rawValue = analogRead(A0); // 读取传感器原始值

int mappedValue = map(rawValue, 0, 1023, 0, 100); // 将原始值映射到0到100的范围内

Serial.print("Mapped value: ");
Serial.println(mappedValue);

在此案例中,使用map()函数将传感器原始值映射到0到100的范围内。然后,将映射后的值输出到串口监视器,用于调试或显示目的。

案例五:输出信号映射:

int inputSignal = 50; // 输入信号值

int mappedSignal = map(inputSignal, 0, 100, 0, 255); // 将输入信号映射到0到255的范围内

analogWrite(9, mappedSignal); // 输出映射后的信号到PWM引脚

在此案例中,使用map()函数将输入信号映射到0到255的范围内。然后,将映射后的信号作为PWM信号输出到引脚,以控制外部设备或执行特定的操作。

案例六:数据调整与归一化:

int sensorValue = analogRead(A0); // 读取传感器值

float adjustedValue = map(sensorValue, 0, 1023, 0.0, 1.0); // 将传感器值映射到0.0到1.0的范围内

在此案例中,使用map()函数将传感器值映射到0.0到1.0的范围内。然后,可以将映射后的值用于数据处理、归一化或其他分析操作。

示例七:通过电位器控制LED

int potPin = A0; // 电位器引脚
int ledPin = 9; // LED引脚

void setup() {
    
    
  pinMode(ledPin, OUTPUT);
}

void loop() {
    
    
  int potValue = analogRead(potPin); // 读取电位器的值
  int brightness = map(potValue, 0, 1023, 0, 255); // 将电位器的值从0到1023映射到亮度值0到255
  analogWrite(ledPin, brightness); // 根据映射后的亮度值控制LED的亮度
}

在这个示例中,map()函数被用来将从电位器读取的值(0-1023)映射到LED的亮度值(0-255),从而控制LED的亮度。

示例八:温度转换(使用温度传感器)

int tempPin = A1; // 温度传感器引脚
int minTemp = 0; // 最低温度
int maxTemp = 100; // 最高温度

void setup() {
    
    
  Serial.begin(9600);
}

void loop() {
    
    
  int rawValue = analogRead(tempPin); // 读取温度传感器的模拟值
  float temperature = map(rawValue, 0, 1023, minTemp, maxTemp); // 将读取的值映射到指定的温度范围
  Serial.print("温度:");
  Serial.print(temperature);
  Serial.println(" °C");
  delay(1000);
}

在这个示例中,map()函数被用来将从温度传感器读取的模拟值(0-1023)映射到温度值(0-100),并通过串口打印出来。

示例九:通过距离传感器控制舵机

#include <Servo.h>

int distancePin = A2; // 距离传感器引脚
int servoPin = 9; // 舵机引脚

Servo myservo;

void setup() {
    
    
  myservo.attach(servoPin); // 将舵机连接到指定引脚
}

void loop() {
    
    
  int distance = analogRead(distancePin); // 读取距离传感器的值
  int servoPosition = map(distance, 0, 1023, 0, 180); // 将读取的距离值映射到舵机的角度范围
  myservo.write(servoPosition); // 根据映射后的角度控制舵机的位置
  delay(100);
}

在这个示例中,map()函数被用来将从距离传感器读取的值(0-1023)映射到舵机的角度范围(0-180),从而控制舵机的位置。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41659040/article/details/132647877