Привет, я могу без проблем запустить этот код на 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(" ");
}
@gre_gor Я хочу использовать каждое значение, похожее на UNO, потому что я использую ESP32 для тестирования uno. Вот почему я не хочу использовать какую-либо библиотеку (я буду отправлять данные клиенту с esp32).
@Tryingtogetsome Этот код, который вы используете, не работает (даже в UNO). Помимо разного размера целых чисел, это работает случайно. Порядок выполнения ( Wire.read() | Wire.read() << 8)
не определен. Поэтому вы можете получить разные интерпретации даже в одном и том же бинарном файле.
@m2j Взял отсюда howtomechatronics.com . У него видео на ютубе 233 млрд просмотров. Я думал, что это правда, и именно поэтому я использовал его. Я также использовал это на C с stm. Я написал это как data_rec[1]<<8 | data_rec[0]
это правильно?
Вместо использования Int
, которое зависит от платформы. Используйте int16_t
, если вам это нужно для кросс-платформенной согласованности.
@Tryingtogetsome доступ к обоим индексам массива за один вызов не проблема. Вы не знаете порядок выполнения, но результат в любом случае хорошо определен. В отличие от Wire.read()
: здесь результат зависит от того, выбирает ли компилятор начать с левого или правого вызова. Я только что посмотрел на ваш источник. Они делают это неправильно. Сохраните первый и второй байт в промежуточных переменных, а затем соедините их. Лучше всего для этого написать небольшую функцию (например, readInt16()).
На Arduino Uno есть 16-битные целые числа. ADXL345, кажется, получает этот формат данных. Поэтому все играет красиво. Вы используете 32-битные целые числа на ESP32. Поэтому вы должны явно выбрать правильный тип данных. В противном случае отрицательные числа появляются в положительной области.
Порядок выполнения 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», теперь он работает.
int
на Uno — 16-бит, на ESP32 — 32-бит. Почему бы вам не использовать библиотеку, которая должна справиться с этим должным образом для вас?