Hello digispark users,
finally my digisparks arrived here in germany, and I started to remember my C knowledge from the past. My only experience up to now with embedded systems is the Lego NXT with NXC. Given that and that my practical C experience is older than 10 years, that might be likely the reason for my problems.
To get used to the IDE and the work flow, my initial idea was to write a small blink program, which blinks a given text in morsecode, just with the on board LED.
As I was not able to get that working, I tried, to debug the program. That seems to be an very important point, as I was till today not able, to get some serial or USB communication ready, which would allow me reading printed debug statements. If a user has a simple how-to, how to debug sketches under windows, it would be more than welcome as well!
So I decided to use the digispark-LCD display, which I ordered as well, for debugging. The following program is now stripped down to demonstrate my problem. it can be used together with the LCD shield.
The program looks up each character of a given string (here
char greeting[]) in the string
const char morse_index[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ". The position of the character is equal to the position of the final morsecode in the array
const char * const morse_codes[].
Here the problem is starting! When I define morse_codes with real morsecodes the application just stucks. When I define shorter strings -like in the example- the application just works as it should do.
With the longer strings compiling and downloading works just perfect, but at that point, the application should start, my PC tells me, that an USB device was not recognized. Sometimes the application is starting, but only showing garbage in the display.
Whats going wrong? What have I missed? Thanks for any hint!
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
#include <LiquidCrystal_I2C.h> // for LCD w/ GPIO MODIFIED for the ATtiny85
#define GPIO_ADDR 0x27 // (PCA8574A A0-A2 @5V) typ. A0-A3 Gnd 0x20 / 0x38 for A - 0x27 is the address of the Digispark LCD modules.
LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); // set address & 16 chars / 2 lines
const char morse_index[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
/*
//does not work with this data :-(
const char * const morse_codes[] = { ". -", "- . . .", "- . - .", "- . .", ".", ". . - .", "- - .", ". . . .",
". .", ". - - -", "- . -", ". - . .", "- -", "- .", "- - -", ". - - .",
"- - . -", ". - .", ". . .", "-", ". . -", ". . . -", ". - -", "- . . -",
"- . - -", "- - . .", "- - - - -", ". - - - -", ". . - - -", ". . . - -", ". . . . -", ". . . . .",
"- . . . .", "- - . . .", "- - - . .", "- - - - .", " "};
*/
//however works with this definition
const char * const morse_codes[]= {"AAA", "BB", "CCC", "DD", "EEE", "FF", "GGG", "HH", "III", "JJ", "KKK", "LL", //12
"MM", "NN", "OO", "PP", "QQ", "RR", "SS", "TT", "UU", "VV", "WW", "XX", //12
"YY", "ZZ", "00", "11", "22", "33", "44", "55", "66", "77", "88", "99999999", "__" }; //13
//but not with that definition :-(
/*const char * const morse_codes[]= {"AAAAA", "BBBBB", "CCCCC", "DDDDD", "EEEEE", "FFFFF", "GGGGG", "HHHHH", "IIIII", "JJJJJ", "KKKKK", "LLLLL", //12
"MMMMM", "NNNNN", "OOOOO", "PPPPP", "QQQQQ", "RRRRR", "SSSSS", "TTTTT", "UUUUU", "VVVVV", "WWWWW", "XXXXX", //12
"YYYYY", "ZZZZZ", "00000", "11111", "22222", "33333", "44444", "55555", "66666", "77777", "88888", "99999", "_____" }; //13
*/
int firstPos( char index, const char *searchIn) {
int retval = -1;
for ( int len = 0; len < strlen(searchIn); len++) {
if (index == searchIn[len]) {
retval = len;
break;
}
}
return retval;
}
void send_char( char snd_char) {
int posi=firstPos(snd_char, morse_index);
lcd.setCursor(0, 0);
char message[17];
sprintf(message, "Char: %c : %3d", snd_char, posi);
lcd.print(message);
lcd.setCursor(0, 1);
if ( posi >= 0 ) {
sprintf(message, "Code: %-9s", morse_codes[posi]);
lcd.print(message);
} else {
lcd.print("Code: n/a ");
}
delay(850);
}
void send_string( char *text_to_send) {
for ( byte len = 0; len < strlen(text_to_send); len++) {
send_char(text_to_send[len]);
}
}
char greeting[] = "abcdAaBCcDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
void setup() {
TinyWireM.begin(); // initialize I2C lib - comment this out to use with standard arduinos
lcd.init(); // initialize the lcd
lcd.backlight(); // Print a message to the LCD.
pinMode(1, OUTPUT); //LED on Model A
}
void loop() {
send_string(greeting);
}
regards
Gogol
Follow Up:
Reading this Thread:
http://digistump.com/board/index.php/topic,686.0.html it looks like, that I have the same problem. I was not aware, that I have only 512 bytes for heap and stack (what this thread is telling).
I have now rewritten the example, following the advice from the other thread, and separated the single codes into individual functions.
Doing this, I should have only one code at a given time on the stack, however i still run into problems.
When I compile the whole sketch without comments/remarks it compiles to 4566 bytes, which should be far from the 6010 my Spark has available. When I comment out the last two lines, like in the following example, the sketch compiles to 4490 bytes. With the two last lines commented out, the program works, with those two lines in, the program stops at random points, the Spark reboots and continues. Sometimes it does a full loop, before rebooting, sometimes it does that every 3 seconds.
#include <TinyWireM.h> // I2C Master lib for ATTinys which use USI - comment this out to use with standard arduinos
#include <LiquidCrystal_I2C.h> // for LCD w/ GPIO MODIFIED for the ATtiny85
#define GPIO_ADDR 0x27 // (PCA8574A A0-A2 @5V) typ. A0-A3 Gnd 0x20 / 0x38 for A - 0x27 is the address of the Digispark LCD modules.
LiquidCrystal_I2C lcd(GPIO_ADDR,16,2); // set address & 16 chars / 2 lines
void morse_A(char *morse){strcpy(morse, ". -");}
void morse_B(char *morse){strcpy(morse, "- . . .");}
void morse_C(char *morse){strcpy(morse, "- . - .");}
void morse_D(char *morse){strcpy(morse, "- . .");}
void morse_E(char *morse){strcpy(morse, ".");}
void morse_F(char *morse){strcpy(morse, ". . - .");}
void morse_G(char *morse){strcpy(morse, "- - .");}
void morse_H(char *morse){strcpy(morse, ". . . .");}
void morse_I(char *morse){strcpy(morse, ". .");}
void morse_J(char *morse){strcpy(morse, ". - - -");}
void morse_K(char *morse){strcpy(morse, "- . -");}
void morse_L(char *morse){strcpy(morse, ". - . .");}
void morse_M(char *morse){strcpy(morse, "- -");}
void morse_N(char *morse){strcpy(morse, "- .");}
void morse_O(char *morse){strcpy(morse, "- - -");}
void morse_P(char *morse){strcpy(morse, ". - - .");}
void morse_Q(char *morse){strcpy(morse, "- - . -");}
void morse_R(char *morse){strcpy(morse, ". - .");}
void morse_S(char *morse){strcpy(morse, ". . .");}
void morse_T(char *morse){strcpy(morse, "-");}
void morse_U(char *morse){strcpy(morse, ". . -");}
void morse_V(char *morse){strcpy(morse, ". . . -");}
void morse_W(char *morse){strcpy(morse, ". - -");}
void morse_X(char *morse){strcpy(morse, "- . . -");}
void morse_Y(char *morse){strcpy(morse, "- . - -");}
void morse_Z(char *morse){strcpy(morse, "- - . .");}
void morse_0(char *morse){strcpy(morse, "- - - - -");}
void morse_1(char *morse){strcpy(morse, ". - - - -");}
void morse_2(char *morse){strcpy(morse, ". . - - -");}
void morse_3(char *morse){strcpy(morse, ". . . - -");}
void morse_4(char *morse){strcpy(morse, ". . . . -");}
void morse_5(char *morse){strcpy(morse, ". . . . .");}
void morse_6(char *morse){strcpy(morse, "- . . . .");}
void morse_7(char *morse){strcpy(morse, "- - . . .");}
void morse_8(char *morse){strcpy(morse, "- - - . .");}
/* the two lines are commented out, to make the sketch working
void morse_9(char *morse){strcpy(morse, "- - - - .");}
void morse_blank (char *morse){strcpy(morse, " ");}
*/
void char2morse( char chr, char *morse) {
strcpy(morse, "");
switch (chr) {
case 'A' : morse_A( morse); break;
case 'B' : morse_B( morse); break;
case 'C' : morse_C( morse); break;
case 'D' : morse_D( morse); break;
case 'E' : morse_E( morse); break;
case 'F' : morse_F( morse); break;
case 'G' : morse_G( morse); break;
case 'H' : morse_H( morse); break;
case 'I' : morse_I( morse); break;
case 'J' : morse_J( morse); break;
case 'K' : morse_K( morse); break;
case 'L' : morse_L( morse); break;
case 'M' : morse_M( morse); break;
case 'N' : morse_N( morse); break;
case 'O' : morse_O( morse); break;
case 'P' : morse_P( morse); break;
case 'Q' : morse_Q( morse); break;
case 'R' : morse_R( morse); break;
case 'S' : morse_S( morse); break;
case 'T' : morse_T( morse); break;
case 'U' : morse_U( morse); break;
case 'V' : morse_V( morse); break;
case 'W' : morse_W( morse); break;
case 'X' : morse_X( morse); break;
case 'Y' : morse_Y( morse); break;
case 'Z' : morse_Z( morse); break;
case '0' : morse_0( morse); break;
case '1' : morse_1( morse); break;
case '2' : morse_2( morse); break;
case '3' : morse_3( morse); break;
case '4' : morse_4( morse); break;
case '5' : morse_5( morse); break;
case '6' : morse_6( morse); break;
case '7' : morse_7( morse); break;
case '8' : morse_8( morse); break;
/* the two lines are commented out, to make the sketch working
case '9' : morse_9( morse); break;
case ' ' : morse_blank ( morse); break;
*/
}
}
void send_char( char snd_char) {
lcd.setCursor(0, 0);
char message[17];
sprintf(message, "Char: %c ", snd_char);
lcd.print(message);
lcd.setCursor(0, 1);
char code[12];
char2morse(snd_char, code);
if ( strlen(code) > 0 ) {
sprintf(message, "Code: %-9s", code);
lcd.print(message);
} else {
lcd.print("Code: n/a ");
}
delay(850);
}
void send_string( char *text_to_send) {
for ( byte len = 0; len < strlen(text_to_send); len++) {
send_char(text_to_send[len]);
}
}
char greeting[] = "AbCDeFGHIJkLMNOPQRSTUVWXYZ0123456789 ";
void setup() {
TinyWireM.begin();
lcd.init();
lcd.backlight();
}
void loop() {
send_string(greeting);
}
Any additional hints ??
regards
Gogol