Electoday 2025

ไมโครคอนโทรลเลอร์ => AVR and Arduino => Topic started by: mpcomputer on February 01, 2013, 10:09:17 PM

Title: I2C EEPROM
Post by: mpcomputer on February 01, 2013, 10:09:17 PM
เก็บค่า long int แบบตัวแปรหลายตัว ลง EEPROM ภายนอกครับ 24lc256 มีวิธีไหนบ้างครับ
struct real         
{
  int rcoin;
  int rqp;
  long int rpl1;
  long int rpl2;
  long int rpl3;
  long int rpl4;
  long int rpl5;
  long int rpl6;
  long int rpl7;
  long int rpl8;
  long int rpl9;
  long int rpl10;
}
rlist;

ไม่เข้าใจการเขียนโค๊ดว่าต้องเขียนลงยังไงอ่านยังไงครับ ขอบคุณครับ
Title: Re: I2C EEPROM
Post by: firmware.c on February 01, 2013, 10:17:50 PM
ก่อนอื่นเลยต้งถามก่อนว่าติดต่อ i2c EEPROM 24c256 ได้หรือยังครับ ถ้าติดต่อได้แล้วต่อไปวิธีการเก็บต้องแยกเก็บทีละ byte อาจจะใช้การ shift bit หรือเทคนิคการใช้ union ก็ได้แล้วแต่ความเหมาะสม
Title: Re: I2C EEPROM
Post by: mpcomputer on February 03, 2013, 08:15:18 PM
ยังไม่เข้าใจเลยครับ ขอแนวทางอีกนิดครับ ขอบคุณครับ
Title: Re: I2C EEPROM
Post by: firmware.c on February 03, 2013, 10:14:01 PM
EEPROM_write_long(unsigned long in_eep) {
    union {
       unsigned long  ulong;
       struct {
            unsigned char lo_lo;
            unsigned char lo_hi;
            unsigned char hi_lo;
            unsigned char hi_hi;
       } byte;
    } eep;
     
    eep.ulong = in_eep;
    Eeprom_write_byte(0, eep.byte.lo_lo);
    Eeprom_write_byte(1, eep.byte.lo_hi);
    .........
    .........
}
Title: Re: I2C EEPROM
Post by: firmware.c on February 03, 2013, 10:17:12 PM
ถ้าเป็นแบบอย่างด้านนที่คุณเพิ่ง edit คำถามไป ผมแนะนำให้ pack ลง structure หรือไม่ก็ array
Title: Re: I2C EEPROM
Post by: firmware.c on February 04, 2013, 03:31:24 PM
struct real {
  int rcoin;
  int rqp;
  long int rpl1;
  long int rpl2;
  long int rpl3;
  long int rpl4;
  long int rpl5;
  long int rpl6;
  long int rpl7;
  long int rpl8;
  long int rpl9;
  long int rpl10;
} rlist;

unsigned short eep_size;
unsigned char  eep_adr;
unsigned char *p_eep_dat;

eep_size = sizeof(rlist);
p_eep_dat = (unsigned char *)&rlist;
do {
eeprom_write_byte(eep_adr, *p_eep_dat);
eep_adr++; p_eep_dat++;
} while (--eep_size);
Title: Re: I2C EEPROM
Post by: mpcomputer on February 04, 2013, 08:52:05 PM
ขอบคุณครับท่าน firmware.c  ประโยชน์ทั้งนั้นขอเก็บก่อนนะครับ
Title: Re: I2C EEPROM
Post by: mpcomputer on February 10, 2013, 03:43:18 PM
#include <WProgram.h>
#define DEVICE 0x50 //this is the device ID from the datasheet of the 24LC256

//in the normal write anything the eeaddress is incrimented after the writing of each byte. The Wire library does this behind the scenes.

template <class T> int eeWrite(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
int i;
Wire.beginTransmission(DEVICE);
Wire.send((int)(ee >> 8)); // MSB
Wire.send((int)(ee & 0xFF)); // LSB
for (i = 0; i < sizeof(value); i++)
Wire.send(*p++);
Wire.endTransmission();
return i;
}

template <class T> int eeRead(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
int i;
Wire.beginTransmission(DEVICE);
Wire.send((int)(ee >> 8)); // MSB
Wire.send((int)(ee & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(DEVICE,sizeof(value));
for (i = 0; i < sizeof(value); i++)
if(Wire.available())
*p++ = Wire.receive();
return i;
}


ผมใช้ไลบรารี่อันนี้ครับ มันเก็บข้อมูล
long int rpl7;
  long int rpl8;
  long int rpl9;
  long int rpl10;
ช่วงนี้ไม่ได้สงสัยมันจะเกินหน้าหรืออะไรนี่แหละครับ
พออ่านตัวอื่นอ่านได้ที่เหลือมันเป็น0ครับ
Title: Re: I2C EEPROM
Post by: mpcomputer on February 17, 2013, 10:48:48 PM
rlist.rpl1  = (readEEPROM(disk1, 2)*10000) +(readEEPROM(disk1, 3)*1000) +(readEEPROM(disk1, 4)*100) +(readEEPROM(disk1, 5)*10) +readEEPROM(disk1, 6);

มันอ่านค่าได้เป็นHEXครับทำใหค่าที่ได้เพี้ยนไปหมดเลยครับ ผมแยกเลขเป็นหลักแล้วเขียนลงไป แต่เวลาอ่านด้วย
Serial.println(readEEPROM(disk1, x),DEC);
ค่าที่ได้ตรงตามที่เขียนลงไปครับอย่างนี้แก้ยังไงครับ
Title: Re: I2C EEPROM
Post by: firmware.c on February 17, 2013, 11:32:11 PM
ผมไม่รู้นะว่า lib arduino ใช้ยังไงแต่ที่สังเกตุได้อย่างหนึ่งคือ
readEEPROM(disk1' 2)*10000
readEEPROM return ค่าออกมาเป็น byte ใช่ไหมครับลอง type case ดูแบบนี้ก็ได้
readEEPROM(disk1' 2)*10000L
Title: Re: I2C EEPROM
Post by: JMew on February 19, 2013, 12:28:59 AM
ภาษา C ยากจังเนาะ ไม่ manipulate variable type ให้ด้วย ถ้าเป็น Basic นะ

CONFIG SDA = (Pin อะไร)
CONFIG SCL = (Pin อะไร)

(ซึ่งปกติแล้วจะใช้ SDA กับ SCL ที่ระบุมากับ Datasheet)

CONFIG I2CSLAVE = (Address อะไร)

เสร็จแล้วปุ๊บ $lib "24lc256.lib" แล้วอยากให้ตัวแปรอะไรแบบไหนไปเก็บได้เลย ผสมกันได้ด้วยเช่น

DIM rcoin AS ERAM Interger
DIM rqp AS ERAM Integer
DIM rpl1 AS ERAM Long
DIM rpl2 AS ERAM Long
DIM rpl3 AS ERAM Long

บลา ๆ ๆ

เอาเป็นตัวหนังสือยาว ๆ ก็ได้นะ เช่น

DIM mytext AS ERAM String * 15

mytext = "electoday.com"
Title: Re: I2C EEPROM
Post by: mpcomputer on February 20, 2013, 08:18:29 PM
aa = readEEPROM(disk1, 2);
  bb = readEEPROM(disk1, 3);
  cc = readEEPROM(disk1, 4);
  dd = readEEPROM(disk1, 5);
  ee = readEEPROM(disk1, 6);
  aa = aa*10000;
  bb = bb*1000;
  cc = cc*100;
  dd = dd*10;
  Serial.println(aa);
  Serial.println(bb);
  Serial.println(cc);
  Serial.println(dd);
  Serial.println(ee);
  rlist.rpl1 = aa+bb+cc+dd+ee;
  Serial.println(rlist.rpl1);


ผมแก้ไขโดยเขียนแบบนี้  ผ่านแล้วครับค่าที่ได้ตรงแล้วครับ ขอบคุณทุกๆท่านครับ ใครมีอะไรแนะนำต่อได้เลยนะครับ อยากรู้ อยากเป็น เพราะไม่ได้เรียนมาด้านนี้เลยครับ
Title: Re: I2C EEPROM
Post by: firmware.c on February 21, 2013, 09:22:53 PM
อย่างที่บอกครับดูว่ามัน return ค่าออกมาเป็นแบบไหน แล้วตัวแปรที่เอาไปใช้งานต่อเป็น type ไหน