ArduinoからQSTEERを操作してみた。

今回はArduino Duemilanove 328(オープンソースハードウェア)を使ってQSTEERを操縦したのでコードを記載します。

Arduinoの13番とGNDに赤外線LEDを挿して以下のコードを書けば動かせます。
※動作はAch Bchのみ検証しました。
Arduinoへの命令の伝達はシリアル通信になります。Processingにコードを書いてキーバインドから操作を可能にしました。

キーバインドのキー配列は適当なので操作性は悪いです。
あと、Arduinoのpinが20mAしかないので通信距離が短く、付属のコントローラーのが操作しやすいですね。

Processing

import processing.serial.*;
Serial port;

void setup() {
  port=new Serial(this,"/dev/cu.usbserial-A6008kVu",9600);
  print(port.readString());
}

void draw() {
  if(keyPressed) port.write(key);
}

Arduino

#define LED 13
int data[15];
int g = 0;
byte b = B001111;

void setup(){
  Serial.begin(9600);
  Serial.println("Ready"); 
  pinMode(LED , OUTPUT); 
}

void loop(){
  static int v = 0;
  if ( Serial.available() > 0 ) {
    char ch = Serial.read();
    switch(ch) {
      case '1':
        setbit(B0001);
        break;
      case '2':
        setbit(B0010);
        break;
      case '3':
        setbit(B0110);
        break;
      case '4':
        setbit(B0111);
        break;
      case '5':
        setbit(B1010);
        break;
      case '6':
        setbit(B1011);
        break;
      case '7':
        setbit(B0011);
        break;
      case '8':
        setbit(B0100);
        break;
      case '0':
        setbit(B1111);
        break;
      case 'a':
        setbit(B0101);
        break;
      case 'b':
        setbit(B1100);
        break;
      case 'c':
        setbit(B1000);
        break;
      case 'd':
        setbit(B1001);
        break;
      case 'e':
        setbit(B1101);
        break;
      case 'f':
        setbit(B1110);
        break;
      case 'A':
        setch(B00);
        break;
      case 'B':
        setch(B01);
        break;
      case 'C':
        setch(B10);
        break;
      case 'D':
        setch(B11);
        break;
    }
  }
}

void setch(byte bb){
  bitWrite(b,4,bitRead(bb,0));
  bitWrite(b,5,bitRead(bb,1));
}
void setbit(byte bb){
  for (int i=0; i < 4; i++){
    bitWrite(b,i,bitRead(bb,i));
  }
  execpwm();
}

void execpwm(){
  g = 0;
  int pwm = 7540;
  int ch1 = bitRead(b,4);
  int ch2 = bitRead(b,5);
  if (ch1 == 0 && ch2 == 0) pwm = 7540;
  if (ch1 == 0 && ch2 == 1) pwm = 21860;
  if (ch1 == 1 && ch2 == 0) pwm = 36200;
  if (ch1 == 1 && ch2 == 1) pwm = 50570;
  
  setpwm(pwm);
  setpwm(1740);
  runpwm();
  sendpwm();
}
void setpwm(int pwm){
  data[g] = pwm;
  g++;
}
void runpwm(){
  for (int i=5; i >= 0; i--){
    setpwm(400);
    int pwm = (bitRead(b,i) == 1) ? 900 : 430;
    setpwm(pwm);
  }
}

void sendpwm(){
  for (int cnt = 0; cnt <  sizeof(data) / sizeof(int) -1 ; cnt++) {
    unsigned long len = data[cnt];
    unsigned long us = micros();
    do {
      digitalWrite(LED, 0 + (cnt&1));
      delayMicroseconds(8);
      digitalWrite(LED, 0);
      delayMicroseconds(7);
    } while (long(us + len - micros()) > 0);
  }
}