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

在这里插入图片描述
在这里插入图片描述
什么是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数学运算 sqrt()
sqrt()是Arduino中的数学运算函数,用于计算一个数的平方根。它接受一个参数:待计算平方根的数值,并返回计算结果。它的适用范围:
1)计算一些数学公式或算法,例如勾股定理、二次方程、牛顿法等。
2)实现一些物理模拟或控制,例如速度、加速度、距离、角度等。
3)实现一些特殊的效果,例如音量调节、LED灯的呼吸灯等。

应用场景:
1)几何计算:sqrt()函数常用于几何计算中,如计算三角形的斜边长度、圆的半径或球的半径等。通过计算平方根,可以得到与几何形状相关的尺寸信息。
2)物理计算:在物理学中,很多公式涉及到平方根的计算,如速度、加速度、力等。使用sqrt()函数可以方便地计算这些物理量的值,以进行物理实验或模拟。
3)数据处理与分析:在数据处理与分析中,可能需要对数据进行平方根运算,以进行归一化、平滑或其他操作。sqrt()函数可以用于对数据进行处理,以满足特定的数据处理需求。

使用sqrt()函数时,需要注意以下事项:
1)sqrt()函数可以接受整数或浮点数作为参数,但是返回的结果类型与参数类型相同。如果要将结果赋值给不同类型的变量,需要进行类型转换。
2)sqrt()函数只能接受一个参数,即被开方的数值。如果要计算多个数值的平方根,需要分别调用sqrt()函数或使用乘法运算符。
3)sqrt()函数使用浮点数运算,所以可能会产生舍入误差或溢出。如果需要更精确或更大范围的计算,可以使用其他库或方法。
4)sqrt()函数的参数可以是整数类型(如int、long等)或浮点数类型(如float、double等)。但需要注意,如果参数是整数类型,结果可能会被截断为整数,导致精度丢失。若需要保持浮点数精度,建议使用浮点数类型作为参数。
5)参数必须大于等于零。如果参数为负数,函数将返回NaN(Not a Number)。
6)在使用sqrt()函数时,需要注意数值范围和精度问题。确保所使用的数值在函数的有效范围内,并注意避免负数参数和精度丢失。

以下是Arduino数学运算sqrt()的三个实际运用程序案例:
案例一:使用超声波传感器和LCD显示屏测量距离。超声波传感器可以发射和接收声波,并根据声波的时间差计算距离。使用sqrt()函数计算声波的速度,考虑到温度的影响。

// 引入LiquidCrystal库
#include <LiquidCrystal.h>
// 定义超声波传感器和LCD显示屏的引脚
#define TRIG_PIN 2
#define ECHO_PIN 3
#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);
// 定义温度传感器的引脚和初始温度,单位为摄氏度
#define TEMP_PIN A0
#define INIT_TEMP 20.0

void setup() {
    
    
  // 初始化串口通信,设置波特率为9600
  Serial.begin(9600);
  // 设置超声波传感器的引脚模式
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  // 初始化LCD显示屏,设置列数为16,行数为2,并清屏
  lcd.begin(16,2);
  lcd.clear();
}

void loop() {
    
    
  // 读取温度传感器的模拟值,并将其转换为摄氏度
  int temp_value = analogRead(TEMP_PIN);
  float temp = temp_value * (5.0 / 1023.0) * 100.0;
  
   // 使用sqrt()函数计算声波在当前温度下的速度,单位为厘米每微秒
   // 声波速度与温度成正比,公式为v = sqrt(1.4 * R * T)
   // 其中v是声波速度,R是空气的气体常数(29 J/(mol*K)),T是绝对温度(K)
   // 将单位换算后得到v = sqrt(0.000401 * T),T = temp + 273.15
   float speed = sqrt(0.000401 * (temp + 273.15));
   
   // 让超声波传感器发射10微秒的脉冲信号
   digitalWrite(TRIG_PIN, LOW);
   delayMicroseconds(2);
   digitalWrite(TRIG_PIN, HIGH);
   delayMicroseconds(10);
   digitalWrite(TRIG_PIN, LOW);
   
   // 计算超声波传感器接收到回响信号的时间差,单位为微秒
   long duration = pulseIn(ECHO_PIN, HIGH);
   
   // 根据声波的速度和时间差,计算距离,单位为厘米
   // 距离等于声波的速度乘以时间差除以2,因为声波是往返的
   float distance = speed * duration / 2.0;
   
   // 在LCD显示屏上显示当前的温度和距离,保留一位小数
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Temp: ");
   lcd.print(temp,1);
   lcd.print(" C");
   
   lcd.setCursor(0,1);
   lcd.print("Dist: ");
   lcd.print(distance,1);
   lcd.print(" cm");
}

案例二:使用陀螺仪和舵机实现平衡小车功能。当小车倾斜时,舵机转动相反的角度,使小车恢复平衡。使用sqrt()函数计算小车的倾斜角度。

// 引入Wire库和Servo库
#include <Wire.h>
#include <Servo.h>
// 定义陀螺仪的地址
#define GYRO_ADDR 0x68
// 创建舵机对象
Servo servo;
// 定义舵机的引脚和初始角度
#define SERVO_PIN 9
#define INIT_ANGLE 90

void setup() {
    
    
  // 初始化串口通信,设置波特率为9600
  Serial.begin(9600);
  // 初始化I2C通信,加入I2C总线
  Wire.begin();
  // 向陀螺仪发送指令,激活陀螺仪
  Wire.beginTransmission(GYRO_ADDR);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  // 将舵机连接到第9号引脚,并转动到初始角度
  servo.attach(SERVO_PIN);
  servo.write(INIT_ANGLE);
}

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轴方向上的倾斜角度,单位为度,范围为-90到90
   // 使用sqrt()函数计算分母中的平方根项
   float angle_x = atan2(acc_x, sqrt(acc_y * acc_y + acc_z * acc_z)) * RAD_TO_DEG;
   
   // 根据倾斜角度计算舵机的目标角度,使其与倾斜角度相反,实现平衡效果
   int target_angle = INIT_ANGLE - angle_x;
   
   // 使用constrain()函数限制舵机的角度在0到180度之间
   target_angle = constrain(target_angle,0,180);
   
   // 将舵机转动到目标角度
   servo.write(target_angle);
}

案例三:使用陀螺仪和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
   // 使用sqrt()函数计算分母中的平方根项
   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(".");
}

案例四:几何计算:

float sideA = 3.0; // 三角形的一条边长
float sideB = 4.0; // 三角形的另一条边长

float hypotenuse = sqrt(pow(sideA, 2) + pow(sideB, 2)); // 计算三角形的斜边长度

Serial.print("Hypotenuse length: ");
Serial.println(hypotenuse);

在此案例中,使用sqrt()函数计算由两条直角边构成的三角形的斜边长度。首先使用pow()函数计算两条直角边的平方和,然后将结果传递给sqrt()函数进行平方根计算。最后,将计算结果输出到串口监视器,用于显示或后续的处理。

案例五:物理计算:

float velocity = 10.0; // 物体的速度

float kineticEnergy = 0.5 * pow(velocity, 2); // 计算物体的动能

float mass = 2.0; // 物体的质量

float momentum = mass * sqrt(2 * kineticEnergy); // 计算物体的动量

Serial.print("Momentum: ");
Serial.println(momentum);

在此案例中,使用sqrt()函数计算物体的动量。首先使用pow()函数计算物体的动能,然后根据动能和质量计算物体的动量。最后,将计算结果输出到串口监视器,用于显示或后续的处理。

案例六:数据处理与分析:

float dataValue = 25.0; // 数据值

float normalizedValue = sqrt(dataValue); // 对数据值进行平方根运算(数据归一化)

// 使用归一化后的数据值进行后续的处理或分析
// ...

在此案例中,使用sqrt()函数对数据进行归一化处理。通过对数据进行平方根运算,可以将数据值进行归一化,以满足特定的数据处理需求。然后,可以使用归一化后的数据值进行后续的处理或分析,例如进行比较、计算或输出。

案例七:计算直角三角形斜边长度:

float a = 3.0; // 直角三角形的一条边长
float b = 4.0; // 直角三角形的另一条边长
float c = sqrt(pow(a, 2) + pow(b, 2)); // 计算直角三角形的斜边长度

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

void loop() {
    
    
  Serial.print("直角三角形的斜边长度:");
  Serial.println(c);
  delay(1000);
}

在这个例子中,我们使用sqrt()函数计算直角三角形的斜边长度。通过应用勾股定理,计算并开平方底边和高边的平方和。

案例八:计算物体自由落体的时间:

float height = 10.0; // 物体的下落高度(单位:米)
float gravity = 9.8; // 重力加速度(单位:米/秒^2)
float time = sqrt(2 * height / gravity); // 计算物体自由落体的时间

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

void loop() {
    
    
  Serial.print("物体自由落体的时间:");
  Serial.println(time);
  delay(1000);
}

在这个例子中,我们使用sqrt()函数计算物体自由落体的时间。通过应用自由落体运动的公式,计算并开平方高度与重力加速度关系的乘积。

案例九:计算频谱分析中的频率:

float period = 0.01; // 信号的周期(单位:秒)
float frequency = 1 / period; // 计算信号的频率

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

void loop() {
    
    
  Serial.print("信号的频率:");
  Serial.println(frequency);
  delay(1000);
}

在这个例子中,我们使用sqrt()函数计算信号的频率。通过应用频率与周期的倒数关系,计算并开平方周期的倒数。

在这里插入图片描述

猜你喜欢

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