Problems with for loop

30 posts / 0 new
Author
Message

Hey,

I want to create a for-loops to give a waveform on my lcd. I have 102 values to fill the 8 rows of my lcd regarding to the input that can be adjusted using a poti. I used the following code:

.....

char pattern[]= //my array for the LCD
{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
};

......

for (j=0; j*13>=bin_number; j++) //every 13nth value compare with present data and if match add one line of ones on my lcd
{
y =y++;
pattern[y] = 0b11111;
}
for (j=7; bin_number>j*13; j--) //every 13nth value of the present data compare the other way around, add one line of zeros on my lcd
{
y == y--;
pattern[y] = 0b00000;
}
write_lcd_one_step(0x8C,pattern[y]);

It shows me some characters, but not a waveform, like line after line, related to the adjusted value.

Instead of "y=y++;"    just use "y++;

Here you use a comparison symbol "=="

"y==y--;"    should be just  "y--;"

Jim

ki0bk wrote:

Full instructions here: http://www.avrfreaks.net/comment...

I'm very confused.  Tell [much] more about this eight-row LCD.  Is it some kind of bargraph segment module?  Character LCD?  Some type of graphic display?

Are you trying to do something like this on a character LCD?

Or on a graphics LCD?

If not, describe, or give a picture.  How do you put 102 values onto 8 rows?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Yes! That is exactly what I am trying to do, the first and the second pictures!

How do you put 102 values onto 8 rows?

I devided 102/8 =12.75, since i work with int, I started with 13 first, which is a little bit more.

Brand_New wrote:
Yes! That is exactly what I am trying to do, the first and the second pictures!

How many characters on your display?  Rows and columns.

The short answer is that you can do something like picture 1 or 2.  But not the character-LCD equivalent of the "waveform" display as in the graphic LCD in picture 3.  Why?  There are only 8 defineable characters, so you cannot have a different value in each "bit position" across the display.

I still don't understand about the "102".  Are you trying to put five different values in e.g. column 1, then five different values in column 2, etc?  You won't be able to in the general case, as there are only eight user-definable characters.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

You have not given us much to go on.  No picture or diagram or ASCII-art of what you want to do.  And the mystery function write_lcd_one_step().

You might be interested in http://www.avrfreaks.net/comment... where I linked to http://www.avrfreaks.net/comment...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Elm-Chan built this from a graphic display...

http://elm-chan.org/works/akilcd...

But 10+ years later, there are a lot of more modern graphics displays to choose from.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Simpler :

cat -with your mouse- and paste existing green code.

```char pattern[]=

{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
};

for (j=0; j*13>=bin_number; j++)
//every 13nth value compare with present data and if match add one line of ones on my lcd
{
y =y+1 ; // or y ++;
pattern[y] = 0b11111;
}
for (j=7; bin_number>j*13; j--)
//every 13nth value of the present data compare the other way around, add one line of zeros on my lcd
{
y--; // = != ==
pattern[y] = 0b00000;
}
write_lcd_one_step(0x8C,pattern[y]);```

```int set = getadc(0)*8/1023; //value of adc tranfer into lcd 8 rows 5 lines

for (i=0; i<set; i++)
{
pattern[i]=0b00000;
}
for (i=i; i<8; i++)
{
pattern[i]=0b11111;
}
for (j=0; j<8; j++)
{
write_lcd(0,0x8C);      //position on lcd
write_lcd(1,pattern[j]); //data on lcd
}```

I can generate a 'pi' sign using this code, but i think that this comes from my cgram.

I give up.

If you want me to pay further attention, show a picture or diagram of what you want to end up with.  And for now, eliminate the "for loop" and use some constant test data.

Without that, I still think you are dealing with the 8-character maximum.  Tell more about what "fading" means.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Hey guys,

thanks for your help. I solved the problem. Is there anything I need to do for this regarding these posts/topic?

Brand_New wrote:
Is there anything I need to do for this regarding these posts/topic?

For the benefit of future readers, describe how, exactly, you "solved the problem".

If one (or more) of the replies gave the answer to your question, use the 'Mark Solution' button to identify it/them.

EDIT (update & generalisation - for future reference)

It seems that you can only select the 'Mark Solution' button for one post:

So, if you feel multiple posts have all contributes to the solution, you can write a summary post and select the 'Mark Solution' button for that one.

EDIT 2

Note that marking the solution does also flag it in the topic lists;  so there is no need to also edit the thread title with "Solved", or suchlike.

#MarkSolution #MarkAsSolution

Last Edited: Wed. Sep 27, 2017 - 04:01 PM
```char pattern[]=

{
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
};

for (j=0; j*13>=bin_number; j++)
//every 13nth value compare with present data and if match add one line of ones on my lcd
{
y =y+1 ; // or y ++;
pattern[y] = 0b11111;
}```

Now I don't know what "bin_number" is in this or what value it may hold but I cannot help thinking this code is going to be writing to at least 13 locations of an array that has only allocated 8 bytes!

Brand_New wrote:
Hey guys,

thanks for your help. I solved the problem

Why bother? He already solved his problem. ;D

I don't know why I'm still doing this hobby

Are you sure, Micro Gyro?

Maybe he is overoptimistic (some people think a problem is solved and do not check thoroughly / verify code can be understood by themselves 6 months later, when they have forgotten every thing and want to add/remove/alter functionalities....)

MicroGyro wrote:
Well he didn't if he really is allocating 8 bytes and writing 13+

That's another good reason for sharing the "solution" here - it can be reviewed!

Post 10 writes into a 8 bytes array (set is upper bounded by 8; unless adc grows 12... 16 bits; in 1rst loop, array index is < 8 (in 2nd loop , too) .

First post with code is more difficult to understand (bin is a binary number? a dust bin? I was very puzzled -as might be OP next year, if he dares to reuse/madify  modify code)

Edited : weird, unintented typo corrected

Last Edited: Wed. Jun 28, 2017 - 10:29 AM

dbrion0606 wrote:

Are you sure, Micro Gyro?

Maybe he is overoptimistic (some people think a problem is solved and do not check thoroughly / verify code can be understood by themselves 6 months later, when they have forgotten every thing and want to add/remove/alter functionalities....)

lol... don't too carried away

clawson wrote:

MicroGyro wrote:
Well he didn't if he really is allocating 8 bytes and writing 13+

He's offering to explain ;)

I don't know why I'm still doing this hobby

Here is the code that solved my problem on displaying a waveform on an char lcd proportional to the input voltage coming from my adc.

```int set = getadc(0)*8/1023;  //lcd has 8 rows, so convert adc to rows
for (j=0; j<8; j++)
{
for (i=i; i<8; i++) //write zeros to char 'graph'
{
graph[i]=0b00000;
write_lcd(1,graph[i]);
}
for (i=0; i<set; i++) //write ones to char 'graph' regarding the adc input
{
graph[i]=0b11111;
write_lcd(1,graph[i]);
}
write_lcd(0,0x40); //write to cgram
}
write_lcd(0,0x8C); //display on lcd location
write_lcd(1,0);		//display data```

Last Edited: Fri. Jun 30, 2017 - 04:20 PM

Excuse me, but I am afraid you swapped 2 loops (that would be slightly faster : you define "set" caharcters a 1, then 8-set chars as zeoes... -> 8 writes to the LCD (instad of  8 + set)

```int set = getadc(0)*8/1023;  //lcd has 8 rows, so convert adc to rows
for (j=0; j<8; j++)
{
for (i=i; i<8; i++) //write zeros to char 'graph'
/* i is not initialized ? did your compiler warn you?
{
graph[i]=0b00000;
write_lcd(1,graph[i]);
}
/* maybe should be put **** before*** previous loop
for (i=0; i<set; i++) //write ones to char 'graph' regarding the adc input
{
graph[i]=0b11111;
write_lcd(1,graph[i]);
}
write_lcd(0,0x40); //write to cgram
}
write_lcd(0,0x8C); //display on lcd location
write_lcd(1,0);		//display data```

Hey and thanks for ur suggestions. I will try it :)

`/* i is not initialized ? did your compiler warn you?`

It is but i did not show it in the code ;)

I still have a problem reading my present adc-value into an array.

I used a timer interrupt, like this:

```ISR(TIMER1_OVF_vect)
{
cnt++;
if (cnt==j) // ja can be defined on a keypad and shauld adjust the sample rate
{
newcnt++;
cnt = 0;
}
}```

Now, i want to use "newcnt" to log my data, I tried simple:

```int volt_array[99]

int main (void)

{
//newcnt = cnt;
if (newcnt >= 100)
{
newcnt=0;
}

}```

But i think that this does not put my data into the array "volt_array" 100 times and overwrites the values each time it counts up again.

Is there something I do wrong?

variables shared between main() and ISR() must be declared volatile.

`int newcnt;`

should be

`volatile int newcnt;`

and if larger then 8 bit, then read atomically as well.

Last Edited: Fri. Jun 30, 2017 - 08:55 PM

And volt_array is too small.

Stefan Ernst

And the code presented above is not complete, and will not build clean...

PLEASE, when you have a problem with actual code do not post code that you just typed in. Copy the malfunctioning code from your editor into a forum post. It is essential that we see the actual code that you have, not some inexact replication of it. Your computer has copy/paste-functionality. Use it.

There is a missing semicolon at the definition of volt_array.

main() has a declared return type of int, yet no return statement is present.

Also, there is no actual loop in your main() so execution will just rush though it once.

The optimal situation is that

you post a minimal but complete program that we can copy into Studio, build and run,

you describe as accurately and to the point as possible the symptoms of malfunction that you see at your end,

we can repeat your symptoms by using the code you posted without any alterations at all.

Honestly, I cant make heads or tails of " this does not put my data into the array "volt_array" 100 times and overwrites the values each time it counts up again".

Tell us exactly what you want your program to do.

Tell us exactly what you observe your program doing.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

Last Edited: Sat. Jul 1, 2017 - 09:43 AM

copying into voltArray[newCount] should be atomic, too (is longer than 8 octets; by unluck, you might copy half before being interrupted, leading to weird, hard to reproduce, inconsistencies).

```#define TAILLE 100
int voltArray[100];

void main (void) {
// initializations
while (LEMONDE == LEMONDE) {

{
//newcnt = cnt;
if (newCount == (TAILLE -1)) // Sternst remark
{
newCount=0;
}
ATOMICBLOCK(FORCEON) { // http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html
voltArray[newCount] = getadc(0); // hope getAdc is not too slow... anayway, getAdc should be in the ISR, maybe in a simplified form
}
}// while
} // main ```

dbrion0606 wrote:
should be atomic, too (is longer than 8 octets; by unluck, you might copy half

You mean "8 bits", not "8 octets" right?

Atomicity issues is not only about accessing larger-tha-byte values. Even for byte-sized values there might be problems if two independent "threads of execution" accesses such a value.

Example:

the variable x has the value 42.

`x += 7;`

`x = x * 2;`

Suppose thread A is bout to start it's operation on x:

1. It reads from the location x into a register, that now holds the value 42.
2. It adds 7 to that register, so that it now holds the value 49.
3. By some mechanism (e.g. an interrupt) now thread B starts its operation on x.
4. It reads from location x into some register, that now holds the value 42.
5. It multiplies it by 2, so that it holds 84.
6. It stores that value back to the location x.
7. Thread B now relinquishes control.
8. Thread A commences Remember, it has the value 49 in "its" register.
9. Thread A stores the value 49 at position x.

We end up with the update from thread B being overwritten/lost.

Making both accesses atomic means forcing them to execute in sequence rather than interleaved. The common technique is to disable interrupts while accessing data. In ISRs interrupts are disabled automagically, so unless you've enabled interrupts explicitly in the ISR there's nothing special to do there. In other code you could use CLI/SEI explicitly, or (better, if avr-gcc/avrlibc is used) the macros from atomic.h .

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

You mean "8 bits", not "8 octets" right?

Well, I agree I was wrong : (and OPs way of writing is complicated , as there is a function call . If he wants to get results at a regular time rate, this getAdc call might be , in a simplified form, put into the interrupt (if rate is too high, whether AD conversion  is in the inetrrupt or not does not matter).

I bet OP has avr-gcc and avr-libc working, as he uses arduino (arduino is the easiest way of getting avr-gcc + avrdude+ under xxxPi 's GNU linux (Rapsberry, nanoPi)  without forgetting anything , even if versions are older than the official)...

I think -untested- that part of the program I gave had less errors (or very trivial ones) than before. But structure of his program makes me uneasy....

Last Edited: Sat. Jul 1, 2017 - 03:39 PM