Squama Ethernet을 통한 I2C 통신 (이어서 UDP로 전송) (Arduino)

소개



이번에도 마지막에 계속 Squama Ethernet을 사용합니다.
테마는 I2C 통신입니다.

하드웨어



I2C 디바이스



I2C 테스트를 위해 16bit ADC의 ADS1115를 사용하고 싶습니다.
Adafruit가 ADS1115 기판를 판매하기 때문에 Arduino 라이브러리도 있습니다.
최근에는 아마존에서도 동등 기판이 팔고 있으므로 입수성도 좋습니다. (예 : 여기)

데이터 시트도 일단 보자. (일본어 번역한다면 모두 해 주었으면 좋겠다 w 여기 )

I2C 주소



데이터 시트를 참조하십시오.


감지할 장치



이것은 무엇이든 좋은 것이지만, 손에 있던 로드셀을 사용합니다.
아키즈키 전자에서 팔다 녀석이네요.

브레드 보드에 의한 배선



Fritzing에 Squama Ethernet이 없기 때문에 대신 Arduino Pro Mini로 기재하고 있습니다만, 아래와 같이 배선합니다.
I2C의 SDA와 SCL은 사용하는 기판마다 적절히 읽어 주시면 좋겠습니다.
Amazon에서 사면 2개 붙어 있으므로, 2개 사용해 버립니다.
(또, 후술의 소프트에서는, 로드셀을 1개 밖에 접속하고 있지 않습니다.수중에 4개 없고… 죄송합니다…)


소프트웨어



ADS1115 라이브러리



Adafruit의 라이브러리는 여기.
사전에 Arduino로 가져옵니다.

소스 코드


#include <SPI.h>
#include <Ethernet2.h>
#include <EthernetUdp2.h>

#include <Adafruit_ADS1X15.h>

// ------ADS1115-------
Adafruit_ADS1115 ads_1;  /* Use this for the 16-bit version */
Adafruit_ADS1115 ads_2;  /* Use this for the 16-bit version */
Adafruit_ADS1115 ads_3;  /* Use this for the 16-bit version */
float multiplier_1 = 0.1875F;
float multiplier_2 = 0.1875F;
float multiplier_3 = 0.1875F;

// ------Ethernet-------
byte mac[] = {
  0xA8, 0x61, 0x0A, 0xAE, 0x66, 0xC7
};

IPAddress ip(192, 168, 0, 11);   // 自身のIPアドレス
unsigned int localPort = 10000;

IPAddress destIP (192, 168, 0, 1);  //相手のPCのIPアドレス
int destPort = 20000;  //send側ポート

EthernetUDP Udp;


float set_maltiplier(adsGain_t gain) {
  float ret = 0;
  if (gain == GAIN_TWOTHIRDS) {
    ret = 0.1875;
  } else if (gain == GAIN_ONE) {
    ret = 0.125;
  } else if (gain == GAIN_TWO) {
    ret = 0.0625;
  } else if (gain == GAIN_FOUR) {
    ret = 0.03125;
  } else if (gain == GAIN_EIGHT) {
    ret = 0.015625;
  } else if (gain == GAIN_SIXTEEN) {
    ret = 0.0078125;
  }
  return ret;
}

float setup_ads(Adafruit_ADS1115 &ads, int address, adsGain_t gain) {
  ads.setGain(gain);
  // i2c address
  ads.begin(address);
  return set_maltiplier(gain);
}

void setup() {
  // put your setup code here, to run once:
  // ------Ethernet-------
  Ethernet.init(10);  // CS信号設定. Most Arduino shields
  Ethernet.begin(mac, ip);
  Udp.begin(localPort);

  // ------ADS1115-------
  multiplier_1 = setup_ads(ads_1, 0x49, GAIN_SIXTEEN);
  multiplier_2 = setup_ads(ads_2, 0x49, GAIN_ONE);
  multiplier_3 = setup_ads(ads_3, 0x48, GAIN_ONE);
}

void loop() {
  // put your main code here, to run repeatedly:
  int16_t results = ads_1.readADC_Differential_0_1();
  float multi = results * multiplier_1;
  int16_t results_2 = ads_2.readADC_Differential_2_3();
  float multi_2 = results_2 * multiplier_2;
  int16_t results_3 = ads_3.readADC_Differential_0_1();
  float multi_3 = results_3 * multiplier_3;
  int16_t results_4 = ads_3.readADC_Differential_2_3();
  float multi_4 = results_4 * multiplier_3;

  sendUDP(results, multi, results_2, multi_2, results_3, multi_3, results_4, multi_4);
}

void sendUDP(int16_t i_val, float val, int16_t i_val_2, float val_2, int16_t i_val_3, float val_3, int16_t i_val_4, float val_4) {
  // UDP SEND
  int digit = 4;
  Udp.beginPacket(destIP, destPort);
  Udp.print(millis() / 1000, DEC);
  Udp.write(",");
  Udp.print(i_val);
  Udp.write(",");
  Udp.print(val, digit);
  Udp.write(",");
  Udp.print(i_val_2);
  Udp.write(",");
  Udp.print(val_2, digit);
  Udp.write(",");
  Udp.print(i_val_3);
  Udp.write(",");
  Udp.print(val_3, digit);
  Udp.write(",");
  Udp.print(i_val_4);
  Udp.write(",");
  Udp.print(val_4, digit);

  Udp.write("\n");
  Udp.endPacket();
}

거의 샘플을 이용하고 있습니다.
1개의 기판으로 2개의 게인을 사용하고 싶었기 때문에, ads_1ads_2로 나누고 있습니다만, 라이브러리의 개량으로 1개에 정리할 수 있을 것 같네요.

또한 ADS1115의 통신 기능으로는 single-shot modecontinuous mode라는 것이 있습니다.
이번에는 하나씩 채널을 single-shot mode에서 데이터 수신하고 있기 때문에 continuous mode보다 시간이 걸리고 있습니다.continuous mode의 테스트도 실시했습니다만, 복수ch를 받기 위해 이번 사용하고 있지 않다 ALRT Pin을 사용해 처리하지 않으면 안 되는 것 같기 때문에, 포기했습니다.
1ch분이면 잡한 설계일지도 모릅니다만 ALRT Pin을 사용하지 않고 continuous mode로 수신할 수 있습니다.

덧붙여서, UDP의 데이터 레이트입니다만, ADS1115를 2개 사용해 4ch분의 데이터를 UDP로 PC에 송신하고 있는 것을 WireShark로 확인했는데, 대략 20FPS였습니다.

데이터 수신 및 간단한 시각화



이번에도 Unity에서 UDP를 수신하고 있습니다. 왼쪽 상단의 문자열이 수신 데이터입니다.
4ch 가운데, 1ch 밖에 로드셀을 붙이고 있지 않고, 그 이외의 ch는 3.3 V를 그대로 돌진하고 있거나 하고 있으므로 양해 바랍니다.

그 1ch의 로드셀로부터 받은 값을 적선 그래프로 하고 있는 것과, 그 값으로 원의 Scale를 바꾸고 있습니다.
로드셀에 가하는 힘에 따라 전압값이 변화하기 때문에 그래프와 원의 크기가 바뀌는 것을 알 수 있을까 생각합니다.


결론



Squama 이더넷으로 I2C 통신을 시도했습니다.
역시 기판 사이즈가 작고 이더넷 접속할 수 있는 Squama Ethernet은 좋은군요. 편리.

문제는 continuous mode입니까? 20FPS에서는 조금 느립니다.
I2C 통신의 속도 업으로 고속으로 할 수 있을지도 모릅니다.

마지막으로, ADS1115의 게인이나 Unity 부분 등 상당히 단단히 쓰고 있기 때문에 비망록감이 강해져 버립니다.
더 제대로 써야겠네요...

좋은 웹페이지 즐겨찾기