EEPROM writing

Hi hope you guys can point me in the right direction.

I have code that will allow me to store data in EEPROM, but I want to store data o different lengths, and whilst I can change the BUFSIZE to get the different lengths I don't seem to understand how to get data of different lengths stored.

So I send in an SMS:-

SMS107xxxxxxxxx // this stores the number

but I would then like 20 characters for a text description stored.

TEXTI WANT TO SAVE THIS // can be shorter but no longer

I would then like to store

NUM1234. // These are numbers 1 to 5 but I am wish to store all 5 or a selection of.

I can do all these individually by setting the BUFSIZE in the following code, but I want to be able to do all the differen combinations. where do i start.

Current code in its entirity not just this section:-

#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial mySerial(7, 8);

String no1;
String no2;
String SMS1;
String ATD1 = "ATD" + no1 + ";";
String Recieved;
String Message2 = "Alarm";
String Siteid = "Home\r";
String Message;
String Message1 = "Arm";

const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 1023;
boolean eeprom_is_addr_ok(int addr) {
  return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
  // counter
  int i;
  if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
    return false;
  }
  for (i = 0; i < numBytes; i++) {
    EEPROM.update(startAddr + i, array[i]);
  }
  return true;
}
boolean eeprom_write_string(int addr, const char* string) {
  int numBytes; // actual number of bytes to be written
  //write the string contents plus the string terminator byte (0x00)
  numBytes = strlen(string) + 1;
  return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}
boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
  byte ch; // byte read from eeprom
  int bytesRead; // number of bytes read so far
  if (!eeprom_is_addr_ok(addr)) { // check start address
    return false;
  }

  if (bufSize == 0) { // how can we store bytes in an empty buffer ?
    return false;
  }

  // is there is room for the string terminator only, no reason to go further
  if (bufSize == 1) {
    buffer[0] = 0;
    return true;
  }

  bytesRead = 0; // initialize byte counter
  ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
  buffer[bytesRead] = ch; // store it into the user buffer
  bytesRead++; // increment byte counter

  while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
    // if no stop condition is met, read the next byte from eeprom
    ch = EEPROM.read(addr + bytesRead);
    buffer[bytesRead] = ch; // store it into the user buffer
    bytesRead++; // increment byte counter
  }
  if ((ch != 0x00) && (bytesRead >= 1)) {
    buffer[bytesRead - 1] = 0;
  }
  return true;
}
const int BUFSIZE = 13;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
int i;
void setup()
{

  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);

  mySerial.println("AT+DDET=1");
 // mySerial.println("AT+CMGD=ALL");
// Serial.print("AT+CMGD=ALL");
  delay(100);
}

void loop()

{
  if (Serial.available() > 0)
    switch (Serial.read())

    {
      case '1':
        Message = Siteid + Message1;
        SendMessage();
        break;

      case '2':
        Message = Siteid + Message2;
        SendMessage();
        break;

      case'd':
        DialCall();
        break;

      case 'm':
        ProcessNumber();
        break;

      case 'n':
        Current();
        break;
      case 't':
        TestLoop();
        break;

      case'r':
        RecieveMessage();
        break;
    }

  if (mySerial.available() > 0)
    Serial.write(mySerial.read());

}

void SendMessage()
{
  eeprom_read_string(0, buf, BUFSIZE);
  Serial.println(buf);
  no1 =(buf);
  no1.remove(0,1);
  Serial.println(no1);
  
 
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  SMS1 = "AT+CMGS=\"" + no1 +"\"\n\r";
  // SMS1 = "AT+CMGS=\"07815698180\"\n\r";

  mySerial.println(SMS1); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");
  delay(1000);
  mySerial.print(Message);// The SMS text you want to send
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void ProcessNumber()
{Serial.println(no1);
no2 =no1;
no2.remove(1);
Serial.println(no2);
Serial.println(no1);
Serial.println(no1.length());

int i = no2.toInt();
i=i-1;
if (i<=4){
     if (no1.length()<14){
      Serial.print("Not enough numbers");
      RecieveMessage();
}else{
   if (no1.length()>14){
      Serial.print("Too many numbers");
      RecieveMessage();
}else{
      Serial.print("Saving variable string to address: ");
      Serial.println(i * 14);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((i * 14), buf);
      Serial.print("Reading string from address : ");
      Serial.println(i * 14);
      eeprom_read_string((i * 14), buf, BUFSIZE);
      Serial.println(buf);
      RecieveMessage();}}
}else{
Serial.print("Only allowed 5 Numbers");

RecieveMessage();
}}


void Site() {
  Serial.println("SITE details submitted");

 Serial.print("Saving variable string to address: ");
      Serial.println(100);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((100), buf);
      Serial.print("Reading string from address : ");
      Serial.println(100);
      eeprom_read_string((100), buf, BUFSIZE);
      Serial.println(buf);

  
  Serial.print("AT+CMGD=ALL");
  mySerial.flush();
  Serial.flush();
  
  
}

void RecieveMessage() {
  mySerial.println("AT+CMGF=1\r");
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
  while (1) {
    if (mySerial.find("SMS")) {
      no1 = mySerial.readString();
      mySerial.flush();
     ProcessNumber();
    }
    else {
      if (mySerial.find("SITE")) {
      no1 = mySerial.readString();

        Site();

      }
    }

  } //end while
}//end recieve messages function

void DialCall()
{
  eeprom_read_string(0, buf, BUFSIZE);
  Serial.println(buf);
  no1 = buf;
  ATD1 = "ATD" + no1 + ";";
  mySerial.println(ATD1); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!"ATD07815698180;"
  delay(100);
  
  while (1) {
    if (mySerial.find("+DTMF:")) {
      int cmd = mySerial.parseInt();
      mySerial.flush();

      switch (cmd) {
        case 0:
          Serial.println("0");
          Serial.println("Call Acknowledged and Terminated");
          delay(10);
          mySerial.println("ATH");
          break;
        case 1:
          Serial.println("1");
          break;
        case 2:
          Serial.println("2");
          break;
        case 3:
          Serial.println("3");
          break;
        case 4:
          Serial.println("4");
          break;
        case 5:
          Serial.println("5");
          break;
        case 6:
          Serial.println("6");
          break;
        case 7:
          Serial.println("7");
          break;
        case 8:
          Serial.println("8");
          break;
        case 9:
          Serial.println("9");
          break;
      }
    }

  }
}

void Current()
{
  int i;
  for (i = 0; i < 5; i++) {
    Serial.print("Current Mobile No:");
    Serial.println(i + 1);
    eeprom_read_string((i * 14), buf, BUFSIZE);
    no1 =(buf);
    no1.remove(0,1);
    Serial.println(no1);  
  }
}

void TestLoop()
{ //mySerial.println("AT+CMGF=1\r");
  mySerial.println ("AT+CMGD=1");
}

Thanks

Have a look at .put() and .get() :wink:

Hi, thanks for your reply, I have been looking but it hasn't yet clicked I will look some more and have a play.

This link EEPROM.put() using a multi-variable struct - Firmware - Particle

should get me on the right track, now to integrate?

No real need for a struct... Yes, you can also store a struct in EEPROM via EEPROM.put(). And you mighyt even have to do that for strings... Mm, interesting, not sure even!

My head is hurting, need a coffee.

hmmm whilts my solution currently is

#include <SoftwareSerial.h>
#include <EEPROM.h>
SoftwareSerial mySerial(7, 8);

String no1;
String no2;
String SMS1;
String ATD1 = "ATD" + no1 + ";";
String Recieved;
String Message2 = "Alarm";
String Siteid = "Home\r";
String Message;
String Message1 = "Arm";

const int EEPROM_MIN_ADDR = 0;
const int EEPROM_MAX_ADDR = 1023;
boolean eeprom_is_addr_ok(int addr) {
  return ((addr >= EEPROM_MIN_ADDR) && (addr <= EEPROM_MAX_ADDR));
}
boolean eeprom_write_bytes(int startAddr, const byte* array, int numBytes) {
  // counter
  int i;
  if (!eeprom_is_addr_ok(startAddr) || !eeprom_is_addr_ok(startAddr + numBytes)) {
    return false;
  }
  for (i = 0; i < numBytes; i++) {
    EEPROM.update(startAddr + i, array[i]);
  }
  return true;
}
boolean eeprom_write_string(int addr, const char* string) {
  int numBytes; // actual number of bytes to be written
  //write the string contents plus the string terminator byte (0x00)
  numBytes = strlen(string) + 1;
  return eeprom_write_bytes(addr, (const byte*)string, numBytes);
}
boolean eeprom_read_string(int addr, char* buffer, int bufSize) {
  byte ch; // byte read from eeprom
  int bytesRead; // number of bytes read so far
  if (!eeprom_is_addr_ok(addr)) { // check start address
    return false;
  }

  if (bufSize == 0) { // how can we store bytes in an empty buffer ?
    return false;
  }

  // is there is room for the string terminator only, no reason to go further
  if (bufSize == 1) {
    buffer[0] = 0;
    return true;
  }

  bytesRead = 0; // initialize byte counter
  ch = EEPROM.read(addr + bytesRead); // read next byte from eeprom
  buffer[bytesRead] = ch; // store it into the user buffer
  bytesRead++; // increment byte counter

  while ( (ch != 0x00) && (bytesRead < bufSize) && ((addr + bytesRead) <= EEPROM_MAX_ADDR) ) {
    // if no stop condition is met, read the next byte from eeprom
    ch = EEPROM.read(addr + bytesRead);
    buffer[bytesRead] = ch; // store it into the user buffer
    bytesRead++; // increment byte counter
  }
  if ((ch != 0x00) && (bytesRead >= 1)) {
    buffer[bytesRead - 1] = 0;
  }
  return true;
  
}

/*
struct UserSpecificData{
  char Number[13];
  char SITE[19];
} userSpecificData;

*/
const int BUFSIZE = 13;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
int i;



void setup()
{

  mySerial.begin(9600);   // Setting the baud rate of GSM Module
  Serial.begin(9600);    // Setting the baud rate of Serial Monitor (Arduino)
  delay(100);

  mySerial.println("AT+DDET=1");
 // mySerial.println("AT+CMGD=ALL");
// Serial.print("AT+CMGD=ALL");
  delay(100);
}

void loop()

{
  if (Serial.available() > 0)
    switch (Serial.read())

    {
      case '1':
        Message = Siteid + Message1;
        SendMessage();
        break;

      case '2':
        Message = Siteid + Message2;
        SendMessage();
        break;

      case'd':
        DialCall();
        break;

      case 'm':
        ProcessNumber();
        break;

      case 'n':
        Current();
        break;
      case 't':
        TestLoop();
        break;

      case'r':
        RecieveMessage();
        break;
    }

  if (mySerial.available() > 0)
    Serial.write(mySerial.read());

}

void SendMessage()
{
  eeprom_read_string(0, buf, BUFSIZE);
  Serial.println(buf);
  no1 =(buf);
  no1.remove(0,1);
  Serial.println(no1);
  
 
  mySerial.println("AT+CMGF=1");    //Sets the GSM Module in Text Mode
  delay(1000);  // Delay of 1000 milli seconds or 1 second
  SMS1 = "AT+CMGS=\"" + no1 +"\"\n\r";
  // SMS1 = "AT+CMGS=\"07815698180\"\n\r";

  mySerial.println(SMS1); // Replace x with mobile number mySerial.println("AT+CMGS=\"xxxxx\"\n\r");
  delay(1000);
  mySerial.print(Message);// The SMS text you want to send
  delay(100);
  mySerial.println((char)26);// ASCII code of CTRL+Z
  delay(1000);
}

void ProcessNumber()
{
  const int BUFSIZE = 13;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
//int i;
  
Serial.println(no1);
no2 =no1;
no2.remove(1);
Serial.println(no2);
Serial.println(no1);
Serial.println(no1.length());

int i = no2.toInt();
i=i-1;
if (i<=4){
     if (no1.length()<14){
      Serial.print("Not enough numbers");
      RecieveMessage();
}else{
   if (no1.length()>14){
      Serial.print("Too many numbers");
      RecieveMessage();
}else{
      Serial.print("Saving variable string to address: ");
      Serial.println(i * 14);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((i * 14), buf);
      Serial.print("Reading string from address : ");
      Serial.println(i * 14);
      eeprom_read_string((i * 14), buf, BUFSIZE);
      Serial.println(buf);
      RecieveMessage();}}
}else{
Serial.print("Only allowed 5 Numbers");

RecieveMessage();
}}


void Site() {
const int BUFSIZE = 20;
char buf[BUFSIZE];
String myString;
char myStringChar[BUFSIZE];
String strip;
//int i;
  Serial.println("SITE details submitted");

 Serial.print("Saving variable string to address: ");
      Serial.println(100);
      Serial.println(no1);
      myString = no1;
      myString.toCharArray(myStringChar, BUFSIZE); //convert string to char array
      strcpy(buf, myStringChar);
      eeprom_write_string((100), buf);
      Serial.print("Reading string from address : ");
      Serial.println(100);
      eeprom_read_string((100), buf, BUFSIZE);
      Serial.println(buf);

  
  Serial.print("AT+CMGD=ALL");
  mySerial.flush();
  Serial.flush();
  
  
}

void RecieveMessage() {
  mySerial.println("AT+CMGF=1\r");
  mySerial.println("AT+CNMI=2,2,0,0,0\r"); // AT Command to recieve a live SMS
 

  while (1) {
    if (mySerial.find("SMS")) {
      no1 = mySerial.readString();
      mySerial.flush();
     ProcessNumber();
    }
    else {
      if (mySerial.find("SITE")) {
      no1 = mySerial.readString();

        Site();

      }
    }

  } //end while
}//end recieve messages function

void DialCall()
{
  eeprom_read_string(0, buf, BUFSIZE);
  Serial.println(buf);
  no1 = buf;
  ATD1 = "ATD" + no1 + ";";
  mySerial.println(ATD1); // ATDxxxxxxxxxx; -- watch out here for semicolon at the end!!"ATD07815698180;"
  delay(100);
  
  while (1) {
    if (mySerial.find("+DTMF:")) {
      int cmd = mySerial.parseInt();
      mySerial.flush();

      switch (cmd) {
        case 0:
          Serial.println("0");
          Serial.println("Call Acknowledged and Terminated");
          delay(10);
          mySerial.println("ATH");
          break;
        case 1:
          Serial.println("1");
          break;
        case 2:
          Serial.println("2");
          break;
        case 3:
          Serial.println("3");
          break;
        case 4:
          Serial.println("4");
          break;
        case 5:
          Serial.println("5");
          break;
        case 6:
          Serial.println("6");
          break;
        case 7:
          Serial.println("7");
          break;
        case 8:
          Serial.println("8");
          break;
        case 9:
          Serial.println("9");
          break;
      }
    }

  }
}

void Current()
{
  int i;
  for (i = 0; i < 5; i++) {
    Serial.print("Current Mobile No:");
    Serial.println(i + 1);
    eeprom_read_string((i * 14), buf, BUFSIZE);
    no1 =(buf);
    no1.remove(0,1);
    Serial.println(no1);  
  }
}

void TestLoop()
{ //mySerial.println("AT+CMGF=1\r");
  mySerial.println ("AT+CMGD=1");


  
}

not so sure its smart or effcient bu for now its working

        case 1:
          Serial.println("1");
          break;
        case 2:
          Serial.println("2");
          break;
        case 3:
          Serial.println("3");
          break;
etc, etc

Why not just Serial.println(cmd); before the switch/case ?

I assume that you are going to add more code for some/all of the cases

UKHeliBob, Thanks for your input.

Not sure how this will come across so apologies if it sounds ungrateful.

At this moment in time I am learning and as I am getting so dam old its not as quick as I would like, so prefer to deal with the questions at hand first if thats okay.

I am certain that the code can be improved dramatically by those with much more knowledge than I, however one step at a time.

Thanks

I am certain that the code can be improved dramatically by those with much more knowledge than I, however one step at a time.

It's always better to have something that works, so that has to be the first objective. If it can be improved on then so much the better.

My point was that you test the value of cmd then print a string confirming what was received when you might just as well print the value in the first place. Something to think about for a future version perhaps.

Hi Bob,

I have now implemented

Serial.println(cmd); before       switch (cmd) {

and removed the corresponding lines that are not in use, not sure its 100% better mind without a proper play.

noticed the serial monitor miss the odd number this way but to be fair only really need the numbers with a function to register and these are going to be limited to max of 3 different numbers possibly, like hang up. dial next and just send texts possibly.

noticed the serial monitor miss the odd number this way

Your code or hardware may miss numbers but the Serial monitor won't

Please post your updated code.

Take your word it must be the device then, I can see what I have used on the phone and can see if serial monitor confirms.

but not a big issue either way.

just need to look at smarting up some code to make less of it, but probably best to start a seperate thread.