Go Down

Topic: (solved) trying to set repeating code parts, but don't know how (Read 1 time) previous topic - next topic

JO3RI

Mar 06, 2011, 07:31 pm Last Edit: Mar 07, 2011, 08:51 pm by JO3RI Reason: 1
Below you see the code for a rotating arrow. Now as you can see it is actually 3 character sets being put on after an other. Actually I need something like 123212321232 and so on, but I don't know how to do that.

Code: [Select]
#include  <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int x = 250;
int y = 0;
int z = 1;

byte arrowA1[8] = {B00000,B11000,B10100,B10010,B10010,B10100,B11000,B00000};
byte arrowA2[8] = {B00000,B00000,B11000,B10110,B10110,B11000,B00000,B00000};
byte arrowA3[8] = {B00000,B00000,B00000,B11110,B11110,B00000,B00000,B00000};

void setup() {
lcd.begin(16, 2);
lcd.write(0);
}

void loop() {
       arrow();
}

void arrow(){
       lcd.clear();
  lcd.createChar(0, arrowA1);
       lcd.setCursor(y,z);
       lcd.write(0);
       delay(x);
       lcd.createChar(0, arrowA2);
       lcd.setCursor(y,z);
       lcd.write(0);
       delay(x);
       lcd.createChar(0, arrowA3);
       lcd.setCursor(y,z);
       lcd.write(0);
       delay(x);
       lcd.createChar(0, arrowA2);
       lcd.setCursor(y,z);
       lcd.write(0);
       delay(x);  
}


What I want do do is having the part:

Code: [Select]
lcd.createChar(0, arrowA1);
       lcd.setCursor(y,z);
       lcd.write(0);
       delay(x);


only once and change the arrowA1 to arrowA2, arrowA3, arrowA2, arrowA1,arrowA2, ... well you get the point.

MarkT

Firstly you seem to be redefining chars - I think you only need to define each one once?

Also separate out the code into separate function - very easy.

So something like this (although not tested, I've not used the lcd library).

Code: [Select]

void define_char (byte [] data, char code)
{
    lcd.clear();
    lcd.createChar(code, data);
}

void show_char (char code)
{
    lcd.setCursor(y,z);
    lcd.write(code);
    delay(x);
}

void setup ()
{
   define_char (arrowA1, 0) ;
   define_char (arrowA2, 1) ;
   define_char (arrowA3, 2) ;
}

void loop ()
{
    show_char (0) ;
    show_char (1) ;
    show_char (2) ;
    show_char (1) ;
}

[ I won't respond to messages, use the forum please ]

JO3RI

Well actually the code I wrote does work and I DO have to create every char because they are 3 different drawings of an arrow.

so the part:
Code: [Select]
byte arrowA1[8] = {B00000,B11000,B10100,B10010,B10010,B10100,B11000,B00000};
byte arrowA2[8] = {B00000,B00000,B11000,B10110,B10110,B11000,B00000,B00000};
byte arrowA3[8] = {B00000,B00000,B00000,B11110,B11110,B00000,B00000,B00000};


has to stay.

It is the part where I try to put the chars on the LCD I want to simplify. I tried this, but it doesn't work:

Code: [Select]

#include  <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
byte x = 0; //set row on LCD
byte y = 0; // set column on LCD
int z = 250; // set animation speed (actual the delay between each frame of the animation)

byte arrowA1[8] = {B00000,B11000,B10100,B10010,B10010,B10100,B11000,B00000}; // set up arrow 1
byte arrowA2[8] = {B00000,B00000,B11000,B10110,B10110,B11000,B00000,B00000}; // set up arrow 2
byte arrowA3[8] = {B00000,B00000,B00000,B11110,B11110,B00000,B00000,B00000}; // set up arrow 3

byte arrowA[]={1,2,3,2}; // set up each animation step: arrow 1, arrow 2, arrow 3, arrow 2
int character = 0; // set up the character number (we can only have 8 characters at the same time on the display, but now we only need one, 0 in this case)

void setup() {
lcd.begin(16, 2);
}

void loop() {
  for(int i=0; i<3; i++)
  {
        lcd.clear();
  lcd.createChar(character, arrowA[i]); //here we actually create the character on position character
        lcd.setCursor(x,y); // here we set the cursor on location x and y (row and column)
        lcd.write(character); // write the "characterpos" we defined in lcd.createChar to the LCD
        delay(z); // wait for z millisecs
  }


normally the
Code: [Select]
for(int i=0; i<3; i++) should write each arrow on the same location with a delay of 250 millisecs and do this accordingly to
Code: [Select]
byte arrowA[]={1,2,3,2}; this should be: arrowA1, arrowA2, arrowA3, arrowA2, but it gives me:
sketch_mar07a.cpp: In function 'void rotatingarrow()':
sketch_mar07a:16: error: invalid conversion from 'int' to 'uint8_t*'
sketch_mar07a:16: error: initializing argument 2 of 'void LiquidCrystal::createChar(uint8_t, uint8_t*)'

one would think arrowA[] would be replaced by 1 then 2 then 3 and then 2 again.

PaulS

Quote
one would think arrowA[] would be replaced by 1 then 2 then 3 and then 2 again.

Why would one think that?

byte *arrows[3] = {arrowA1, arrowA2, arrowA3};
seems to be more in line with what you want to do. Then, draw using arrows[0], arrows[1], and arrows[2].

JO3RI

you are completly right,
Quote
why would one think that?
:D

In my case it would just replace arrowA by 1,2,3 and 2 again and it should replace it with arrowA1, arrowA2, arrowA3, arrowA2

So I changed the

Code: [Select]
byte arrowA[]={1,2,3,2};
to
Code: [Select]
byte *arrows[4] = {arrowA1, arrowA2, arrowA3, arrowA2};
and
Code: [Select]
lcd.createChar(character, arrows[i]); to match arrows instead of the confusing arrowA
I'll test this within 2 hours, but I think you helped me out. I tried to fill out those arrowA1 ... in byte arrows[], but it gave an error. when putting * in front of arrows it compiles sketch. Why is that? what does the * mean?

thanks again

PaulS

The * in front of a variable name (byte *arrows) means that the variable is a pointer. Or, in your case, an array of pointers. Since an array is itself a pointer (to the first element of the array), what you have is an array of arrays.

arrows[n] then is a pointer to the bytes that are pointed to by arrowAn, where n is 1, 2, or 3.

JO3RI

Quote
The * in front of a variable name (byte *arrows) means that the variable is a pointer

aha, Ok I understand your explanation and I tested the code: IT WORKS  8)

Now I cleaned up the code and I've put it here as a reference:

A rotating arrow on a 16x2 LCD
Code: [Select]
#include  <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int z = 250; // set animation speed (actual the delay between each frame of the animation)
byte arrowA1[8] = {B00000,B11000,B10100,B10010,B10010,B10100,B11000,B00000}; // set up arrow 1
byte arrowA2[8] = {B00000,B00000,B11000,B10110,B10110,B11000,B00000,B00000}; // set up arrow 2
byte arrowA3[8] = {B00000,B00000,B00000,B11110,B11110,B00000,B00000,B00000}; // set up arrow 3
byte *arrows[4]={arrowA1,arrowA2,arrowA3,arrowA2}; // set up each animation step: arrow 1, arrow 2, arrow 3, arrow 2

void setup() {
lcd.begin(16, 2);
}

void loop() {
  for(int i=0; i<4; i++)
  {
    lcd.clear();
    lcd.createChar(0, arrows[i]); //here we actually create the character on position zero
    lcd.setCursor(0,0); // here we set the cursor on location x and y (row and column)
    lcd.write(0); // write the character we defined in lcd.createChar to the LCD
    delay(z); // wait for z millisecs
  }
}

Go Up