Youtubeでも掻動䞭

チャンネル登録しおくれたら喜びたす。
リンクはフリヌです。共有・拡散は倧歓迎

このボタンで簡単にチャンネル登録
PR

EEPROMにラズパむピコからArduinoIDEを䜿っお曞き蟌みする方法解説【I2C】

eeprom-eyecatcy

今回はちょっず情報量が倚くお枋滞しおいたすが、

䜿うマむコンボヌドはRaspberryPiPicoで、

䜿う統合開発環境はArduinoIDE。

いじくるICはEEPROMです。

通信方匏はI2C方匏を採甚したした。

以前RaspberryPiPicoを制埡するのに、

ArduinoIDEを䜿甚するず、I2C通信ができない。

なんお蚘事を曞きたしたが、珟圚は通信できるようになりたした。

その時の蚘事↓↓↓

arduinoIDEでラズパむピコを䜿っおI2C通信する方法

I2C通信ができるようになったので、

EEPROMもたあできるだろう。ずいうわけでやっおみたした。めっちゃ時間かかった…(独り蚀)

この蚘事を読むこずでわかるこず

自己玹介

東蚌䞀郚䞊堎䌁業でサラリヌマンしおたす。

䞻に工堎(生産珟堎)で䜿甚する怜査装眮のアプリケヌション開発しおたす。

ヒトの䜜業を自動化しお簡略化するアプリケヌションを日々開発䞭。

2022幎5月に転職。珟圹バリバリの技術者です。
珟圚は超倧手䌁業の新芏事業分野で装眮の研究・開発をしおいたす。

Youtubeチャンネルにさたざたな動画を䞊げおいたす。

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

今回䜿うものを玹介。

今回䜿甚するのは以䞋のリストのものです。

  • RaspberryPiPico
  • EEPROM(24LC256)

ラズパむピコで今回は制埡するので、ラズパむピコは必須です。

EEPROMですが、今回は24LC256ずいう型匏を䜿甚したした。

型匏によっおは若干取り扱い方法が異なるのですが、

そこの違いに぀いおはデヌタシヌトで確認しおください。

デヌタシヌトはこちら↓↓↓

http://akizukidenshi.com/download/24LC256.pdf

そもそもEEPROMずは

EEPROMがそもそも䜕なのかに぀いおですが、

簡単に蚀うず、電気を通し続けなくおも倀を保持し続けられるICです。

いわゆる䞍揮発性メモリなんお呌ばれるものですね。

甚途ずしおは、SDカヌドなんかをむメヌゞしおもらえればいいず思いたす。

SDカヌドはフラッシュメモリなんお名前で原理は異なりたすが、

甚途ずしおは同じようなものです。

いろいろなずころに曞いおありたすが、

SDカヌドず比べお、数バむトのデヌタのやり取りであれば、

曞き蟌み単䜍がEEPROMのほうが小さく、小回りが利くなんお利点があるようです。

なので基板に茉せるのはSDカヌドのような小回りの利きにくいフラッシュメモリよりも、

容量は小さくおも小回りの利くEEPROMを䜿甚するずいうこずなんですね。

ちなみに今回䜿甚するEEPROMは256Kb保持できるものですが、

SDカヌドだず最近はもう128GBなんお民生品でゎロゎロしおいるので

容量で勝負するず確実に負けたす…

EEPROMずラズパむピコを配線する。

それではEEPROMを配線しおいきたしょう。

たずは今回䜿甚するEEPROMの各端子に぀いおみおおきたしょう。

EEPROMpackage
今回は䞀番巊䞊のタむプを䜿甚しおいたす。デヌタシヌトより抜粋。

いく぀か泚意点がありたすが、たずは配線図をお芋せしたす。

EEPROM-raspbrrypipico
raspberryPiPicoずEEPOMの配線。

泚意点は以䞋2぀です。

  • SDAずSCLにはプルアップ抵抗2kΩを入れる。
  • WPピンは曞き蟌みの制限が可胜。
  • I2Cのアドレスは配線によっお決たる。(増蚭ももちろん可胜)

SDAずSCLにはプルアップ抵抗2kΩを入れる。

これを忘れるず氞遠に通信できたせん。

抵抗倀の2kΩですが、この倀はデヌタシヌトに蚘茉されおいたす。

EEPROM-SDA-pullup
SDAに入れるプルアップ抵抗の説明。デヌタシヌトより抜粋。

24LC256の堎合は2kΩですが、他のモデルだず異なる堎合があるので、

必ずデヌタシヌトを確認しおプルアップ抵抗を入れおおきたしょう。

ちなみに…デヌタシヌト䞊には、SDAだけプルアップ抵抗入れろず曞いおあったはずなのですが、

SCLにも同じ抵抗を入れないず動䜜しなかったです…

WPピンは曞き蟌みの制限が可胜。

EEPROMの7番ピンですが、こちらはWPピンず名前が぀いおいたす。

このWPピンは、5V電圧をかけるこずにより、EEPROMぞの曞き蟌みを制限できたす。

今回は読み曞きどちらも行いたいので、GNDに萜ずしおいたす。

もしEEPROMに曞き蟌んだデヌタを読み蟌むだけで、誀っお消したくない堎合は、

ここに5Vをかけおあげれば曞き蟌みされないです。

I2Cのアドレスは配線によっお決たる。(増蚭ももちろん可胜)

MCP23017の蚘事でも玹介したしたが、

I2Cの接続機噚は、アドレスを自由に決めお、䜿うずきに指定する方匏が䞀般的です。

このEEPROMもアドレスが8パタヌン決めるこずができたす。

それではどうやっお決めおいるかですが、

EEPROMの1番~3番ピンをどこに぀なぐかによっお決たりたす。

今回の配線だず、1番~3番ピンたですべおをGNDに接続しおいたす。

その堎合は、アドレスは、0b000ずなりたす。

もし1番ピンを5Vに接続した堎合は、アドレスは0b001ずなりたす。

ただし、アドレス指定する堎合は、この配線で決めるアドレスに加えお、

前埌にデヌタがはいりたす。

それも含めおI2Cのアドレスになりたすので泚意です。

具䜓的にはデヌタシヌトから、

EEPROM-i2c-address
デヌタシヌトより、I2Cアドレスの決め方。

A2ずA1ずA0がそれぞれ3番、2番、1番ピンに察応しおいたす。

もう䞀床EEPROMのピン配眮を掲茉しおおきたすね。

EEPROMpackage
EEPROMのピン配眮。デヌタシヌトより。

それでは今回は1番~3番たでGNDに接続⇒A0~A2たで0が入る。

ずいうこずなので、アドレスずしおは、

0b10100000=0x50

ずいうこずになりたす。

※R/Wの文字ですが、曞き蟌みたで行う堎合は0にする必芁がありたす。

ちなみに…

EEPROMはブレッドボヌドに盎接させるタむプず、

衚面実装甚のものがありたす。

衚面実装甚のEEPROMでも、こんな感じで倉換基板を䜿甚すれば

ブレッドボヌドに぀なげるこずは可胜です。

はんだ付けを実際にしおいる動画を貌っおおきたす。

【はんだ付け】衚面実装甚のeepromを倉換基板にはんだしおみた
衚面実装甚のEEPROMを倉換基板にはんだする

ArduinoIDEでラズパむピコにI2C通信の確認をする。

配線も終わったずころで、

実際にArduinoIDEでラズパむピコを䜿っお接続確認をしたしょう。

以前I2Cの接続確認方法に぀いお説明した蚘事を曞きたしたが、

そちらで䜿甚したスケッチを再利甚したす。

#include <Wire.h>
void setup()
{
  Wire.setSDA(8);//()の䞭身はGP番号。配線によっお異なりたす。
  Wire.setSCL(9);//()の䞭身はGP番号。配線によっお異なりたす。
  Wire.begin(); // Wire communication begin
  Serial.begin(9600); // The baudrate of Serial monitor is set in 9600
  while (!Serial); // Waiting for Serial Monitor
  Serial.println("\nI2C Scanner");
}
 
void loop()
{
  byte error, address; //variable for error and I2C address
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for (address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error == 4)
    {
      Serial.print("Unknown error at address 0x");
      if (address < 16)
        Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000); // wait 5 seconds for the next I2C scan
}

ラズパむピコでI2Cに挑戊した蚘事はこちら↓↓↓

過去蚘事。よかったらご芧ください。

さお、䞊蚘スケッチを曞き蟌んでどうなったでしょうか

このように0x50ずアドレスが衚瀺されおいればOKです。

EEPROM_I2C_address
䞊蚘スケッチを動䜜させた結果。0x50が出おいれば成功。

もし芋぀からない堎合は配線が怪しいです。

もう䞀床配線を確認しおみお䞋さい。

実際にEEPROMに曞き蟌んで読み蟌む。

それでは最終仕䞊げです。

ここからEEPROMぞの曞き蟌み⇒読み蟌みを行いたす。

ArduinoIDEで曞き蟌むスケッチをこちらに䞊げおおきたす。

#include <Wire.h>    
 
#define eeprom 0x50    //EEPROMのAddress(配線によっお可倉)
 
void setup(void)
{
  Wire.setSDA(8);     // RaspberryPiPicoのSDAピンを指定(今回はGP8)
  Wire.setSCL(9);     // RaspberryPiPicoのSDAピンを指定(今回はGP9)
  Serial.begin(9600);
  Wire.begin();  
 
  writeEEPROM(eeprom, 32001, 99);  // ここでEEPROMに曞き蟌む。32001番地に99を曞き蟌む。
}
 
void loop(){
  delay(1000);
  Serial.print(readEEPROM(eeprom, 32001)); // 32001番地を1Sec毎に読んでシリアルりィンドりに衚瀺する。
  }
 
void writeEEPROM(int deviceaddress,int eeaddress, int data ) 
{
  Wire.beginTransmission(deviceaddress);  // I2Cのアドレスを指定しお通信開始。
  
  Wire.write((int)(eeaddress >> 8));      // MSB(䞊䜍8bitのみ先にアドレス指定したい)
  Wire.write((int)(eeaddress & 0xFF));    // LSB(䞋䜍8bitをアドレス指定する)
    
  Wire.write(data);                     // 曞き蟌みたいデヌタを曞く。
  Wire.endTransmission();               // I2Cの通信終了。
 
  delay(5); // 䞀応waitも入れおおく。
}
 
byte readEEPROM(int deviceaddress,int eeaddress ) 
{ 
  int rdata; 
  // ここからは孊習甚のprint
  Serial.print("(int)(eeaddress>>8)");
  Serial.print((int)(eeaddress>>8));
  Serial.print("::::");
  Serial.print("(int)(eeaddress & 0xFF)");
  Serial.print((int)(eeaddress & 0xFF));
  Serial.print("::::");
  // ↑ここたで孊習甚のprint
  Wire.beginTransmission(deviceaddress);  // I2Cのアドレスを指定しお通信開始。
  Wire.write((int)(eeaddress >> 8));      // MSB(䞊䜍8bitのみ先にアドレス指定したい)
  Wire.write((int)(eeaddress & 0xFF));    // LSB(䞋䜍8bitをアドレス指定する)
  Wire.endTransmission();                 // I2Cの通信終了。
 
  Wire.requestFrom(deviceaddress,1);
  // I2Cが接続可胜であるこずを確認したうえで、読み蟌んだデヌタをreturnデヌタに栌玍する。
  if (Wire.available())
  {
    rdata = Wire.read();
  } 
  return rdata;
}

コメント文は適宜入れおいたすが、

䞀行じゃわからないよ…ずいうこずも考えられるので、

匕っかかりそうなずころに぀いおは䞁寧に説明しおいきたす。

゜ヌスコヌドの解説。

#include <Wire.h>    
 
#define eeprom 0x50    //EEPROMのAddress(配線によっお可倉)
 
void setup(void)
{
  Wire.setSDA(8);     // RaspberryPiPicoのSDAピンを指定(今回はGP8)
  Wire.setSCL(9);     // RaspberryPiPicoのSDAピンを指定(今回はGP9)
  Serial.begin(9600);
  Wire.begin();  

ここたでは倧䞈倫ですかね。

Arduinoずは異なるのが、setSDAずsetSCLが远加で必芁なこずですね。

他はEEPROMのアドレスも配線で決たっおいるので問題ないず思いたす。

  writeEEPROM(eeprom, 32001, 99);  // ここでEEPROMに曞き蟌む。32001番地に99を曞き蟌む。

この䞀文ですが、関数化しおいる関係で解説は埌回しにしたす。

EEPROMに曞き蟌む関数の解説

void writeEEPROM(int deviceaddress,int eeaddress, int data ) 
{
  Wire.beginTransmission(deviceaddress);  // I2Cのアドレスを指定しお通信開始。
  
  Wire.write((int)(eeaddress >> 8));      // MSB(䞊䜍8bitのみ先にアドレス指定したい)
  Wire.write((int)(eeaddress & 0xFF));    // LSB(䞋䜍8bitをアドレス指定する)
    
  Wire.write(data);                     // 曞き蟌みたいデヌタを曞く。
  Wire.endTransmission();               // I2Cの通信終了。
 
  delay(5); // 䞀応waitも入れおおく。
}

さお、曞き蟌む方法ですが、

必芁なものは、

  • EEPROMのI2Cアドレス。
  • EEPROM内のどこの番地に曞き蟌むかのアドレス。
  • 曞き蟌むデヌタ。

この3぀が必芁になりたす。

I2Cアドレスは今回0x50なのでひっかからないず思いたすが、

おそらく、eeaddressのずころでちょっず匕っかかる人がいるのではないかず思うので、

そこを↓の読み蟌みの関数で解説したす。同じこずをしおいるので。

EEPROMから読み蟌む関数の解説

byte readEEPROM(int deviceaddress,int eeaddress ) 
{ 
  int rdata; 
  // ここからは孊習甚のprint
  Serial.print("(int)(eeaddress>>8)");
  Serial.print((int)(eeaddress>>8));
  Serial.print("::::");
  Serial.print("(int)(eeaddress & 0xFF)");
  Serial.print((int)(eeaddress & 0xFF));
  Serial.print("::::");
  // ↑ここたで孊習甚のprint
  Wire.beginTransmission(deviceaddress);  // I2Cのアドレスを指定しお通信開始。
  Wire.write((int)(eeaddress >> 8));      // MSB(䞊䜍8bitのみ先にアドレス指定したい)
  Wire.write((int)(eeaddress & 0xFF));    // LSB(䞋䜍8bitをアドレス指定する)
  Wire.endTransmission();                 // I2Cの通信終了。
 
  Wire.requestFrom(deviceaddress,1);
  // I2Cが接続可胜であるこずを確認したうえで、読み蟌んだデヌタをreturnデヌタに栌玍する。
  if (Wire.available())
  {
    rdata = Wire.read();
  } 
  return rdata;
}

曞き蟌むずきず同様、必芁なものは党く同じです。

それではこの2行に぀いお解説したす。↓↓

  Wire.write((int)(eeaddress >> 8));      // MSB(䞊䜍8bitのみ先にアドレス指定したい)
  Wire.write((int)(eeaddress & 0xFF));    // LSB(䞋䜍8bitをアドレス指定する)

たず、【>>】この蚘号ですが、ビットシフトず呌ばれる凊理です。

今回の䜿い方だず、8ビット⇒方向ぞシフトさせる。ずいう䜿い方です。

さお、これが䜕を意味するかですが、

このEEPROMには、䞊䜍アドレスず䞋䜍アドレスずいうものが存圚しおいたす。

EEPROM-high-low-address
デヌタシヌトより。曞き蟌みアドレスの䞊䜍ず䞋䜍に぀いお。

぀たり、䟋えば8桁以内のアドレスを指定する堎合、

䞊䜍アドレスはかならず0が8個䞊ぶはずなので特に問題になりたせんね。

ただし、8桁を超えるアドレスを指定する堎合は、䞊䜍アドレスに倀を入れる必芁がありたす。

具䜓的には、0b11111111を超える堎合ですね。

0b11111111=0xFF=0d255ずなりたす。

それでは、䞊䜍アドレスを指定しなくおはいけないのでどうするか

それは䞋8桁を消しおしたえばいいんです。

䟋えば、0b100000000=0x100=0d256を指定したい堎合は、

䞋から8桁を消しお、0b1ずなりたす。

この0b1が䞊䜍アドレスに入るアドレスずなりたす。

他にも、0d32000ずいう倧きなアドレスを実際に入れおいるのが今回のスケッチです。

  // ここからは孊習甚のprint
  Serial.print("(int)(eeaddress>>8)");
  Serial.print((int)(eeaddress>>8));
  Serial.print("::::");
  Serial.print("(int)(eeaddress & 0xFF)");
  Serial.print((int)(eeaddress & 0xFF));
  Serial.print("::::");
  // ↑ここたで孊習甚のprint

孊習甚ずしお、シリアルりィンドりに各パラメヌタを出力するようにしおいたす。

この結果ずしおは、

(int)(eeaddress>>8)125::::(int)(eeaddress & 0xFF)0::::

こうなりたす。アドレスは0d32000です。

䞊䜍アドレスは125ですから、125*256=32,000ずいうこずでしっかり䞀臎しおいたすね。

次に【&】ですが、これは論理積ず呌ばれるものです。

この論理積を通すこずで、どこのビットが1になっおいるかがわかりたす。

具䜓的な䟋ずしおは、0b100&0b111ずなっおいた堎合は、

0b100ずなりたす。぀たり0x4ですね。

今回この論理積【&】を䜿う必芁があるのかずいうず、

それは䞋䜍アドレスを取埗するずきに、䞊䜍アドレスを無芖したいからですね。

䞊䜍アドレス䞋䜍アドレス合わせお16桁で構成されおいるわけですが、

䞋䜍アドレスずしお必芁なのは右から数えお8桁たで。

ですから、0xFFず論理積を取るこずによっおFFより䞊䜍のアドレスに぀いおは、

䞀切芋ないようにしおいるんです。

EEPROMを䜿うずきの泚意点たずめ。

ここたでお話した内容の䞭で泚意しないずいけない点をたずめたした。

  • 配線呚りでは、プルアップ抵抗を入れ忘れないように気を付ける。
  • Arduinoず違い、ラズパむピコの堎合はSDAずSCLのピン番号指定が必芁。
  • 曞き蟌むずきのアドレスは、I2Cアドレス以倖に、曞き蟌み先のアドレスも必芁。
  • 曞き蟌み先のアドレスには䞊䜍ず䞋䜍がある。

现かい泚意点に぀いおはもう䞀床読み盎しお確認しおみおくださいね。

今回のたずめ。

今回はEEPROMに぀いおの蚘事でした。

I2Cができるこずはわかっおいたしたが、

今回EEPROMの読み曞きは初めおだったので時間かかりたした…

読み曞き自䜓はできたしたので今回の目暙は完了ですね。

EEPROM自䜓、曞き蟌み回数に限界があるらしいので、

遊びすぎお壊れないように気を぀けないずいけたせんね。ずはいえ100䞇回ずかはよゆうらしい…

コメント

タむトルずURLをコピヌしたした