项目笔记| 基于Arduino和IR2101的无刷直流电机控制器

news2024/11/13 9:51:43

本文介绍如何使用 Arduino UNO 板构建无传感器无刷直流 (BLDC) 电机控制器或简单的 ESC(电子速度控制器)。

无刷直流电机有两种类型:有传感器和无传感器。有感无刷直流电机内置3个霍尔效应传感器,这些传感器检测无刷直流电机的转子位置。控制有传感器的BLDC电机很容易,因为我们知道转子的位置,就像在下面的项目中所做的那样:

在这里插入图片描述

项目电路原理图如下图所示。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

/* Sensorless brushless DC (BLDC) motor control with Arduino UNO (Arduino DIY ESC).
 * This is a free software with NO WARRANTY.
 * http://simple-circuit.com/
 */


#define SPEED_UP          A0          // BLDC motor speed-up button
#define SPEED_DOWN        A1          // BLDC motor speed-down button
#define PWM_MAX_DUTY      255
#define PWM_MIN_DUTY      50
#define PWM_START_DUTY    100

byte bldc_step = 0, motor_speed;
unsigned int i;
void setup() {
  DDRD  |= 0x38;           // Configure pins 3, 4 and 5 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;           // Configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;
  // Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR1A = 0;
  TCCR1B = 0x01;
  // Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR2A = 0;
  TCCR2B = 0x01;
  // Analog comparator setting
  ACSR   = 0x10;           // Disable and clear (flag bit) analog comparator interrupt
  pinMode(SPEED_UP,   INPUT_PULLUP);
  pinMode(SPEED_DOWN, INPUT_PULLUP);
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
  // BEMF debounce
  for(i = 0; i < 10; i++) {
    if(bldc_step & 1){
      if(!(ACSR & 0x20)) i -= 1;
    }
    else {
      if((ACSR & 0x20))  i -= 1;
    }
  }
  bldc_move();
  bldc_step++;
  bldc_step %= 6;
}
void bldc_move(){        // BLDC motor commutation function
  switch(bldc_step){
    case 0:
      AH_BL();
      BEMF_C_RISING();
      break;
    case 1:
      AH_CL();
      BEMF_B_FALLING();
      break;
    case 2:
      BH_CL();
      BEMF_A_RISING();
      break;
    case 3:
      BH_AL();
      BEMF_C_FALLING();
      break;
    case 4:
      CH_AL();
      BEMF_B_RISING();
      break;
    case 5:
      CH_BL();
      BEMF_A_FALLING();
      break;
  }
}

void loop() {
  SET_PWM_DUTY(PWM_START_DUTY);    // Setup starting PWM with duty cycle = PWM_START_DUTY
  i = 5000;
  // Motor start
  while(i > 100) {
    delayMicroseconds(i);
    bldc_move();
    bldc_step++;
    bldc_step %= 6;
    i = i - 20;
  }
  motor_speed = PWM_START_DUTY;
  ACSR |= 0x08;                    // Enable analog comparator interrupt
  while(1) {
    while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){
      motor_speed++;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
    while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
      motor_speed--;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
  }
}

void BEMF_A_RISING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR |= 0x03;            // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR &= ~0x01;           // Set interrupt on falling edge
}
void BEMF_B_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_B_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR &= ~0x01;
}
void BEMF_C_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_C_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR &= ~0x01;
}

void AH_BL(){
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void AH_CL(){
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void BH_CL(){
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void BH_AL(){
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void CH_AL(){
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}
void CH_BL(){
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}

void SET_PWM_DUTY(byte duty){
  if(duty < PWM_MIN_DUTY)
    duty  = PWM_MIN_DUTY;
  if(duty > PWM_MAX_DUTY)
    duty  = PWM_MAX_DUTY;
  OCR1A  = duty;                   // Set pin 9  PWM duty cycle
  OCR1B  = duty;                   // Set pin 10 PWM duty cycle
  OCR2A  = duty;                   // Set pin 11 PWM duty cycle
}

传感器BLDC电机的换向是根据霍尔效应传感器状态完成的。

无传感器BLDC电机没有任何传感器来检测其转子位置,其换向基于定子绕组中产生的BEMF(反电动势)。

无传感器BLDC电机控制的主要优点是系统成本较低,主要缺点是电机必须以最小速率移动才能产生足够的BEMF来检测。

无传感器BLDC电机控制的主要优点是系统成本较低,主要缺点是电机必须以最小速率移动才能产生足够的BEMF来检测。

在这里插入图片描述

如上图所示,BEMF信号与霍尔效应传感器信号不同步(相移30°)。在每个通电序列中,两个绕组通电(一个连接到正极,另一个连接到负极),第三个绕组保持打开(浮动)。浮动绕组用于检测过零,因此,所有 3 个过零点的组合用于生成通电序列。我们总共有 6 个事件:

A阶段过零:从高到低,从低到高

B阶段过零:从高到低,从低到高

C阶段过零:从高到低,从低到高

如何检测过零事件?

检测过零事件的最简单方法是使用比较器。比较器有 3 个主端子:2 个输入(正负)和一个输出。如果正电压大于负电压,则比较器输出为逻辑高电平,如果正电压低于负电压,则逻辑低电平。

这个项目基本上需要 3 个比较器,连接如下图所示(B 阶段示例)。每个阶段都需要一个类似的电路。

在这里插入图片描述
所有 3 个比较器的虚拟自然点都是相同的,它是使用 3 个电阻器产生的。当浮动(开路)绕组中产生的BEMF越过零点向正侧时,比较器输出从低电平过渡到高电平。当浮动绕组中产生的BEMF越过零点向负侧时,比较器输出从高电平过渡到低电平。通过具有三个这样的比较器电路,每个相位上一个电路可产生三个数字信号,对应于绕组中的BEMF信号。这三个信号的组合用于推导换向序列。

在这里插入图片描述

项目电路原理图如下图所示:

在这里插入图片描述

请注意,所有接地端子都连接在一起。

在电路中有 2 个按钮,一个用于提高 BLDC 电机速度,第二个用于降低它。

前三个33k(连接到电机相位)和三个10k电阻用作分压器,因为我们不能为微控制器提供12V,其他三个33k电阻产生虚拟自然点。虚拟自然点连接到Arduino引脚6。

Arduino UNO板基于ATmega328P微控制器,该微控制器具有一个模拟比较器。该比较器的正输入位于 Arduino uno 引脚 6 (AIN0) 上,负输入可以是引脚 7 (AIN1)、A0 (ADC0)、A1 (ADC1)、A2 (ADC2)、A3 (ADC3)、A4 (ADC4) 或 A5 (ADC5)。因此,我将虚拟自然点连接到模拟比较器的正极引脚(引脚 6),将 A 相 BEMF 连接到引脚 7 (AIN1),将 B 相 BEMF 连接到引脚 A2,将 C 相 BEMF 连接到引脚 A3。每次比较器都会将虚拟点与一相的 BEMF 进行比较(这是在软件中完成的)。这最大限度地减少了所需的硬件并简化了电路。

IR2104S芯片用于控制每相的高端和低端MOSFET。高压侧和低压侧之间的切换是根据控制线IN和SD完成的。下图显示了输入和输出时序图:

在这里插入图片描述

三IR2104S的 SD 线分别连接到引脚 11、10 和 9,用于相 A、相 B 和相 C。Arduino UNO可以在该引脚上生成PWM信号,其中只有高侧MOSFET是PWM的。

使用Arduino代码的无传感器BLDC电机控制

下面的代码不使用任何 BLDC 电机库。

如上所述,Arduino 引脚 9、10 和 11 可以生成 PWM 信号,其中引脚 9 和引脚 10 与 Timer1 模块(OC1A 和 OC1B)相关,引脚 11 与 Timer2 模块 (OC2A) 相关。两个定时器模块都配置为生成频率约为 31KHz、分辨率为 8 位的 PWM 信号。当按下按钮时,PWM信号的占空比会通过写入其寄存器(OCR1A、OCR1B和OCR2A)来更新(加速或减速)。

模拟比较器将正输入AIN0(Arduino引脚6)与负输入(AIN1(引脚7)、ADC2(引脚A2)或ADC3(引脚A3))进行比较。当正引脚电压高于负引脚电压时,设置模拟比较器ACO的输出,当正引脚电压低于负引脚电压时,ACO被清除。

在这个项目中,我使用了模拟比较器中断,并在上升时使用中断(从低到高的转换)和下降时的中断(从高到低的转换),这使得过零事件中断微控制器。

要完全理解代码,请阅读 ATmega328 数据表!

/* Sensorless brushless DC (BLDC) motor control with Arduino UNO (Arduino DIY ESC).
 * This is a free software with NO WARRANTY.
 * https://simple-circuit.com/
 */

#define SPEED_UP          A0
#define SPEED_DOWN        A1
#define PWM_MAX_DUTY      255
#define PWM_MIN_DUTY      50
#define PWM_START_DUTY    100

byte bldc_step = 0, motor_speed;
unsigned int i;
void setup() {
  DDRD  |= 0x38;           // Configure pins 3, 4 and 5 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;           // Configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;
  // Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR1A = 0;
  TCCR1B = 0x01;
  // Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR2A = 0;
  TCCR2B = 0x01;
  // Analog comparator setting
  ACSR   = 0x10;           // Disable and clear (flag bit) analog comparator interrupt
  pinMode(SPEED_UP,   INPUT_PULLUP);
  pinMode(SPEED_DOWN, INPUT_PULLUP);
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
  // BEMF debounce
  for(i = 0; i < 10; i++) {
    if(bldc_step & 1){
      if(!(ACSR & 0x20)) i -= 1;
    }
    else {
      if((ACSR & 0x20))  i -= 1;
    }
  }
  bldc_move();
  bldc_step++;
  bldc_step %= 6;
}
void bldc_move(){        // BLDC motor commutation function
  switch(bldc_step){
    case 0:
      AH_BL();
      BEMF_C_RISING();
      break;
    case 1:
      AH_CL();
      BEMF_B_FALLING();
      break;
    case 2:
      BH_CL();
      BEMF_A_RISING();
      break;
    case 3:
      BH_AL();
      BEMF_C_FALLING();
      break;
    case 4:
      CH_AL();
      BEMF_B_RISING();
      break;
    case 5:
      CH_BL();
      BEMF_A_FALLING();
      break;
  }
}

void loop() {
  SET_PWM_DUTY(PWM_START_DUTY);    // Setup starting PWM with duty cycle = PWM_START_DUTY
  i = 5000;
  // Motor start
  while(i > 100) {
    delayMicroseconds(i);
    bldc_move();
    bldc_step++;
    bldc_step %= 6;
    i = i - 20;
  }
  motor_speed = PWM_START_DUTY;
  ACSR |= 0x08;                    // Enable analog comparator interrupt
  while(1) {
    while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){
      motor_speed++;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
    while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
      motor_speed--;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
  }
}

void BEMF_A_RISING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR |= 0x03;            // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR &= ~0x01;           // Set interrupt on falling edge
}
void BEMF_B_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_B_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR &= ~0x01;
}
void BEMF_C_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_C_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR &= ~0x01;
}

void AH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void AH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void BH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void BH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void CH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}
void CH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}

void SET_PWM_DUTY(byte duty){
  if(duty < PWM_MIN_DUTY)
    duty  = PWM_MIN_DUTY;
  if(duty > PWM_MAX_DUTY)
    duty  = PWM_MAX_DUTY;
  OCR1A  = duty;                   // Set pin 9  PWM duty cycle
  OCR1B  = duty;                   // Set pin 10 PWM duty cycle
  OCR2A  = duty;                   // Set pin 11 PWM duty cycle
}

参考资料

  • [1] 【YouTube@Hyperspace Pirate】Brushless DC Speed Controller
  • [2] 使用Arduino和IR2101的无刷直流电机控制器
  • [3] 使用Arduino的无传感器BLDC电机控制 – DIY ESC
  • [4] Sensorless brushless motor control with PIC16F887

MOSFETs: IRLZ44
Flyback Diodes: MUR120G
MOSFET Drivers: IR2101
5V Linear Regulator: LM7805
MOSFET Driver supply regulator: LM317

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1940639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

宝塔SSL续签失败

我有2个网站a和b&#xff08;文字中用baidu.com替换我的域名&#xff09; b是要续签那个&#xff0c;但续签报错&#xff1a; nginx version: nginx/1.22.1 nginx: [emerg] host not found in upstream "github.com" in /www/server/panel/vhost/nginx/proxy/a.bai…

【Redis进阶】事务

1. Redis与MySQL的事务差别 相信一谈到事务&#xff0c;大家马上就能联想到MySQL的事务&#xff0c;其事务具有ACID四大特性&#xff0c;但是Redis的事务相比较于MySQL&#xff0c;那就是个"弟中弟"&#xff0c;下面我们就来简单对比两者的事务特性&#xff1a; 原…

用神经网络求解微分方程

微分方程是物理科学的主角之一&#xff0c;在工程、生物、经济甚至社会科学中都有广泛的应用。粗略地说&#xff0c;它们告诉我们一个量如何随时间变化&#xff08;或其他参数&#xff0c;但通常我们对时间变化感兴趣&#xff09;。我们可以了解人口、股票价格&#xff0c;甚至…

【Java面向对象】二进制I/O

文章目录 1.二进制文件2.二进制 I/O 类2.1 FileInputStream 和 FileOutputStream2.2 FilterInputStream和 FilterOutputStream2.3 DatalnputStream 和 DataOutputStream2.4 BufferedInputStream 和 BufferedOutputStream2.5 ObjectInputStream 和 ObjectOutputStream 2.6 Seria…

深入理解 Linux Zero-copy 原理与实现策略图解

用户态和内核态 一般来说&#xff0c;我们在编写程序操作 Linux I/O 之时十有八九是在用户空间和内核空间之间传输数据&#xff0c;因此有必要先了解一下 Linux 的用户态和内核态的概念。 从宏观上来看&#xff0c;Linux 操作系统的体系架构分为用户态和内核态&#xff08;或者…

昇思25天学习打卡营第24天|ResNet50迁移学习

课程打卡凭证 迁移学习 迁移学习是机器学习中一个重要的技术&#xff0c;通过在一个任务上训练的模型来改善在另一个相关任务上的表现。在深度学习中&#xff0c;迁移学习通常涉及在一个大型数据集&#xff08;如ImageNet&#xff09;上预训练的模型上进行微调&#xff0c;以便…

设计模式之策略模式_入门

前言 最近接触了优惠券相关的业务&#xff0c;如果是以前&#xff0c;我第一时间想到的就是if_else开始套&#xff0c;这样的话耦合度太高了&#xff0c;如果后期添加或者删除优惠券&#xff0c;必须直接修改业务代码&#xff0c;不符合开闭原则&#xff0c;这时候就可以选择我…

vue3.0学习笔记(一)——vue3简介与vite脚手架的使用

1. 为什么学vue3 Vue3现状&#xff1a; vue-next 2020年09月18日&#xff0c;正式发布vue3.0版本。但是由于刚发布周边生态不支持&#xff0c;大多数开发者处于观望。现在主流组件库都已经发布了支持vue3.0的版本&#xff0c;其他生态也在不断地完善中&#xff0c;这是趋势。…

Python | Leetcode Python题解之第268题丢失的数字

题目&#xff1a; 题解&#xff1a; class Solution:def missingNumber(self, nums: List[int]) -> int:n len(nums)total n * (n 1) // 2arrSum sum(nums)return total - arrSum

Qt第十三章 目录和文件操作

目录和文件操作 文章目录 目录和文件操作设备I/O简介I/O设备的类型基本文件读写QFileQTemporaryFile 流操作QTextStreamQDataStream QFileInfoQDirQFileSystemWatcherQStandardPathsQSettings 设备I/O 简介 I/O设备的类型 基本文件读写 QFile QFile file("C:/Users/PV…

Cisco 路由重发布 —— 实现路由信息在不同路由域间的传递

一、技术背景 在实际的组网中&#xff0c;可能会遇到这样一个场景&#xff1a;在一个网络中同时存在两种或者两种以上的路由协议。例如客户的网络原先是纯 Cisco 的设备&#xff0c;使用 EIGRP 协议将网络的路由打通。但是后来网络扩容&#xff0c;增加了一批华为的设备&#…

HAL库源码移植与使用之低功耗模式

低功耗特性对用电池供电的产品&#xff1a; 更小电池体积&#xff08;降低了大小和成本&#xff09; 延长电池寿命 电磁干扰更小&#xff0c;提高无线通信质量 电源设计更简单&#xff0c;无需过多考虑散热问题 电源供电区分为&#xff1a; 分为VDD供电区…

平面五杆机构运动学仿真matlab simulink

1、内容简介 略 89-可以交流、咨询、答疑 2、内容说明 略 ] 以 MATLAB 程序设计语言为平台 , 以平面可调五杆机构为主要研究对象 , 给定机构的尺寸参数 , 列出所 要分析机构的闭环矢量方程 , 使用 MATLAB 软件中 SIMULINK 仿真工具 , 在 SIMULINK 模型窗口下建立数…

深入理解TensorFlow底层架构

目录 深入理解TensorFlow底层架构 一、概述 二、TensorFlow核心概念 计算图 张量 三、TensorFlow架构组件 前端 后端 四、分布式计算 集群管理 并行计算 五、性能优化 内存管理 XLA编译 六、总结与展望 深入理解TensorFlow底层架构 一、概述 TensorFlow是一个开…

从0开始的STM32HAL库学习8

PWM控制舵机 配置环境 1. 选择TIM2时钟 2.选择内部时钟模式&#xff0c;打开通道二 3.分频系数PSC:72-1 自动重装寄存器ARR:20000-1 输出比较寄存器 CCR:500~2500( 后面可调整 ) 脉冲选择500后期可以改 编辑代码 调用启动函数 HAL_TIM_PWM_Start(&htim2,TIM_CHANN…

一分钟图情论文:《智慧数据视角下古籍数字出版的创新路径》

由武汉大学的雷珏莹和王晓光合著的《智慧数据视角下古籍数字出版的创新路径研究》论文从智慧数据1的视角出发&#xff0c;探讨了我国古籍数字出版的现状及其发展瓶颈&#xff0c;提出了古籍数字出版在内容、形式、服务和技术四个方面的创新路径。 文中, 研究者首先详细分析了当…

使用Fiddler进行Android和IOS抓包

Android抓包 要使用Telerik Fiddler Classic捕获Android设备的网络流量&#xff0c;您需要执行以下步骤&#xff1a; 在Fiddler Classic上进行设置&#xff1a; 确保已安装并使用BouncyCastle作为证书生成器。较新的Android版本会拒绝有效期超过两年的证书&#xff0c;目前只…

构建本地智能知识问答系统:基于Langchain和ChatGLM的简单实践

在数字化时代&#xff0c;智能知识问答系统成为了提升企业效率和数据安全性的关键工具。本文将介绍如何基于Langchain和ChatGLM构建一个本地化、支持中文的智能知识问答系统。该系统不仅能够实现完全本地化推理&#xff0c;而且对开源模型友好&#xff0c;可满足企业对数据隐私…

Windows中修改pip下载源

目录 一. 打开此电脑或文件管理器&#xff0c;输入 %APPDATA% 回车跳转 二. 在此目录中新建一个文件夹命令为pip 三. 进入这个目录&#xff0c;新建一个pip.ini文件 四. 复制阿里云镜像配置 五. CMD终端下载验证 六. 常用的国内镜像网站 一. 打开此电脑或文件管理器…

编程中的智慧六:单例、原型、建造者

上一篇咱们结合Spring介绍了设计模式中的工厂模式相关方法&#xff0c;其实现在Java开发基本上都是基于Spring框架开发&#xff0c;所以后续我们在开发过程中基本上很少自己重写一个工厂模式&#xff0c;都是直接使用Spring来完成。今天咱们接着看剩下的创建型设计模式&#xf…