P3022-V1-CW360的精度调试(原理是基于AD采样)

一、模块了解

我们在使用模块时,要进行所用的传感器的有一定的了解,霍尔角度传感器是一种微型360度传感器,其基于霍尔效应原理工作。它与DFRobot重力传感器接口兼容,并使用5V DC电源。模拟输出也是0〜5V,因此可以直接与Arduino一起使用。

霍尔角度传感器通过将其角度信息转换为电信号来工作。当物体的旋转角度传递到旋转轴传感器时,它会输出与旋转角度成比例的电信号。

首先要特性了解:
在这里插入图片描述
其次是机械结构了解:
在这里插入图片描述

二、模块连接图(单模块)

在这里插入图片描述
将P3022-V1-CW360模块的OUT引脚连接到Uno的A2模拟口,GNG<–>GND,VCC<–>5V。(这有个注意点,我们应该用电压表测量一下基准电压的实际大小,我的实际测量就是4.980,有的可能误差很大。)

三、测试代码(单模块)

AD采样的代码(未将其转化成角度):

/***************************************************
* Hall angle sensor
* ****************************************************
* This example for AD
* @author YUYU
* @version  V1.0
* @date  2019-10-19
* ****************************************************/

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  float analogValue = analogRead(A2);     //Voltage reading
  float Voltage = analogValue/1024.0 * 4.980;  //Angle calculation  (  UNO is a 10-bit AD )
  Serial.print("Voltage:");
  Serial.println(Voltage);
}

测试结果:
在这里插入图片描述
由上测试结果可看:误差在0.01v。

转化为角度的第一版测试代码如下:

/***************************************************
* Hall angle sensor
* ****************************************************
* This example for AD
* @author YUYU
* @version  V1.0
* @date  2019-10-20
* ****************************************************/
const int PIN_AD = A0; //pin connection
float sensorVolt; //unit: mV
float angle; //unit: centigrade
void setup()
{
  sensorVolt =0;
  pinMode(PIN_AD,INPUT);
  Serial.begin(115200);
}

void loop()
{
  sensorVolt = analogRead(PIN_AD); //转后的电压值
 angle =(sensorVolt)/1024 * 360.0;  //Angle calculation  (  UNO is a 10-bit AD )
 Serial.print("angle: "); //print the result
 Serial.println(angle);
 Serial.println("°");  
}

执行的结果:
在这里插入图片描述
又找了比较多的资料,进行改版后的代码:

/***************************************************
* Hall angle sensor
* ****************************************************
* This example for AD
* @author YUYU
* @version  V1.0
* @date  2019-10-21
* ****************************************************/
const int PIN_AD = A0; //pin connection
float sensorVolt; //unit: mV
float angle; //unit: centigrade
void setup()
{
  sensorVolt =0;
  pinMode(PIN_AD,INPUT);
  Serial.begin(115200);
}

void loop()
{
  sensorVolt = analogRead(PIN_AD); //转后的电压值
angle=sensorVolt/2.82;  //这个代码的改写原理有点没搞懂,但是可以实现306度
 Serial.print("angle: "); //print the result
 Serial.println(angle);
 Serial.println("°");  
}

执行结果:
在这里插入图片描述

四、整体测试(电机+激光+角度传感器)

1.采样频率为默认情况下的测试
测试代码:

/***************************************************
* Hall angle sensor
* ****************************************************
* This example for AD
* @author YUYU
* @version  V1.1
* @date  2019-10-22
* ****************************************************/
#define dir_pin 2
#define en_pin 5
#define stp_pin 6

//角度传感器的相关参数
const int PIN_AD = A0; //pin connection
float sensorVolt =0; //unit: mV
float angle; //unit: centigrade

//激光雷达的相关变量机常量
float range = 0;//目标距离
unsigned char uart[8]={0},counter = 0;//存放雷达测量的数据
unsigned char data[3]={0};
unsigned char sign=0;
const unsigned char HEADER=0x55;//数据包帧头
const unsigned char END=0xAA;//终止序列

//将接收的数据整合到一个结构体中,使其存储到一个连续的内存中,较为高效
struct Target_Bits
{
  unsigned char    Target_header:8;        /* 0:7    */
  unsigned char    Target_key:8;           /* 8:15   */
  unsigned char    Target_value:8;          /* 16:23  */
  unsigned char    Target_data1:8;         /* 24:31  */
  unsigned char    Target_data2:8;          /* 32:39  */
  unsigned char    Target_data3:8;         /* 40:47  */
  unsigned char    Target_CRC:8;            /* 48:55  */
  unsigned char    Target_end:8;           /* 56:63  */
};

//联合表示几个变量公用一个内存位置, 在不同的时间保存不同的数据类型和不同长度的变量
typedef union{                    
  unsigned char Byte[8];
  struct  Target_Bits bit;
}TargetData;

void setup()
{  
  Serial.begin(115200);//设置arduino与电脑连接串口的波特率
  Serial1.begin(115200);//设置雷达与arduino连接串口的波特率
           
  //set timer4
    TCCR4A = 0;
    TCCR4B = 0;
    TCNT4  = 0;
    // Mode 10: phase correct PWM with ICR4 as Top (= F_CPU/2/25000)
    // OC4A OC4B OC4C as Non-Inverted PWM output
    ICR4   = (F_CPU/2000)/2;
    TCCR4A =_BV(COM4A1) | _BV(COM4B1) | _BV(COM4C1) | _BV(WGM41);
    TCCR4B = _BV(WGM43) | _BV(CS40);
    
    // Set the PWM pin as output.
    pinMode(2,OUTPUT);
    pinMode(6,  OUTPUT);
    //模拟量输入
    pinMode(PIN_AD,INPUT);
    
}

void loop()
{
    //just set this for step motor
    Pwm_out(6,1000);
    digitalWrite(2,HIGH);

    sensorVolt = analogRead(PIN_AD); //转后的电压值
    angle=sensorVolt/2.82; 
//    Serial.print("angle: "); //print the result
//    Serial.print(angle);    
//    Serial.println(" 度"); 
    
    if(sign)
   { 
       sign=0;
       if(uart[1]==0x07)
       {
          TargetData TargetData;
          for (uint8_t i = 0; i < 8; i++)
          {
            TargetData.Byte[i] = uart[i];    //  Buf指向有效数据起始
    //       Serial.print(TargetData.Byte[i]);
    //       Serial.print("\n");
          }
          for(int j =0;j<3;++j)
          {
            data[j]=TargetData.Byte[j+3];
           }
         range=readCharToLL(data,3);
         Serial.print(range);
         Serial.print(",");
         Serial.print(angle);    
         Serial.print("\n");
       }                               
    } 
    
}

//激光数据采集
void serialEvent1() {
    while (Serial1.available()) {
    uart[counter]=(unsigned char)Serial1.read();
    if(counter==0&&uart[0]!=HEADER) return;      //第0号数据不是帧头             
    counter++;   
    if(counter==8)             //接收到8个数据
    { 
       counter=0;               //重新赋值,准备下一帧数据的接收 
       sign=1;
    }   
  }
}

/** 
 * 将unsigned char数组转换成long long数值
 * @param str 数组 
 * @param len str数组长度
 * @returns 0 on error
 */
int readCharToLL(unsigned char* str, int len)
{
    if (str == NULL||len <= 0)  //指针的判断
    {
        return 0;
    }
    int i = 0;
    int value = 0;
    for (i=0;i<len;i++)
    {
        value = value*16*16 + (str[i]/16)*16 + str[i]%16;
    }
    return value;
}

//motor driver 
void Pwm_out(int pin ,int value)
{ 
  switch(pin){
    case 5:
        OCR3A = value;
        break;    
    case 6:
        OCR4A = value;
        break;
    case 7:
        OCR4B = value;
        break;
    case 8:
        OCR4C = value;
        break;
    default:
        //no other pin will work
        break;  
  }
}

测试结果:
在这里插入图片描述
从上图看,角度值有缺失(这个问题还有待探究)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值