Возникли проблемы с совместной печатью 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. Будем признательны за любую помощь!

, 👍1

Обсуждение

Вы никогда не меняете ЭКГ на что-либо от 0, поэтому, конечно, это всегда ноль., @Majenko

Я даже не знаю, с чего начать эту программу. Это такой беспорядок, я не думаю, что это можно спасти. Вы должны изучить базовый синтаксис C, прежде чем начать программировать., @Majenko


1 ответ


1

Устранение неполадок I2C может быть неприятным. Чтобы разобраться в этой проблеме, я рекомендую вам построить простейший скетч Arduino, используя только два датчика, которые, по-видимому, имеют проблемы при совместной работе. Вы должны быть в состоянии написать очень простую программу, которая ничего не делает, кроме как получает простое значение от каждого датчика, скажем, 2 раза в секунду.

Как только у вас будет запущена самая простая из возможных программ, вы сможете ее понять. Прямо сейчас вся сложность вашей программы делает ее сложнее, чем она должна быть.

Удачи!

Фрэнк

,