ESP32 ADXL345 не получает отрицательных значений

Привет, я могу без проблем запустить этот код на Arduino UNO. Мой вывод выглядит так: 0.05 0.10 1.01 Но когда я запускаю этот код на ESP32, мой вывод: 255.89 255.81 0.99, и я не вижу отрицательного значения. В чем проблема?
Необработанные значения X, Y, Z ESP32, такие как: 6500 0 , 65000 , 1. ESP32 не может получить отрицательные значения. Мне нужно что-то сделать с wire.h, и мне нужно что-то изменить в uint8_t или uint16_t, но я действительно не понимаю, как мне решить эту проблему.

#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
float X, Y, Z ;
void setup() {
  Serial.begin(115200); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device
  Wire.write(0x31);
  Wire.write(0x0B);
  Wire.endTransmission();

  Wire.beginTransmission(ADXL345);
  Wire.write(0x20); // Z-axis offset register
  Wire.write(-7);
  Wire.endTransmission();
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(0x08); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
  Wire.endTransmission();
  Wire.beginTransmission(ADXL345);
  Wire.write(0x2C);
  // Enable measurement
  Wire.write(0x09); //For low power 000x x pin set to 1  /1001 determine Hz
  Wire.endTransmission();
  delay(10);
}
void loop() {
  unsigned long Time = millis();
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
  X = X_out /256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
  Y = Y_out /256;
  Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
  Z = Z_out /256;
  delay(20);
  Serial.print(X);
  Serial.print(" ");
  Serial.print(Y);
  Serial.print(" ");
  Serial.print(Z);
  Serial.println(" ");
}
int на Uno — 16-бит, на ESP32 — 32-бит. Почему бы вам не использовать библиотеку, которая должна справиться с этим должным образом для вас?
gre_gor 08.12.2022 15:17

@gre_gor Я хочу использовать каждое значение, похожее на UNO, потому что я использую ESP32 для тестирования uno. Вот почему я не хочу использовать какую-либо библиотеку (я буду отправлять данные клиенту с esp32).

Tryingtogetsome 08.12.2022 15:31

@Tryingtogetsome Этот код, который вы используете, не работает (даже в UNO). Помимо разного размера целых чисел, это работает случайно. Порядок выполнения ( Wire.read() | Wire.read() << 8) не определен. Поэтому вы можете получить разные интерпретации даже в одном и том же бинарном файле.

m2j 08.12.2022 16:34

@m2j Взял отсюда howtomechatronics.com . У него видео на ютубе 233 млрд просмотров. Я думал, что это правда, и именно поэтому я использовал его. Я также использовал это на C с stm. Я написал это как data_rec[1]<<8 | data_rec[0] это правильно?

Tryingtogetsome 08.12.2022 20:39

Вместо использования Int, которое зависит от платформы. Используйте int16_t, если вам это нужно для кросс-платформенной согласованности.

hcheung 09.12.2022 00:40

@Tryingtogetsome доступ к обоим индексам массива за один вызов не проблема. Вы не знаете порядок выполнения, но результат в любом случае хорошо определен. В отличие от Wire.read(): здесь результат зависит от того, выбирает ли компилятор начать с левого или правого вызова. Я только что посмотрел на ваш источник. Они делают это неправильно. Сохраните первый и второй байт в промежуточных переменных, а затем соедините их. Лучше всего для этого написать небольшую функцию (например, readInt16()).

m2j 09.12.2022 13:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
  1. На Arduino Uno есть 16-битные целые числа. ADXL345, кажется, получает этот формат данных. Поэтому все играет красиво. Вы используете 32-битные целые числа на ESP32. Поэтому вы должны явно выбрать правильный тип данных. В противном случае отрицательные числа появляются в положительной области.

  2. Порядок выполнения Wire.read()-вызовов не определен в вашем коде. Поэтому компилятор может объединить байты 0xAA и 0xBB с 0xAABB или 0xBBAA. Вы должны добавить точку следования, чтобы убедиться, что код делает то, что задумано.

Я не тестировал этот код. Это должен быть правильный порядок, если я правильно понял описание таблицы:

int16_t readInt16()
{
    int lsb = Wire.read();
    int msb = Wire.read();
    return int16_t(lsb | msb << 8);
}

X_out = readInt16() / 256.f;
Y_out = readInt16() / 256.f;
Z_out = readInt16() / 256.f;

Спасибо @ m2j, я уже изменил свой код после того, как вы сказали мне, но я не смог получить значение с плавающей запятой. После этого комментария я добавил «256.f», теперь он работает.

Tryingtogetsome 10.12.2022 10:14

Другие вопросы по теме