常用传感器讲解一--遥控杆-KY-023(joystick)

简介: 常用传感器讲解一

主要电子材料

截屏2023-12-27 下午7.15.33.png

具体讲解

Arduino Uno操纵杆控制器主要用于机器人手臂,记录坐标。允许重复记录坐标一次单击按钮或重复。使用Arduino Uno基板,不用附加板。需要USB连接(2A)或6V / 2A电源。使用四个伺服SG90进行测试。
按下操纵杆k1上的按钮开始记录坐标。按下操纵杆1上的按钮结束坐标记录。
按下操纵杆2上的按钮,开始重播录制的坐标。按下操纵杆2上的按钮停止重播录制的坐标。按住操纵杆2上的按钮,开始循环自动回放所记录的坐标。

硬件连线

截屏2023-12-27 下午7.15.56.png

截屏2023-12-27 下午7.16.27.png

这里只有两个伺服连接的测试板。连接4台伺服电机见原理图。

代码展示

/* meArm analog joysticks version 1.3.1 - UtilStudio.com Dec 2018
   Uses two analogue joysticks and four servos.

   In version 1.3 was improved recording of coordinates.
   Some bugs was removed.

   First joystick moves gripper forwards, backwards, left and right,
   button start/stop recording positions.

   Second joystick moves gripper up, down, and closes and opens,
   button start/stop playing recorded positions.
   Press button for 2 seconds to autoplay.

   Pins:
   Arduino    Stick1    Stick2    Base   Shoulder  Elbow    Gripper   Record/
      GND       GND       GND    Brown     Brown   Brown     Brown    Auto play
       5V       VCC       VCC      Red       Red     Red       Red    LED
       A0       HOR
       A1       VER
       PD2      BUTT
       A2                 HOR
       A3                 VER
       PD3                BUTT
       11                       Yellow
       10                                 Yellow
        9                                         Yellow
        6                                                   Yellow
       PD4                                                            X
*/
#include <Servo.h>

bool repeatePlaying = false; /* Repeatedly is running recorded cycle */
int delayBetweenCycles = 2000; /* Delay between cycles */

int basePin = 11;       /* Base servo */
int shoulderPin = 10;   /* Shoulder servo */
int elbowPin = 9;       /* Elbow servo */
int gripperPin = 6;     /* Gripper servo */

int xdirPin = 0;        /* Base - joystick1*/
int ydirPin = 1;        /* Shoulder - joystick1 */
int zdirPin = 3;        /* Elbow - joystick2 */
int gdirPin = 2;        /* Gripper - joystick2 */

//int pinRecord = A4;     /* Button record - backward compatibility */
//int pinPlay = A5;       /* Button play  - backward compatibility */
int pinRecord = PD2;     /* Button record - recommended (A4 is deprecated, will by used for additional joystick) */
int pinPlay = PD3;       /* Button play  - recommended (A5 is deprecated, will by used for additional joystick) */
int pinLedRecord = PD4;  /* LED - indicates recording (light) or auto play mode (blink one) */

bool useInternalPullUpResistors = false;

const int buffSize = 512; /* Size of recording buffer */

int startBase = 90;
int startShoulder = 90;
int startElbow = 90;
int startGripper = 0;

int posBase = 90;
int posShoulder = 90;
int posElbow = 90;
int posGripper = 0;

int lastBase = 90;
int lastShoulder = 90;
int lastElbow = 90;
int lastGripper = 90;

int minBase = 0;
int maxBase = 150;
int minShoulder = 0;
int maxShoulder = 150;
int minElbow = 0;
int maxElbow = 150;
int minGripper = 0;
int maxGripper = 150;

const int countServo = 4;
int buff[buffSize];
int buffAdd[countServo];
int recPos = 0;
int playPos = 0;

int buttonRecord = HIGH;
int buttonPlay = HIGH;

int buttonRecordLast = LOW;
int buttonPlayLast = LOW;

bool record = false;
bool play = false;
bool debug = false;

String command = "Manual";
int printPos = 0;

int buttonPlayDelay = 20;
int buttonPlayCount = 0;

bool ledLight = false;

Servo servoBase;
Servo servoShoulder;
Servo servoElbow;
Servo servoGripper;

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

  if (useInternalPullUpResistors) {
   
   
    pinMode(pinRecord, INPUT_PULLUP);
    pinMode(pinPlay, INPUT_PULLUP);
  }
  else
  {
   
   
    pinMode(pinRecord, INPUT);
    pinMode(pinPlay, INPUT);
  }

  pinMode(xdirPin, INPUT);
  pinMode(ydirPin, INPUT);
  pinMode(zdirPin, INPUT);
  pinMode(gdirPin, INPUT);

  pinMode(pinLedRecord, OUTPUT);

  servoBase.attach(basePin);
  servoShoulder.attach(shoulderPin);
  servoElbow.attach(elbowPin);
  servoGripper.attach(gripperPin);

  StartPosition();

  digitalWrite(pinLedRecord, HIGH);
  delay(1000);
  digitalWrite(pinLedRecord, LOW);
}

void loop() {
   
   

  buttonRecord = digitalRead(pinRecord);
  buttonPlay = digitalRead(pinPlay);

  //  Serial.print(buttonRecord);
  //  Serial.print("\t");
  //  Serial.println(buttonPlay);
  //  for testing purposes

  if (buttonPlay == LOW)
  {
   
   
    buttonPlayCount++;

    if (buttonPlayCount >= buttonPlayDelay)
    {
   
   
      repeatePlaying = true;
    }
  }
  else buttonPlayCount = 0;

  if (buttonPlay != buttonPlayLast)
  {
   
   
    if (record)
    {
   
   
      record = false;
    }

    if (buttonPlay == LOW)
    {
   
   
      play = !play;
      repeatePlaying = false;

      if (play)
      {
   
   
        StartPosition();
      }
    }
  }

  if (buttonRecord != buttonRecordLast)
  {
   
   
    if (buttonRecord == LOW)
    {
   
   
      record = !record;

      if (record)
      {
   
   
        play = false;
        repeatePlaying = false;
        recPos = 0;
      }
      else
      {
   
   
        if (debug) PrintBuffer();
      }
    }
  }

  buttonPlayLast = buttonPlay;
  buttonRecordLast = buttonRecord;

  float dx = map(analogRead(xdirPin), 0, 1023, -5.0, 5.0);
  float dy = map(analogRead(ydirPin), 0, 1023, 5.0, -5.0);
  float dz = map(analogRead(zdirPin), 0, 1023, 5.0, -5.0);
  float dg = map(analogRead(gdirPin), 0, 1023, 5.0, -5.0);

  if (abs(dx) < 1.5) dx = 0;
  if (abs(dy) < 1.5) dy = 0;
  if (abs(dz) < 1.5) dz = 0;
  if (abs(dg) < 1.5) dg = 0;

  posBase += dx;
  posShoulder += dy;
  posElbow += dz;
  posGripper += dg;

  if (play)
  {
   
   
    if (playPos >= recPos) {
   
   
      playPos = 0;

      if (repeatePlaying)
      {
   
   
        delay(delayBetweenCycles);
        StartPosition();
      }
      else
      {
   
   
        play = false;
      }
    }

    bool endOfData = false;

    while (!endOfData)
    {
   
   
      if (playPos >= buffSize - 1) break;
      if (playPos >= recPos) break;

      int data = buff[playPos];
      int angle = data & 0xFFF;
      int servoNumber = data & 0x3000;
      endOfData = data & 0x4000;

      switch (servoNumber)
      {
   
   
        case 0x0000:
          posBase = angle;
          break;

        case 0x1000:
          posShoulder = angle;
          break;

        case 0x2000:
          posElbow = angle;
          break;

        case 0x3000:
          posGripper = angle;
          dg = posGripper - lastGripper;
          break;
      }

      playPos++;
    }
  }

  if (posBase > maxBase) posBase = maxBase;
  if (posShoulder > maxShoulder) posShoulder = maxShoulder;
  if (posElbow > maxElbow) posElbow = maxElbow;
  if (posGripper > maxGripper) posGripper = maxGripper;

  if (posBase < minBase) posBase = minBase;
  if (posShoulder < minShoulder) posShoulder = minShoulder;
  if (posElbow < minElbow) posElbow = minElbow;
  if (posGripper < minGripper) posGripper = minGripper;

  servoBase.write(posBase);
  servoShoulder.write(posShoulder);
  servoElbow.write(posElbow);

  bool waitGripper = false;
  if (dg < 0) {
   
   
    posGripper = minGripper;
    waitGripper = true;
  }
  else if (dg > 0) {
   
   
    posGripper = maxGripper;
    waitGripper = true;
  }

  servoGripper.write(posGripper);
  if (play && waitGripper)
  {
   
   
    delay(1000);
  }

  if ((lastBase != posBase) | (lastShoulder != posShoulder) | (lastElbow != posElbow) | (lastGripper != posGripper))
  {
   
   
    if (record)
    {
   
   
      if (recPos < buffSize - countServo)
      {
   
   
        int buffPos = 0;

        if (lastBase != posBase)
        {
   
   
          buffAdd[buffPos] = posBase;
          buffPos++;
        }

        if (lastShoulder != posShoulder)
        {
   
   
          buffAdd[buffPos] = posShoulder | 0x1000;
          buffPos++;
        }

        if (lastElbow != posElbow)
        {
   
   
          buffAdd[buffPos] = posElbow | 0x2000;
          buffPos++;
        }

        if (lastGripper != posGripper)
        {
   
   
          buffAdd[buffPos] = posGripper | 0x3000;
          buffPos++;
        }

        buffAdd[buffPos - 1] = buffAdd[buffPos - 1] | 0x4000;

        for (int i = 0; i < buffPos; i++)
        {
   
   
          buff[recPos + i] = buffAdd[i];
        }

        recPos += buffPos;
      }
    }

    command = "Manual";
    printPos = 0;

    if (play)
    {
   
   
      command = "Play";
      printPos = playPos;
    }
    else if (record)
    {
   
   
      command = "Record";
      printPos = recPos;
    }

    Serial.print(command);
    Serial.print("\t");
    Serial.print(printPos);
    Serial.print("\t");
    Serial.print(posBase);
    Serial.print("\t");
    Serial.print(posShoulder);
    Serial.print("\t");
    Serial.print(posElbow);
    Serial.print("\t");
    Serial.print(posGripper);
    Serial.print("\t");
    Serial.print(record);
    Serial.print("\t");
    Serial.print(play);
    Serial.println();
  }

  lastBase = posBase;
  lastShoulder = posShoulder;
  lastElbow = posElbow;
  lastGripper = posGripper;

  if ( repeatePlaying)
  {
   
   
    ledLight = !ledLight;
  }
  else
  {
   
   
    if (ledLight)
    {
   
   
      ledLight = false;
    }

    if (record)
    {
   
   
      ledLight = true;
    }
  };

  digitalWrite(pinLedRecord, ledLight);
  delay(50);
}

void PrintBuffer()
{
   
   
  for (int i = 0; i < recPos; i++)
  {
   
   
    int data = buff[i];
    int angle = data & 0xFFF;
    int servoNumber = data & 0x3000;
    bool endOfData = data & 0x4000;

    Serial.print("Servo=");
    Serial.print(servoNumber);
    Serial.print("\tAngle=");
    Serial.print(angle);
    Serial.print("\tEnd=");
    Serial.print(endOfData);
    Serial.print("\tData=");
    Serial.print(data, BIN);
    Serial.println();
  }
}

void StartPosition()
{
   
   
  int angleBase = servoBase.read();
  int angleShoulder = servoShoulder.read();
  int angleElbow = servoElbow.read();
  int angleGripper = servoGripper.read();

  Serial.print(angleBase);
  Serial.print("\t");
  Serial.print(angleShoulder);
  Serial.print("\t");
  Serial.print(angleElbow);
  Serial.print("\t");
  Serial.print(angleGripper);
  Serial.println("\t");

  posBase = startBase;
  posShoulder = startShoulder;
  posElbow = startElbow;
  posGripper = startGripper;

  servoBase.write(posBase);
  servoShoulder.write(posShoulder);
  servoElbow.write(posElbow);
  servoGripper.write(posGripper);
}
相关文章
|
人工智能 搜索推荐 算法
豆包角色制作指南
这篇文章是一份豆包角色制作指南,介绍了如何使用虚拟角色生成器创建IP或非IP角色,以及创作对话人物sp的技巧和Bot主动发消息的技巧。
|
传感器 编解码 IDE
ESP32开发板引脚介绍【附有引脚使用实例】
ESP32开发板引脚介绍👨‍🏫内容1:背景👨‍⚖️内容2:限制类引脚👨‍💻内容3:ESP32 周边设备🍉文末备注 👨‍🏫。
ESP32开发板引脚介绍【附有引脚使用实例】
|
9月前
|
编解码 Java Shell
安卓虚拟摄像头,vcam虚拟摄像头,安卓免root虚拟摄像头
采用动态Hook+视频流替换方案,通过Xposed框架拦截系统相机服务,实现免Root环境下的虚拟摄像头功能
|
传感器 IDE 开发工具
使用两块ESP8266实现ESP-NOW通信
ESP-NOW是一个强大的协议,可以在没有Wi-Fi网络的情况下实现设备间的快速通信。通过以上步骤,你可以使用两块ESP8266开发板建立一个简单的ESP-NOW通信系统。这种方式特别适用于低功耗、低延迟和无需网络基础设施的应用场景。希望这篇博客能帮你快速入门ESP-NOW,开启你的无线通信开发之旅。
1954 4
|
安全 C语言
C 标准库 - <stddef.h>详解
`&lt;stddef.h&gt;` 是 C 标准库的一个头文件,定义了常用类型和宏,包括 `size_t`(表示对象大小)、`ptrdiff_t`(指针间差值)、`NULL`(空指针)和 `offsetof`(计算结构体成员偏移量)。
|
容器
【LVGL快速入门】LVGL开源框架入门教程之框架使用(二)
【LVGL快速入门】LVGL开源框架入门教程之框架使用(二)
977 1
|
图形学
ThreeJs创建管道效果
这篇文章介绍了在Three.js中创建管道(Tube)效果的方法和技术细节。
596 4
ThreeJs创建管道效果
|
JavaScript API
给 element-plus 增加一个防抖的功能(一)
element-plus 功能非常强大,但是好像只有 el-autocomplete 提供了一个防抖功能,其他表单子控件并没有提供防抖功能,而 el-autocomplete 的防抖和我想要的效果又不太一样,所以只好写个函数实现我想要的防抖效果。