ページ

ラベル Arduino の投稿を表示しています。 すべての投稿を表示
ラベル Arduino の投稿を表示しています。 すべての投稿を表示

2015年4月11日土曜日

Arduinoと戯れる 11 - I2CLiquidCrystalコード読み -

I2CLiquidCrystalを読み解く

確認の時に使用したライブラリの中を見てみる。
まずはヘッダ

・I2CLiquidCrystal.h
#ifndef I2CLiquidCrystal_h
#define I2CLiquidCrystal_h

#include <inttypes.h>
#include <Print.h>

// commands
#define LCD_CLEARDISPLAY 0x01
#define LCD_RETURNHOME 0x02
#define LCD_ENTRYMODESET 0x04
#define LCD_DISPLAYCONTROL 0x08
#define LCD_CURSORSHIFT 0x10
#define LCD_FUNCTIONSET 0x20
#define LCD_SETCGRAMADDR 0x40
#define LCD_SETDDRAMADDR 0x80

// flags for display entry mode
#define LCD_ENTRYRIGHT 0x00
#define LCD_ENTRYLEFT 0x02
#define LCD_ENTRYSHIFTINCREMENT 0x01
#define LCD_ENTRYSHIFTDECREMENT 0x00

// flags for display on/off control
#define LCD_DISPLAYON 0x04
#define LCD_DISPLAYOFF 0x00
#define LCD_CURSORON 0x02
#define LCD_CURSOROFF 0x00
#define LCD_BLINKON 0x01
#define LCD_BLINKOFF 0x00

// flags for display/cursor shift
#define LCD_DISPLAYMOVE 0x08
#define LCD_CURSORMOVE 0x00
#define LCD_MOVERIGHT 0x04
#define LCD_MOVELEFT 0x00

// flags for function set
#define LCD_8BITMODE 0x10
#define LCD_4BITMODE 0x00
#define LCD_2LINE 0x08
#define LCD_1LINE 0x00
#define LCD_5x10DOTS 0x04
#define LCD_5x8DOTS 0x00

class I2CLiquidCrystal : public Print {
public:
  I2CLiquidCrystal();
  I2CLiquidCrystal(uint8_t contrast, bool is5V);

  void init();
  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
  void clear();
  void home();

  void noDisplay();
  void display();
  void noBlink();
  void blink();
  void noCursor();
  void cursor();
  void scrollDisplayLeft();
  void scrollDisplayRight();
  void leftToRight();
  void rightToLeft();
  void autoscroll();
  void noAutoscroll();

  void createChar(uint8_t, uint8_t[]);
  void setCursor(uint8_t, uint8_t);
  virtual size_t write(uint8_t);
  void command(uint8_t);

  using Print::write;
private:
  void send(uint8_t, uint8_t);

  bool _is5V;
  uint8_t _contrast;
  uint8_t _displayfunction;
  uint8_t _displaycontrol;
  uint8_t _displaymode;

  uint8_t _initialized;

  uint8_t _numlines,_currline;
  uint8_t I2C_ADDR, I2C_RS;
};

#endif
Printクラスを継承している。
次にソース部分

・I2CLiquidCrystal.cpp
#include "I2CLiquidCrystal.h"

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <Wire.h>
#include "Arduino.h"

// When the display powers up, it is configured as follows:
//
// 1. Display clear
// 2. Function set: 
//    DL = 1; 8-bit interface data 
//    N = 0; 1-line display 
//    F = 0; 5x8 dot character font 
// 3. Display on/off control: 
//    D = 0; Display off 
//    C = 0; Cursor off 
//    B = 0; Blinking off 
// 4. Entry mode set: 
//    I/D = 1; Increment by 1 
//    S = 0; No shift 
//
// Note, however, that resetting the Arduino doesn't reset the LCD, so we
// can't assume that its in that state when a sketch starts (and the
// I2CLiquidCrystal constructor is called).

// This library has been modified for I2C based LCD by Straberry Linux in Japan.
// The controller is ST7032i.
//  21 Aug. 2012, Noriaki Mitsunaga

const static uint8_t I2C_ADDR_AKIZUKI = 0x50;

I2CLiquidCrystal::I2CLiquidCrystal()
{
  I2C_ADDR = I2C_ADDR_AKIZUKI;  // Akizuki denshi
  I2C_RS = 0x80;
  init();
}

I2CLiquidCrystal::I2CLiquidCrystal(uint8_t contrast, bool is5V)
{
  I2C_ADDR = 0x3e; // Strawberry Linux
  I2C_RS = 0x40;
  _contrast = contrast;
  _is5V = is5V;
  init();
}

void I2CLiquidCrystal::init()
{
  Wire.begin();
  _displayfunction = 0;
  //  begin(16, 1);  
}

void I2CLiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
  if (lines > 1) {
    _displayfunction |= LCD_2LINE;
  }
  _numlines = lines;
  _currline = 0;

  // for some 1 line displays you can select a 10 pixel high font
  if ((dotsize != 0) && (lines == 1)) {
    _displayfunction |= LCD_5x10DOTS;
  }

  // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
  // according to datasheet, we need at least 40ms after power rises above 2.7V
  // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
  delayMicroseconds(50000); 

  if (I2C_ADDR != I2C_ADDR_AKIZUKI) { // Strawberry Linux
    // set # lines, font size, etc.
    //command(0b00110000 | _displayfunction);  
    command(0x38); ★2
    delayMicroseconds(50);

    // again
    //command(0b00110000 | _displayfunction);  
    command(0x39); ★2
    delayMicroseconds(50);

    // Internal OSC frequency
    command(0x14); ★2
    delayMicroseconds(50);

    // Contrast set
    command(0x70 | (_contrast & 0xF)); ★2
    delayMicroseconds(50);

    // Power/ICON/Contrast control
    if (!_is5V) ★2
      command(0x5c | ((_contrast >> 4) & 0x3));
    else
      command(0x58 | ((_contrast >> 4) & 0x3)); 
    delayMicroseconds(50);

    // Follower Control
    command(0x6c); ★2
    delay(400);
  } else { // Akizuki LCD
    command(0b00110000 | _displayfunction);  
    delayMicroseconds(4100);
    command(0b00110000 | _displayfunction);  
    delayMicroseconds(100);
  }

  // Function set (set so as to be compatible with parallel LCD)
  command(0b00110000 | _displayfunction);  

  // turn the display on with no cursor or blinking default
  _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;  
  display();

  // clear it off
  clear();

  // Initialize to default text direction (for romance languages)
  _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
  // set the entry mode
  command(LCD_ENTRYMODESET | _displaymode);
}

/********** high level commands, for the user! */
void I2CLiquidCrystal::clear()
{
  command(LCD_CLEARDISPLAY);  // clear display, set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}

void I2CLiquidCrystal::home()
{
  command(LCD_RETURNHOME);  // set cursor position to zero
  delayMicroseconds(2000);  // this command takes a long time!
}

void I2CLiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row >= _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }

  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

// Turn the display on/off (quickly)
void I2CLiquidCrystal::noDisplay() {
  _displaycontrol &= ~LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void I2CLiquidCrystal::display() {
  _displaycontrol |= LCD_DISPLAYON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turns the underline cursor on/off
void I2CLiquidCrystal::noCursor() {
  _displaycontrol &= ~LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void I2CLiquidCrystal::cursor() {
  _displaycontrol |= LCD_CURSORON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// Turn on and off the blinking cursor
void I2CLiquidCrystal::noBlink() {
  _displaycontrol &= ~LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}
void I2CLiquidCrystal::blink() {
  _displaycontrol |= LCD_BLINKON;
  command(LCD_DISPLAYCONTROL | _displaycontrol);
}

// These commands scroll the display without changing the RAM
void I2CLiquidCrystal::scrollDisplayLeft(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
}
void I2CLiquidCrystal::scrollDisplayRight(void) {
  command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
}

// This is for text that flows Left to Right
void I2CLiquidCrystal::leftToRight(void) {
  _displaymode |= LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This is for text that flows Right to Left
void I2CLiquidCrystal::rightToLeft(void) {
  _displaymode &= ~LCD_ENTRYLEFT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'right justify' text from the cursor
void I2CLiquidCrystal::autoscroll(void) {
  _displaymode |= LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// This will 'left justify' text from the cursor
void I2CLiquidCrystal::noAutoscroll(void) {
  _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
  command(LCD_ENTRYMODESET | _displaymode);
}

// Allows us to fill the first 8 CGRAM locations
// with custom characters
void I2CLiquidCrystal::createChar(uint8_t location, uint8_t charmap[]) {
  location &= 0x7; // we only have 8 locations 0-7
  command(LCD_SETCGRAMADDR | (location << 3));
  for (int i=0; i<8; i++) {
    write(charmap[i]);
  }
}

/*********** mid level commands, for sending data/cmds */

inline void I2CLiquidCrystal::command(uint8_t value) {
  send(value, LOW);
}

inline size_t I2CLiquidCrystal::write(uint8_t value) {
  send(value, HIGH);
  return 1; // assume sucess
}

/************ low level data pushing commands **********/

// write either command or data, with automatic 4/8-bit selection
void I2CLiquidCrystal::send(uint8_t value, uint8_t mode) { ★1

  Wire.beginTransmission(I2C_ADDR);
  if (mode == LOW)
    Wire.write(0x0);   // Co = 0, RS = 0    // Co: continue
  else
    Wire.write(I2C_RS);  // Co = 0, RS = 1
  Wire.write(value);
  Wire.endTransmission();
}

以下解析
★1
実際にコマンドを送る所。
  Co : 0 -> 一回のコマンドで完結
  Co : 1 -> 続きのコマンドがある
  RS : 0 -> 設定系のコマンド時
  RS : 1 -> データの読み書き時

★2
  初期設定
     初期化の流れとしては・・・
         1. 電源電圧が安定してから40ms以上ウェイト
         2. Function Set (0x38)
         3. Function Set (0x39)
         4. Internal OSC frequency(内部クロック周波数)
         5. Contrast set
         6. Power / ICON / Contrast constrol
         7. Follower control
         8. Display ON/OFF Control



2015年4月4日土曜日

Arduinoと戯れる 10 - I2C -

I2Cについてちゃんと勉強してみる


I2C
  ・・・フィリップス社で開発されたシリアルバスである。低速な周辺機器をマザーボードへ接続したり、組み込み、携帯電話などで使われている。Inter-Integrated Circuit の略

SCL(シリアル・クロック)と、双方向のSDA(シリアル・データ)の2本の信号線(GNDは含まず)で通信する同期式のシリアル通信


ここで出てくるシリアル通信だったり、UARTだったりと混乱しそうなのでまとめ↓

■ パラレル通信
    > 複数の信号線をつなぎ、一度に数ビットづつ送信

■ シリアル通信
    > 1本の線をつなぎ、一度に1ビットづつ送信
     ・同期シリアル通信
            > コンピュータ同士で通信のタイミングを同期させるクロック線がある

     ・非同期シリアル通信
            > コンピュータ同士であらかじめ通信速度を決めておき、受信側ではスタートのタイミングから自分のコンピュータ内のクロックで受信タイミングを決める方式
           → UART

シリアル通信の種類

■ EIA232
    > 通常のシリアル通信 PCのRS232Cもこれ

■ SPI
   > 同期シリアル通信の一種で、送信線、受信線、クロック線の3本から構成され、マスタとスレーブの1対1通信で、数Mbpsで通信できる。マイコンとメモリデバイスをシリアルで高速にデータのやりとりをする場合によく使われる

■ I2C
  > 同期シリアル通信の1種で、1つのクロック線と1つのデータ線で、1つのマスタに対して8個までのスレーブを接続できる。通信速度は100kbpsか400kpbsで通信され、データ線は1つしかないが双方向で通信できる(タイミングにより送信になったり受信になったりする)。マイコンとその他のICを通信するのによく使われる

参考サイト
http://www.robotsfx.com/robot/robohow/RoboHow92/RoboHow92.html

通信プロトコル等参考サイト
http://www.picfun.com/c15.html


マルツパーツで買ってきたLCDのI2Cプロトコルの説明が難解だったのでメモ
























各コマンドのデータ(DB0〜DB1)は2バイト目、RSは1バイト目の値
RWはスレーブアドレスを送る際の値

ん〜解りにくいorz

2015年3月27日金曜日

Arduinoと戯れる 9 - LCD表示 -

以前挑戦して惨敗したLCD表示に挑戦してみる!!

とりあえず今日は半田付け〜動作確認まで。

・LCD
    マルツパーツで売られている「MI2CLCD-01」を使用




































いざ半田付け開始!!


















ほぼ初心者なので手が震えるorz
なんとか完成しました^^;


















へ、下手!! orz
とりあえずこれで進めるとして、液晶を取り付けて完成。


















とりあえず半田付けがちゃんとできているか確認。
今回は確認なので他力本願、サンプルにある「I2CLiquidCrystal」を使用。

・スケッチ
/*
  LiquidCrystal Library - Cursor

 Demonstrates the use a 16x2 LCD display.  The LiquidCrystal
 library works with all LCD displays that are compatible with the 
 Hitachi HD44780 driver. There are many of them out there, and you
 can usually tell them by the 16-pin interface.

 This sketch prints "Hello World!" to the LCD and
 uses the cursor()  and noCursor() methods to turn
 on and off the cursor.

 The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)

 Library originally added 18 Apr 2008
 by David A. Mellis
 library modified 5 Jul 2009
 by Limor Fried (http://www.ladyada.net)
 example added 9 Jul 2009
 by Tom Igoe 
 modified 22 Nov 2010
 by Tom Igoe

 This example code is in the public domain.

 http://arduino.cc/en/Tutorial/LiquidCrystalCursor

 */

// include the library code:
#include <I2CLiquidCrystal.h>
#include <Wire.h>

// initialize the library
// uncomment next line if you are using a LCD from Straberry Linux
I2CLiquidCrystal lcd(20, false);
                  //  |    +--- set true if the power suply is 5V, false if it is 3.3V
                  //  +-------- contrast (0-63)
// uncomment next line if you are using a LCD from Akizuki denshi
// I2CLiquidCrystal lcd;

void setup() {
  // set up the LCD's number of columns and rows: 
  lcd.begin(A5, A4);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // Turn off the cursor:
  lcd.noCursor();
  delay(500);
  // Turn on the cursor:
  lcd.cursor();
  delay(500);
}

・Arduinoとの接続


















ざっくりですが・・・

↓実際に動かしてみた所


















表示できている!! か、感動><

最初、Arduino側の電源を3.3Vにつないでいたんですが、Arduino側が5Vで動作する場合は
5Vでいいらしい。

次回は中身を把握しながら進めようと思います。

参考URL

2014年11月24日月曜日

Arduinoと戯れる 8 - EEPROM -

EEPROMを使ってみる

EEPROM
  Arduino UNO R3には、1Kバイトの不揮発性メモリーEEPROMが備わっている。
  これを使う事で電源を切ってもデータを保管できる

1. スケッチの作成
  • EEPROM.hのインクルード
  • 主な関数
           void EEPROM.write(int adr, byte val)
           byte EEPROM.read(int adr)
           ※adr (Arduino UNOの場合は0〜1023)

実際にスケッチを作成してみる



実際にArduinoで動作させてみる



リセットボタンを押す度にカウントアップされる。
容量は少ないけど、ちょっとしたデータを保存しておくには良さげ。

2014年9月20日土曜日

Arduinoと戯れる 7 - PWM -

PWMをお勉強

PWM(Pulse Width Modulation : パルス幅変調)とは・・・

  変調方法の一つ、パルス比のデューティー比を変化させて変調すること。

らしい。。デューティー比って何?
http://ja.wikipedia.org/wiki/デューティ比
う〜ん。きっと1秒間に何回HIGHとLOWを繰り返すかの割合だろう^^;

ArduinoのPWMに関しては、analogWrite関数で490Hz間隔で、HIGH/LOWを切り替えて電圧を変化させている。
例) analogWrite(pin, 0) => 常にLOW 0V
      analogWrite(pin, 51) => 20%の割合でHIGHになる 1V
      analogWrite(pin, 153) => 60%の割合でHIGHになる 3V
      analogWrite(pin, 255) => 常にHIGH 5V


PWM制御によるLED回路

analogWrite関数を使ってLEDを明るくしたり、暗くしたりしてみる。
※実際はLEDの明るさは流れる電流で決まるが、今回は可変抵抗が無いので、PWMで制御
LEDに取り付ける抵抗値(Ω)は

  LEDに取り付ける抵抗値(Ω) = (電源電圧 - LED規格電圧) / 定格電流

で求められるのだが、規格が分からなかったので、本の通り
(5V - 3.3V) / 0.02 = 85Ωとして、それ以上の抵抗値220Ωを使用して配線。




















analogWriteを使ってスケッチを作成。
























実行してみると、1秒毎に変化が見られました。

2014年8月24日日曜日

Arduinoと戯れる 6 - スピーカーで音を出す -

スピーカーを使って音を出してみる。


マルツパーツで安いスピーカーを購入。


















以下を参考に接続。
http://mathrax.sakura.ne.jp/mathrax_com/ws/page10.html


















digitalWriteとdelayMicro~を使用して振動を発生させる。
また、tone関数を使用して音階を発生。

以下スケッチの例

// Arduino + Sound WS
// 2011.11.26-27
//
// 01-1:Arduinoで音を出そう
// "音が鳴るサンプル"


//スピーカーのピンを9ピンにする
int speakerPin = 9;



void setup(){

  //スピーカーのピンを出力モードに
  pinMode(speakerPin, OUTPUT);
  //圧電スピーカーを鳴らす
  tone(speakerPin, 329, 125);  //ミ
  //休符
  delay(150);
  tone(speakerPin, 329, 125); //ミ
  //休符
  delay(300);
  tone(speakerPin, 329, 125); //ミ
  //休符
  delay(300);
  tone(speakerPin, 261, 125); //ド
  //休符
  delay(150);
  tone(speakerPin, 329, 125); //ミ
  //休符
  delay(300);
  tone(speakerPin, 391, 125); //ソ
  //休符
  delay(650);
  tone(speakerPin, 195, 125); //低いソ
  //休符
  delay(150);
}

void loop(){

}

マ○オの音楽が流れました^^

2014年8月23日土曜日

Arduinoと戯れる 5 - 温度測定 TMP102 -

温度測定をやってみる。

温度計をスイッチサイエンスから購入。
http://www.switch-science.com/catalog/1474/

慣れない半田ごて作業でピンヘッダを接着。
























http://blog.goo.ne.jp/mikotolv5/e/3890d443221cc2f144034e592d4bc23d
上記サイトを参考に配線してみる。



















ADD0をGNDに接続したのでI2Cのアドレスは0x48で設定。
スケッチ。

#include "Wire.h"

#define TMP102_I2C_ADR    0x48


void setup() {
  Wire.begin();
  Serial.begin(9600);
}

void getTemp102() {
  byte high, low;
  int val;
  float convtemp;
  float currtemp;

  Wire.beginTransmission(TMP102_I2C_ADR);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(TMP102_I2C_ADR, 2);
  Wire.endTransmission();

  high = (Wire.read());
  low = (Wire.read());

  val = ((high) << 4);
  val != ((low) >> 4);

  convtemp = val * 0.0625;
  currtemp = convtemp - 5;

  Serial.print(convtemp);
  Serial.println("C");
}

void loop() {
  getTemp102();
  delay(5000);
}

シリアルモニタの結果。



2014年8月17日日曜日

Arduinoと戯れる 4 - Cdsセル -

Cdsセル

参考サイト
http://strange-storage-5084.blogspot.jp/2012/03/arduinocds.html

Cdsを使って明るさを取得してみる。
配線


















スケッチ
























参考サイトと比べて室内の明るさが違うので、閾値を変更。
手をかざしたりして、明るさを変更しLEDの点灯/消灯を行う。

Arduinoと戯れる 3 - スイッチのIO -

デジタルIO

1. タクトスイッチ











いつも迷うのでメモ。
赤が常に接続、青が押されて接続。。。

実際にテストしてみる。


















DO2チャンネルをpinMode(2, INPUT_PULLUP)として宣言。
スイッチを押すとLEDが点灯するようにスケッチを作成。
























スイッチを押すとLEDが点灯することを確認^^




















今度はスイッチを押す度にLED表示/非表示を切り替える様にスケッチを作成。

























チャタリング対策していない為、スイッチが不安定^^;
チャタリング対策を入れたスケッチを作成。
























ちゃんと切り替わっている様子。

2014年8月9日土曜日

Arduinoと戯れる 2 - プルアップ抵抗 -

プルアップ抵抗について

デジタル入力の場合にHIGHとLOWの中間電圧の状態では誤作動を起こす。
Arduinoではこの対策として、「pinMode」関数にプルアップ抵抗を取り入れ誤作動を防止している。
digitalRead関数の戻り値は「pinMode」がINPUT又は未設定の場合にはHIGH(約3.0V以上)か
LOW(約2.0V以下)を返す。しかし思った値にならない場合がある。


プルアップ抵抗の確認テスト
D8番ピンとGNDを接続
























ケーブルを抜き差ししても0と1が一定の値にならない。














pinModeの第二引数をINPUTからINPUT_PULLUPに変更してみる。














今度はGNDにつなげたら0が、切り離した場合1が表示しています。

参考URL

乾電池の電圧測定

analogRead関数を使って乾電池の電圧を測定。
※測定できる乾電池は5Vまで。










































↓ちゃんと読み込まれているもよう。。。


2014年8月4日月曜日

Arduinoと戯れる 1 - UNO購入!! -

ArduinoUNOを購入。


定番ですが、SWITCHSIENCEから購入。
基盤表

MBAにIDEをインストール。ドライバーもPlug&Playなので
USBを差し込んだだけでドライバがインストール。

まずはド定番のLEDチカチカ^^








↓こんな感じ。