Go Down

Topic: I2C port expander mcp23017 and arduino eeprom? (Read 1 time) previous topic - next topic

kh602

Jan 10, 2015, 02:59 am Last Edit: Jan 10, 2015, 04:56 pm by kh602
Hi there,

i have recently tested the MCP23017 16BIT i2c expander using the adafruit library https://github.com/adafruit/Adafruit-MCP23017-Arduino-Library which works toggling simple leds with mom switches etc.

My question is how do i save the output state of the I2C expander to the arduino's eeprom?

I used a bit of code from awhile back which allowed me to save the arduino pins 6 to 13 output states to a specific address location in the arduino's eeprom eg.

Code: [Select]
// Save the state of the lights using bitWrite()
unsigned char lights = 0;
for (i=6; i<14; i++) {
   bitWrite(lights, i-6, digitalRead(i));
}
eepromWrite(location, lights);

// restore the lights using bitRead()
lights = eepromRead(location);
for (i=6; i<14; i++) {
   digitalWrite(i, bitRead(lights, i-6));
}


Using the adafruit library i have used the following to set up the mcp23017 to read and write/toggle outputs of the expander. It's just to quickly show you the types of code that enables you to read and write to expander pins.

Code: [Select]
#include "Adafruit_MCP23017.h"
Adafruit_MCP23017 mcp;

void setup(){
  mcp.begin();      // use default address 0
  mcp.pinMode(0, INPUT); //assign which mcp pin whether its input or output
  mcp.pullUp(0, HIGH);  // turn on a 100K pullup internally
 
  //MCP PINS 21-28 = 0-7 FOR GPA
  //MCP PINS 1-8   = 8-15 FOR GPB
 }
void loop(){
    mcp.digitalWrite(1, HIGH); //mcp version of digital write/toggle pin 1 (which is pin 22 on the IC)
    if (mcp.digitalRead(1) == HIGH);}


Is there a way to incorporate the 2 types of code to save the 8 or 16bit states of the expander in to the arduino eeprom, if that makes sense?

Peter_n

Which eepromWrite() and eepromRead() functions are that ?

rmetzner49


This should help somewhat  Here I write a 2D array of INT[128][2] to the CPU's EEProm.  Rip out the Serial.print (or comment out) once you are done.  It's just useful to leave in until you no longer need it.
The read and write functions use the WIRE library and code generated by RTillart



Code: [Select]
#include <EEPROM.h>

#define RAM_SZ 100
#define E2_SZ (RAM_SZ*4)
#define LP_OFF (RAM_SZ*2)
#define LP     1                              // Array index LOW PULSES
#define HP     0                              // Array index HIGH PULSES

//unsigned char ReadBytes [512];              // RAM Array of Bytes to reclaim stored data
unsigned int Input  [RAM_SZ][2];               // pair is high and low pulse
unsigned int Output [RAM_SZ][2];                 // RAM Array of INTS to reclaim stored data
unsigned char Button = 1;
int i;  int j;  int b;




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

 // Input Data array is SAME memory regardless of BUTTON#
 // Store in RAM, (HB,LB) at i, i+1
  int i;
  for (i=0; i<RAM_SZ; i++)  {
    Input [i][0]= 0x1000+i;                // not significant, just DATA
    Input [i][1]= 0x2000+i;
  }
delay(8000);
CopyToEEPROM();
}

// FUNCTION CopyToEEPROM *** Save the button's worth of values
// Returns Checksum nothing
void CopyToEEPROM(void)  {
// Store as [HB, LB] 
  unsigned char hb;    unsigned char lb;   unsigned int Temp; 
  unsigned int b=Button*E2_SZ;

  for (i=0; i<RAM_SZ; i++) {
    j=i*2+b;
    // split high pulses int LB & HB
    Temp=(Input[i][0]);               // integer array
    hb=((Temp & 0x0000FF00)>>8);      //
    lb=((Temp & 0x000000FF));
    EEPROM.write ((j+0),hb);
    EEPROM.write ((j+1),lb);

  // split low pulses int LB & HB
    Temp=(Input[i][1]);
    hb=((Temp & 0x0000FF00)>>8);
    lb=((Temp & 0x000000FF));
    EEPROM.write ((j+LP_OFF),hb);
    EEPROM.write ((j+LP_OFF+1),lb);
    }
}//--------------------------------------------------------------------------





//****************************** ReadToInt **********************************
void ReadToInt(void)  {
    unsigned char msb;
    unsigned char lsb;
    unsigned int  temp;
    unsigned int b=Button*E2_SZ;
   
  for (i=0; i<RAM_SZ; i++){
    j=i*2+b;
    Serial.print("i:");
    if (i<10) Serial.print(" ");
    Serial.print(i);
    Serial.print("  Input:");
    Serial.print(Input [i][0],HEX);
    Serial.print("  j:");
    if (i<100) Serial.print(" ");
    Serial.print(j);
//*****************************************************************
    msb =  EEPROM.read(j);            // high pulses at  HIGH BYTE
    lsb =  EEPROM.read(j+1);          // high pulses at LOW BYTE
    Serial.print("   EEhipulses bytes: ");
    temp =  msb<<8;                   // shift to correct value
    temp = temp | lsb;                // combine to make INT
    Output [i][0] = temp;
    Serial.print(Output [i][0],HEX);  // print result

    msb =  EEPROM.read(j+LP_OFF);     // low  pulses at 512-766  HIGH BYTE
    lsb =  EEPROM.read(j+LP_OFF+1);   // low  pulses at 512-767  LOW BYTE
    temp =  msb<<8;                   // shift to correct value
    temp = temp | lsb;
    Serial.print("   EElowpulses: ");
    Output [i][1] = temp;
    Serial.println(temp,HEX);          // print result
  }
 }//--------------------------------------------------------------------------


//*****************MAIN LOOP*********************
void loop() {
  ReadToInt();
  delay(300);
}//--------------------------------------------------------------------------

 

Go Up