Аналоговое преобразование угла из +70° в -70°

Я использую указанный ниже датчик (акселерометр). Мое приложение — это солнечный трекер, где я хотел преобразовать выходной сигнал датчика в формат от +70° до -70°.

Мой вопрос: как мне преобразовать угол?

#define ADC_ref 2.56
#define zero_x 1.569
#define zero_y 1.569    
#define zero_z 1.569    
#define sensitivity_x 0.3    
#define sensitivity_y 0.3    
#define sensitivity_z 0.3

unsigned int value_x;
unsigned int value_y;
unsigned int value_z;

float xv;
float yv;
float zv;

float angle_x;
float angle_y;
float angle_z;

void setup() {    
  //analogReference(INTERNAL2V56);    
  Serial.begin(9600);    
}

void loop() {    
  value_x = analogRead(A0);

//  value_y = analogRead(A1);
  //value_z = analogRead(A2);

  Serial.print("voltage  of x");
  Serial.println(value_x);
  /*Serial.print("voltage  of y");
   Serial.println(value_y);
   Serial.print("voltage  of z");
   Serial.println(value_z);
   */
  //xv=(value_x/1024.0*2.5)/sensitivity_x;
/*  zv=(value_z/1024.0*ADC_ref-zero_z)/sensitivity_z;
  yv=(value_y/1024.0*ADC_ref-zero_y)/sensitivity_y;
  xv=(0.0032226562499999998*value_x)/sensitivity_x;
  angle_x =atan2(-yv,-zv)*57.2957795+90;

  Serial.print ("x= ");
  Serial.println (xv);
  Serial.print("x_degree= ");
  Serial.print(angle_x);
  Serial.println(" deg");    

  /*Serial.print(" g ");       

   Serial.print ("y= ");
   Serial.print (yv);
   Serial.print(" g ");



   Serial.print ("z= ");
   Serial.print (zv);
   Serial.print(" g ");

   Serial.print("\n");

   Serial.print("Rotation ");

   Serial.print("x= ");

   angle_x =atan2(-yv,-zv)*57.2957795+180;

   Serial.print(angle_x);
   Serial.print(" deg");
   Serial.print(" ");

   Serial.print("y= ");

   angle_y =atan2(-xv,-zv)*57.2957795+180;

   Serial.print(angle_y);
   Serial.print(" deg");
   Serial.print(" ");

   Serial.print("z= ");

   angle_z =atan2(-yv,-xv)*57.2957795+180;

   Serial.print(angle_z);
   Serial.print(" deg");
   Serial.print("\n");
   */
  delay(1000);
  //delay(1000);
}
  • Описание

  • Техническое описание ADXL335

У меня есть инклинометр с полки, его Vout составляет 0~5 В, а угол измеряется от -70° до 70°, и я рассчитал, как показано ниже.

void calcPos()
{    
  Sensor_Value=analogRead(A3); 
  voltage = Sensor_Value * ARDUINO_ANALOG_SCALING;
  tracker_actual_pos=(30*voltage)-75;
}

, 👍2

Обсуждение

Если вы используете многоосевой акселерометр, такой как вы связали, для измерения углов, то вам, вероятно, нужно взять арктангенс отношения между двумя осями. Если это окажется слишком утомительным для вычисления, вы можете создать таблицу поиска тангенсов для каждого градуса или около того и искать в ней ближайшее значение., @Chris Stratton

Подождите... что не так с calcPos()?, @Anonymous Penguin

[CORDIC](https://en.wikipedia.org/wiki/CORDIC) может быть подходящим методом в качестве замены тригонометрическим функциям., @CharlieHanson

@CharlieHanson: Вы бы действительно использовали CORDIC на процессоре, у которого _есть_ аппаратный множитель? Вы когда-нибудь пробовали?, @Edgar Bonet

С таким вопросом сначала подумайте, *зачем* вам нужен угол в градусах. Если это для передачи в какую-то другую систему, возможно, можно передать в единицах измерения и заставить другую систему взять арктангенс. Или, если это для отображения с ограниченным разрешением, таблица поиска может быть вариантом. Вероятно, если вы делаете немного больше, ваш Arduino может вычислить арктангенс любым из нескольких методов, но в более нагруженной системе размышления о природе проблемы могут привести к лучшим решениям., @Chris Stratton


1 ответ


1

Таким образом, atan2(y,x) дает угол CCW от оси x в радианах, ограниченный [-pi,pi].

Если вы хотите преобразовать его в градусы по часовой стрелке от оси Y, вам нужно сделать

azimuth=90.0-atan2(y,x)*57.295779;  

Если вам нужно ограничить его значением -70,70, то:

azimuth_constrained=constrain(azimuth,-70,70);
,