Memory (PART 7)

Part 123456, 7

The previous post shows how to store from tens to  thousands of lines in an EEPROM chip and how to print them on a LCD unit. But the sketch which stores the strings can’t exceed the memory space available : 32kB (flash memory) – 0.5kB (boot loader) = 31.5kB (On arduino UNO and compatible boards). One way to get around this issue is to type the text when the program runs instead of storing the text directly in the program. This is not a big deal with the Arduino’s serial monitor :

serial monitor

Clicking on the top-right buttons spawns a serial monitor window

The following sequence shows how to do so :

  • Initialize the EEPROM chip and the serial communication
  • Append a newly typed character in a buffer
  • Sore the buffer in EEPROM if the trailing character is a Carriage Return (CR)

The carriage return detection induces the need for … a carriage return. Making the serial monitor append a carriage return when the key “enter” is typed is easy, just select the following option :

line ending

Choose the “carriage return” line ending. Don’t forget to set the appropriate baudrate too.

In the Arduino environment, retrieving the incoming characters can be achieved in the serialEvent() function. This function is called after loop() when at least one character is available in the input buffer.

So, we brought some improvements on the original sketch described in the previous post. The initialization is performed as follows :

void setup()
{
	InitEEPROM();
	InitSerial();
}

void InitEEPROM()
{
	/* Reset all CS pins from PORTB */
	DDRB |= 0x07; /* Set PB0:2 as output ports */
	PORTB |= 0x07; /* Set PB0:2 to high */
	MEM.InitializeSPI_EEPROM(&PORTB, PINB2, SPI_EEPROM_25LC320);
	/* Compute the number of lines that can be stored depending on the flash device */
	_max_lines = MEM.Pages() * MEM.PageSize() / 16;
}

void InitSerial()
{
	Serial.begin(115200);
	Serial.print("Welcome !");
	Serial.println();
	Serial.print("Please enter an author name :");
	Serial.println();
}

And the repetitively called functions() :

void loop()
{
	/* no blocking code here (such as delay()). */
}

void serialEvent()
{
	/* defines the two possible states and the size of the buffers */
	const uint16_t author = 100;
	const uint16_t sentence = 1000;
	/* a short array to store an author name */
	static char authorBuffer[author + 1];
	/* a large array to store a  sentence */
	static char sentenceBuffer[sentence + 1];
	/* the first string to write is the author name*/
	static uint16_t state = author;
	/* points to the current buffer */
	static char* currentBuffer = authorBuffer;
	/* the temporary characters count */
	static uint16_t cursor = 0;
	
	/* process each character from the input buffer */
	while (Serial.available()) {
		char c = (char)Serial.read(); /* the returned data type of read() is int */
		if(c == '\r'){ /* the carriage return written by the monitoring software */
			currentBuffer[cursor] = '\0'; /* explicitly end the line */
			Serial.println();
			if(state == author){
				/* prepare a sentence */
				Serial.print("Please enter a sentence :");
				Serial.println();
				currentBuffer = sentenceBuffer;
				state = sentence;
			} else {
				/* actually store the sentence and its author */
				WriteSentence(authorBuffer, sentenceBuffer);
				/* print few statistics */
				Serial.print(_lines);
				Serial.print(" lines in the EEPROM. ");
				Serial.print(_lines * 100 / _max_lines);
				Serial.print(" % full");
				Serial.println();
				Serial.println();
				Serial.print("Please enter an author name:");
				Serial.println();
				/* prepare the next author */
				currentBuffer = authorBuffer;
				state = author;
			}
			cursor = 0;
		} else if(cursor < state){ /* input a regular character and avoid a buffer overflow */
			Serial.print((char)c);
			currentBuffer[cursor] = c;
			cursor += 1;
		}
	}
}

That’s it !

 

memory_7_example

Leave a Reply

You must be logged in to post a comment.