Hi
I am a hardware developer and just started with the ardunio. I have some c skills, but this is first time I try c++.
So I lack some basic programming knowledge, but I have used Atmel MCUs for 12 years, so I have played with them a bit
I am building a wifi webserver on the duemilanove.
I store the website in the flash, because it is rather simple and only takes a few Kbytes.
I get an error when I try to print the entire webpage to the wifi module.
If I only print parts of the webpage, everything works.
When I try to print the whole page, which is about 1 Kbyte I think, the arduino seems to do "strange stuff". it even killed the bootloader entirely first time I did it, but I use my normal AVRISP mkII now.
I guess that when I use the function client.write() or client.println(), the entire string is copied to ram, and thereby uses, and even overflows, all ram. Am I correct in this?
my questions
How can I print a string from flash, without copying larger amounts to ram.?
or can I sence if the TX buffer is empty, so that I know that I can send more data?
What kind of delay routine can I use, that wont interfear with HW serial TX? I have heard that a simple while() delay cannot be interrupted by other events, and I do not know if the standard delay() works. I have not had any luck with that.
Which version of IDE are you using and which board?
The internal buffer size can be seen in hardware serial.h, but it makes no sense to increase that,
You should think of printing the page in chunks.
size_t HardwareSerial::write(uint8_t c)
{
int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit
// ???: return 0 here instead?
while (i == _tx_buffer->tail)
;
_tx_buffer->buffer[_tx_buffer->head] = c;
_tx_buffer->head = i;
sbi(*_ucsrb, _udrie);
// clear the TXC bit -- "can be cleared by writing a one to its bit location"
transmitting = true;
sbi(*_ucsra, TXC0);
return 1;
}
the printing itself blocks until the tailpointer is moved in an interrupt.
What baud rate are you using?
Hi Robtillaart
Thankyou for your reply
I use IDE 1.05, and my board is a arduino duemilanove with a ATMEGA328P
Baudrate is 115K without flow control. I am not sure if the wifi module accepts higher, but I will try to maximize it soon.
Sorry my programming skills is not high enough to understand the code you post, but it looks like something that should be in the serial hardware library.
I have tried printing in chunks with a few seconds delay. That did not seem to work, maybe I did not try enough. But I think you are correct and that it wil solve my problems.
I think I will modyfi the hardware serial library, so that I can call a function that returns if the buffer is empty on not.
How can you expect others to help you when you haven't posted your code?
The hardware serial library has no problem with printing long character strings. So the problem must be in your code, or in the wifi module. It may be that you need to use flow control. If you are using the String class, don't.
Hi
I have made some tests, and the serial communication works correct. I am trying to locate my error.
A nother simple thing is that I am trying to store a image in flash. I have converted the image to SVG and embed it in my HTML code.
I would like to make a #define LOGO "my svg picture code on 2.3Kbytes"
In my code I want to use things like
client.write(LOGO);
client.write(menu);
But when I add my real logo string on the 2.3Kbytes it creates a lot of erros
I get a stack overflow and more errors than I can count saying something like:
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
How can I define a long string in flash and point to it without getting errors? I can of cause break it up
That string ( define ) will be in ram if used, there are things you need to set for data to reside in flash. However if you have that part sorted already I might have an answer for you.
I had errors printing from flash using the ethernet shield, it was due to the flash print code outputting one char at a time, therefore there was an overload of packets being sent. To solve the problem I created a buffered printer which collects x bytes before sending it on, so packets became a reasonable size:
uint8_t buff[ 10 ];
EthernetClient c; //c would be your EthernetClient.
BufferedPrinter b( c, buff, 10 );
b.print( F("This is a buffered string read from progmem!") );
b.flush();
I am now sure that my problem is that I use all ram.
I try to do this with my longest string, sinde that one causes most problems, and the others will not create errors if stored in RAM.
I try to store my strings in flash, but however I write it, I keep getting the overflow error from the compiler. As if it still stores it in ram.
Can somebody pleace tell me exactly how to put this string in flash.
in your own compiler.
I have tryed to store it in flash any way I have found. Including this one. I keep getting overflow error. I try to do it in the blink example, so that I know nothing interfers
The string might create too many elements (addresses can only reference so much memory), I'll have a quick look to see what it says, looks mighty long though.
Thank you for trying Pyro_65
Yes I think its about 2.3Kbyte string
It should be possible to write from an address, like say reserve the last 3Kbyte flash.
My read will then just print it from address until a specific character
I can easely break the string up, but I think it should be possible to store anything in flash, where you just specify the start address.
Is there a sort of force command?
Did yours start compiling or did java spew out exceptions before any real output.
I’ll have a try of a few ideas, I’m pretty sure I’ve had objects larger than that in PROGMEM…
Yes I have, this sketch I wrote a while ago fills an entire mega with 30,000 byte PROGMEM chunks:
Binary sketch size: 258,048 bytes (of a 258,048 byte maximum)
#define nothing
template< uint64_t C, typename T >
struct LargeStruct{
T Data;
LargeStruct< C - 1, T > Next;
};
template< typename T > struct LargeStruct< 0, T >{ };
typedef LargeStruct< 80, uint64_t > Container;
PROGMEM LargeStruct< 50, Container > l_Struct;
PROGMEM LargeStruct< 50, Container > l_Struct1;
PROGMEM LargeStruct< 50, Container > l_Struct2;
PROGMEM LargeStruct< 50, Container > l_Struct3;
PROGMEM LargeStruct< 50, Container > l_Struct4;
PROGMEM LargeStruct< 50, Container > l_Struct5;
PROGMEM LargeStruct< 50, Container > l_Struct6;
PROGMEM LargeStruct< 50, Container > l_Struct7;
PROGMEM LargeStruct< 431, uint16_t > l_Struct8;
void setup()
{
volatile int i = ( int ) &l_Struct;
volatile int i1 = ( int ) &l_Struct1;
volatile int i2 = ( int ) &l_Struct2;
volatile int i3 = ( int ) &l_Struct3;
volatile int i4 = ( int ) &l_Struct4;
volatile int i5 = ( int ) &l_Struct5;
volatile int i6 = ( int ) &l_Struct6;
volatile int i7 = ( int ) &l_Struct7;
volatile int i8 = ( int ) &l_Struct8;
}
void loop(){}
For now, that string is too large, the IDE hangs trying to parse it. You will have to try the compiler directly maybe.
Hi
I just want to thank you all for the help.
Most of my webpage is stored in flash now and "evereything works"
I will post my code here when I am done.
I am making a wifi acess point with webserver. I have 3 webpages + an image, all stored in internal flash. the webpages has some setup options for the arduino and show some sensor input and feedback from the arduino.
Minor problem now is that the frontpage with my image takes 22sec to load:) I will try to tweek things. but it works
Looks like you are sending the web page data as 1 byte per Ethernet packet, which wil be slow. You should read a number of characters from flash into a buffer (try between 10 and 50 characters), and then send them all in a single call to client.write.
[DISCLAIMER: I haven't worked with Arduino web servers myself, I am going on the information provided in reply #5, which sounds entirely plausible to me.]
Thankyou, I will try that.
I thought the mcu would get the next data byte while the hardware clocked out the bits, so that there would not be any speedgain in sending packets.
I just checked the datasheets.
The max uart speed for my wifi module is 921.6 kbps. That should help too. But I have to change the xtal to 14.7456MHz.
I will try to send in packets first