秋招打印机模块基础+原理

具体参考飞书文档  STM32版本、ESP32版本 两个版本 以stm32为主

课程内容:

基础部分资料: 

1、先跑起来(点亮LED&打印Helloworld)

LED闪烁:


//头文件->可以理解为Arduino工具箱
#include <Arduino.h>  

//初始化函数,只执行一次,把只需执行一次的代码放到setup
void setup() {

}

//循环执行函数,重复执行,把需要重复执行的代码放到loop
void loop() {

}

//这两个函数是arduino固定的,可以理解为代码运行的入口,每次开机都从setup开始运行
//头文件
#include <Arduino.h>

//定义LED灯引脚为常量,因为程序跑起来就不需要更改IO值
#define PIN_LED_15

void setup() {
  //初始化引脚为输出
  pinMode(PIN_LED,OUTPUT);
}

void loop() {
    //设置为高电平(3.3V),1s后设置为低电平(0V),再1s后重复
    digitalWrite(PIN_LED, HIGH);
    delay(1000);
    digitalWrite(PIN_LED, LOW);
    delay(1000);
}

打印信息到电脑:

#include <Arduino.h>  

void setup() {
    //初始化串口,波特率位9600
    Serial.begin(9600);
    //打印“setup”字符到电脑,\n为换行符
    Serial.printf("setup\n");
}

void loop() {
    //打印“loop”字符到电脑,\n为换行符
    Serial.printf("loop\n");
    //延时1000ms
    delay(1000);
}
2、LED是怎么被点亮的,LED是怎么被点亮的?

点灯原理:

插件led灯珠长引脚为正极,短引脚为负极。

 LED(发光二极管)两端存在电压差,有一定的电流流过时会亮起。电流可以理解为水流,电压差可以理解为水位差,当两个点水位高度不一样时,水流会从高水位流向低水位。

                                               

//头文件
#include <Arduino.h>

//定义LED灯引脚为常量,因为程序跑起来就不需要更改IO值
#define PIN_LED_18;
void setup() {
  //初始化引脚为输出
  pinMode(PIN_LED,OUTPUT)
}

void loop() {
    //设置为高电平(3.3V),1s后设置为低电平(0V),再1s后重复
    digitalWrite(PIN_LED, HIGH);
    delay(1000);
    digitalWrite(PIN_LED, LOW);
    delay(1000);
}
 3、芯片的运行状态打印到电脑显示,但它的技术原理是怎么样的?(打印字符到电脑

与电脑上位机软件通信、与Android工控机通讯

串口模块:以太网、WiFi、蓝牙、Zigbee、Lora等串口模块

什么是串口?

串行通讯端口,简称串口,也称COM口,串行接口的数据是通过一条线一位位地顺序传送。

并行接口,简称并口,是指8位数据同时通过8条并行线进行传送。

串口形容一下就是一条车道,而并口就是有8个车道同一时刻能传送8位(一个字节)数据。但是并不是并口快,由于8位通道之间的互相干扰。传输受速度就受到了限制。而且当传输出错时,要同时重新传8个位的数据。串口没有干扰,传输出错后重发一位就可以了。

                              

 什么是串口波特率?

波特率(bandrate),指的是串口通信的速率,也就是串口通信时每秒钟可以传输多少个二进制位。比如每秒钟可以传输9600个二进制(传输一个二进制位需要的时间是1/9600秒,也就是104us),波特率就是9600。

串口的通信波特率不能随意设定,而应该再一些值中去选择。一般常见的波特率是9600或者115200(低端的单片机如51常用9600,高端的单片机和嵌入式SOC一般用115200)。

                   

数据位:

1010 1010 -> 0xaa ->170

10*16+10

也就是说我们可以通过控制引脚按上面的高低电平,每104us改变一次,就可以完成一个字节的传输。

但是芯片已经帮我们做好了这些操作,我们要做的只是配置好波特率,然后填写数据即可。

参考代码: 
//引入头文件
#include <Arduino.h>

uint8_t temp_data;

void setup() {
  Serial.begin(9600);
  // Serial.begin(115200);
  Serial.print("setup\n");
}

void loop() {
  delay(1000);
  Serial.print("loop\n");
  //判断串口是否可用
  while(Serial.available()) {
    //读取接收到的数据
    temp_data = Serial.read();
    if(temp_data == '$') {
      Serial.printf("get data %d\n",temp_data);
    }
  }
}

/*
如果设置Serial.begin(115200);
则需要在platformio.ini中添加
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
*/

//可以尝试,使用电脑控制LED灯
4、如何读取按键状态?

通过IO读取引脚的电平,判断是否有信号触发。

什么是电压?什么是电平?高电平?低电平?

以TTL电路为例:

TTL电源电压是3.3V,高电平是2.4V--3.3V,低电平0V--0.8V,按照惯例,使用1来表示高电平,使用0表示低电平。

按键输入
#include <Arduino.h>

//34 35 36 39仅可以作为输入INPUT,不支持INPUT_PULLUP
#define PIN_KEY 5

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //设置为上拉输入,初始化后默认电平为高
  pinMode(PIN_KEY, INPUT_PULLUP);  

  Serial.print("setup\n");
}

void loop() {
  // put your main code here, to run repeatedly:
  // 此处进行按键去抖
  if(digitalRead(PIN_KEY)==LOW){
    Serial.print("KEY Click\n");
    delay(1000);
  }
}
按键消抖
#include <Arduino.h>

//34 35 36 39仅可以作为输入INPUT,不支持INPUT_PULLUP
#define PIN_KEY 5

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  //设置为上拉输入,初始化后默认电平为高
  pinMode(PIN_KEY, INPUT_PULLUP);  

  Serial.print("setup\n");
}

void loop() {
  // put your main code here, to run repeatedly:
  // 此处进行按键去抖
  if(digitalRead(PIN_KEY)==LOW){
    delay(10);
    if(digitalRead(PIN_KEY)==LOW){
      Serial.print("KEY Click\n");
      delay(1000);
    }
  }
}
5、计时与定时

时钟功能、设备工作时长计时功能、设备定时功能

#include <Arduino.h>
#include <Ticker.h>

Ticker timer1;
Ticker timer2;
Ticker timer3;

void timer1_callbackfun(){
  Serial.println("timer1 is running...");
}

void timer2_callbackfun()
{
  timer1.attach_ms(500,timer1_callbackfun);
  Serial.println("timer2 is running...");
}

void timer3_callbackfun()
{
  timer1.detach(); 
  Serial.println("timer3 is running..."); 
}

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

  timer2.once_ms(1000, timer2_callbackfun);        // 1000ms后开启timer1
  timer3.once_ms(5000, timer3_callbackfun);        // 3000ms后关闭timer1
}

void loop(){

}
6、电位器
应用场景

技术原理

前面我们无论是读取输入还是控制输出,都只有高低电平(0和1)的概念,这是我们常说的数字电路,而实际项目中,无论是温度、湿度、重量、电压往往是一个范围内的数值。

接下来我们来看看模拟电路,通过引脚读取一定范围内变化的值。

电位器属于无极性器件,可变电阻的一种,三个触点,通过旋转旋钮改变2号脚的位置,从而改变阻值的大小,1脚和3脚分别接开发板的3.3V和GND,2脚接模拟输入引脚。

无论是温度传感器、湿度传感器都是把环境的温湿度通过材料的特性,最终转换为引脚能够测量的电压值,所以,一旦学会读取电位器的电压,也就使用同样的办法读取温湿度、重量传感器的数据,仅仅是转换表或公式的不同而已。

#include <Arduino.h>

#define PIN_ADC 12

void setup() {
  Serial.begin(9600);
  
  //set the resolution to 12 bits (0-4096) 设置分辨率为12位
  analogReadResolution(12);
}

void loop() {
  // read the analog / millivolts value for pin 12: 读取引脚12的模拟量和电压值,注意,仅有部分引脚支持ADC
  int analogValue = analogRead(PIN_ADC);
  int analogVolts = analogReadMilliVolts(PIN_ADC);
  
  // print out the values you read:
  Serial.printf("ADC analog value = %d\n",analogValue);
  Serial.printf("ADC millivolts value = %d\n",analogVolts);
  
  delay(1000);  // delay in between reads for clear read from serial
}
7、舵机控制
应用场景

舵机的控制原理

                                                

舵机是一种位置伺服的电机,与马达不同,我们需要马达提供的是旋转,控制的是转速和方向。而舵机不需要整圈的旋转,需要的是旋转角度并维持住。一般舵机旋转的角度范围是0 度到180 度。舵机引线为3线,分别用棕、红、橙三种颜色进行区分,舵机品牌和生产厂家不同,会有些许差异,使用之前需查看资料。我们使用的是最常见的舵机,棕、红、橙分别对应“电源负极,电源正极,控制信号”。

舵机控制

通过向舵机的信号信号线发送PWM信号来控制舵机的转动位置

下面举个例子;

当我们向舵机发送脉冲宽度为1.5毫秒(ms)的信号时,舵机的输出轴将移至中间位置(90度);

脉冲宽度为1ms时,舵机的输出轴将移至最小的位置(0度);

脉冲宽度为2ms时,舵机的输出轴将移至最小的位置(180度);

舵机连续转动原始IO实现:

#include <Arduino.h>

#define PIN_SERVO 23

void setup() {
  //设置波特率
  Serial.begin(9600);
  pinMode(PIN_SERVO, OUTPUT);
}

/**
 * @brief 输入角度值控制舵机转动
 * 
 * @param angle 
 */
void motor_run(int angle){
  if(angle < 0 || angle > 180)
    return;
  float hight_time = 0.0;
  float low_time = 0.0;
  float all_time = 20.0;
  //舵机90°时,基准脉宽为1.5ms
  //hight_time = (angle / 180.0) + 1.0; //1ms-0度 2ms-180的舵机使用
  hight_time = (angle / 90.0) + 0.5;    //0.5ms-0度 2.5ms-180度的舵机使用
  low_time = all_time - hight_time;
  Serial.printf("h = %f l = %f\n",hight_time,low_time);
  digitalWrite(PIN_SERVO, HIGH);
  delayMicroseconds(hight_time*1000);
  digitalWrite(PIN_SERVO, LOW);
  delayMicroseconds(low_time*1000);
}



void loop() {
//原来代码有问题,需要按舵机电平持续发送才行,不能只发一次高低电平切换
//  motor_run(45);
//  delay(3000);
//  motor_run(130);
//  delay(3000);
  int index = 0;
  while(1){
      motor_run(45);
      index ++;
      if(index > 100)
          break;
  }
  index  = 0
   while(1){
      motor_run(130);
      index ++;
      if(index > 100)
          break;
  }
}
舵机与电位器联动

#include <Arduino.h>
#include <ESP32Servo.h>

#define PIN_SERVO 23
#define PIN_SENSOR 12

Servo servo;

int angle = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("setup\n");  

  //set the resolution to 10 bits (0-1023)
  analogReadResolution(10);
  //频率设置50Hz 1s 50个脉冲 每个脉冲20ms
  servo.setPeriodHertz(50);      
  // 例如,如果范围是1000us到2000us, 1000us等于0的角,1500us等于90度,2000us等于1800 度。
  servo.attach(PIN_SERVO,1000,2000);
  ////部分舵机跑不到位置,这里1000改为500 2000改为2500
}

void loop() {
  // put your main code here, to run repeatedly:
  int val=analogRead(PIN_SENSOR);
  //函数的使用率比较高,将某一区间的值转换为另外区间的值。
  //数值转换,将[0,1023]产生的模拟值转换成[0,180]中的值
  int angle=map(val,0,1023,0,180);
  Serial.printf("val = %d angle = %d\n",val,angle);
  //servo.write(45)表示舵机旋转到45°的位置
  servo.write(angle);
  //原理,通过计算脉冲宽度转换为控制角度,脉冲频率转换为控制速度
  delay(100);
}
8、蜂鸣器
应用场景

大部分的电子产品、家电(风扇、空调、电水壶)都会有蜂鸣器,用于提示设备的工作状态

原理

蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号。

蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器

有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定。

无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音。

蜂鸣器有正负极,顶部印有+号的为正极,若蜂鸣器引脚没剪,则长的为正极。

 参考代码

有源蜂鸣器

#include <Arduino.h>

//蜂鸣器引脚
#define PIN_BUZZER 18

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

void loop()                     
{
  digitalWrite(PIN_BUZZER, HIGH);
  delay(2000); 
  digitalWrite(PIN_BUZZER, LOW); 
  delay(2000);      
}

无源蜂鸣器

PWM:脉冲宽度调制

 

#include <Arduino.h>

//蜂鸣器引脚
#define PIN_BUZZER 18

int freq = 2000;    //设置频率2000kHz
int channel = 0;    //通道号,取值0 ~ 15
int resolution = 8; //分辨率,取值0~20,占空比duty最大取值为2^resolution-1

void setup() {
  Serial.begin(9600);
  //设置通道频率和分辨率
  ledcSetup(channel, freq, resolution);
  //将通道0与引脚15连接
  ledcAttachPin(PIN_BUZZER, channel); 

  //输出指定音阶、音调
  ledcWriteNote(channel,NOTE_D,5);
  delay(3000);
  ledcWrite(channel, 0);
}

void loop() {
  //设置通道频率
  ledcWriteTone(channel, 2000);
  //动态修改占空比
  for (int dutyCycle = 0; dutyCycle <= 255; dutyCycle = dutyCycle + 10) {
    Serial.println(dutyCycle);
    ledcWrite(channel, dutyCycle);
    delay(1000);
  }
  
  //设置通道占空比 125/2^8 50%
  ledcWrite(channel, 125);
  //动态修改频率
  for (int freq = 255; freq < 10000; freq = freq + 250) {
    Serial.println(freq);
    ledcWriteTone(channel, freq);
    delay(1000);
  }
}
10、屏幕显示

SSD1306 Oled显示模块共有4个引脚,标记为GND, VCC, SCL和SDA。这种Oled显示模块可以使用3.3V到5V轻松上电。

#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>

#define SCL 22
#define SDA 23

// IIC version 方向 时钟信号 数据信号 复位数据
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, SCL, SDA, U8X8_PIN_NONE);

void setup(void)
{
    u8g2.begin();
}

void loop(void)
{
    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0, 24, "Hello World!");
    u8g2.sendBuffer();
    delay(1000);

    u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_ncenB14_tr);
    u8g2.drawStr(0, 24, "embeded!");
    u8g2.sendBuffer();
    delay(1000);
}
10、直流&步进驱动

 

什么是直流电机?

直流电机是最常见的电机类型。直流电动机通常只有两个引线,一个正极和一个负极。如果将这两根引线直接连接到电池正负极,电机将旋转,如果切换引线,电机将以相反的方向旋转,通过改变提供给电机的电压,您可以改变电机的速度。

什么是步进电机?

步进电机是一种将电脉冲信号转换成相应角位移的电机,它可以实现更精准的位置控制

现在想象一个打印机。打印机内有很多移动部件,包括电机。一个电机用作进纸,当墨水开始印在纸上时旋转滚轴移动纸张。此电机需要能够将纸张移动一个精确的距离,以便能够打印下一行文本或图像的下一行。(论文用到)

直流电机与步进电机的对比:
直流电机:

优点:价格低、控制方便 缺点:由于电刷和换向器的存在,有刷电机的结构复杂,可靠性差,故障多,维护工作量大,寿命短,换向火花易产生电磁干扰。

步进电机:

优点:低速扭矩大,控制更精准,成本相对低; 缺点:步进电机存在空载启动频率,所以步进电机可以低速正常运转,但若高于一定速度时就无法启动,并伴有尖锐的啸叫声,同时,步进电机是开环控制,控制精度和速度都没有伺服电机那么高。

直流电机的控制

#include <Arduino.h>

int motorPin1 = 18;

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

void loop() {
   digitalWrite(motorPin1, HIGH);
   delay(2000);
   digitalWrite(motorPin1, LOW);
   delay(2000);
}
控制转速

直流电机的速度可以通过改变其输入电压来控制,使用单片机控制转速可以通过PWM控制。

PWM是一种通过发送一系列ON-OFF脉冲来调整输入电压平均值的技术。该平均电压与脉冲的宽度成正比,称为占空比。

占空比越高,施加到直流电机的平均电压就越高,从而导致电机速度增加。占空比越短,施加到直流电机的平均电压越低,导致电机速度降低。

下图显示了具有各种占空比和平均电压的PWM技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值