ESP-WROOM-02(ESP8266)で和音を鳴らしてみた

ESP8266 Arduinoで和音を鳴らしてみた。
まだ不可解な現象がありますが、ソフトウェアPWMの特性だということにして、これ以上深堀するのはやめます。

回路

ESP8266の4番ピンにトランジスタとスピーカをつなげています。
試していないけど、イヤホンジャックなどをコンデンサ通してつなげても動くと思います。

ソフトウェア

ESP8266のArduinoを使って和音を鳴らしてみようと思います。
矩形波の場合のみうまく動くことを確認しました。(ノコギリ波にするとうまく動かないことも確認しました)

PWMを32kHz周期に設定し、timer0の割り込みを10000クロック後(160MHzの場合は16kHz周期)に設定します。
ndという変数にタイマ割り込みのたびにdd足していきます。これがオシレータです。
矩形波を作りたいのでndの16ビット目が0か1かで0か256を返すような計算式を作ります。


((nd>>15)&1 == 1)?0:256

これをAnalogWriteすることで音が鳴ります。
音階を作るには少し計算をする必要があります。
ndの16ビット目をみているのでddが1の場合は16K/2^16 Hzの音が鳴るはず(0.24414..という音にならない周波数だけど)
で、ddを変数として意図した周波数を鳴らすための数式は

f:id:inajob:20180225210000p:plain

となる。
式変形して

f:id:inajob:20180225210059p:plain

これを音階ごとに計算すればよい。こうやって計算した値をtonesという変数に用意しています。

和音が鳴らしたいので上記のような変数を4つばかり配列として作成して、足し算します。
AnalogWriteは0-1024までなのでうまくその範囲に収まるように調整します。

以上で和音が作成できます。
ソースコードはこんな感じ。

 

#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX


const unsigned int tones[] = {
0,
1802  , // A  1
1909  , // A+ 2
2023  , // B  3
2143  , // C  4
2271  , // C+ 5
2406  , // D  6
2549  , // D+ 7
2700  , // E  8
2861  , // F  9
3031  , // F+ 10
3211  , // G 11
3402  , // G+12
3604  , // A 13
3819  , // A+14
4046  , // B 15
4286  , // C 16
4541  , // C+17
4811  , // D 18
5098  , // D+19
5401  , // E 20
5722  , // F 21
6062  , // F+22
6422  , // G 23
6804  , // G+24
7209  , // A 25
7638  , // A+26
8092  , // B 27
8573  , // B+28
};

const unsigned int melody[3][16] = {
{ 4, 6, 8, 9,11,13,15,16,16,15,13,11, 9, 8, 6, 4 },
{ 8, 0,11, 0,15, 0,18, 0,13, 0, 9, 8, 0, 4, 9, 8 },
{16, 0,20, 0,23, 0, 0,28, 0,27, 0,23, 0,20, 0, 0 },
};
int pos = 0;

volatile unsigned int nd[4] = {0,0,0,0};
volatile unsigned int dd[4] = {0, 0, 0, 0};
volatile unsigned int out;

void timer0_ISR (void) {
  timer0_write(ESP.getCycleCount() + 10000L ); // 160M/16K
  nd[0] += dd[0];
  nd[1] += dd[1];
  nd[2] += dd[2];
  nd[3] += dd[3];

  out = (((nd[0] >> 16)&1 == 1)?0:256) +
        (((nd[1] >> 16)&1 == 1)?0:256) +
        (((nd[2] >> 16)&1 == 1)?0:256) +
        (((nd[3] >> 16)&1 == 1)?0:256);
  analogWrite(4, out);
}

void setup() {
  WiFi.mode(WIFI_OFF);

  analogWriteFreq(32000); // pwm 32kHz

  noInterrupts();
  timer0_isr_init();
  timer0_attachInterrupt(timer0_ISR);
  timer0_write(ESP.getCycleCount() + 10000L ); // 160M/16K
  interrupts();

  Serial.begin(115200);
}

unsigned int counter;

void loop() {
  counter ++;
  if(counter%100000 == 0){
    dd[0] = tones[melody[0][pos]];
    dd[1] = tones[melody[1][pos]];
    dd[2] = tones[melody[2][pos]];
    pos ++;
    if(pos >= 16){
      pos = 0;
    }
    Serial.println("tick");
  }

}

 

動画

 

何かおかしい

矩形波はこれでよい感じに鳴ったのだが、ノコギリ波や、ほかの波形を鳴らそうとするとなぜか音にならない。
おそらくこれはESP8266のPWMがソフトウェアで実装されていることにより、頻繁に値が変わるような波形では速度が追い付いていないのではないか?と思われる。

何か気づいたことがある人は教えてほしいです。

3Dプリンタでフリスク太鼓たたき装置を作った

これは何?

手回しオルゴールのように、ハンドルをくるくる回すとリズムよくフリスクをたたいてくれる装置です

工夫したところ

毎度のことですが設計はFusino360を使いました。

f:id:inajob:20180204112359p:plain

床と壁は、別々の部品で作り、ずぼっとはめ込むスタイルにしました。

3DプリンタはZ方向にでかいものを作るのが遅い、ということと積層方向に弱いということから、壁をXY方向に作るのがよいと考えたからです。

穴の大きさと、差し込む部品の大きさについては、今回は全く同じ寸法で作りましたが、3Dプリントすると部品は少し大きめになり、穴は少し小さめに出力されるため、ヤスリで削らないとはまりませんでした。少し大きさを変えて出してもよいのですが、あまりガバガバになってしまうと固定できないので、ヤスリで調整するくらいがちょうどよいのかなと思っています。

f:id:inajob:20180204112719p:plain

ドラムのツメは、このように斜めの面取りをしてあります。これは3Dプリンタで造形する際に、うまく積層できるようにする工夫です。これをしないと空中にプラスチックを射出してしまいうまく造形ができないと思います。

f:id:inajob:20180204112941p:plain

シャフトと回転部分はこのように四角柱のシャフトを通しています。回転する軸受けの部分は四角い穴の開いた丸いリングをはめています。四角いシャフトにすることで連動して回転することができます。

f:id:inajob:20180204114008p:plain

3Dプリンタで出力するときは、いくつかの部品をまとめて出力しました。

プリント時間はかかるけれども、待ってるだけで一気に部品が作れるので作業効率が上がります。

f:id:inajob:20180204114821p:plain

完成動画

もともとフリスクを置く予定はなかったのですが、プラスチックをたたいてもしょぼい音しか出なかったので、「よく響く缶」ということで、手元にあったフリスクのケースを使いました。

 

 

 

感想

3Dプリンタでギアを使ったものが作りたい!と思って作り始めたので、その欲求は満たすことができました。3Dプリンタで作るとき特有の工夫もある程度わかったので、次やるときはもう少しスムーズにできるかなと思います。

こういう試行錯誤をするのにFusion360は非常に使いやすかったです。

タッチパネルと3Dプリンタで激安自作キーボードを作ってみた。

これは何?

Arduinoを使ったゲーム機などを作っているときにキーボードを搭載したくなることがあります。

PS/2接続のキーボードをつなげるというのもよいのですが、できれば筐体に収まるようなかわいらしいキーボードが欲しいなと思っていました。

もちろんタクトスイッチをたくさん並べてオリジナルの小型キーボードを作るのもよいのですが、、、部品もたくさん必要だし、大量のはんだ付けが必要です。制御も面倒です。

 

そこで今回はもっと手軽に作れるキーボードを考えてみました。

 

タッチパネル

今回使ったのはこれ。

www.aitendo.com

aitendoで数百円で買えます。

これはいわゆるNintendo DSとかのタッチパネル部分などに使われているような感圧式のタッチパネルです。ふつうはディスプレイと重ねて使用するものですが、今回はこのタッチパネルだけを利用します。

 

このタッチパネルは専用ICでX,Y座標を取り出すこともできますが、中身は単純な可変抵抗なので、ArduinoだけでもX,Y座標を取り出すことができます。

参考:タッチスクリーンをArduinoから使う – SF Bay Music Tech

 

 この記事とはあまり関係ないですが、ここまでの知識で、このような楽器のようなものが作れます。

 

キーパッドプラスチック

なんといったものか、、

こういうプラスチックです。

f:id:inajob:20180117232914p:plain

裏返すとこんな感じ

f:id:inajob:20180117233026p:plain

3Dプリンタの制約上、上下両側に凸になっている形状は作れないため、2つの部品を貼り合わせるように設計します。

これをタッチパネルの上に固定することで、キーボードのボタンを作成します。

ボタンを押し込むと、裏側の出っ張りが下がり、タッチパネルの特定の個所をタッチするわけです。

f:id:inajob:20180117234023p:plain

特定の位置、と言っても多少はぶれるのでArduinoで値をうまいこと丸め込んで、どのキーが押されたのかを特定します。

 

f:id:inajob:20180201004036p:plain

部品の4隅に穴をあけておいて、ねじとナットで締め付けることで固定します。

完成

 こんな感じ。

文字の表示はこれを使いました。

www.aitendo.com

 

ディスプレイの制御は下記ライブラリを使いました(Arduino IDEのライブラリマネージャからインストールできました)

github.com

 

仕組み上、まれに隣のキーが押されるような挙動をすることがあります。閾値やタイミングの調整で減らせるかなと思っていますが、ゼロにするのは難しそうです。

 

ソースコード

キーボードのタッチ位置の測定部分は現物合わせで調整した値なので、あまり参考にならないです。

 

#include <LCD_ST7032.h>
LCD_ST7032 lcd;

#define Y1 A0
#define X1 A1
#define Y2 A2
#define X2 A3
#define SPEAKER 9

int buttonTrig;
int xavg, yavg;

char charMap[3][10] = {
    {'\n', ' ', ',', 'M', 'N', 'B', 'V', 'C', 'X', 'Z'},
    {';', 'L', 'K', 'J', 'H', 'G', 'F', 'D', 'S', 'A'},
    {'P', 'O', 'I', 'U', 'Y', 'T', 'R', 'E', 'W', 'Q'}
  };

void reset(){
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);

  digitalWrite(A0, LOW);
  digitalWrite(A1, LOW);
  digitalWrite(A2, LOW);
  digitalWrite(A3, LOW);
}

void setup() {
  buttonTrig = 0;
  xavg = yavg = 0;
  reset();
  pinMode(SPEAKER, OUTPUT);
  
  lcd.begin();
  lcd.setcontrast(24);

  lcd.setCursor(0, 0);  //LINE 1, ADDRESS 0
  lcd.cursor();
  lcd.print("Hello World");
}


void loop() {
  int x, y;
  reset();
  // x sensor
  digitalWrite(X1, HIGH);
  pinMode(Y1, INPUT);
  pinMode(Y2, INPUT);
  delay(1);
  x = analogRead(Y1);

  reset();
  
  // y sensor
  digitalWrite(Y1, HIGH);
  pinMode(X1, INPUT);
  pinMode(X2, INPUT);
  delay(1);
  y = analogRead(X1);

    
  if(x != 0 && y != 0){
    if(buttonTrig > 4){  // delay 4 frame to wait stable 
      xavg = ((xavg + x) >> 1);
      yavg = ((yavg + y) >> 1);
    }else{
      xavg = x;
      yavg = y;
    }

    if(buttonTrig == 8){
      tone(SPEAKER, 440 + x);
      
      byte yrow = 0;
      if(yavg > 100) yrow = 1;
      if(yavg > 300) yrow = 2;
      if(yavg > 500) yrow = 3;

      byte xrow = 0; // 
      if(xavg > 100) xrow = 1;
      if(xavg > 150) xrow = 2;
      if(xavg > 220) xrow = 3;
      if(xavg > 300) xrow = 4;
      if(xavg > 380) xrow = 5;
      if(xavg > 430) xrow = 6;
      if(xavg > 480) xrow = 7;
      if(xavg > 550) xrow = 8;
      if(xavg > 630) xrow = 9;
      if(xavg > 690) xrow = 10;

      if(charMap[yrow - 1][xrow - 1] == '\n'){
        lcd.clear();
        lcd.setCursor(0, 0);
      }else{
        lcd.write(charMap[yrow-1][xrow-1]);
      }
    }

    buttonTrig ++;
    
  }else{
    noTone(SPEAKER);
    buttonTrig = 0;
    xavg = 0;
    yavg = 0;
  }
}

Arduboy Writerを作ってみた

これは何?

Arduboy用の書き込み装置です。Arduboy( https://arduboy.com/ )とはパソコンを通じてゲームを書き換え、書き換えたのちは1種類のゲームだけが遊べるというArduinoベースの携帯ゲーム機です。

しかし、出先でもArduboyのゲームを切り替えたいと思い作ったのがこれです。

(ちなみにGamebuino ( Getting started - Gamebuino Wiki) という同じくArduinoベースの携帯ゲーム機はSDカードスロットを搭載しており、そこからゲームを切り替えることができます。)

 

f:id:inajob:20180105194749p:plain

構成

仕組みも何もRaspberryPi Zeroです。

去年スイッチサイエンスで購入したものですが、なんかもったいなくて道具箱にしまいっぱなしにしていました。このままだと積み基板になってしまうということで使いました。

そしてOLEDとタクトスイッチを3つ。最後に3Dプリンタで作ったケースにより構成されています。

f:id:inajob:20180106185903p:plain

回路

とても簡単ですが回路図です。スイッチのプルアップはRaspberryPi Zero内部で行うので直結です。

f:id:inajob:20180105195658p:plain

f:id:inajob:20180105195117p:plain

ソフトウェア

RaspberryPi Zeroといっても中身は普通のLinuxです。Pythonを使ってI2C経由でOLEDを操作します。また、ブート時に自動的に起動させるためにsystemdのserviceファイルを作ります。

この記事が参考になりました。

qiita.com

雑ですがコードはこんな感じ。

import RPi.GPIO as GPIO

import time
import os
import subprocess

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306

from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont

# Input pins:
A_pin = 17
B_pin = 27
C_pin = 22

GPIO.setmode(GPIO.BCM)

GPIO.setup(A_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
GPIO.setup(B_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up
GPIO.setup(C_pin, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Input with pull-up

# Raspberry Pi pin configuration:
RST = 24
# Note the following are only used with SPI:
DC = 23
SPI_PORT = 0
SPI_DEVICE = 0

# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)

# Initialize library.
disp.begin()

# Clear display.
disp.clear()
disp.display()

# Load default font.
font = ImageFont.load_default()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)

buttons = [0,0,0];

hexes = os.listdir('./data')
position = 0;

def flashWrite():
  draw.rectangle((0,0,width,height), outline=0, fill=0)
  draw.text((0,30), 'writing...', font=font, fill=255);

  disp.image(image)
  disp.display()
  result = subprocess.call(['./leonardoUploader', '/dev/ttyACM0', './data/'+hexes[position]]);
  if result == 0:
    draw.text((0,30), 'success', font=font, fill=255);
  else:
    draw.text((0,30), 'error', font=font, fill=255);

  disp.image(image)
  disp.display()
  time.sleep(1)

def scan():
  global position
  global mode

  if not GPIO.input(A_pin):
    if buttons[0] == 0:
      position = position + 1
      if position >= len(hexes):
        position = 0;
    buttons[0] = 1
  else:
    buttons[0] = 0
  if not GPIO.input(B_pin):
    if buttons[1] == 0:
      position = position - 1
      if position < 0:
        position = len(hexes) - 1;
    buttons[1] = 1
  else:
    buttons[1] = 0

  if not GPIO.input(C_pin):
    if buttons[2] == 0:
      flashWrite();
    buttons[2] = 1
  else:
    buttons[2] = 0

def repaint():
  draw.rectangle((0,0,width,height), outline=0, fill=0)

  if buttons[0]:
    draw.rectangle((0,0,10,10), outline=255, fill=1);
  else:
    draw.rectangle((0,0,10,10), outline=255, fill=0);

  if buttons[1]:
    draw.rectangle((10,0,20,10), outline=255, fill=1);
  else:
    draw.rectangle((10,0,20,10), outline=255, fill=0);

  if buttons[2]:
    draw.rectangle((20,0,30,10), outline=255, fill=1);
  else:
    draw.rectangle((20,0,30,10), outline=255, fill=0);

  draw.text((0,30), hexes[position], font=font, fill=255);

  disp.image(image)
  disp.display()

scan()
repaint()

dirty = False
def sig(n):
  global dirty
  scan()
  dirty = True

GPIO.add_event_detect(A_pin, GPIO.BOTH, callback=sig, bouncetime=20);
GPIO.add_event_detect(B_pin, GPIO.BOTH, callback=sig, bouncetime=20);
GPIO.add_event_detect(C_pin, GPIO.BOTH, callback=sig, bouncetime=20);

try:
    while 1:
        if dirty:
          repaint()
          dirty = False
        #time.sleep(.01)

except KeyboardInterrupt:
    GPIO.cleanup()

肝心のArduboyにhexをアップロードする部分は

github.com

このソフトウェアを使いました。

起動時にプログラムを実行するために、systemdのservice定義を書きました。

[Unit]
Description=arduboyWriter
After=syslog.target

[Service]
Type=simple
WorkingDirectory=/home/pi/arduboyWriter
ExecStart=/usr/bin/python main.py
TimeoutStopSec=5
StandardOutput=null

[Install]
WantedBy = multi-user.target

 

これを/eyc/systemd/systemにコピーして systemctl enable arduboy-writerなどとして有効化できます。

ケース

Fusion360モデリングして、3Dプリンタで出力しました。3層の構造を4本のねじとナットでサンドイッチすることで固定しています。

Raspberry Pi ZeroのGPIOにはメスのピンヘッダをつけたので、ちょうどこの2層目がかっちりはまって、安定します。

f:id:inajob:20180105194916p:plain

f:id:inajob:20180105194949p:plain

まとめ

RaspberryPi ZeroでArduboyのゲームを書き込むのは、冷静に考えるとちぐはぐな解決策です。RaspberryPi ZeroのほうがArduboyの何倍も高スペックだからです。しかし、Arduboyは軽量で、ゲーム機として非常によくできているため、多少ちぐはぐであってもかまわないかな、ということで作ってみました。

世の中にはUSBホストになれるマイコンもあるようなので、そういったもので同じようなものが作れればよりスマートだと思います。(PIC32でできる気がするが、まだ僕にはそのスキルがありません・・勉強せねば・・)

RaspberryPi Zeroを使ったプロダクトは初めて作りましたが、この小ささはとても魅力的だと実感しました。小さいと3Dプリンタでケースを作るのも楽だし、成果物も小さく収められます。

ただ、Linuxをブートするため、起動時間が数十秒かかるというのがネックです。これも前述したUSBホストになれるマイコンを使うことで解決できそうです。

 

 

2017まとめ

所感

今年はお家を買いました。去年は入籍でしたし、人生ゲームの駒が進み始めた感じがしています。

そして5月にテレビ番組としてのハッカソンイベント「メイキンクエスト」に参加したのも、良い経験になりました。(動画無料で見れますよ! メ~テレ開局55周年記念番組「メイキン クエスト」-動画[無料]|GYAO!|バラエティ・スポーツ)さらに11月には深センに旅行に行き、世界の広さを感じてきました。

 3Dプリンタを買ったことで工作の幅が広がり、電子工作のみならず、様々なものを作りました。Arduboy向けのゲームもいくつか作りました。

仕事では去年に続きkubernetes周りのことをやってます。kubernetesは活発に開発されており、学んでも学んでも次々に新しい機能や概念が出てくるので日々勉強!という感じです。

英語もぼちぼち勉強しており、そのおかげかArduboyがらみで海外のフォーラムに投稿したりもできています。まぁ英語は継続が大切なのでこれからもやっていきたいところ。

体調不良が定期的に訪れる年でもあり、もう少し体を鍛えるなり、気を付けるなりする必要があると感じました(毎年言ってるな・・)

ハードウェア系の活動は結構できたのですが、もうちょっとWeb系の活動もしたいかな。

ステータス

  • 引っ越してから1年目(今年引っ越した!)
  • 会社に入ってから8年(来年度で9年目)
  • 結婚してから1年ちょっと

今年学んだスキル

月別振り返り

 

 

参考

Hack Day 10th anniv. に参加しました

Hack Day 10th anniv. に参加してきました。

数えると6回目の参加。そして名前の通りHack Dayは10周年!めでたい!

 

Hack Day( http://hackday.jp/ )というのは、土日の24時間(本当に12時〜翌日12時)という時間制約のもと「動く」プロダクトを開発し、その後90秒で発表するというYahoo! JAPANの名物イベントのOpen版です。 

作ったもの

「スマートスピーカー2.0」

f:id:inajob:20171211180336p:plain

 

 

Google Homeや、Amazon Echo。 今流行っているスマートスピーカーですが、これを拡張して、「話しかけてくる」、「ジェスチャーで操作できる」などの機能を追加しました。

f:id:inajob:20171211174639p:plain

これにより従来のスマートスピーカーでは実現できなかったこんなことができるようになります

 

いつものコマンドを自動実行

スマートスピーカーの履歴を分析することで、朝いつもニュースを聞いている、などの情報を取得し、さらにセンサーを用いて人の接近を認識することで、「朝、スマートスピーカーの前に来ると自動的にいつものニュースが再生される。」というものを実現できます。

 

f:id:inajob:20171211175333p:plain

会話の拡張

スマートスピーカの前で何人かで会話をしていると、「スマートスピーカーが会話内容を認識し、沈黙発生時にその内容を加味した話題をふってくれます。」

 

ジェスチャーでの会話キャンセル

それでもスマートスピーカーは意図しない内容を話し始めることがあります。そのような際には、「手を振るジェスチャーをすることで会話をキャンセル」できます。

 

参加メンバー

  • @kasahi 安定の仕切り役 プレイングマネージャ
  • ばりーさん そういえば深センにも一緒に行きました。
  • matsuchiさん 仕事はWebデザイナー
  • @kotauchisunsun 最近はQiitaの記事を頑張って書いてる なんでもやる系エンジニア

当日まで

前回、前々回とこのチームではぎりぎりまでネタが決まらなかった。今回は早めに決めよう!ということで、HackDayの3週間前くらいから、軽く打ち合わせを始めたにもかかわらず、、結局内容が決まったのはHackDay開催の直前となりました。

今流行りの技術である、何かが使いたいな、、ということで「スマートスピーカー」をテーマにしようという流れになってきました。

センサーが必要ということも決まっていたので、HackDay当日までにとりあえず買うだけ買っておきました。

またRaspberryPiを利用するということで、ネットワークの設定や、必要なパッケージのインストールなど、会場のWifiで実行すると時間がかかりそうなものについても準備をしました。

(このあたりHackathonに慣れてきたなという感じです。)

HackDay当日

12:00から開始ということで、割とぎりぎりに会場に到着。各自自宅のGoogleHomeを持ってきたので、机の上はGoogleHomeでいっぱい。

軽い気持ちで「OK Google」というと、すべてのGoogle Homeが反応するという状態で開発をしました。今回技術的にやることはある程度決まっていたのですが、これの便利さがどういうときに発揮されるのか、どういうストーリーだと効果的に伝えられるか、というところが難しく、このあたりは@kasahiさん matsuchiさんが詰めてくれました。

 

エンジニア陣も作業分担

私はセンサーからの値を読み取り、プログラムで値を読み取り必要に応じて中央サーバーにおくるところ

ばりーさんは中央サーバーの作成

@kotauchisunsun さんはGoogleHomeに任意の言葉を話すことができる

https://github.com/noelportugal/google-home-notifier の準備と、Juliusを使った音声認識部分

苦悩の夜

センサーの一つにジェスチャーセンサーを使っていたのですが、これの制御が難しい、、

APDS9960使用光学式ジェスチャーセンサモジュールキット: 組立キット 秋月電子通商 電子部品 ネット通販

あまりむき出しにするのも格好が悪いということで、箱に小さな穴をあけて、そこからセンサーを露出させて動かそうとしていたのですが、そのような状況にするとこのセンサーが全く反応しなくなるようです。

僕ははじめRaspberryPiとの接続部分の接触が悪いのかと思い、そこを調べていたのですが、、、どうも的外れのことをしていたようです、、ハードウェアは切り分けが難しい。

 

音声認識でもオープンソース音声認識エンジン http://julius.osdn.jp/ で、なかなか思ったような認識ができずに苦労していました。

最近Google HomeやSiriは難なく日本語を理解しているように見えますが、オープンソースのライブラリでであのレベルまで作ることはまだ難しいなと感じました。

 また、Google Homeの操作履歴を泥臭くヘッドレスブラウザを使って抜き出す部分を@kasahiさんが作っていました。

HackDay二日目

今回は音声やセンサーなど、発表会場の暗い中で動かすことが不安なプロダクトとなったため、発表は映像で行おうということになったため、2日目はまずビデオ撮影から始めます。

開場の廊下を借りていわゆる「寸劇」の撮影をしました。

その後matsuchiさんが字幕を入れたり調整を始めました。

発表の後にデモもあるということで、エンジニア陣はデモ用に調整などをしていました。

 

で、発表です。

今回はやはり私たちのような「ボイスUI」を使った作品が多く、改めてスマートスピーカーの時代が来ているのだなと感じました。

今回は賞は受賞できません出た、、残念。

しかし、発表の後の展示にもちょくちょくお客さんが見に来てくれて、興味を持ってもらえたようで、方向性はそれほど間違っていなかったかなと認識することができました。

 

f:id:inajob:20171211181501p:plain

ニコニコ生放送でも高評価!

 

仕組み

f:id:inajob:20171211175935p:plain

f:id:inajob:20171211173150p:plain

 RaspberryPiに各種センサー、マイクをつないでいます。

Juliusがマイクからの入力を読み込み音声認識をしています。 

RaspberryPiとGoogleHomeをつなぐには2つの方法を使っています。1つは https://github.com/noelportugal/google-home-notifier 。これはChromecastの仕組みを応用してGoogleHomeに任意の音声ファイルをしゃべらせることのできるプログラムです。

もう一つは上の図で「スピーカー」と書いてあるように、RaspberryPiがGoogleHomeに話しかけます。こうすることでGoogleHomeのもつ便利な機能をセンサーをトリガとして実行することができます。

(早くそういうことができるAPIが開放されてほしい)

 

感想

スマートスピーカーは難しい!と感じました。プログラムから制御できることも少なく、簡単にできることはすでにみんなやってしまっているし、、、

電子工作プロダクトを24時間しばりのあるHackDayでやることも難しい!と感じました。何度か電子工作ネタでこのHackDayに出たことがあるのですが、毎回”これだけしかできなかった・・”という感じになります。

と、反省は尽きないのですが、スマートスピーカー自体は我が家でも使っており、今後もっと便利になってほしいので、今回のプロダクトを通じて多くの方に次世代のスマートスピーカーの可能性について伝えることができていればいいなと思っています。

 

画像に含まれている可能性があるもの:4人、、スマイル

過去のHackDay

(今回の参加者に配られたパーカー 歴代のHackDayのロゴがぎっしり!)

f:id:inajob:20171211175747p:plain

Hack Dayは今回で6回めで、僕は過去5回も参加しました。宣伝的にリンクを置いておきます。

 

Hack  Day 10th anniv. 全作品まとめ

 動画をみながら、全作品のまとめを作成しました。ざっとどんな作品があったか見たい方はどうぞ!時間のある方はぜひ動画もご覧ください!

scrapbox.io

深センに行ってきました

深セン

会社の仲間で、一緒にMakerFairTokyoに出ている人たちと一緒にMakerFairShenzhenに行くことになりました。

メインプロダクトは、このWebページで紹介しているものです。

connect-me-net.tumblr.com

 

僕はこのチームで、回路周りでトラブったときのアドバイザー的な役をしており、MakerFairなどの際には、ブースの端をすこし開けてもらって、自分のプロダクトも展示したりしています。

 

今回はこのチームでMakerFairShenzhenに出ようということで、僕にとっては初めての中国旅行でした。

ほかにも中国に行きたい人たちを募って、総勢7人ほど(現地合流の人や、旅程が微妙に違う人もいましたが)の旅となりました。

準備

飛行機は日程に会うものがそれほどなかったので、すっと決定。往復で3万とちょっと。

ホテルはまとめて予約してもらったので詳細はよく知らない。(ありがとうございます)

MakerFair向けには、英語と、中国語で説明用チラシを作成。

f:id:inajob:20171114144640p:plainf:id:inajob:20171114144710p:plainf:id:inajob:20171114144745p:plain

こんな感じ。

英語中国語を併記して、テキトーにレイアウトしたが、どうにもパチモンのような感じになってしまったような・・

 

持って行ったもの

inajob.hatenablog.jp

 

www.youtube.com

 

inajob.hatenablog.jp

 

MakerFairShenzhen

そんなこんなでMakerFairShenzhen

f:id:inajob:20171114145452p:plain

日本と同じく、メインのプロダクト(ひげにゃん、にゃんぼっと)と、僕のプロダクト(Kumihimo

Maker、RakuChord, DIY Gamebuino)を展示しました。

 

僕のプロダクトは、RakuChord(楽器)、DIY Gamebuino(ゲーム機)は一目で何かわかるものなので、言葉が不自由でもなんとか理解してもらえました。

Kumihimo Makerについては、説明がちょっと難しいのですが、頑張って説明して、相手に伝わったときは相手にも、自分にも謎の一体感が形成されたように感じました。

常時このくらいの客入り。大成功

特に自撮りむけ猫型マスクガジェットである「ひげにゃん」が女性に大人気!皆さん列をなして、ひげにゃんを使って自撮りをしていました。

MakerFairTokyoと比べてもこういうのを好む若い女性客がかなり多かったのが印象深かったです。

 

記念写真。ブース右側が僕の作品コーナーです。

華強北(ファーチャンペイ)

折角深センに来たので、「中国の秋葉原」ともいわれる華強北も見に行きました。

特に事前知識なく「中国の秋葉原」というネーミングからなんか面白いものがあるだろうと思ってました。

華強北 - 深センまとめ Wiki* にある地図がとても参考になりました。

期待通り

  • ビル丸ごと電子部品
  • 怪しい露店でスマフォを売っている

期待と違う

  • Arduinoなどはほとんど売っていない
  • 怪しいガジェットなどはあまりない
  • スマフォアクセサリーといってもスマフォケースなどプラスチック製品が多い

 

f:id:inajob:20171114151101p:plain

攻殻機動隊で怪しい天然オイルを商っているアジアの電子街が出てきましたが、まさにそんな雰囲気なところもありました。

Arduinoは無いの?って店員さんに聞いたら、「オンラインでみんな買うからないよ」と言われた。そういえばこの町ではいわゆるC向けの電子工作グッズはあまり扱っていないようでした。

MakerFairShenzhenではそういうものもたくさんあったので、単に華強北はそういう街ではないだけなのかな?

中国雑感

wechat payが便利

WeChatから使える電子マネー wechat payが非常に便利。

「wechat pay」の画像検索結果

露天ですらもこれが使える。「微信? wei xin?」と伝えると、おもむろにスマートフォンを取り出してきて、決済してくれる。日本人が使うためにはちょっとした工夫が必要なので、中国旅行に行く方は参考に。

日本語版WeChatでWeChat Pay (微信支付)を使う方法【中国の口座不要】 : チケスト社長@ashikagunsoのチラシの裏

中国旅行の新定番! ポケットチェンジでWeChat Payにチャージする:旅人目線のデジタルレポ 中山智 - Engadget 日本版

割り勘もできるので、今回の旅行では大変活躍していました。

乗り捨てレンタル自転車

自転車が歩道に無秩序に並んでいる。これらはレンタル自転車です。自転車についているQRコードを専用アプリで認識させることによりロックを解除でき、テキトーなところで乗り捨てられるというものです。おかげでどこの歩道もこんな感じで自転車があふれてます。

スマートフォンで自転車を映してロックを解除するところが、ハッキングしているみたいでテンションが上がりました

それ以外にも、レンタル傘、レンタルスマフォバッテリーなど、レンタル方式のものがやたらとありました。使うためにはまずデポジットをとり、無事返却したらデポジット分は帰ってくるという方式のようで、電子マネーが普及した中国だからこそできるのだなと感じました。

優しい中国人

MakerFairShenzhenでは僕はつたない英語で説明をしていたのですが、お客さんの中には英語のわからない方もたくさんいらっしゃいました。そんな方にはなんと僕の説明を理解したお客さんが、説明してくれました!これは大変助かりました!

MakerFairShenzhenでは屋台での軽食はすべて電子マネーでの決済でした。僕はその時電子マネーがなくなってしまいおおきな現金しかもっていなかったのですが、それを店員に伝えると店員さんが「だれかーくずせる人いる?」的なことを叫んでくれて、お客さんの中で小銭を持っている人が崩そうとしてくれたりしました。

会場の近くの料理屋で夕食を食べたのですが、その店員さん、ほとんど英語が通じない。我々はつたない英語しかしゃべれない。そんな中でも店員さんはジェスチャーや、「ナンバーワン!」(おすすめ?)などを駆使して我々に接客をしてくれました。

この少ない期間の滞在でもこんなにエピソードがあり、中国人は優しいなと感じました。

 

まとめ

初めての中国!初めての非英語圏!ということで得るものがたくさんありました。

海外旅行をするといつも思うのですが、日本とは違うルールや常識があり、そしてそのうえでバランスが取れている。「おー、こういうのもアリなんだ」という発見がたくさんありました。

MakerFairでは「これ売らないの?」という声を掛けてくれる人もいました。中国なら電子マネーで決済も簡単そうだし、多少荒く作っても許してくれる雰囲気が(良いか悪いかは置いておいて・・)あるので、次来るときは何かを売りに行きたいなと思いました。