I am sometimes getting some strange characters from the USB/serial monitor after "upload".
It does not occur after reset or if I close the serial monitor and reopen it.
(please see the attached PNG file as I do not seem to be able to copy text from the monitor window)
I have tried adding delays, rearranging the variables, enlarging the buffer, Serial.flush() ....
Is there a way to 'clear' the outgoing serial buffer in setup ?
This is the code (and it does do a nice dump of the EEPROM). The device is a Nano.
/* Program: EEPROM Dump
This program print the entire contents of the EEPROM
in HEX and ASCII (when applicable) to the USB/RS232 terminal */
#include <EEPROM.h>
unsigned long addr; // used fro address in EEPROM
byte i,j,c; // i=1 to 16 bytes, j=HEX index, c= single character
char buffer[22]; // char array for ASCII string
void setup()
{ Serial.begin(9600); // initalize serial port
buffer[0] = ' '; // put space at beginning of char array
buffer[1] = ' '; // put second space at beginning of char array
buffer[18] =0; // string termination for buffer
buffer[19] =0; // belts and suspenders
Serial.println (F("EEPROM DUMP:")); // information, notice the F() wrapper
do
{ /* Read 16 characters from the EEprom into our buffer */
/* ------ Print the address padded with spaces ------ */
if (addr<1000) {Serial.print(' ');} // space padding, char(32) is a space
if (addr<100) {Serial.print(' ');} // space padding
if (addr<10) {Serial.print(' ');} // space padding
Serial.print (addr, DEC); // starting address for line
Serial.print (" "); // seperator, could be replaced with a tab ("\t")
for (i=0; i<16; ++i) // 16 bytes at a time
{ c= EEPROM.read(addr + i); // read one byte
buffer[i+2]=char(c); // stuff the character in our buffer
/*--- print HEX value ---*/
if (c < 0x10) {Serial.print('0');} // pad HEX value with 0, 0x10 = F0 = 16
Serial.print (c, HEX); // usinh HEX tells Serial how to format the number
++j; // increment index for serperator
if (j == 4) // if we have print 4 values
{ Serial.print(' '); // print a seperator
j=0; // set our index to zero to start over
}
/*--- Evaluate character ---*/
if (c < 32) {buffer[i+2]='.';} // do not print control codes
if (c ==92) {buffer[i+2]='.';} // do not print "\"
if (c >126) {buffer[i+2]='.';} // do not print 'extended' characters
}
Serial.println(buffer); // begin wiht a new line
addr=addr +16;
} while (addr < E2END); // E2END is the end of the EEPROM
/* used to check ending address
Serial.println(addr,DEC);
Serial.println(E2END,DEC);
*/
}
void loop() { } // do nothing
Second question:
Can I set a second char array to point at "buffer[2]" .
Well I know it can be done, I have just not had much luck doing it.
The idea is avoid the extra "i+2" calculations and just use "i".
I have tried things like:
char buffe2[] = buffer[2];
char * buffe2[] = & buffer[2];
char buffe2[] = * buffer[2];
Compiler says "Does not compute" (or words to that effect).
I think that output is just spurious data picked up by the serial port while it is syncing to the clock.
Regarding the buffer, you can either manipulate the buffer as a c-string (null-terminated char array) or character-by-character as you are doing. Given that you are writing characters to successive positions in the array, rather than calculating what the position should be from the loop counter you could use a separate array index to record the 'current' entry in the array.
I notice that some of your output is done via buffer and some is done directly using Serial.print statements. Maybe it does what you want by coincidence (and maybe it doesn't) but it doesn't make much sense to me. Either print the characters out directly, or buffer them and print out the whole lot in one go. It doesn't particularly matter which apporoach you use, but choose one or the other and stick to it.
do/while loops are almost never a good idea. How often do you really want to execute the body of the loop even when then terminate condition is false? Loose the do/while and use a reasonable while loop. Let us know if you still have a problem.
@ PeterH
"I notice that some of your output is done via buffer and some is done directly using Serial.print statements."
The serial.print() statements handles the values as they are read.
All the hex values in a line must be printed before the ASCII can be printed.
One alternative is to go back and read the same data again for the ASCII characters.
EEPROM is slow compared to SRAM so I do not want to reread the data.
Thus I store the characters in an array as the values are read.
Another alternative is to build the entire string with the Address, Hex Values and ASCII.
That is a more complex task.
Yet another alternative is to store the values in an array and then print them one at a time.
"There are many ways to skin a cat": I chose what seemed to be the simplest aproach.
"I think that output is just spurious data picked up by the serial port while it is syncing to the clock."
Probably ... now how does one eliminate it ?
"you could use a separate array index"
I did something similar to begin with actually, then realized that it could be done with less variables.
I note that there will be no real savings in space used as an additional pointer will be required for the second array.
The real reason for asking the question is:
I know that it can be done.
I did it decades ago when I was more familiar with such things.
However I am getting old and senile (been senile for a while really).
Having considered the idea, having a function that takes a array[60-64] with address and 16 bytes defined and returns it as a formatted string could be advantageous for future projects (dumping PROGMEM for example). See what you have done! Now I have to go figure out the proper method to return a array pointer from a function.
@ PaulS
"How often do you really want to execute the body of the loop even when then terminate condition is false? Loose the do/while and use a reasonable while loop."
I believe that your point is more one of programming style. I am an old redneck from the deep south so I am very much out of style and politically incorrect.
In this case I always want to execute the loop at least once and keep executing it until I have reached the
destination. If it were a condition where one might not ever want to execute the loop then I would agree
with you, the "while () {}" structure would be the proper choice.
The "do {} while ()" structure can be easier to read/understand than
the "while () {}" structure that has no end except for a lonely little curly brace.
Regardless:
the problem occurs before execution gets to the loop in question
if the loop continued past the end address then it would simply wrap around to the beginning and print the first line(s) again.
(and yes I have tested that theory)
if (the compiler can not generate proper object level code for a particular structure)
{then that structure should be remove from the listed supported structures;}
else
{it is likely to be used;}
both versions randomly exhibit the same strange phenomena
The "do {} while ()" structure can be easier to read/understand than
the "while () {}" structure that has no end except for a lonely little curly brace.
Each to his own, but I don't agree. As long as the code is properly formatted** the code block for while is easily identified and it fits the style of other commands such as if and for.
** by this I mean that each brace is on its own line and that the Auto Formatting tool has been used or that the code has been manually indented. The IDE also neatly identifies the other end of a pair of brackets of all kinds when the cursor is placed after a bracket.
I believe that your point is more one of programming style. I am an old redneck from the deep south so I am very much out of style and politically incorrect.
It isn't about "style", it is about "intent".
A "do..while" will always execute the loop body at least once, whereas a "while" (or it's first cousin "for") may not execute the loop body at all.
The "do {} while ()" structure can be easier to read/understand than
the "while () {}" structure that has no end except for a lonely little curly brace.
Each to his own, but I don't agree. As long as the code is properly formatted** the code block for while is easily identified and it fits the style of other commands such as if and for.
** by this I mean that each brace is on its own line and that the Auto Formatting tool has been used or that the code has been manually indented. The IDE also neatly identifies the other end of a pair of brackets of all kinds when the cursor is placed after a bracket.
That depends on how long the code block is. It is true that the IDE editor tries to match beginning and ending braces but I have painful memories of working in LISP before editors learned to do such tricks. I learned to appreciate a definitive end (usually a remark in the case of lisp) particularly when I had to go back and look at the code a decade later.
Putting a single brace on each line can make the program listing extremely long. That is especially true where you have a bunch nested loops or other structures. In some cases putting everything on one line is much more intuitive. An example of four lines vs one.
void loop()
{
// do nothing
}
void loop() {} // do nothing
That being said "C" was never intended to be easy to read. It was intended to be efficient to process.
lewtwo:
Now I have to go figure out the proper method to return a array pointer from a function.
Typically, the best answer is to pass the empty array IN to the function (together with its length, if this isn't implicitly known) and design the function to fill the array it is given.
Thank you. What I was imaging happening was something along the lines of:
char buffer[15]= 0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00;
...
Serial.println(newfunction(Buffer,4));
// output: "41414141 AAAA"
...
char newfunction( char inarray[], int i)
{ int j= (3*i)+2;
While (i != 0}
{
inarray[j--]=convert (inarray[i--]);
}
return inarray[];
}
In this manner it would not require a new array and could be used by other
functions such as print. Obviously course the incoming array would have to be sized correctly
for the number of data bytes and the algorithm would be a little more complex.
Well, its your code at the end of the day, but in my view it would make more sense to have a function that reads a specified number of bytes from a specified offset in the EEPROM and writes them into a supplied data buffer, and a function that takes a supplied data buffer and output text buffer and formats the data into the buffer as you wish, and then just print the content of the buffer. The main logic would be three function calls, and each function would be self-contained and provide a sensible abstraction.
I agree. There is a view that a code block or a function for that matter should all be visible on the screen at once. Screens, of course, have always (with very few exceptions) been the wrong shape, being laid out as landscape as opposed to portrait and I had better keep my opinion of widescreen monitors to myself for the fear of offending someone with my bad language. You can change the font size used in the IDE which can help somewhat if you can still read it at a reduced size.
Screens, of course, have always (with very few exceptions) been the wrong shape, being laid out as landscape as opposed to portrait
Well at least these days you can rotate them around :~
Only if you have one of those new fangled 'pad things which, without a separate keyboard are an abomination to program on. I predict they they will not catch on
No, most decent quality monitors and stands allow you to view them in portrait.
I have one 24" in landscape for general use, with another in portrait for coding.
UKHeliBob:
Only if you have one of those new fangled 'pad things which, without a separate keyboard are an abomination to program on. I predict they they will not catch on
ah ... I was thinking of an external desktop monitor.
regarding the PADs/Tablet ... the screens are too tiny to do much (efficiently) in the way of programing.
about the only thing that I use my Galaxy2 for is reading email, browsing the internet, reading PDFs or ebooks.
I actually purchased it to replace my kindle after I had the third paper-white display crack.