常用传感器讲解一--遥控杆-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);
}
相关文章
|
物联网 智能硬件
物联卡如何选择
选择物联卡需综合考量设备类型与数量、流量需求及卡种特性。明确设备属性后,挑选适宜流量套餐,并了解普通物联网卡、语音卡、NB-IoT卡及陶瓷卡等不同类型的应用场景。同时考虑网络覆盖、服务质量及成本预算,优选性价比高且售后服务完善的运营商,确保物联卡兼容设备并顺利完成实名认证。
物联卡如何选择
|
存储 JSON 物联网
设备管理组件功能介绍
设备管理组件功能介绍
640 2
|
传感器 编解码 IDE
|
人工智能 监控 算法
基于蓝牙iBeacon定位技术与3DCIS技术的室内定位导航系统,助力智慧空间管理
**维小帮室内定位导航系统**采用3D可视化、蓝牙iBeacon、AI路径规划及物联网技术,提供精准室内导航。系统支持3D/AR导航、实时定位、电子围栏功能,广泛应用于商场、医院、办公楼和园区,提升用户体验并优化管理。例如,商场中的精准营销,医院的智能导诊,办公楼的效率提升,园区的综合管理。通过智能路径规划,确保用户在复杂环境中无碍通行。
745 1
基于蓝牙iBeacon定位技术与3DCIS技术的室内定位导航系统,助力智慧空间管理
|
数据可视化 定位技术 vr&ar
商场3D楼层导视软件功能详解与实施效益
**维小帮3D楼层导视软件**提供创新的商场导航体验:3D地图清晰呈现楼层布局,跨楼层导航智能规划路径;实时定位防止迷路;AR实景导航增强沉浸感;广告推送及可视化招商平台助力商业运营。软件结合VR、AR技术,优化顾客导航,促进营销,实现智慧化管理与招商,引领商场服务升级。
795 1
商场3D楼层导视软件功能详解与实施效益
|
安全 算法 小程序
院内智能导航系统赋能医院智慧化转型,加速医疗服务升级
**智慧医院的智能导航系统**是医疗数字化转型的关键,它改善患者就医体验,减轻医务人员压力,优化资源配置并强化安全监管。3D导航、AR指路、VR辅助、自动导诊和停车管理等先进技术,结合实时定位功能,确保精准、快捷的导航服务。此系统减少患者寻路时间,降低服务台咨询量,优化医院交通,增强患者安全,同时提高就医效率和医院信息化水平。
543 1
院内智能导航系统赋能医院智慧化转型,加速医疗服务升级
|
消息中间件 分布式计算 网络协议
从管道路由到共享内存:进程间通信的演变(内附通信方式经典面试题及详解)
进程间通信(Inter-Process Communication, IPC)是计算机科学中的一个重要概念,指的是运行在同一系统或不同系统上的多个进程之间互相发送和接收信息的能力。IPC机制允许进程间共享数据、协调执行流程,是实现分布式系统、多任务操作系统和并发编程的基础。
355 1
从管道路由到共享内存:进程间通信的演变(内附通信方式经典面试题及详解)