6

光の強度を測定するために、OPT101 をスレーブ arduino に接続しています。OPT101 回路から受信したデータを、シリアル モニターにデータを出力するマスター arduino に送信したいと考えています。コードをテストすると、画面に何も表示されません。(「こんにちは」を送信してテストしたため、i2c接続ではないことはわかっています)。私はarduino leonardoをスレーブとして、arduino unoをマスターとして使用しています。

OPT101 回路のコードは次のとおりです。

#define inPin0 0

void setup() {

  Serial.begin(9600);
  Serial.println();

}

void loop() {

  int pinRead0 = analogRead(inPin0);
  double pVolt0 = pinRead0 / 1024.00 * 5.0;
  Serial.print(pVolt0, 4 );
  Serial.println();

  delay(100);

}

スレーブ コードと OPT101 コードを組み合わせてこれを取得するのにうんざりしました: #include

#define inPin0 0

void setup() {

  Wire.begin(2);

}

void loop() {

  Wire.beginTransmission(2);
  Wire.onRequest(requestEvent);
  Wire.endTransmission();

}

void requestEvent()
{  
  int pinRead0 = analogRead(inPin0);
  int pVolt0 = pinRead0 / 1024.0 * 5.0;
  Wire.write((byte)pVolt0);
}

そして、これは私のマスターコードです:

#include <Wire.h>

void setup()
{

  Wire.begin();
  Serial.begin(14400);

  Wire.requestFrom(2, 8);

  while(Wire.available())
  {

    char c = Wire.read();
    Serial.print(c);
  }
}

void loop()
{
}
4

3 に答える 3

5

マスターとスレーブの I2C デバイス間で通信するには、以下の手順に従う必要があります。

  • 読み取りまたは書き込み要求を開始できるのはマスターだけです。
  • 読み取りまたは書き込み要求は同期的である必要があります。つまり、スレーブはマスターが要求した後にのみデータを返すことができ、書き込みの場合はその逆になります。
  • 0 ~ 7 のスレーブ アドレスは使用しないでください。これらは予約済みです。8 ~ 127 の範囲のスレーブ アドレスを使用します。
  • Arduino I2C では、1 バイトしか送受信できません。複数のバイトを持つ整数、倍精度を送信または受信するには、最初にそれらを分割し、反対側でそれらを同等のデータ型に結合する必要があります。(間違っていたら訂正してください。)

コードは次のようになります。

マスタースケッチ:

#include <Wire.h>
#define SLAVE_ADDRESS 0x40

// This macro reads two byte from I2C slave and converts into equivalent int
#define I2C_ReadInteger(buf,dataInteger) \
    buf[0] = Wire.read(); \
    buf[1] = Wire.read(); \
    dataInteger = *((int *)buf);

// Returns light intensity measured by 'SLAVE_ADDRESS' device
int GetLightIntensity()
{
    byte Temp[2];
    int Result;

    // To get integer value from slave, two are required
    int NumberOfBytes = 2;

    // Request 'NumberOfBytes' from 'SLAVE_ADDRESS'
    Wire.requestFrom(SLAVE_ADDRESS, NumberOfBytes);

    // Call macro to read and convert bytes (Temp) to int (Result)
    I2C_ReadInteger(Temp, Result);

    return Result;
}

void setup()
{
    // Initiate I2C Master
    Wire.begin();

    // Initiate Serial communication @ 9600 baud or of your choice
    Serial.begin(9600);
}

void loop()
{
    // Print light intensity at defined interval
    Serial.print("Light Intensity = ");
    Serial.println(GetLightIntensity());

    delay(1000);
}


スレーブ スケッチ:

#include <Wire.h>
#define SLAVE_ADDRESS 0x40
#define inPin0 0

// Preapres 2-bytes equivalent to its int
#define IntegerToByte(buf,intData) \
  *((int *)buf) = intData;

// Sends int to Master
void I2C_SendInteger(int Data)
{
  byte Temp[2];

  // I2C can only send a byte at a time.
  // Int is of 2bytes and we need to split them into bytes
  // in order to send it to Master.
  // On Master side, it receives 2bytes and parses into
  // equvivalent int.
  IntegerToByte(Temp, Data);

  // Write 2bytes to Master
  Wire.write(Temp, 2);
}

void setup()
{
  // Initiate I2C Slave @ 'SLAVE_ADDRESS'
  Wire.begin(SLAVE_ADDRESS);

  // Register callback on request by Master
  Wire.onRequest(requestEvent);
}


void loop()
{
}

//
void requestEvent()
{  
  // Read sensor
  int pinRead0 = analogRead(inPin0);
  int pVolt0 = pinRead0 / 1024.0 * 5.0;

  // Send int to Master
  I2C_SendInteger(pVolt0);
}

このコードは Arduino バージョン: 1.6.7でテストされています。I2C 通信の詳細については、Arduino の例:マスター リーダーを参照してください。

于 2016-02-02T07:16:37.587 に答える
1

関数を使用する代わりにwhile、関数にループを入れているのはなぜですか?setup()loop()

しかし、もっと紛らわしいのはこの行int pVolt0 = pinRead0 / 1024.0 * 5.0;です。初期コードでは、変数はintbutではありませんdouble。元の行を使用して再コーディングすることをお勧めします: double pVolt0 = pinRead0 / 1024.00 * 5.0;

そして、それから に減らしintます。

于 2015-01-12T21:25:07.430 に答える
0

Arduino I2C では 1 バイトしか送受信できず、それらを同等のデータ型に結合する必要があります。

于 2020-07-24T02:12:30.297 に答える