2016年7月3日日曜日

ATTINY85のi2cスレーブデバイスをOPENWRTにつないでみる



さて、虎の子のGPIOを使ってしまったのでリレーをつなげなくなってしまった。
シリアルポートにarduinoをつなげるという手も考えた・・・っていうか作ったのだけど

i2cのスレーブにarduinoのようなもの をぶら下げるほうがいいと思えた。


tinywireSというライブラリがあるっぽい。
http://qiita.com/mt08/items/46d73c4e1957c1eb55f5


DIGISPARKは持ってないけど、ATTINY85,45なら持っているのでサクッとブートローダーを書いて
適当にサンプルソースを書き換える。


// ATTiny based I2C relay control
// ForkRobotics 2012
//

#include "TinyWireS.h"                  // wrapper class for I2C slave routines

#define I2C_SLAVE_ADDR  0x26            // i2c slave address
#define Relay1_PIN  1
#define Relay2_PIN  4
#define Relay3_PIN  3

void setup() {
  pinMode(Relay1_PIN, OUTPUT);
  pinMode(Relay2_PIN, OUTPUT);
  pinMode(Relay3_PIN, OUTPUT);
  digitalWrite(Relay1_PIN, HIGH); //HIGHでOFFのリレー用
  digitalWrite(Relay2_PIN, HIGH);
  digitalWrite(Relay3_PIN, HIGH);

  TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode
}

void loop() {
  byte byteRcvd = 0;
  if (TinyWireS.available()) {          // got I2C input!
    byteRcvd = TinyWireS.receive();     // get the byte from master
    switch (byteRcvd) {
      case 0x01:
        digitalWrite(Relay1_PIN, LOW);
        break;
      case 0x02:
        digitalWrite(Relay2_PIN, LOW);
        break;

      case 0x03:
        digitalWrite(Relay3_PIN, LOW);
        break;
      case 0x11:
        digitalWrite(Relay1_PIN, HIGH);
        break;

      case 0x12:
        digitalWrite(Relay2_PIN, HIGH);
        break;
      case 0x13:
        digitalWrite(Relay3_PIN, HIGH);
        break;


    }

  }
}

void Switch(int relay) {
  if (digitalRead(relay) == HIGH) {
    digitalWrite(relay, LOW);
  }
  else {
    digitalWrite(relay, HIGH);
  }
}

超絶手抜きだけど気にしない。

#6番ピンON/OFF
#i2cset -y 0 0x26 0x01 0x00 b
#i2cset -y 0 0x26 0x11 0x00 b


ふつうは正論理でいいはずなのだけど、arduino用の5vリレーは大抵負論理なので注意
途中に抵抗を入れてやらなきゃいけなかったりもするしめんどくさい。
ebayに3.3v用のリレーが売ってるのを買ってつなげたほうが手っ取り早い。



OPENWRTにLCDをつなげてみる


GL-MT300Nではほかに供用されていないGPIOでピンが出ているのは

WPSボタン用2番
未使用の44番

これをi2cにして液晶をつなげてみる。

これにはちょっと問題があって、この手のルータは大抵3.3v 

LCDに変換ボードがついているものは大抵5vだ。

ただ、いくつか例外があって、変換ボードを介さないACM1602 ACM802なんてのは3.3v

ちょうど手元にあった スイッチサイエンスの液晶(3.3v版)

を接続してみる。

まずは参考にするページ

https://wiki.openwrt.org/doc/hardware/port.i2c

http://netlog.jpn.org/r271-635/2013/01/raspberry_pi_i2c_lcd.html
配線は
SCL->GPIO 2
SDA-> GPIO 44
VCC->3.3v
GNDー>GND


といたってシンプル

# opkg update
# opkg install kmod-i2c-gpio-custom kmod-i2c-core
# insmod i2c-dev
# insmod i2c-gpio-custom bus0=0,2,44
ところがどっこい、こやつにはi2c-toolsがないので


# wget http://dl.eko.one.pl/chaos_calmer/ramips/packages/i2c-tools_3.1.2-1_ramips_24kec.ipk

# opkg install i2c-tools_3.1.2-1_ramips_24kec.ipk


確認
# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- 26 -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 3e --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

3eが見えていればOK。

起動時ロードさせるには

# echo "i2c-gpio-custom bus0=0,2,44" > /etc/modules.d/99-i2c-gpio-custom

んなのでええんでないのと。
先人のありがたいスクリプトをリスペクト(古い)しよう

# opkg install bash perl

# vi i2c_lcd.sh

#!/bin/bash
function usage {
    echo "Usage: $0 [-ic] [-p pos] message" > /dev/stderr;
    echo "       -i : LCD init, -c : Clear Screen" > /dev/stderr
    echo "       -p : position (0:top left, 40:bottom left)" > /dev/stderr
    exit 1
}
[ $# = 0 ] && usage

while getopts "icp:" flag; do
    case $flag in
        \?) usage ;;
        i)  i2cset -y 0 0x3e 0 0x38 0x39 0x14 0x70 0x5e 0x6c i
            sleep 0.25
            i2cset -y 0 0x3e 0 0x0c 0x01 0x06 i
            sleep 0.05
            ;;
        c)  i2cset -y 0 0x3e 0 0x01 ;;
        p)  i2cset -y 0 0x3e 0 $((OPTARG+128)) ;;
    esac
done
shift $((OPTIND-1))
[ $# = 0 ] && exit

LANG=C
MSG=`echo -n "$1" | perl -pe '$_=join" ",map{ord }split//'`
#echo $MSG
i2cset -y 0 0x3e 0x40 $MSG i

で保存。


# chmod +x ./i2c_lcd.sh
#  ./i2c_lcd.sh -i
#  ./i2c_lcd.sh  "hogehoge"
#  ./i2c_lcd.sh -c