Arduino, Passing array pointer/reference(?) into function, but getting bad data? - pointers

TL;DR I think I'm passing my array into a function wrongly, and thus the data thats read from it is not right causing it to possibly mangle Arduino memory.
Full code can be found >here<
After a bit of reading, I'm still a tad confused the best way to go about passing an array into a function and modifying its data within that function.
So far these 2 questions sort of helped, and thus allowed my code to compile; but after a bit of testing I'm having issues whereby the data I would be expecting to see is not being read back correctly when I'm within the function.
Array/pointer/reference confusion
Passing an array by reference in C?
The basic program...
It lights up 3 LED strips with a base colour purple (after an initial fade each light one by one), then makes a sort of colours trail effect (7 pixels long) trace along the strip, and loop back from the beginning again.
Video can be seen here of the effect https://www.youtube.com/watch?v=S8tVfFfsiqI
I'm going to do the same effect but I have since tried to re-factor my code so that its easier for everyone to adjust the parameters of the colours.
Original source code can be found here >Click to View< (feel free to copy/modify/use the code how ever you want, its for anyone to use really, all in good fun)
What I'm trying to do now...
So the goal now is to re-factor the code from above so that its easier to set the Trail effect colour based on the user's preferences. Thus I want to define the colour of the trail elsewhere, and then have each instance of the trail just passed into function that handles updating it (this is done without using classes, just Structs and Arrays, as thats confusing for non programmery types which this code is aimed for)
//Setting up Trail effect length
#define TRAIL_LENGTH 7
typedef struct Color {
byte r;
byte g;
byte b;
};
typedef struct TrailPixel {
uint16_t position;
Color color;
};
//Function Prototypes
void trailEffectForward (Adafruit_NeoPixel &strip, struct TrailPixel (*trailArray)[TRAIL_LENGTH] );
//Make the arrays
TrailPixel trailLeft[TRAIL_LENGTH];
TrailPixel trailBottom[TRAIL_LENGTH];
TrailPixel trailRight[TRAIL_LENGTH];
So as you can see from the above, I create two Structs, and then make 3 arrays of those structs. I then populate the "position" value of each of the trail effects with...
for (int i = 0; i < TRAIL_LENGTH; i++) {
trailLeft[i].position = i + 5; //start just off the strip
trailBottom[i].position = 15 - i; //start off screen, but timed in a way so to look like the Left and Right trails converge onto the bottom at the same time
trailRight[i].position = i + 5; //start just off strip
}
Later on in the code, I call the function that I want to process the effect, and I hand off the details of the array to it. I want to have inside this function, to commands to update the pixel colour on the light strip and then update the position for next time.
BUT Things get mangled really fast to the point where my Arduino reboots every few seconds and colours aren't behaving as expected.
Here how I currently call the trail effect function...
trailEffectForward ( stripBottom , &trailBottom );
Once in there to try and figure out whats going on, I added some serial output to check the values.
void trailEffectForward(Adafruit_NeoPixel &strip, TrailPixel (*trailArray)[TRAIL_LENGTH]) {
Serial.println("---------------------");
Serial.println(trailArray[0]->position);
Serial.println(trailArray[1]->position);
Serial.println(trailArray[2]->position);
Serial.println(trailArray[3]->position);
Serial.println(trailArray[4]->position);
Serial.println(trailArray[5]->position);
Serial.println(trailArray[6]->position);
I would EXPECT if things worked according to plan, I would see the numbers
---------------------
15
14
13
12
11
10
9
But what I end up having is this :(
---------------------
15
5
5
43
1000
0
0
The full code that is currently in a state of Work In Progress can be found http://chiggenwingz.com/quads/ledcode/quad_leds_v0.2workinprogress.ino
Note: I've commented out a lot of the meat that applies colour to the pixels as I trying to narrow down what was going wrong. Basically I would be expecting the output as listed above to stop happening.
Once again feel free to use any of the code in your own projects :)

Okie it looks I found my answer from here [ Passing an array of structs in C ]
So the function was this previously...
void trailEffectForward(Adafruit_NeoPixel &strip, TrailPixel (*trailArray)[TRAIL_LENGTH])
and is now this
void trailEffectForward(Adafruit_NeoPixel &strip, struct TrailPixel trailArray[TRAIL_LENGTH] )
Got rid of the whole pointer/reference fun stuff. Had to put the word "struct" there I believe.
So when I call the function, I was previously using...
trailEffectForward ( stripBottom , &trailBottom );
but now I use this
trailEffectForward ( stripBottom , trailBottom );
I no longer have mangled data, and everything apperars to be working happily again.
Hopefully this helps someone out there in the years to come :)

Related

Updating Uniform Buffer Data in WebGL 2?

Different from OpenGL ES 3, without gl.mapBufferRange and gl.bufferSubData (It exists), what is the efficient way to update uniform buffer data in WebGL 2?
For example, a PerDraw Uniform block
uniform PerDraw
{
mat4 P;
mat4 MV;
mat3 MNormal;
} u_perDraw;
gl.bufferSubData exists so it would seem like you create a buffer then create a parallel typedArray. Update the typedArray and call
gl.bufferSubData to copy it into the buffer to do the update and gl.bindBufferRange to use it.
That's probably still very fast. First off all value manipulation stays in JavaScript so there's less overhead of calling into WebGL. If you have 10 uniforms to update it means you're making 2 calls into WebGL instead of 10.
In TWGL.js I generate ArrayBufferViews for all uniforms into a single typed array so for example given your uniform block above you can do
ubo.MV[12] = tx;
ubo.MV[13] = ty;
ubo.MV[14] = tz;
Or as another example if you have a math library that takes an array/typedarray as a destination parameter you can do stuff like
var dest = ubo.P;
m4.perspective(fov, aspect, zNear, zFar, dest);
The one issue I have is dealing with uniform optimization. If I edit a shader, say I'm debugging and I just insert output = vec4(1,0,0,1); return; at the top of a fragment shader and some uniform block gets optimized out the code is going to break. I don't know what the standard way of dealing with this is in C/C++ projects. I guess in C++ you'd declare a structure
struct PerDraw {
float P[16];
float MV[16];
float MNormal[9];
}
So the problem kind of goes away. In twgl.js I'm effectively generating that structure at runtime which means if your code expects it to exist but it doesn't get generated because it's been optimized out then code break.
In twgl I made a function that copies from a JavaScript object to the typed array so I can skip any optimized out uniform blocks which unfortunately adds some overhead. You're free to modify the typearray views directly and deal with the breakage when debugging or to use the structured copy function (twgl.setBlockUniforms).
Maybe I should let you specify a structure from JavaScript in twgl and generate it and it's up to you to make it match the uniform block object. That would make it more like C++, remove one copy, and be easier to deal with when debugging optimizations remove blocks.

Trying to understand recursive function

To better understand recursion, I'm trying to count how many characters are between each pair of (),
not counting characters that are within other ()s. For example:
(abc(ab(abc)cd)(()ab))
would output:
Level 3: 3
Level 2: 4
Level 3: 0
Level 2: 2
Level 1: 3
Where "Level" refers to the level of () nesting. So level three would mean that the characters are within a pair(1) within a pair(2) within a pair(3).
To do this, my guess is that the easiest thing to do is to implement some sort of recursive call to the function, as commented inside the function "recursiveParaCheck". What is my approach as I begin thinking about a recurrence relationship?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int recursiveParaCheck(char input[], int startPos, int level);
void main()
{
char input[] = "";
char notDone = 'Y';
do
{
//Read in input
printf("Please enter input: ");
scanf(" %s", input);
//Call Recursive Function to print out desired information
recursiveParaCheck(input, 1, 1);
printf("\n Would you like to try again? Y/N: ");
scanf(" %c", &notDone);
notDone = toupper(notDone);
}while(notDone == 'Y');
}
int recursiveParaCheck(char input[], int startPos, int level)
{
int pos = startPos;
int total = 0;
do
{
if(input[pos] != '(' && input[pos] != ')')
{
++total;
}
//What is the base case?
if(BASE CASE)
{
//Do something?
}
//When do I need to make a recursive call?
if(SITUATION WHERE I MAKE RECURSIVE CALL)
{
//Do something?
}
++pos;
}while(pos < 1000000); // assuming my input will not be this long
}
Recursion is a wonderful programming tool. It provides a simple, powerful way of approaching a variety of problems. It is often hard, however, to see how a problem can be approached recursively; it can be hard to "think" recursively. It is also easy to write a recursive program that either takes too long to run or doesn't properly terminate at all. In this article we'll go over the basics of recursion and hopefully help you develop, or refine, a very important programming skill.
What is Recursion?
In order to say exactly what recursion is, we first have to answer "What is recursion?" Basically, a function is said to be recursive if it calls itself.
You may be thinking this is not terribly exciting, but this function demonstrates some key considerations in designing a recursive algorithm:
It handles a simple "base case" without using recursion.
In this example, the base case is "HelloWorld(0)"; if the function is asked to print zero times then it returns without spawning any more "HelloWorld"s.
It avoids cycles.
Why use Recursion?
The problem we illustrated above is simple, and the solution we wrote works, but we probably would have been better off just using a loop instead of bothering with recursion. Where recursion tends to shine is in situations where the problem is a little more complex. Recursion can be applied to pretty much any problem, but there are certain scenarios for which you'll find it's particularly helpful. In the remainder of this article we'll discuss a few of these scenarios and, along the way, we'll discuss a few more core ideas to keep in mind when using recursion.
Scenario #1: Hierarchies, Networks, or Graphs
In algorithm discussion, when we talk about a graph we're generally not talking about a chart showing the relationship between variables (like your TopCoder ratings graph, which shows the relationship between time and your rating). Rather, we're usually talking about a network of things, people, or concepts that are connected to each other in various ways. For example, a road map could be thought of as a graph that shows cities and how they're connected by roads. Graphs can be large, complex, and awkward to deal with programatically. They're also very common in algorithm theory and algorithm competitions. Luckily, working with graphs can be made much simpler using recursion. One common type of a graph is a hierarchy, an example of which is a business's organization chart:
Name Manager
Betty Sam
Bob Sally
Dilbert Nathan
Joseph Sally
Nathan Veronica
Sally Veronica
Sam Joseph
Susan Bob
Veronica
In this graph, the objects are people, and the connections in the graph show who reports to whom in the company. An upward line on our graph says that the person lower on the graph reports to the person above them. To the right we see how this structure could be represented in a database. For each employee we record their name and the name of their manager (and from this information we could rebuild the whole hierarchy if required - do you see how?).
Now suppose we are given the task of writing a function that looks like "countEmployeesUnder(employeeName)". This function is intended to tell us how many employees report (directly or indirectly) to the person named by employeeName. For example, suppose we're calling "countEmployeesUnder('Sally')" to find out how many employees report to Sally.
To start off, it's simple enough to count how many people work directly under her. To do this, we loop through each database record, and for each employee whose manager is Sally we increment a counter variable. Implementing this approach, our function would return a count of 2: Bob and Joseph. This is a start, but we also want to count people like Susan or Betty who are lower in the hierarchy but report to Sally indirectly. This is awkward because when looking at the individual record for Susan, for example, it's not immediately clear how Sally is involved.
A good solution, as you might have guessed, is to use recursion. For example, when we encounter Bob's record in the database we don't just increment the counter by one. Instead, we increment by one (to count Bob) and then increment it by the number of people who report to Bob. How do we find out how many people report to Bob? We use a recursive call to the function we're writing: "countEmployeesUnder('Bob')". Here's pseudocode for this approach:
function countEmployeesUnder(employeeName)
{
declare variable counter
counter = 0
for each person in employeeDatabase
{
if(person.manager == employeeName)
{
counter = counter + 1
counter = counter + countEmployeesUnder(person.name)
}
}
return counter
}
If that's not terribly clear, your best bet is to try following it through line-by-line a few times mentally. Remember that each time you make a recursive call, you get a new copy of all your local variables. This means that there will be a separate copy of counter for each call. If that wasn't the case, we'd really mess things up when we set counter to zero at the beginning of the function. As an exercise, consider how we could change the function to increment a global variable instead. Hint: if we were incrementing a global variable, our function wouldn't need to return a value.
Mission Statements
A very important thing to consider when writing a recursive algorithm is to have a clear idea of our function's "mission statement." For example, in this case I've assumed that a person shouldn't be counted as reporting to him or herself. This means "countEmployeesUnder('Betty')" will return zero. Our function's mission statment might thus be "Return the count of people who report, directly or indirectly, to the person named in employeeName - not including the person named employeeName."
Let's think through what would have to change in order to make it so a person did count as reporting to him or herself. First off, we'd need to make it so that if there are no people who report to someone we return one instead of zero. This is simple -- we just change the line "counter = 0" to "counter = 1" at the beginning of the function. This makes sense, as our function has to return a value 1 higher than it did before. A call to "countEmployeesUnder('Betty')" will now return 1.
However, we have to be very careful here. We've changed our function's mission statement, and when working with recursion that means taking a close look at how we're using the call recursively. For example, "countEmployeesUnder('Sam')" would now give an incorrect answer of 3. To see why, follow through the code: First, we'll count Sam as 1 by setting counter to 1. Then when we encounter Betty we'll count her as 1. Then we'll count the employees who report to Betty -- and that will return 1 now as well.
It's clear we're double counting Betty; our function's "mission statement" no longer matches how we're using it. We need to get rid of the line "counter = counter + 1", recognizing that the recursive call will now count Betty as "someone who reports to Betty" (and thus we don't need to count her before the recursive call).
As our functions get more and more complex, problems with ambiguous "mission statements" become more and more apparent. In order to make recursion work, we must have a very clear specification of what each function call is doing or else we can end up with some very difficult to debug errors. Even if time is tight it's often worth starting out by writing a comment detailing exactly what the function is supposed to do. Having a clear "mission statement" means that we can be confident our recursive calls will behave as we expect and the whole picture will come together correctly.

Using strconv for negative hex values in Go

I've been building an assembler for no good reason the past day or so using Go so I can get familiar with the language. It's my first real program using Go so I expected problems, but I have a consistent bug coming up time and time again. I just figured out other hacky ways to fix it in other cases, but this time I think I need an answer so I feel like I'm actually doing this right.
Basically, I have to parse tons of byte values. Some of these are signed bytes so -1 = 0xFF and so on. When calculating the address of a label I need to find the offset of it from the current address. The following code is a stripped down basic version of what I use to get the offset:
// lbladdr holds the target label address
// address holds current address in memory
// label[x] holds the offset
if address > lbladdr {
lbladdr -= address
}
label[x] = strconv.FormatInt(int64(lbladdr), 16)
This works for positive values, but when I get a negative address (address > lbladdr) then instead of getting a value like FE I get -2. I don't get why the standard library would append a negative sign to a hex number and I haven't been able to find anything in the documentation about it. I've looked a lot of other places but I can't seem to find anyone with the same problem either.
I hope it's just something on my end that is a simple fix.
It's perfectly reasonable to use a negative sign on hexadecimal numbers. I know that when working with assembly it's common to use the actual bitpattern for the register you are representing in hex to represent the signs. However Go doesn't know you are doing that. Neither is go's formatting function written to support hex values as they would be in a CPU register. Further the bitpatterns will differ depending on the register size (16 vs 32 vs 64 and big vs little endian). you would be storing them in. So the base isn't enough to print them the way you want. You will need to write your own formatting lib that supports formatting for the type of Register you want to represent.
It's by design: http://golang.org/src/pkg/strconv/itoa.go?s=628:668#L8
What you may want is to cast to uint64:
package main
import (
"fmt"
"strconv"
)
func main() {
i := -1
fmt.Printf("%x\n", uint64(i))
fmt.Println(strconv.FormatUint(uint64(i), 16))
}

slow execution of string comparision

my problem why my program takes much large time to execute, this program is supposed to check the user password, the approach used is
take password form console in to array and
compare it with previously saved password
comparision is done by function str_cmp()-returns zero if strings are equal,non zero if not equal
#include<stdio.h>
char str_cmp(char *,char *);
int main(void)
{
int i=0;
char c,cmp[10],org[10]="0123456789";
printf("\nEnter your account password\ntype 0123456789\n");
for(i=0;(c=getchar())!=EOF;i++)
cmp[i]=c;
if(!str_cmp(org,cmp))
{
printf("\nLogin Sucessful");
}
else
printf("\nIncorrect Password");
return 0;
}
char str_cmp(char *porg,char *pcmp)
{
int i=0,l=0;
for(i=0;*porg+i;i++)
{
if(!(*porg+i==*pcmp+i))
{
l++;
}
}
return l;
}
There are libraries available to do this much more simply but I will assume that this is an assignment and either way it is a good learning experience. I think the problem is in your for loop in the str_cmp function. The condition you are using is "*porg+i". This is not really doing a comparison. What the compiler is going to do is go until the expression is equal to 0. That will happen once i is so large that *porg+i is larger than what an "int" can store and it gets reset to 0 (this is called overflowing the variable).
Instead, you should pass a size into the str_cmp function corresponding to the length of the strings. In the for loop condition you should make sure that i < str_size.
However, there is a build in strncmp function (http://www.elook.org/programming/c/strncmp.html) that does this exact thing.
You also have a different problem. You are doing pointer addition like so:
*porg+i
This is going to take the value of the first element of the array and add i to it. Instead you want to do:
*(porg+i)
That will add to the pointer and then dereference it to get the value.
To clarify more fully with the comparison because this is a very important concept for pointers. porg is defined as a char*. This means that you have a variable that has the memory address of a 'char'. When you use the dereference operator (*, for example *porg) on the variable, it returns the value at stored in that piece of memory. However, you can add a number to the memory location to move to a different memory location. porg + 1 is going to return the memory location after porg. Therefore, when you do *porg + 1 you are getting the value at the memory address and adding 1 to it. On the other hand, when you do *(porg + 1) you are getting the value at the memory address one after where porg is pointing to. This is useful for arrays because arrays are store their values one after another. However, a more understandable notation for doing this is: porg[1]. This says "get the value 1 after the beginning of the array" or in other words "get the second element of the array".
All conditions in C are checking if the value is zero or non-zero. Zero means false, and every other value means true. When you use this expression (*porg + 1) for a condition it is going to do the calculation (value at porg + 1) and check if it is zero or not.
This leads me to the other very important concept for programming in C. An int can only hold values up to a certain size. If the variable is added to enough where it is larger than that maximum value, it will cycle around to 0. So lets say the maximum value of an int is 256 (it is in fact much larger). If you have an int that has the value of 256 and add 1 to it, it will become zero instead of 257. In reality the maximum number is 65,536 for most compilers so this is why it is taking so long. It is waiting until *porg + i is greater than 65,536 so that it becomes zero again.
Try including string.h:
#include <string.h>
Then use the built-in strcmp() function. The existing string functions have already been written to be as fast as possible in most situations.
Also, I think your for statement is messed up:
for(i=0;*porg+i;i++)
That's going to dereference the pointer, then add i to it. I'm surprised the for loop ever exits.
If you change it to this, it should work:
for(i=0;porg[i];i++)
Your original string is also one longer than you think it is. You allocate 10 bytes, but it's actually 11 bytes long. A string (in quotes) is always ended with a null character. You need to declare 11 bytes for your char array.
Another issue:
if(!(*porg+i==*pcmp+i))
should be changed to
if(!(porg[i]==pcmp[i]))
For the same reasons listed above.

Finding cycles with a stack-based depth first search

I know that you use a recursive implementation of DFS where all nodes start as white, are colored gray when they are first encountered, and are colored black after all of their children are explored, you know that there is a cycle if you ever encounter a gray node.
But how do you do this with a stack implementation?
This answer on Stackoverflow is pointing to a Java code sample implementing DFS with stack.
Besides, if you feel comfortable with C and I hope you like chess as me too, I strongly advise you to study Andy DuPlain's fbk2rbm's source code released in the public domain.
It's a handy utility to convert Fritz power-books to Rebel 7 format (Opening libraries in the chess parlance).
It makes use of stack, chess move beeing seen as node.
Excerpt :
...
/* Used to hold move */
struct Move {
char FromFile, FromRank;
char ToFile, ToRank;
unsigned char Eval;
char StartVar;
};
/* List of moves seen */
struct Move Moves[256];
...
Extending the program to address position cylcing detection (given that different move sequences may lead to the same position / collision) would be an excellent exercise related to your question.

Resources