Hi guys,
If I try to write in the program space using the c++ compiler with something like this:
#include <pololu/OrangutanLCD.h>
#include <pololu/OrangutanPushbuttons.h>
#include <pololu/OrangutanTime.h>
#include <pololu/OrangutanSerial.h>
#include <pololu/Uico.h>
#include <string.h>
// This include file allows data to be stored in program space. The
// ATmega168 has 16k of program space compared to 1k of RAM, so large
// pieces of static data should be stored in program space.
#include <avr/pgmspace.h>
// Introductory messages. The "PROGMEM" identifier causes the data to
// go into program space.
const char welcome_line1[] PROGMEM = " Pololu";
const char welcome_line2[] PROGMEM = "3\xf7 Robot"; // \xf7 is a greek
// pi character
const char demo_name_line1[] PROGMEM = "Demo";
const char demo_name_line2[] PROGMEM = "Program";
.....
int main()
{
// set up the 3pi
initialize();
Uico controller;
// This is the "main loop" - it will run forever.
while(1)
{
menu_select();
}
}
It gives me a warning:
ico.cpp:17: warning: only initialized variables can be placed into program memory area
I’m kind of scared in trying to program it with this error. Is it normal?
When you post the warning messages, you should also post the g++ command line that generated the error. In this case, it looks like you have defined CFLAGS but not CXXFLAGS, so the compiler is not getting the -mmcu option when compiling your c++ files. Can you try adding a CXXFLAGS declaration to your Makefile?
Great! So you’re able to load your C++ code onto the board now? Is this the neural network library that you were talking about before? I hope you’ll tell us how that project goes.
Yes is a simple controller based on a temporal hebbian learning rule called ICO-ISO learning http://www.berndporr.me.uk/isolearn/. But I’m planning to develop also traditional neural networks and digital filters. So it will be useful for everybody.
Argh there’s something wrong in the function:
OrangutanLCD::printFromProgramSpace
For instance even a simple program like this:
#include <pololu/OrangutanLCD.h>
#include <pololu/OrangutanPushbuttons.h>
#include <pololu/OrangutanTime.h>
#include <pololu/OrangutanSerial.h>
#include <pololu/OrangutanBuzzer.h>
#include <string.h>
// This include file allows data to be stored in program space. The
// ATmega168 has 16k of program space compared to 1k of RAM, so large
// pieces of static data should be stored in program space.
#include <avr/pgmspace.h>
const prog_char demo_name_line1[] = "Demo";
const prog_char demo_name_line2[] = "Program";
OrangutanLCD lcd;
OrangutanPushbuttons buttons;
void print_two_lines_delay_1s(const prog_char *line1, const prog_char *line2)
{
// Play welcome music and display a message
lcd.clear();
lcd.printFromProgramSpace(line1);
lcd.gotoXY(0,1);
lcd.printFromProgramSpace(line2);
OrangutanTime::delayMilliseconds(1000);
}
void print_two_string_delay_1s(const char *line1, const char *line2)
{
// Play welcome music and display a message
lcd.clear();
lcd.print(line1);
lcd.gotoXY(0,1);
lcd.print(line2);
OrangutanTime::delayMilliseconds(1000);
}
void menu_select()
{
static int menu_index = 0;
//This code is not working
print_two_lines_delay_1s(main_menu_intro_line1,main_menu_intro_line2);
//But using embedded strings is working
//print_two_string_delay_1s("Main","Menu");
}
// This is the main function, where the code starts. All C programs
// must have a main() function defined somewhere.
int main()
{
// This is the "main loop" - it will run forever.
while(1)
{
menu_select();
}
}
When you run it on the LCD there are some garbage characters, I think because is loading the ASCII strings from some other memory locations.
When I change that single line, it works fine for me, with no garbage characters. What version of avr-g++ are you using now? A new WinAVR was just released a couple of days ago; you might want to give it a try.
-Paul
Yes that code works but this simple reduced one, still gives me garbage characters:
#include <pololu/OrangutanLCD.h>
#include <pololu/OrangutanPushbuttons.h>
#include <pololu/OrangutanTime.h>
#include <pololu/OrangutanSerial.h>
#include <pololu/OrangutanBuzzer.h>
#include <string.h>
// This include file allows data to be stored in program space. The
// ATmega168 has 16k of program space compared to 1k of RAM, so large
// pieces of static data should be stored in program space.
#include <avr/pgmspace.h>
// Introductory messages. The "" identifier causes the data to
// go into program space.
// pi prog_character
const prog_char demo_name_line1[] = "Demo";
const prog_char demo_name_line2[] = "Program";
const prog_char main_menu_intro_line1[] = " Main";
const prog_char main_menu_intro_line2[] = " Menu";
OrangutanLCD lcd;
OrangutanPushbuttons buttons;
void print_two_lines_delay_1s(const prog_char *line1, const prog_char *line2)
{
// Play welcome music and display a message
lcd.clear();
lcd.printFromProgramSpace(line1);
lcd.gotoXY(0,1);
lcd.printFromProgramSpace(line2);
OrangutanTime::delayMilliseconds(1000);
}
void print_two_string_delay_1s(const char *line1, const char *line2)
{
// Play welcome music and display a message
lcd.clear();
lcd.print(line1);
lcd.gotoXY(0,1);
lcd.print(line2);
OrangutanTime::delayMilliseconds(1000);
}
void menu_select()
{
//static int menu_index = 0;
//This code is not working
print_two_lines_delay_1s(demo_name_line1,demo_name_line2);
print_two_lines_delay_1s(main_menu_intro_line1,main_menu_intro_line2);
}
// This is the main function, where the code starts. All C programs
// must have a main() function defined somewhere.
int main()
{
// This is the "main loop" - it will run forever.
while(1)
{
menu_select();
}
}
I can’t understand why because is so simple!
I’m using the last version from Debian repository, but oky I can try on windows too and see what happen tomorrow.
Thanks for the help again.
Okay, I finally got around to trying this on my 3pi and it works fine, displaying your text endlessly. I’m using Ubuntu with avr-gcc 4.2.2. What version do you have?
It looks like attaching the progmem attribute to a typedef no longer works in gcc 4.3.0 and above, and thus “prog_char” is now acting just as “char” would. So, to make your program work with those compilers, instead of using “prog_char”, just use “PROGMEM char”. But then you will have to tolerate some warning messages that say “only initialized variables can be placed into program memory area”, which are silly because your variables are initialized. Moreover, for parameters to functions, just use “char”, because the progmem attribute is advice to the compiler only about where to allocate the data when initializing it, not advice about how to use pointers to it (unfortunately).