Возникли проблемы с совместной печатью MPU6050 и AFE4404, потенциальный конфликт?
У меня возникли проблемы с совместной работой двух датчиков. Всего к Arduino подключено четыре датчика, и хотя MPU и AFE по отдельности отлично работают с двумя другими датчиками, когда они объединены, появляется только последовательный плоттер для AFE, в то время как MPU остается на нуле. Сначала я предположил, что у них были конфликты адресов, но их адреса i2c разные: AFE на 0x58 и MPU на 0x68 или 0x69. Как я могу решить проблему, чтобы распечатать графики всех четырех датчиков? Ниже мой код Arduino:
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
//целое предзначение = 0;
String str = "0, 0, 0, 0";
int mic = A0;
MPU6050 mpu;
int16_t ax, ay, az;
//Продукты PPG
#define NUM_REGISTERS 40
/* Pinbelegung */
int RESETZ = 4;
int CLK = 5;
int INT = 6;
//const int ocr1aval = 1; //||0 = 8 МГц|| 1 = 4 МГц || 3 = 2 МГц || 7 = 1 МГц ||
const byte interruptPin = 2;
char LED2 = 0x2A; // LED2 на AFE4404
struct Register {
uint8_t addr;
uint32_t val;
};
/* Variablendeklaration */
// с плавающей запятой befehl = 0;
bool Ready = 1;
int AFE_ADDR = 0x58;
unsigned long counter = 0;
/* AFE440X registers */
#define AFE_CONTROL0 0x00
#define AFE_LED2STC 0x01
#define AFE_LED2ENDC 0x02
#define AFE_LED1LEDSTC 0x03
#define AFE_LED1LEDENDC 0x04
#define AFE_ALED2STC 0x05
#define AFE_ALED2ENDC 0x06
#define AFE_LED1STC 0x07
#define AFE_LED1ENDC 0x08
#define AFE_LED2LEDSTC 0x09
#define AFE_LED2LEDENDC 0x0A
#define AFE_ALED1STC 0x0B
#define AFE_ALED1ENDC 0x0C
#define AFE_LED2CONVST 0x0D
#define AFE_LED2CONVEND 0x0E
#define AFE_ALED2CONVST 0x0F
#define AFE_ALED2CONVEND 0x10
#define AFE_LED1CONVST 0x11
#define AFE_LED1CONVEND 0x12
#define AFE_ALED1CONVST 0x13
#define AFE_ALED1CONVEND 0x14
#define AFE_ADCRSTSTCT0 0x15
#define AFE_ADCRSTENDCT0 0x16
#define AFE_ADCRSTSTCT1 0x17
#define AFE_ADCRSTENDCT1 0x18
#define AFE_ADCRSTSTCT2 0x19
#define AFE_ADCRSTENDCT2 0x1A
#define AFE_ADCRSTSTCT3 0x1B
#define AFE_ADCRSTENDCT3 0x1C
#define AFE_PRPCOUNT 0x1D
#define AFE_CONTROL1 0x1E
#define AFE_TIA_GAIN_SEP 0x20
#define AFE_TIA_GAIN 0x21
#define AFE_LEDCNTRL 0x22
#define AFE_CONTROL2 0x23
#define AFE_ALARM 0x29
#define AFE_LED2VAL 0x2A
#define AFE_ALED2VAL 0x2B
#define AFE_LED1VAL 0x2C
#define AFE_ALED1VAL 0x2D
#define AFE_LED2_ALED2VAL 0x2E
#define AFE_LED1_ALED1VAL 0x2F
#define AFE_CONTROL3 0x31
#define AFE_PDNCYCLESTC 0x32
#define AFE_PDNCYCLEENDC 0x33
#define AFE_PROG_TG_STC 0x34
#define AFE_PROG_TG_ENDC 0x35
#define AFE_LED3LEDSTC 0x36
#define AFE_LED3LEDENDC 0x37
#define AFE_CLKDIV_PRF 0x39
#define AFE_OFFDAC 0x3A
#define AFE_DEC 0x3D
#define AFE_AVG_LED2_ALED2VAL 0x3F
#define AFE_AVG_LED1_ALED1VAL 0x40
void setup() {
Serial.begin(115200);
//ЭКГ
pinMode(10, INPUT); // Настройка обнаружения отсоединения LO +
pinMode(11, INPUT); // Настройка для обнаружения отведений LO -
//ПКГ
/*none needed*/
//ППГ
pinMode(RESETZ, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(INT, INPUT);
AFE_Init();
//SCG
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// инициализируем устройство
mpu.initialize();
}
void PCG_Init()
{
double micOut;
const int sampleTime = 50;
double preValue = 0;
}
void loop() {
// поместите сюда ваш основной код для многократного запуска:
String ECG = "0";
// Строка SCG = "0";
int PCG_val;
String PCG;
PCG_val = PCG_loop();
PCG = String(PCG_val);
int PPG_val;
String PPG;
PPG_val = PPG_loop() * -1;
PPG = String(PPG_val);
// int ECG_val;
// строка ЭКГ;
// ECG_val = ECG_loop();
// ЭКГ = строка(ECG_val);
int SCG_val;
String SCG;
SCG_val = SCG_loop();
SCG = String(SCG_val);
str = PCG + "," + PPG + "," + ECG + "," + SCG;
Serial.println(str);
delay(10);
}
// Цикл ЭКГ
int ECG_loop() {
// поместите сюда ваш основной код для многократного запуска:
if((digitalRead(10) == 1)||(digitalRead(11) == 1)){
Serial.println('!');
}
else{
// отправить значение аналогового входа 0:
Serial.println(analogRead(A1));
}
//Подождем немного, чтобы последовательные данные не насыщались
delay(1);
// задержка (30);
}
//Цикл SCG
int SCG_loop() {
mpu.getAcceleration(&ax, &ay, &az);
Serial.println(az/(pow(2,9)*1.0));
}
// Цикл PCG
int PCG_loop() {
//выключатель
//Случай 1:
int returnfill;
double micOutput = findPTPAmp();
returnfill = VUMeter(micOutput);
return returnfill;
}
// Находим функцию амплитуды от пика к пику
double findPTPAmp(){
// Переменные времени для нахождения размаха амплитуды
unsigned long startTime= millis(); // Начало окна примера
/*unsigned int*/ double PTPAmp = 0;
// Переменные сигнала для определения размаха амплитуды
/*unsigned int*/ double maxAmp = 0;
/*unsigned int*/ double minAmp = 1023;
// Найдите максимальное и минимальное значение выходного сигнала микрофона за период 50 мс
while(millis() - startTime < sampleTime)
{
micOut = analogRead(mic);
if( micOut < 1023) //предотвратить ошибочные показания
{
if (micOut > maxAmp)
{
maxAmp = micOut; //сохраняем только максимальное значение
}
else if (micOut < minAmp)
{
minAmp = micOut; //сохраняем только минимальное значение
}
}
}
PTPAmp = maxAmp - minAmp; // (макс. усилие) - (минимальное усиление) = размах амплитуды
double micOut_Volts = (PTPAmp * 3.3) / 1024; // Преобразование АЦП в напряжение
return PTPAmp;
}
// Функция Volume Unit Meter: сопоставьте амплитуду PTP с единицей громкости от 0 до 10.
int VUMeter(double micAmp){
double fill = map(micAmp, 23, 750, 0, 10);
while(fill != preValue)
{
preValue = fill;
}
return fill;
}
//Цикл PPG
signed long val = 0;
void readADC()
{
{
val = AFE_Reg_Read(LED2);
Ready = 1;
}
}
int PPG_loop() {
if (digitalRead(INT))
{
val = AFE_Reg_Read(LED2);
}
return val;
}
//Дополнительные сведения о PPG
void AFE_Init()
{
AFE_RESETZ_Init();
AFE_Enable_HWPDN();
AFE_Disable_HWPDN();
AFE_Trigger_HWReset();
Wire.begin();
Wire.beginTransmission (AFE_ADDR);
Serial.println("Initializing AFE4404...");
if (Wire.endTransmission () == 0)
{
AFE_Enable_Write (); // разрешаем запись в регистры
AFE_Reg_Init();
AFE_CLK_Init();
AFE_Enable_Read (); // разрешить чтение из регистров
Serial.println("Initialized Success!");
}
else
Serial.println("Initialized Fail!");
}
/**********************************************************************************************************/
/* AFE4404_Registerinitialisierung */
/**********************************************************************************************************/
void AFE_Reg_Init()
{
//AFE_Reg_Write(34, 0x0033C3);
AFEinitRegisters();
}
/**********************************************************************************************************/
/* AFE4404_Enable_Read */
/**********************************************************************************************************/
void AFE_Enable_Read () //Запретить запись в регистры
{
byte configData[3];
configData[0] = 0x00;
configData[1] = 0x00;
configData[2] = 0x01;// 0x01
I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}
/**********************************************************************************************************/
/* AFE4404_Disable_Read */
/**********************************************************************************************************/
void AFE_Enable_Write () // Разрешить запись в регистры
{
byte configData[3];
configData[0] = 0x00;
configData[1] = 0x00;
configData[2] = 0x00; //0x00
I2C_write (AFE_ADDR, AFE_CONTROL0, configData, 3);
}
/**********************************************************************************************************/
/* RESETZ des AFE4404 wird Initialisiert */
/**********************************************************************************************************/
void AFE_RESETZ_Init()
{
digitalWrite(RESETZ, HIGH);
delayMicroseconds(30);
}
/**********************************************************************************************************/
/* Reset internal registers by setting RESETZ = LOW for 25 - 50 us */
/**********************************************************************************************************/
void AFE_Trigger_HWReset()
{
digitalWrite(RESETZ, LOW); //Устанавливает контакты 22-29 Arduino в НИЗКИЙ уровень
delayMicroseconds(30); //30
digitalWrite(RESETZ, HIGH); // Устанавливает контакты Arduino 22-29 HIGH
delay(10); // 10
}
/**********************************************************************************************************/
/* AFE4404 Power Down */
/**********************************************************************************************************/
void AFE_Enable_HWPDN()
{
digitalWrite(RESETZ, LOW); // Выключите питание, установив вывод RESETZ в LOW более чем на 200 мкс
delay(10);
}
/**********************************************************************************************************/
/* AFE4404 Power Up */
/**********************************************************************************************************/
void AFE_Disable_HWPDN()
{
digitalWrite(RESETZ, HIGH); // Включите AFE, установив вывод RESETZ в состояние HIGH
delay(10);
}
/**********************************************************************************************************/
/* AFE4404 Set Clock Mode to Internal */
/**********************************************************************************************************/
void AFE_CLK_Init()
{
AFE_Reg_Write(35, 0x104218); // Установите режим CLK на внутренние часы (по умолчанию Wert: 124218 с внутренним CLK)
AFE_Reg_Write(41, 0x2); // Не устанавливайте внутренние часы на вывод CLK для внешнего использования
AFE_Reg_Write(49, 0x000021); //Коэффициент деления для режима внешней синхронизации установлен в соответствии с Arduino Mega 16MHz
AFE_Reg_Write(57, 0); // Установите нижнюю частоту дискретизации на 61 Гц (~ 17 мс)
}
/*********************************************************************************************************/
/* AFE4404_Reg_Write */
/*********************************************************************************************************/
void AFE_Reg_Write (int reg_address, unsigned long data)
{
byte configData[3];
configData[0] = (byte)(data >> 16);
configData[1] = (byte)(((data & 0x00FFFF) >> 8));
configData[2] = (byte)(((data & 0x0000FF)));
I2C_write(AFE_ADDR, reg_address, configData, 3);
}
/*********************************************************************************************************/
/* AFE4404_Reg_Read */
/*********************************************************************************************************/
signed long AFE_Reg_Read(int reg_address)
{
byte configData[3];
signed long retVal;
I2C_read (AFE_ADDR, reg_address, configData, 3);
retVal = configData[0];
retVal = (retVal << 8) | configData[1];
retVal = (retVal << 8) | configData[2];
if (reg_address >= 0x2A && reg_address <= 0x2F)
{
if (retVal & 0x00200000) // проверяем, является ли значение ADC положительным или отрицательным
{
retVal &= 0x003FFFFF; // преобразовать его в 22-битное значение
return (retVal ^ 0xFFC00000);
}
}
return retVal;
}
/**********************************************************************************************************/
/* Write to AFE on I2C */
/**********************************************************************************************************/
char I2C_write (int slave_address, int reg_address, byte configData[], int byteCount)
{
int trans_end = 0;
signed long retVal;
Wire.beginTransmission(slave_address);
Wire.write(reg_address);
Serial.print(configData[0]);
Serial.print(",");
Serial.print(configData[1]);
Serial.print(",");
Serial.println(configData[2]);
retVal = configData[0];
retVal = (retVal << 8) | configData[1];
retVal = (retVal << 8) | configData[2];
Serial.println(retVal);
Serial.println(reg_address);
Wire.write(configData, 3);
Serial.println("test");
Wire.endTransmission();
return (trans_end);
/* while(1)
{
if(byteCount == 0)
{
Wire.endTransmission();
Serial.println("test");
return (trans_end);
}else{
//целое число без знака reg_data = (целое число без знака) *write_data++;
Wire.write(configData, 3);
byteCount--;
}
}*/
}
/**********************************************************************************************************/
/* Read Data of AFE on I2C */
/**********************************************************************************************************/
char I2C_read(int slave_address, int reg_address, byte *read_Data, int byteCount)
{
int trans_end = 0;
Wire.beginTransmission(slave_address);
Wire.write(reg_address);
Wire.endTransmission();
Wire.requestFrom(slave_address, 3);
while (Wire.available() && (byteCount != 0))
{
*read_Data++ = Wire.read();
byteCount--;
}
return (trans_end);
}
void AFEinitRegisters(void) {
unsigned char i;
struct Register reg[NUM_REGISTERS];
reg[0].addr = 0x01; reg[0].val = 0x000050;
reg[1].addr = 0x02; reg[1].val = 0x00018F;
reg[2].addr = 0x03; reg[2].val = 0x000320;
reg[3].addr = 0x04; reg[3].val = 0x0004AF;
reg[4].addr = 0x05; reg[4].val = 0x0001E0;
reg[5].addr = 0x06; reg[5].val = 0x00031F;
reg[6].addr = 0x07; reg[6].val = 0x000370;
reg[7].addr = 0x08; reg[7].val = 0x0004AF;
reg[8].addr = 0x09; reg[8].val = 0x000000;
reg[9].addr = 0x0A; reg[9].val = 0x00018F;
reg[10].addr = 0x0B; reg[10].val = 0x0004FF;
reg[11].addr = 0x0C; reg[11].val = 0x00063E;
reg[12].addr = 0x0D; reg[12].val = 0x000198;
reg[13].addr = 0x0E; reg[13].val = 0x0005BB;
reg[14].addr = 0x0F; reg[14].val = 0x0005C4;
reg[15].addr = 0x10; reg[15].val = 0x0009E7;
reg[16].addr = 0x11; reg[16].val = 0x0009F0;
reg[17].addr = 0x12; reg[17].val = 0x000E13;
reg[18].addr = 0x13; reg[18].val = 0x000E1C;
reg[19].addr = 0x14; reg[19].val = 0x00123F;
reg[20].addr = 0x15; reg[20].val = 0x000191;
reg[21].addr = 0x16; reg[21].val = 0x000197;
reg[22].addr = 0x17; reg[22].val = 0x0005BD;
reg[23].addr = 0x18; reg[23].val = 0x0005C3;
reg[24].addr = 0x19; reg[24].val = 0x0009E9;
reg[25].addr = 0x1A; reg[25].val = 0x0009EF;
reg[26].addr = 0x1B; reg[26].val = 0x000E15;
reg[27].addr = 0x1C; reg[27].val = 0x000E1B;
reg[28].addr = 0x1D; reg[28].val = 0x009C3F;
reg[29].addr = 0x1E; reg[29].val = 0x000103;
reg[30].addr = 0x20; reg[30].val = 0x008025; //0x008003
reg[31].addr = 0x21; reg[31].val = 0x000125;//0x000003 //bit8: PROG_TG_EN
reg[32].addr = 0x22; reg[32].val = 0x000100;//ILED2 = 32
reg[33].addr = 0x23; reg[33].val = 0x000000;
reg[34].addr = 0x32; reg[34].val = 0x00155F;
reg[35].addr = 0x33; reg[35].val = 0x00991F;
reg[36].addr = 0x36; reg[36].val = 0x000190;
reg[37].addr = 0x37; reg[37].val = 0x00031F;
reg[38].addr = 0x34; reg[38].val = 0x001563;
reg[39].addr = 0x35; reg[39].val = 0x00991F;
for (i = 0; i < NUM_REGISTERS; i++)
AFE_Reg_Write(reg[i].addr, reg[i].val);
}
Я рисую каждый из четырех датчиков в LabView. Будем признательны за любую помощь!
@anonymous, 👍1
Обсуждение1 ответ
Устранение неполадок I2C может быть неприятным. Чтобы разобраться в этой проблеме, я рекомендую вам построить простейший скетч Arduino, используя только два датчика, которые, по-видимому, имеют проблемы при совместной работе. Вы должны быть в состоянии написать очень простую программу, которая ничего не делает, кроме как получает простое значение от каждого датчика, скажем, 2 раза в секунду.
Как только у вас будет запущена самая простая из возможных программ, вы сможете ее понять. Прямо сейчас вся сложность вашей программы делает ее сложнее, чем она должна быть.
Удачи!
Фрэнк
- Как подключить датчик MPU6050 к Arduino MKR WIFI 1010?
- Несколько датчиков I2C с одинаковым адресом
- Проблемы с подключением I2C на ESP8266 — 12F, какие контакты использовать?
- Как подключить MPU9250 к NodeMCU с помощью SPI или I2C Slave?
- Лазерный датчик ToF (VL53L0X) не работает
- MAX30100 не работает
- Изменение адреса I2C MPU-6050
- Как соединить L293D и MPU6050 для совместной работы?
Вы никогда не меняете ЭКГ на что-либо от 0, поэтому, конечно, это всегда ноль., @Majenko
Я даже не знаю, с чего начать эту программу. Это такой беспорядок, я не думаю, что это можно спасти. Вы должны изучить базовый синтаксис C, прежде чем начать программировать., @Majenko