[Diao Ye learns programming] Mathematical operation fma() in Arduino manual

insert image description here
insert image description here
What is an Arduino?
Arduino is an open source electronic prototyping platform that allows you to create a variety of creative projects with simple hardware and software. Whether you're a beginner or an expert, Arduino offers you endless possibilities. You can use Arduino to control sensors, lights, motors, robots, IoT devices, etc., as long as you can think of it, Arduino can help you achieve it.

If you want to learn more about Arduino, you can visit the official website of Arduino, where there are rich resources and tutorials for your reference. You can also join the Arduino community and exchange ideas and experiences with enthusiasts, students, designers and engineers from all over the world. In addition, you can also use Arduino's online programming tool to write code in the cloud and upload it to your development board.

Arduino is a constantly evolving and innovative platform with a wide range of applications and potential. I hope this manual can stimulate your interest and enthusiasm for Arduino, and let you enjoy the creativity and fun brought by Arduino

insert image description here

Wikipedia's definition
Arduino is an open source embedded hardware platform for users to make interactive embedded projects. In addition, Arduino, as an open source hardware and open source software company, has both projects and user communities. The company designs and manufactures Arduino boards and related accessories. These products are distributed under open source hardware and software licensed under the GNU Lesser General Public License (LGPL) or the GNU General Public License (GPL). Arduino allows anyone to build Arduino boards and distribute software. Arduino boards are sold commercially pre-assembled or purchased as DIY kits.

Introduced in 2005, the Arduino was designed as a student at the Ivrea Institute for Interactive Design in the Ivrea region of Italy, with the aim of providing novices and professionals with a low-cost and easy way to build interactive devices using sensors to interact with the environment. installation. Beginners and hobbyists can use Arduino to create devices such as sensors, simple robots, thermostats, and motion detectors.

The name Arduino comes from a bar in Ivrea, Italy, where some of the project's founders used to hang out. The bar is named after Arduin of Ivrea, count of the frontiers of Ivrea and king of Italy from 1002 to 1014.

insert image description here

17. Arduino Mathematical Operation fma()
Arduino Mathematical Operation fma() is a function that can calculate the product of two values ​​plus the result of the third value, that is, return the value of x * y + z. Its scope of application:
1) Calculate some mathematical formulas or algorithms, such as polynomials, matrix multiplication, linear regression, etc.
2) Realize some physical simulation or control, such as equation of motion, conservation of momentum, circuit analysis, etc.
3) Realize some special effects, such as audio synthesis, image processing, encryption and decryption, etc.

Application scenarios:
1) High-precision calculation: The fma() function is often used in scenarios that require high-precision calculation. By performing multiply-add operations, both multiplication and addition can be performed in one calculation, reducing the accumulation of round-off errors.
2) Signal processing: In digital signal processing, the fma() function can be used for signal weighting and filtering. Weighted averaging and filtering operations on signals can be achieved by multiplying and accumulating signals with weights.
3) Physical simulation: In physical simulation and simulation, the fma() function can be used to calculate the trajectory and interaction of objects. Through a combination of multiplication and addition, precise calculations of an object's position, velocity, and acceleration can be achieved.

When using the fma() function, you need to pay attention to the following:
1) The fma() function can accept integers or floating-point numbers as parameters, but the returned result type is the same as the parameter type. If the result is to be assigned to a variable of a different type, type conversion is required.
2) The fma() function needs to accept three parameters, namely the multiplier x, the multiplier y and the addend z. If you want to calculate the multiplication and addition of multiple values, you need to call the fma() function nested or use an array or loop structure.
3) The fma() function uses floating-point arithmetic, so rounding errors or overflows may occur. If more precise or larger-scale calculations are required, other libraries or methods can be used.

The following are three practical application cases of Arduino mathematical operation fma():
Case 1: Use temperature sensor and LCD display to realize temperature indication function. The output of the temperature sensor is a voltage value, which needs to be converted into a temperature value according to the formula t = v * a + b, where t is the temperature, v is the voltage, and a and b are constants. Use the fma() function to calculate the temperature value.

// 引入LiquidCrystal库
#include <LiquidCrystal.h>
// 定义温度传感器和LCD显示屏的引脚
#define TEMP_PIN A0
#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);
// 定义温度转换公式中的常数a和b
#define A 100.0
#define B -50.0

void setup() {
    
    
  // 初始化LCD显示屏,并清屏
  lcd.begin(16,2);
  lcd.clear();
}

void loop() {
    
    
  // 读取温度传感器的模拟值,并将其转换为电压值,单位为伏特
  int temp_value = analogRead(TEMP_PIN);
  float voltage = temp_value * (5.0 / 1023.0);
  
   // 使用fma()函数计算温度值,单位为摄氏度
   // 温度值等于电压值乘以常数a再加上常数b,公式为t = v * a + b
   float temp = fma(voltage, A, B);
   
   // 在LCD显示屏上显示当前的温度,保留一位小数
   lcd.clear();
   lcd.setCursor(0,0);
   lcd.print("Temp: ");
   lcd.print(temp,1);
   lcd.print(" C");
}

Case 2: Use gyroscope and steering gear to realize the function of balancing the car. When the car is tilted, the steering gear turns the opposite angle to restore the balance of the car. Use the fma() function to calculate the target angle of the servo.

// 引入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;
   
   // 使用fma()函数计算舵机的目标角度,使其与倾斜角度相反,实现平衡效果
   // 舵机的目标角度等于初始角度减去倾斜角度乘以一个系数,公式为a = a_init - k * angle_x
   // 其中a是舵机的目标角度,a_init是初始角度,k是一个系数,angle_x是倾斜角度
   float target_angle = fma(-angle_x, K, INIT_ANGLE);
   
   // 使用constrain()函数限制舵机的角度在0到180度之间
   target_angle = constrain(target_angle,0,180);
   
   // 将舵机转动到目标角度
   servo.write(target_angle);
}

Case 3: Using photoresistor and buzzer to realize sound and light control function

// 定义光敏电阻和蜂鸣器的引脚
#define LDR_PIN A0
#define BUZZ_PIN 3
// 定义光敏电阻的读数的范围
#define LDR_MIN 0
#define LDR_MAX 1023
// 定义蜂鸣器的音调的范围,单位为赫兹
#define TONE_MIN 100
#define TONE_MAX 1000

void setup() {
    
    
  // 设置蜂鸣器为输出模式
  pinMode(BUZZ_PIN, OUTPUT);
}

void loop() {
    
    
  // 读取光敏电阻的模拟值,并将其映射到0-1023范围内
  int ldr_value = analogRead(LDR_PIN);
  ldr_value = map(ldr_value, LDR_MIN, LDR_MAX, 0, 1023);
  
   // 根据光敏电阻的读数计算蜂鸣器的音调,并将其映射到合理的范围内
   float tone_value = (float)ldr_value / (LDR_MAX - LDR_MIN) * (TONE_MAX - TONE_MIN) + TONE_MIN;
   tone_value = constrain(tone_value, TONE_MIN, TONE_MAX);
   // 使用floor()函数将音调转换为整数,并赋值给蜂鸣器
   int tone_value = floor(tone_value);
   tone(BUZZ_PIN, tone_value);
}

Case 4: High-precision calculation:

float a = 0.1; // 浮点数1
float b = 0.2; // 浮点数2
float c = 0.3; // 浮点数3

float result = fma(a, b, c); // 执行乘加操作

Serial.print("Result: ");
Serial.println(result);

In this case, the fma() function is used to perform a multiply-accumulate operation, multiplying the floating-point number a by the floating-point number b, and adding the floating-point number c to the result. By completing the multiplication and addition operations at the same time in one calculation, the accumulation of rounding errors can be reduced and calculation results with higher precision can be obtained.

Case 5: Signal processing:

float signal[] = {
    
    0.1, 0.2, 0.3, 0.4}; // 信号数组
float weights[] = {
    
    0.4, 0.3, 0.2, 0.1}; // 权重数组

float sum = 0.0; // 累加结果

for (int i = 0; i < 4; i++) {
    
    
  sum = fma(signal[i], weights[i], sum); // 乘加操作累加结果
}

Serial.print("Weighted Sum: ");
Serial.println(sum);

In this case, the fma() function is used to multiply and add the signals array and the weights array and add the results. The weighted average operation on the signal can be realized by multiplying the signal with the weight and accumulating. Finally, output the weighted sum to the serial monitor for display or subsequent processing.

Case 6: Physical simulation:

float position = 0.0; // 物体位置
float velocity = 1.5; // 物体速度
float acceleration = 0.8; // 物体加速度

float deltaTime = 0.1; // 时间步长

position = fma(velocity, deltaTime, position); // 计算位置
velocity = fma(acceleration, deltaTime, velocity); // 计算速度

Serial.print("Position: ");
Serial.println(position);
Serial.print("Velocity: ");
Serial.println(velocity);

In this case, the position and velocity of the object is calculated using the fma() function. By multiplying and adding operations, the position and velocity change of an object in a given time step can be calculated from the velocity and acceleration of the object. Finally, the calculation results are output to the serial monitor for display or subsequent processing.

Case 7: Financial calculation:

#include <math.h>

float principal = 1000.0;
float interestRate = 0.05;
float time = 2.5;

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

void loop() {
    
    
  float amount = fma(principal, interestRate, principal * time);  // 计算复利总金额

  Serial.println(amount);
  delay(1000);
}

In this case, the fma() function is used to calculate the total amount compounded. Multiply the principal and the interest rate interestRate, and add the result to the principal multiplied by time principal * time to get the total amount of compound interest.

Case Eight: Image Processing:

#include <Adafruit_ILI9341.h>

Adafruit_ILI9341 tft(TFT_CS, TFT_DC, TFT_RST);

float brightness = 0.5;
float color = 0.8;

void setup() {
    
    
  // ...
  tft.begin();
  // ...
}

void loop() {
    
    
  float result = fma(brightness, color, 0.2);  // 计算最终亮度和颜色

  // 使用计算后的结果进行其他图像处理操作
  // ...
}

In this case, the final brightness and color values ​​are calculated using the fma() function. Multiply the brightness brightness and the color value color, and add the result to the constant 0.2 to get the final brightness and color value. This allows for more precise and high-quality image processing.

Case 9: Physical simulation:

float position = 5.0;
float velocity = 2.0;
float acceleration = 1.5;
float deltaTime = 0.1;

void setup() {
    
    
  // ...
}

void loop() {
    
    
  float newPosition = fma(velocity, deltaTime, position + 0.5 * acceleration * deltaTime * deltaTime);  // 计算新的位置

  // 使用新的位置进行物理模拟操作
  // ...
}

In this case, the new position of the object is calculated using the fma() function. Multiply the current velocity velocity of the object by the time step deltaTime, and then add the result to the current position plus acceleration multiplied by the square of half the time step 0.5 * acceleration * deltaTime * deltaTime to get the new position of the object. This enables accurate and reliable physics simulations.

Summary:
The fma() function is a mathematical operation function in Arduino, which is used to perform precise multiply and add operations of floating point numbers. It has a wide range of applications in financial computing, graphics and image processing, and physical simulation. When using the fma() function, you need to pay attention to the range and precision of the data type to ensure the normal work of the function. By properly using the fma() function, high-precision and accurate floating-point multiplication and addition operations can be realized to meet the needs of specific applications.

insert image description here

Guess you like

Origin blog.csdn.net/weixin_41659040/article/details/132651416