Pages: [1]   Go Down
Author Topic: i2c eeprom help!  (Read 729 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey all,

New to Arduino, finally made the switch from the Picaxe world.  I'm looking to recreate a project I did with picaxe, but I'm having some problems with the i2c interface and/or the new language. 

Basically, I'm looking to log the state of a pin (on or off) every 20ms and store that data on an external i2c EEPROM.  Then be able to play back the recorded states on another pin.

Currently, I'm not getting any where on my own, so I figured I'd ask for help. 

Here is the code I have thus far:
Code:
#include <Wire.h>

int ledPin=12;
int recPin=6;
int inPin=7;
int inval=0;
int counter=0;
byte a=0;
#define eAdd 0x50


void setup ()
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(inPin, INPUT);
  pinMode(recPin, INPUT);
  Wire.begin();
}
void loop()
{
  writedData();
  useData();
}
 
  void writeData()
{
   digitalWrite(13, HIGH);
   while(counter < 200)
     {
     inval=digitalRead(inPin);
     Wire.beginTransmission(eAdd);
     Wire.send(counter >> 8);  //first 8 bits of counter
     Wire.send(counter & 0xFF);  //sencond 8 bits of counter
     Wire.send(inval); //variable to send
     Wire.endTransmission();
     delay (200);
     counter++;
     }
   digitalWrite(ledPin, LOW);
   delay(1000);
   counter=0;
}

byte readData()
 {
  Wire.beginTransmission(eAdd);
  Wire.send(counter >> 8);
  Wire.send(counter & 0xFF);
  Wire.endTransmission();
  Wire.requestFrom(eAdd, 1);
    a= Wire.receive();
 }
 
 void usedata()
 {
   while(counter<1500)
   {
   byte a;
   readdata(a);
   if (a = 0)
    {
      digitalWrite(ledPin, LOW);
    }
   if (a=1)
   {
      digitalWrite(ledPin, HIGH);
   }
   delay(20);
   counter++;
   }
 }
}

I'm sure I have several issues here since I'm just learning the language.  Let me know if you can guide me in the right direction.  Thanks!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 549
Posts: 46063
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
   while(counter < 200)
     {
     inval=digitalRead(inPin);
     Wire.beginTransmission(eAdd);
     Wire.send(counter >> 8);  //first 8 bits of counter
     Wire.send(counter & 0xFF);  //sencond 8 bits of counter
     Wire.send(inval); //variable to send
     Wire.endTransmission();
     delay (200);
     counter++;
     }
All the values that you are sending are byte sized. Why are you not using bytes?

Code:
   while(counter<1500)
   {
Write 200 values and read 1500. Works for me. Does it work for you?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

the counter issue was a mistake.  I was messing around with that and didn't change it back.  Sorry about that. 

Can you explain how to distinguish sending/receiving bytes from what I've currently got there?

In "picaxe" terms, they were different variables (b for bytes and w for words).  As you can see I'm a little confused.  I got the majority of this from tutorials. 

I do think that the EEPROMs data location is supposed to be specified with 2 bytes.

Thanks for the help.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Can you please post code that actually compiles?

Code:
void loop()
{
  writedData();
  useData();
}

Gives:

Code:
sketch_nov21a.cpp: In function 'void loop()':
sketch_nov21a:21: error: 'writedData' was not declared in this scope
sketch_nov21a:22: error: 'useData' was not declared in this scope
sketch_nov21a.cpp: In function 'void usedata()':
sketch_nov21a:59: error: 'readdata' was not declared in this scope
sketch_nov21a.cpp: At global scope:
sketch_nov21a:72: error: expected declaration before '}' token
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This may help, I did some stuff with I2C and EEPROMs:

http://gammon.com.au/i2c
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So here is an updated version of my code.  I'm still not getting anything back.  Not sure if my addressing is the problem. 
Code:
#include <Wire.h>

int ledPin=12;
int inPin=7;
byte inval;
byte a=0;

#define eAdd 0x50


void setup ()
{
  pinMode(ledPin, OUTPUT);
  pinMode(inPin, INPUT);
  Wire.begin();
}
void loop()
{
   digitalWrite(ledPin, HIGH);
   for (int i=0; i<750; i++)
     {
     inval=digitalRead(inPin);
     Wire.beginTransmission(eAdd);
     Wire.send(i);
     Wire.send(inval); //variable to send
     Wire.endTransmission();
     delay (20);
     }
   digitalWrite(ledPin, LOW);
   delay(1000);
   int i=0;
   
for (int i=0; i<750; i++)
{
  Wire.beginTransmission(eAdd);
  Wire.send(i);
  Wire.endTransmission();
  Wire.requestFrom(eAdd, 1);
    a= Wire.receive();
   if (a = 0)
    {
      digitalWrite(ledPin, LOW);
    }
  else
   {
      digitalWrite(ledPin, HIGH);
   }
   delay(20);
   }
digitalWrite(ledPin,LOW);
delay(2000);
}
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16516
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well to verify I2C chip address problems you need first to look at the datasheet for the device. I don't see in this thread a mention of what kind of of eeprom chip you are using. Also any wiring details you might be using if the device can be hardwired to different I2C addresses.

Also here is a useful I2C 'scanner' sketch. Run it and it will try every valid I2C address possible and report if any attached devices are responding and at which addresses.

Code:


/**
 * I2CScanner.pde -- I2C bus scanner for Arduino
 *
 * 2009, Tod E. Kurt, http://todbot.com/blog/
 *
 */

#include "Wire.h"
extern "C" {
#include "utility/twi.h"  // from Wire library, so we can do bus scanning
}

// Scan the I2C bus between addresses from_addr and to_addr.
// On each address, call the callback function with the address and result.
// If result==0, address was found, otherwise, address wasn't found
// (can use result to potentially get other status on the I2C bus, see twi.c)
// Assumes Wire.begin() has already been called
void scanI2CBus(byte from_addr, byte to_addr,
                void(*callback)(byte address, byte result) )
{
  byte rc;
  byte data = 0; // not used, just an address to feed to twi_writeTo()
  for( byte addr = from_addr; addr <= to_addr; addr++ ) {
    rc = twi_writeTo(addr, &data, 0, 1);
    callback( addr, rc );
  }
}

// Called when address is found in scanI2CBus()
// Feel free to change this as needed
// (like adding I2C comm code to figure out what kind of I2C device is there)
void scanFunc( byte addr, byte result ) {
  Serial.print("addr: ");
  Serial.print(addr,HEX);
  Serial.print( (result==0) ? " found!":"       ");
  Serial.print( (addr%4) ? "\t":"\n");
}


byte start_address = 1;
byte end_address = 127;

// standard Arduino setup()
void setup()
{
    delay(2000);
    Wire.begin();
    Serial.begin(38400);
    Serial.println("\nI2CScanner ready!");

    Serial.print("starting scanning of I2C bus from ");
    Serial.print(start_address,HEX);
    Serial.print(" to ");
    Serial.print(end_address,HEX);
    Serial.println("...Hex");

    // start the scan, will call "scanFunc()" on result from each address
    scanI2CBus( start_address, end_address, scanFunc );

    Serial.println("\ndone");
}

// standard Arduino loop()
void loop()
{
    // Nothing to do here, so we'll just blink the built-in LED
    digitalWrite(13,HIGH);
    delay(300);
    digitalWrite(13,LOW);
    delay(300);
}

Lefty
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Code:
if (a = 0)
    {
      digitalWrite(ledPin, LOW);
    }

The variable "a" will always be zero here. You need "==".
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 16
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I managed to get it working.  I suspect it was the EEPROM's internal addressing that I was screwing up.  Many thanks to Nick's link for pointing me in the right direction.  Here is the updated code:

Thanks for everyone's help.  Its taking me a bit to pick up the intricacies of the C++ language.  I will say, with Picaxe I found myself with limited with even my small hobby projects.  I can see a ton more potential with Arduino.  As I get the hang of it, I'm liking it more.  Thanks again!

Code:
int ledPin=12;
int inPin=7;
int state = HIGH;
int previous = LOW;
boolean inval;
int sendval;
int reading;



#define eAdd 0x50
#include <Wire.h>

void setup ()
{
  pinMode(ledPin, OUTPUT);
  pinMode(inPin, INPUT);
  Wire.begin();
}

void loop()
{
   digitalWrite(ledPin, HIGH);
   delay (1000);
   digitalWrite(ledPin, LOW);
   delay (1000);
   digitalWrite(ledPin, HIGH);
   delay (1000);
   digitalWrite(ledPin, LOW);
   
   
    for(int i=0; i<750; i++)
     {
     reading = digitalRead(inPin);
     
     if (reading == HIGH)
     {
       sendval = 1;
     }
     else
      {
        sendval = 0;
     }
     
     Wire.beginTransmission(eAdd);
     Wire.send((byte) (i >>8));
     Wire.send((byte) (i & 0xFF));
     Wire.send(sendval); //variable to send
     Wire.endTransmission();
     digitalWrite(ledPin, sendval);
     delay (20);
     }
   digitalWrite(ledPin, LOW); //set back to off
   delay(1000);
 
digitalWrite(ledPin, HIGH);
delay (1000);
digitalWrite(ledPin, LOW);
delay (100);
int i=0;

for (int i=0; i<750; i++)
{
  Wire.beginTransmission(eAdd);
  Wire.send((byte) (i >> 8));
  Wire.send((byte) (i & 0xFF));
  Wire.endTransmission();
  Wire.requestFrom(eAdd, 1);
   boolean inval= Wire.receive();
   digitalWrite(ledPin, inval);
  delay(20);
   }
digitalWrite(ledPin,LOW);
delay(2000);
}
Logged

Pages: [1]   Go Up
Jump to: