ぱぷりかの機械系技術ノート

なにかのお役に立てばうれしいです

TWELITEとArduinoを使った測定データの収集について4(Arduino用ソースコード)

Arduinoに書き込むスケッチは以下のようにした.

#include <SoftwareSerial.h>
const unsigned long MeasInterval = 30000;  // 測定間隔

// 応答IDの設定
typedef enum
{
  NORMAL_ID = 80,
} ResponseId;

// メッセージの長さの設定
typedef enum
{
  TX_HEADER_LEN = 9,
  MAX_CONTENT_LEN = 22,  // 送信内容の最大文字長
  MEAS_VALUE_LEN = 4,  // 測定値の文字列長
} MessageLength;

// LEDのピンの設定
typedef enum
{
  SENSOR_PIN = 0,
  RX_PIN = 6,
  TX_PIN = 7,
  LED_PIN = 2,
} PinSetting;

// TWELITE論理IDの設定
typedef enum
{
  THIS_TWELITE = 41,  // 0x29
  DOWNSTREAM_TWELITE = 40,  // 0x28
} TweliteId;

SoftwareSerial mySerial(RX_PIN, TX_PIN);
unsigned long previousMillis = 0;

// プロトタイプ宣言
int acquire();
void transmit(int);
int getChecksumOf(const char *);
void toUpperStr(const char *);
void writeToSerial(const char *);

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
  while (!Serial) yield();
  mySerial.begin(9600);
}

void loop()
{
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= MeasInterval)
  {
    int measValue = acquire();
    transmit(measValue);
    previousMillis = currentMillis;
  }
}

// 測定値を取得する.戻り値は整数とする
int acquire()
{
  int rawValue = analogRead(SENSOR_PIN); 
  long volt = map(rawValue, 0, 1023, 0, 3300);
  return ((float)volt - 600.0) / 10.0; 
}

// 測定値を文字列としてTWELITEへ送信する
void transmit(int measValue)
{
  char txMessage[TX_HEADER_LEN + MAX_CONTENT_LEN + 3] = "";
  sprintf(txMessage, ":%02xA0%02xFF%02x%04x",
          DOWNSTREAM_TWELITE, NORMAL_ID, THIS_TWELITE, measValue);
  sprintf(txMessage + (TX_HEADER_LEN + 2 + MEAS_VALUE_LEN * 1), "%02x",
          getChecksumOf(txMessage));
  toUpperStr(txMessage);
  writeToSerial(txMessage);
}

// チェックサムを計算する
int getChecksumOf(const char *message)
{
  char str[3];
  int checksum = 0;
  byte msgLength = strlen(message);
  for (int i = 1; i < msgLength; i = i + 2)
  {
    str[0] = message[i];
    str[1] = message[i + 1];
    str[2] = '\0';
    checksum += strtol(str, NULL, 16);
  }
  return 256 - (checksum % 256);
}

// 大文字に変換する
void toUpperStr(const char *message)
{
  char *p = (char *)message;
  while (*p)
  { 
    *p = toupper(*p);
    p++;
  }
}

// シリアルポートに書き込みを行う
void writeToSerial(const char *txMessage)
{
  digitalWrite(LED_PIN, HIGH);
  Serial.print("TX: ");
  Serial.println(txMessage);
  mySerial.println(txMessage);
  digitalWrite(LED_PIN, LOW);
}

30秒おきにデータを送信するシンプルな内容になっている.

次回はセントラルデバイス側のコードについて書いてみる.