Bizzare output from Arduinio - arduino

I'm trying to do something relatively simple with the Arduino (trying to get some lights to light up like a Simon says game) but I'm getting some really bizarre outputs
I got some really bizarre output on the pins so I took those parts of the code out to see it on a serial monitor to see what the contents of the array that holds the sequence of lights (colors) are. It just really doesn't make sense to me.
What my code is supposed to do is append a random number from 1-4 onto colors[] and then read them back out onto the serial monitor
bool lightValue[4] = { 0 };
// stores whether each LED is lit or not
int buttonPressed;
// 0 - no button pressed / nothing
// 1 - red
// 2 - yellow
// 3 - green
// 4 - blue
int colors[] = { 0 };
// probably not the best name for this variable but oh well
// stores all the colors displayed for the simon says
// refer above to see what each number means
int colorNum = 0;
// again not the best name, stores the number of colors displayed so far
// AKA the length of colors[]
int randomNum;
// will store a random number
// variables
void setup() {
randomSeed(analogRead(0));
Serial.begin(9600);
Serial.println();
Serial.println("PROGRAM START");
}
// pinModes. Lots of pinModes.
void loop() {
randomNum = random(1,5);
colors[colorNum] = randomNum;
Serial.println();
Serial.print(colorNum);
Serial.print(" ");
colorNum++;
// adds another random color onto the end of the color sequence
for (int i = 0; i < colorNum; i++) {
Serial.print(colors[i]);
delay(500);
}
}
Some examples of outputs I got:
0 3
0 1
2 13520
3 145202
4 1552024
5 16520241
6 175202414
7 1852024141
8 19520241414
9 1105202414141
10 11152024141414
0 1
2 13520
3 145202
4 1552024
5 16520241
6 175202414
7 1852024141
8 19520241414
9 1105202414141
10 11152024141414
colorNum, the main increment of this loop for some reason skips over one. The first and second output do not match, the third item in the array is 520, and for some reason, the second item is incrementing by 1 every step. Also, it stops at 10 for some reason.
The only thing I could chalk this inconsistent behavior to is accessing some piece of memory where it shouldn't, but I can't come up for the life of me where I horribly messed up.

int colors[] = { 0 };
defines an integer array with a single element 0.
Here colors[colorNum] = randomNum; you're assigning numbers to indices outside of that array for colorNum > 0. You shouldn't do that. This memory region is not reserved for colors!
So who stops your compiler from storing colorNum right after colors?
So when you assing a value to colors[1] you could very well change the value of colorNum. Same for your loop control variable i.
So the second value is incremented because you're incrementing colorNum which is at the same memory location as colorNum[1].
The print for colorNum == 1 is missing because you assigned 5 to colors[2] which is at the same memory location as your loop control variable i. As 5 > colorNum the loop does not run.
I just did this on a 32bit C++ compiler:
int colors[] = {0};
int colorNum = 0;
int i = 0;
And the addresses printed:
colors[0] # 0x7fff029a5ac4
colorNum # 0x7fff029a5ac8
colors[1] # 0x7fff029a5ac8
i # 0x7fff029a5acc
colors[2] # 0x7fff029a5acc
Note that colorNum is just 4 bytes after colors[0] which is the same address as colors[1]!
Anyway you shouldn't just fill memory in an infinite loop in the first place.
You're on a micro controller where memory is a limited resource

Related

When incrementing double pointer position by 1 the resultant is zero but when incremented by 2 it's the actual value initialised

So I need some help understanding the behaviour at which pointer have, so I have code like this below:
double d1 = 3.5;
double *d1ptr = &d1;
when I increase the pointer position by 1 I get zero i.e d1ptr = d1ptr+1 but when increased by 2 i.e d1ptr = d1ptr + 2 I get the first initialised value that is 3.5
However what is weird that I see is that when I increase by any number greater than 2 the pointer value when I print out gives me 0 i.e when I say printf("%d", *d1ptr)
Can you please explain the behaviour
You are trying to print double using %d, which will result in undefined behavior. Please use %f or %lf so that you can get the expected output.
double d1 = 3.5;
double *d1ptr = &d1;
printf("%lf %u\n", *d1ptr, d1ptr); //prints value and address
d1ptr = d1ptr+2;
printf("%lf %u", *d1ptr, d1ptr); //prints value and address
Output:
3.500000 2255690064
0.000000 2255690080
The address has been increased by 2*(size of double)

How can I make my arduino print "the loop is running for the ....... time"?

i want my arduino to tell me what time running it is E.g. "this is the 22nd time this loop has run." what command/s should i use?
i am currently using this code:
Serial.print("This loop has run ");
Serial.print(loopsRun);
Serial.println(" times.");
loopsRun++;
yes i have declared all variables, i just want to know if there is a way to check the last digit of any int.
22 % 10 = 2 you'd say 22'nd'
1022 % 10 = 2 you'd say 1022 'nd'
27 % 10 = 7 you'd say 7 'th'
457 % 10 = 7 you'd say 457 'th'
Am I getting the pattern right? If so then you need a switch statement and a % operator
unsigned int remainder = loopsRun % 10;
switch (remainder)
{
case 0: suffix = "th"; break;
case 1: suffix = "st"; break;
case 2: suffix = "nd"; break;
<etc>
}

How to translate from decimal to bit-mask?

I have a ACLs system previously built by someone else and I am trying to understand how bit-masking works there. I have this 4 constants defined:
const NONE = 0;
const READ = 1;
const WRITE = 2;
const UPDATE = 4;
const DELETE = 8;
Then in DB I am seeing users with permissions like 1, 2, 5, 9, 15. I have tried to transform them using this tool and I end up with this result:
0 // NONE
1 // READ
2 // WRITE
3 // UPDATE|DELETE
4 // UPDATE
5 // WRITE|DELETE
6 // WRITE|UPDATE
7 // WRITE|UPDATE|DELETE
8 // DELETE
9 // READ|DELETE
10 // READ|UPDATE
11 // READ|UPDATE|DELETE
12 // READ|WRITE
13 // READ|WRITE|DELETE
14 // READ|WRITE|UPDATE
15 // READ|WRITE|DELETE|UPDATE
How I think this work is as follow:
Decimal Hexadecimal
3 00000011
Because the two last bits are 1 I am assuming that those users having 3 will have UPDATE|DELETE permissions (see table above). Is that right? If not what's the right way to translate from decimal to bit-mask?
0 = NONE is a special case which can be checked by simple comparison.
If you want to ask the question is constant cn with the value of 2^(n-1) set, then we do this with (1 = yes, 0 = no, % = modulo):
(value / cn) % 2
If we want to get all flags that are set, you can do this with the following pseudo code:
c := 1
while value > 0
if value % 2 = 1
// constant c is set
...
end if
value := value / 2
c := c * 2
end while

About pointers and ASCII code

im learning more about c language and i have 1 doubt about 1 code that i have seen.
main(){
int i = (65*256+66)*256+67;
int* pi;
char* pc;
pi = &i;
pc = (char*)pi;
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
}
Output is: C B A
I know that ASCII code of A is 65, B is 66, and C is 67 but the variable i is none of them.
If i put variable i=65, the output is just A and dont show B or C, why?
And i would like to know why this code have that output. Thanks for any help.
The line
int i = (65*256+66)*256+67;
turns i into the following
00000000 01000001 01000010 01000011
int = 4 bytes or 4 groups of 8 bits
char = 1 byte or 1 group of 8 bits.
What happens is that a char pointer is used to point to a subset of the original int bits.
At first the pointer points to the 8 least significant bits (the group to the right).
And the letter C is printed. Then, the pointer it self is incremented by 1 which makes it point to the next group of 8 bits in the memory which happens to be B. And once more for the A.
*256 means left shift by 8 bit (1 byte) so the line
int i = (65*256+66)*256+67;
actually put A,B,C on 3 adjacent bytes in memory
then pi pointer made point to the address of integer i, then same address down cast to char pointer pc, so pc actually hold the address to a byte that contains 'A', and of course if you add 1 and 2 to the address that means the adjacent 'B' and 'C' get pointed to and print out.
EDIT: just to clarify a bit more int is 32 bit long but char is 8 bit, that's why u need a char pointer to represent an address valid for 8 bit long.
Characters are stored as bytes, as you probably know. The initializing of the variable 'i' has the following meaning:
65*256 // store 65 ('A') and left shift it by 8 byte (= '*256')
(65*256+66)*256 // add 66 ('B') and shift the whole thing again
(65*256+66)*256+67 // add 67 ('C')
'pi' is initialized as a INT pointer to 'i'
'pc' is initialized as a CHAR pointer to 'pi'
So 'pc' then holds the address of the beginning of the 3 bytes stored in 'i', which holds 'A'.
By adding 1 and 2 to the address in pc, you get the second and third bytes (containing 'B' and 'C'), as follows:
printf("%c %c %c \n", *pc, *(pc+1), *(pc+2));
Working on the bits here ;D

Tricky conditional maths

This one is tricky to me:
I have four groups of 8 LEDs. A is 1-8, B is 9-16, C is 17-24, and D is 25-32.
I'm trying to figure out how to write a conditional where
i = 0 //this would be the LED number
loop {
i = //gets updated here
if (i is in the first group) {
// do stuff
} else {
//do other stuff
}
}
Basically, I need to check an LED before it is turned off to see if it is in the same group as the new LED that is being lit.
If it is in the same group, it will be turned off, if it is NOT in the same group it needs to stay on.
So math-wise I need to see if the number is between a certain range. I guess I could just write four versions
if (i >=8)
...
if(i <=9 && >=16)
...
etc, but that doesn't seem very tidy...
Use integer division. Subtract 1 from both values then integer divide by 8. If they're the same result then both LEDs are in the same bank.
def samebank(i, j):
return ((i - 1) // 8) == ((j - 1) // 8)
GetLedGroup(i)
string[] arrLed = {"A","B","C","D"};
return arrLed[Math.floor(i/8)-1];

Resources