Skip to content

Samples_I2C

Ko-ichiro Sugiyama edited this page May 17, 2022 · 5 revisions

はじめに

I2C クラスのメソッドについては,Class_I2C を参照されたい.

LCD + RTC

以下の LCD, RTC を使って動かす場合.

  • 液晶ディスプレイ(LCD) AQM0802A-RN-GBW
  • リアルタイムクロック (RTC) RC-8035SA
@lcd_address = 0x3e
@rtc_address = 0x32

def lcd_cmd(i2c, cmd)
  i2c.writeto(@lcd_address, [0x00, cmd])
end

def lcd_data(i2c, data)
  i2c.writeto(@lcd_address, [0x40, data])
end

def lcd_clear(i2c)
  lcd_cmd(i2c, 0x01)
  sleep 0.1
end

def lcd_home0(i2c)
  lcd_cmd(i2c, 0x02)
  sleep 0.1
end

def lcd_home1(i2c)
  lcd_cmd(i2c, 0x40|0x80)
  sleep 0.1
end

def lcd_cursor(i2c, x, y)
  pos = (x + y * 0x40) | 0x80
  lcd_cmd(i2c, pos)
  sleep 0.1
end

def lcd_init(i2c)
  sleep 0.2
  [0x38, 0x39, 0x14, 0x70, 0x56, 0x6c].each do |cmd|
    lcd_cmd(i2c, cmd)
  end
  sleep(0.3)
  [0x38, 0x0c, 0x01].each do |cmd|
    lcd_cmd(i2c, cmd)
  end
  sleep(0.1)
end

def lcd_print(i2c, data)
  data.length.times do |n|
    lcd_data(i2c, data[n].ord)
  end
end

def rtc2_init(i2c)
  i2c.writeto(0x32, [0xE0, 0x00, 0x00])
  sleep 0.1
end


def rtc2_set(i2c)
  i2c.writeto(@rtc_address, [0x00, 0x50, 0x59, 0x23|0x80, 0x01, 0x31, 0x10, 0x20])
  sleep 0.1
  i2c.writeto(@rtc_address, [0xF0, 0x00])
  sleep 0.1
end

def rtc2_get(i2c, tt)
  buf = i2c.read(@rtc_address, 8)   # 8 バイト分読み込み --> strings
  p buf
  buf = i2c.readfrom(@rtc_address, 8)   # 8 バイト分読み込み
  p buf

  tt['year'] = buf[7]
  tt['mon']  = buf[6]
  tt['mday'] = buf[5]
  tt['hour'] = buf[3] & 0x3f
  tt['min']  = buf[2]
  tt['sec']  = buf[1]
end


#I2C 初期化
i2c = I2C.new(22, 21)

# LCD 初期化
lcd_init(i2c)

# LCD に "Hello World" 表示
lcd_cursor(i2c, 1, 0)
lcd_print(i2c, "Hello!")

lcd_home1(i2c)
lcd_print(i2c, "from ESP")

# i2c で直接送信.以下のように文字列を送っても同様の操作ができる
# opcode = 0x40.chr
# i2c.write(0x3e, opcode + "from ESP")

sleep(5)

# RTC 初期化. 時刻設定
rtc2_init(i2c)
rtc2_set(i2c)

while true
  # 時刻表示
  tt = {}  #ハッシュ
  rtc2_get(i2c, tt)

  time0 = sprintf("%02x-%02x-%02x", tt['year'], tt['mon'], tt['mday'])
  time1 = sprintf("%02x:%02x:%02x", tt['hour'], tt['min'], tt['sec'])

  lcd_home0(i2c)
  lcd_print(i2c, time0)
  puts time0

  lcd_home1(i2c)
  lcd_print(i2c, time1)
  puts time1

  sleep(1)
end

補足

RTC へ入力する時刻を,決め打ちではなく,メソッドの引数で指定する場合は,以下のように修正すると良い. 但し,メソッドの入力値は 10 進数整数であることを前提としている.

def rtc2_set( i2c, year, mon, mday, wday, hour, min, sec )
#  p year, mon, mday, wday, hour, min, sec

  # BCDコードへ変換. 年(下2桁), 月, 日, 曜日, 時, 分, 秒
  year0 = (year / 10).to_i(2) << 4 | (year % 10).to_i(2)
  mon0  = (mon  / 10).to_i(2) << 4 | (mon  % 10).to_i(2)
  mday0 = (mday / 10).to_i(2) << 4 | (mday % 10).to_i(2)
  wday0 = (wday / 10).to_i(2) << 4 | (wday % 10).to_i(2)
  hour0 = (hour / 10).to_i(2) << 4 | (hour % 10).to_i(2)
  min0  = (min  / 10).to_i(2) << 4 | (min  % 10).to_i(2)
  sec0  = (sec  / 10).to_i(2) << 4 | (sec  % 10).to_i(2)

  i2c.writeto(@rtc_address, [0x00, sec0, min0, hour0|0x80, wday0, mday0, mon0, year0])
  sleep 0.1
  i2c.writeto(@rtc_address, [0xF0, 0x00])
  sleep 0.1
end
Clone this wiki locally