• 机器人控制器编程实践指导书旧版-实践一 LED灯(数字量)


    适用于UNO/2560/DUE/ESP8266/ESP32,2021年之前使用版本。

     


    实践一 LED灯(数字量)

    1.1 实践目的

    • 了解机器人控制器的基本概念和特点
    • 了解Arduino[ESP32]简介及相应的硬件设备
    • 掌握Arduino[ESP32] IDE的安装和使用
    • 掌握Arduino[ESP32]硬件基本资源和编程方法

    1.2 实践设备

    • PC机一台
    • Arduino[ESP32]开发板及配件等
    • 万用表和示波器等

    1.3 实践原理

    • 初级:

    1.3.1 控制13引脚灯闪烁。

    示意图和原理图

    参考代码:

    int led = 13; // integer variable led is declared

    void setup() { // the setup() method is executed only once

    pinMode(led, OUTPUT); // the led PIN is declared as digital output

    }

    void loop() { // the loop() method is repeated

    digitalWrite(led, HIGH); // switching on the led

    delay(1000); // stopping the program for 1000 milliseconds

    digitalWrite(led, LOW); // switching off the led

    delay(1000); // stopping the program for 1000 milliseconds

    }

    1.3.2 跑马灯。

    示意图

    原理图

    参考代码:

    int timer = 100; // The higher the number, the slower the timing.

    void setup() { // use a for loop to initialize each pin as an output:

    for (int thisPin = 2; thisPin < 8; thisPin++) {

    pinMode(thisPin, OUTPUT);

    }

    }

    void loop() {

    // loop from the lowest pin to the highest:

    for (int thisPin = 2; thisPin < 8; thisPin++) {

    // turn the pin on:

    digitalWrite(thisPin, HIGH);

    delay(timer);  

    // turn the pin off:

    digitalWrite(thisPin, LOW);

    }

    // loop from the highest pin to the lowest:

    for (int thisPin = 7; thisPin >= 2; thisPin--) {

    // turn the pin on:

    digitalWrite(thisPin, HIGH);

    delay(timer);

    // turn the pin off:

    digitalWrite(thisPin, LOW);

    }

    }

    1.3.3 按键控制。

    示意图

    原理图

    参考代码:

    // constants won't change. They're used here to

    // set pin numbers:

    const int buttonPin = 2; // the number of the pushbutton pin

    const int ledPin = 13; // the number of the LED pin

    // variables will change:

    int buttonState = 0; // variable for reading the pushbutton status

    void setup() {

    // initialize the LED pin as an output:

    pinMode(ledPin, OUTPUT);

    // initialize the pushbutton pin as an input:

    pinMode(buttonPin, INPUT);

    }

    void loop(){

    // read the state of the pushbutton value:

    buttonState = digitalRead(buttonPin);

    // check if the pushbutton is pressed.

    // if it is, the buttonState is HIGH:

    if (buttonState == HIGH) {

    // turn LED on:

    digitalWrite(ledPin, HIGH);

    }

    else {

    // turn LED off:

    digitalWrite(ledPin, LOW);

    }

    }

    • 中级:

    1.3.4 74HC595。

    本项目使用两个74HC595移位寄存器,仅用3个Arduino管脚控制16个LED。

    示意图

    原理图

    使用74HC595与数字直接控制LED有何优势,写出核心代码。(选做)

    595驱动电流大,35毫安每个端口,操作灵活,需要数据线,时钟线,锁存线,(三态控制线,清零线 可不用),数目多的话用595可以方便的组成动态显示,电路简单成本低。

    void _74hc595_init(void)  

    {

             gpio_config_t io_conf = {

            .intr_type = GPIO_PIN_INTR_DISABLE,

            .mode = GPIO_MODE_OUTPUT,

            .pin_bit_mask = (1ULL<

            .pull_down_en = 1,

            .pull_up_en = 0,

        };

        gpio_config(&io_conf);

        HC595_SCK_Low();

        HC595_RCK_Low();

        HC595_Data_Low();

    }

    void HC595_Save(void)

    {

       HC595_RCK_Low();   // 将RCK拉低

       delay(10);

       HC595_RCK_High();  // 再将RCK拉高,RCK即可产生一个上升沿

    }

    void HC595_Send_Byte(uint8_t byte)

    {

        uint8_t i;

        for (i = 0; i < 8; i ++)  //一个字节8位,传输8次,一次一位,循环8次,刚好移完8位

        {

            HC595_SCK_Low();   // SCK拉低

           if (byte & 0x80){      //先传输高位,通过与运算判断第八是否为1

               HC595_Data_High();    //如果第八位是1,则与 595 DS连接的引脚输出高电平

           }else{                  //否则输出低电平

               HC595_Data_Low();

           }

          

           byte <<= 1;       // 左移一位,将低位往高位移,通过  if (byte & 0x80)判断低位是否为1

           HC595_SCK_High();  // SHCP拉高, SHCP产生上升沿

        }

    }

    void HC595_Send_Multi_Byte(uint8_t *data, uint16_t len)

    {

        uint8_t i;

        for (i = 0; i < len; i ++ ) {

            HC595_Send_Byte(data[i]);

           debug_i("leve  :%d  data:%x",i,data[i]);

        }

        HC595_Save();

       

    }

    1.3.5 旋钮控制灯亮度。

    示意图

    原理图

    • 高级:

    开源机器人操作系统ROS和开源硬件Arduino[ESP32]联调(选修)

    ROS 1.0 Melodic

    /*

     * rosserial Subscriber Example

     * Blinks an LED on callback

     */

    #include

    #include

    ros::NodeHandle  nh;

    void messageCb( const std_msgs::Empty& toggle_msg){

      digitalWrite(13, HIGH-digitalRead(13));   // blink the led

    }

    ros::Subscriber sub("toggle_led", &messageCb );

    void setup()

    {

      pinMode(13, OUTPUT);

      nh.initNode();

      nh.subscribe(sub);

    }

    void loop()

      nh.spinOnce();

      delay(1);

    }

    依次分别在不同终端运行如下命令:

    roscore

    rosrun rosserial_python serial_node.py /dev/ttyUSB0

    rostopic pub toggle_led std_msgs/Empty --once

    观察LED灯状态。

    ROS 2.0 Dashing

    #include

    #define XRCEDDS_PORT  Serial

    void subscribeLed(std_msgs::Bool* msg, void* arg)

    {

      (void)(arg);

      digitalWrite(LED_BUILTIN, msg->data);

    }

    class LedSub : public ros2::Node

    {

    public:

      LedSub()

      : Node("ros2Arduino[ESP32]_sub_node")

      {

        this->createSubscriber("Arduino[ESP32]_led", (ros2::CallbackFunc)subscribeLed, nullptr);

      }

    };

    void setup()

    {

      XRCEDDS_PORT.begin(115200);

      while (!XRCEDDS_PORT);

      ros2::init(&XRCEDDS_PORT);

      pinMode(LED_BUILTIN, OUTPUT);

    }

    void loop()

    {

      static LedSub LedNode;

      ros2::spin(&LedNode);

    }

    1.4 实践内容

    阅读1.3中示意图、原理图和参考代码,在Arduino[ESP32]平台上完成实践。

    1.5 实践问题

    1.5.1交通灯:

    该电路可以被编码,使得汽车和行人交通灯都经过正常循环,直到行人按下按钮。在这种情况下,灯会改变对行人的偏好。

    示意图

    原理图

    请编写代码实现英文简介中的功能。

    void setup() {

            pinMode(LED_G, OUTPUT);

            pinMode(LED_Y, OUTPUT);

            pinMode(LED_R, OUTPUT);

      

    void loop() {

            digitalWrite(LED_G, LOW);点亮 绿灯

            delay(5000);//延时5秒

            digitalWrite(LED_G, HIGH); //熄灭 绿灯

            for(int i=0;i<3;i++)//闪烁交替三次,黄灯闪烁效果

            {

                    delay(500);//延时0.5 秒

                    digitalWrite(LED_Y, LOW);//点亮  黄灯

                    delay(500);//延时0.5 秒

                    digitalWrite(LED_Y, HIGH);//熄灭  黄灯

            }

            delay(500);//延时0.5 秒

            digitalWrite(LED_R, LOW);//点亮 红灯

            delay(5000);//延时5 秒

            digitalWrite(LED_R, HIGH);//熄灭 红灯

    }

    1.5.2 能否调节非PWM口外接的LED灯的亮度,为什么?

    能。

    PWM是一种脉冲宽度调制,也就是看高电平持续的时长。PWM占空比代表的是平均电压,占空比发生变化后LED和限流电阻两端的平均电压就会发生变化,那么流过LED的电流就会发生变化,这就是PWM调节亮度的原理。

    int potpin=0;

    int ledpin=11;

    int val=0;

    void setup()

    {

    pinMode ( ledpin, OUTPUT);

    Serial.begin(9600);

    }

    void loop ()

    {

    val=analogRead(potpin);

    Serial.println(val) ;

    analogWrite(ledpin, val);

    delay(10);

    }

    1.6 实践总结

    回顾本次实践,遇到哪些问题,如何解决,经验和启发有哪些?

    74HC595是一个8位串行输入、并行输出的位移缓存器:并行输出为三态输出。在SCK 的上升沿,串行数据由数据脚(A)输入到内部的8位位移缓存器,并由Q7’输出,而并行输出则是在LCK的上升沿将在8位位移缓存器的数据存入到8位并行输出缓存器。当串行数据输入端OE的控制信号为低使能时,并行输出端的输出值等于并行输出缓存器所存储的值。

    评分:                                                         

                                                                   


  • 相关阅读:
    【JVM基础】Java双亲委派机制
    本周内容整理
    缓存穿透、击穿、雪崩
    引擎入门 | Unity UI简介–第1部分(9)
    SpringBoot SpringBoot 基础篇 4 基于 SpringBoot 的SSMP 整合案例 4.3 实体类快速开发【lombok】
    【目标检测】36、OTA: Optimal Transport Assignment for Object Detection
    TCP SYNCookie机制
    HarmonyOS(鸿蒙)不再适合JS语言开发
    mac打开exe文件的三大方法 mac怎么运行exe文件 mac打开exe游戏 macbookpro打开exe
    持续集成/持续部署(3)Jenkins(2)
  • 原文地址:https://blog.csdn.net/ZhangRelay/article/details/126257248